gcc compile options used the code from affecting this article: http: //xfocus.org Author: alert7
Test Environment Redhat 6.2 ★ Preface This article discusses some of GCC's commonly compiled options to code. Of course, the code has changed, and its memory layout will change, and the Exploit will make a corresponding change. GCC's compilation option is too much, and this text is verified for several most common options. ★ Demo [alert7 @ redhat62 alert7] $ cat> test.c #include
Void Hi (Void)
{
Printf ("hi");
}
Int main (int Argc, char * argv [])
{
Hi ();
Return 0;
}
★ General situation
[Alert7 @ redhat62 alert7] $ gcc -o test test.c
[alert7 @ redhat62 alert7] $ wc -c test
11773 TEST
[alert7 @ redhat62 alert7] $ gdb -q test
(GDB) disass main
Dump of assembler code for function main:
0x80483e4
: PUSH% EBP
0x80483e5
: MOV% ESP,% EBP
0x80483e7
: Call 0x80483d0
0x80483ec
: XOR% EAX,% EAX
0x80483ee
: JMP 0x80483F0
0x80483f0
: Leave
0x80483f1
: RET
....
End of assembler dump.
(GDB) Disass Hi
Dump of assembler code for function hi:
0x80483d0
: PUSH% EBP
0x80483d1
: MOV% ESP,% EBP
0x80483d3
: Push $ 0x8048450
0x80483d8
: Call 0x8048308
0x80483DD
: Add $ 0x4,% ESP
0x80483e0
: Leave
0x80483e1
: RET
0x80483e2
: MOV% ESI,% ESI
End of assembler dump.
Take a look at some memory images
(Memory high site)
------
| bffffbc4 | ARGV address (ie argv [0] address)
0xBffFFB84 --------
| 00000001 | ARGC value
0xBffFFB80 --------
| 400309CB | Main return address
0xBffffb7c ------ <- ESP before calling the main function
| bffffb98 | EBP before calling the main function
0xBffFFB78 ------ <- main function EBP
| 080483EC | Hi () return address
0xBffffB74 --------
| bffffb78 | ESP before calling hi ()
0xBffffb70 --------
| 08048450 | "hi" address
0xBffFFB6C --------
| ... |
(Memory low)
The operation made by the Leave instruction is equivalent to the MOV ESP, EBP and POP EBP
The operation made by the RET instruction is equivalent to POP EIP
★ -o compilation option
With `-o ', The Compiler Tries To Reduce Code Size and Execution Time.
When You Specify `-o ', The Two Options` -fthread-jumps' and`-fdefer-pop' is Turned ON
Optimize, reduce code size and execution time
[alert7 @ redhat62 alert7] $ gcc -o -o test test.c
[alert7 @ redhat62 alert7] $ wc -c test
11757 TEST
[alert7 @ redhat62 alert7] $ gdb -q test
(GDB) disass main
Dump of assembler code for function main:
0x80483d8
: PUSH% EBP
0x80483d9
: MOV% ESP,% EBP
0x80483dB
: Call 0x80483c8
0x80483e0
: XOR% EAX,% EAX
0x80483e2
: Leave
0x80483e3
: RET
0x80483e4
: NOP
...
End of assembler dump.
(GDB) Disass Hi
Dump of assembler code for function hi:
0x80483c8
: PUSH% EBP
0x80483c9
: MOV% ESP,% EBP
0x80483cb
: Push $ 0x8048440
0x80483d0
: Call 0x8048308
0x80483d5
: Leave
0x80483d6
: RET
0x80483d7
: NOP
End of assembler dump.
In Main (), an JMP instruction is optimized, it is clear that this instruction is unwanted.
In hi (), put the add $ 0x4,% ESP, will this not balance the Stack?
Take a look at some memory images
(Memory high site)
------
| bffffbc4 | ARGV address (ie argv [0] address)
0xBffFFB84 --------
| 00000001 | ARGC value
0xBffFFB80 --------
| 400309CB | Main return address
0xBffffb7c ------ <- ESP before calling the main function
| bffffb98 | EBP before calling the main function
0xBffFFB78 ------ <- main function EBP
| 080483E0 | Hi () return address
0xBffffB74 --------
| bffffb78 | ESP before calling hi ()
0xBffffb70 --------
| 08048440 | "hi" address
0xBffFFB6C --------
| ... |
(Memory low)
The operation made by the Leave instruction is equivalent to putting the MOV ESP, EBP then POP EBP
Seeing the Leave instruction does not have, first put EBP -> ESP, then POP EBP, so even if
In the process of stacking ESP, EBP is unbalanced, but as long as it returns the Leave instruction
It will be balanced, so it is no problem with add $ 0x4,% ESP.
★ -O2 compilation option
-O2 Optimize Even More. Nearly All Supported Optimizations That Do
Not Involve a Space-Speed TradeOff Are Performed. Loop Unrolling
And Function Inlineing Are Not Done, for Example. As Compared to -o, this Option Increases Both Compiration Time and The Performance of
The generated code.
[alert7 @ redhat62 alert7] $ gcc -o2 -o test test.c
[alert7 @ redhat62 alert7] $ wc -c test
11757 TEST
[alert7 @ redhat62 alert7] $ gdb -q test
(GDB) disass main
Dump of assembler code for function main:
0x80483d8
: PUSH% EBP
0x80483d9
: MOV% ESP,% EBP
0x80483dB
: Call 0x80483c8
0x80483e0
: XOR% EAX,% EAX
0x80483e2
: Leave
0x80483e3
: RET
...
0x80483ef
: NOP
End of assembler dump.
(GDB) Disass Hi
Dump of assembler code for function hi:
0x80483C8
: PUSH% EBP
0x80483c9
: MOV% ESP,% EBP
0x80483cb
: Push $ 0x8048440
0x80483d0
: Call 0x8048308
0x80483d5
: Leave
0x80483d6
: RET
0x80483d7
: NOP
End of assembler dump.
Since the program is relatively simple, the optimization is not optimized, so the same as the -o.
★ -fomit-frame-pointer compile options
-FOMIT-FRAME-POINTER
Don't Keep The Frame Pointer In a Register for Functions
That Don't Need One. this Avoids the Instructions to Save,
Set up and restore frame points; it also makes an extra
Register Available In Many Functions. It Also Makes
Debugging Impossible on Most Machines.
Ignore the frame pointer. This does not need to save, install, and restore EBP in the program. This EBP is also one
Free's register, you can use it in a function.
[Alert7 @ redhat62 alert7] $ gcc -fomit-frame-pointer -o test test.c
[alert7 @ redhat62 alert7] $ wc -c test
11773 TEST
[alert7 @ redhat62 alert7] $ gdb -q test
(GDB) disass main
Dump of assembler code for function main:
0x80483e0
: Call 0x80483d0
0x80483e5
: XOR% EAX,% EAX
0x80483e7
: JMP 0x80483F0
0x80483e9
: LEA 0x0 (% ESI, 1),% ESI
0x80483f0
: RET
....
End of assembler dump.
(GDB) Disass Hi
Dump of assembler code for function hi:
0x80483d0
: Push $ 0x80484500x80483d5
: Call 0x8048308
0x80483da
: Add $ 0x4,% ESP
0x80483DD
: RET
0x80483de
: MOV% ESI,% ESI
End of assembler dump.
The following instructions have been removed in main () and hi ()
PUSH% EBP
MOV% ESP,% EBP // These two instructions installation
Leave // This instruction is restored
Take a look at some memory images
(Memory high site)
------
| bffffbc4 | ARGV address (ie argv [0] address)
0xBffFFB84 --------
| 00000001 | ARGC value
0xBffFFB80 --------
| 400309CB | Main return address
0xBffFFFB7C --------
| 080483E5 | Hi () return address
0xBffFFB78 --------
| 08048450 | "hi" string address
0xBffffB74 --------
| ... |
(Memory low)
There is no Save an EBP for the upper execution environment.
★ -fomit-frame-pointer &&-od
-FOTIMIT-FRAME-POINTER Compile options have been removed
PUSH% EBP
MOV% ESP,% EBP // These two instructions installation
Leave // This instruction is restored
-O2 compilation options have been removed
Add $ 0x4,% ESP
If the two add together, will these four instructions come together, so that the Stack is unbalanced?
[Alert7 @ redhat62 alert7] $ gcc -fomit-frame-pointer -O2 -o test test.c
[alert7 @ redhat62 alert7] $ wc -c test
11741 TEST
[alert7 @ redhat62 alert7] $ gdb -q test
(GDB) disass main
Dump of assembler code for function main:
0x80483d8
: Call 0x80483c8
0x80483DD
: XOR% EAX,% EAX
0x80483DF
: RET
End of assembler dump.
(GDB) Disass Hi
Dump of assembler code for function hi:
0x80483c8
: Push $ 0x8048430
0x80483cd
: Call 0x8048308
0x80483d2
: Add $ 0x4,% ESP
0x80483d5
: RET
0x80483d6
: MOV% ESI,% ESI
End of assembler dump.
Take a look at some memory images
(Memory high site)
------
| bffffbc4 | ARGV address (ie argv [0] address)
0xBffFFB84 --------
| 00000001 | ARGC value
0xBffFFB80 --------
| 400309CB | Main return address
0xBffFFFB7C --------
| 080483DD | Hi () return address
0xBffFFB78 --------
| 08048430 | "Hi" string address
0xBffffB74 --------
| ... |
(Memory low)
At this time, I didn't optimize Add $ 0x4,% ESP. If you optimize it, the whole stack is
The imbalance will be changed, thereby causing a program error.
★ -fpic compilation option
-fpic if supported for the target machine, Emit position-independent
Code, Suitable for Dynamic Linking, Even if Branches Need Large
Displacements.
Generating a location-independent code (PIC), usually used when you create a shared library.
On x86, the symbolic reference of the PIC's code is operated by EBX.
[alert7 @ redhat62 alert7] $ gcc-fpic -o test test.c
[alert7 @ redhat62 alert7] $ wc -c test
11805 Test
[alert7 @ redhat62 alert7] $ gdb -q test
(GDB) disass main
Dump of assembler code for function main:
0x80483f8
: PUSH% EBP
0x80483f9
: MOV% ESP,% EBP
0x80483fb
: push% EBX
0x80483FC
: Call 0x8048401
0x8048401
: POP% EBX / / get the address of the instruction
0x8048402
: Add $ 0x1093,% ebx // This time is stored in the EBX address of the GOT table
0x8048408
: Call 0x80483d0
0x804840d
: XOR% EAX,% EAX
0x804840F
: JMP 0x8048411
0x8048411
: MOV 0xFffffFfc (% EBP),% EBX
0x8048414
: Leave
0x8048415
: RET
...
End of assembler dump.
(GDB) Disass Hi
Dump of assembler code for function hi:
0x80483d0
: PUSH% EBP
0x80483d1
: MOV% ESP,% EBP
0x80483d3
: push% EBX
0x80483d4
: Call 0x80483d9
0x80483d9
: POP% EBX
0x80483da
: Add $ 0x10bb,% EBX
0x80483e0
: LEA 0xffffefdc (% EBX),% EDX
0x80483e6
: MOV% EDX,% EAX
0x80483e8
: push% EAX
0x80483e9
: Call 0x8048308
0x80483ee
: Add $ 0x4,% ESP
0x80483f1
: MOV 0xFffffFfc (% EBP),% EBX
0x80483f4
: Leave
0x80483f5
: RET
0x80483f6
: MOV% ESI,% ESI
End of assembler dump.
Take a look at some memory images
(Memory high site)
------
| bffffbc4 | ARGV address (ie argv [0] address)
0xBffFFB84 --------
| 00000001 | ARGC value
0xBffFFB80 --------
| 400309CB | Main return address
0xBffffb7c ------ <- ESP before calling the main function
| bffffb98 | EBP before calling the main function
0xBffFFB78 ------ <- main function EBP
| 401081 EC | Saved EBX
0xBffffB74 --------
| 0804840d | (stored the next instruction address of Call 0x8048401)
0xBffffb70 -------- | bffffb78 | ESP before calling hi ()
0xBffFFB6C --------
| 08049494 | GOT table address
0xBffffb68 --------
| 08048470 | (Store the next instruction address of Call 0x80483D9)
0xBffffB64 --------
| ... |
(Memory low)
★ -static compilation option
-static
On Systems That Support Dynamic Linking, this prevents
Linking with the shared libraries. on Other Systems,
This Option Has No Effect.
Compile some functions to the program without dynamic links.
[alert7 @ redhat62 alert7] $ gcc -o test -static test.c
[alert7 @ redhat62 alert7] $ wc -c test
962808 TEST
[alert7 @ redhat62 alert7] $ gdb -q test
(GDB) disass main
Dump of assembler code for function main:
0x80481B4
: PUSH% EBP
0x80481B5
: MOV% ESP,% EBP
0x80481B7
: Call 0x80481a0
0x80481BC
: XOR% EAX,% EAX
0x80481BE
: JMP 0x80481C0
0x80481c0
: Leave
0x80481C1
: RET
...
End of assembler dump.
(GDB) Disass Hi
Dump of assembler code for function hi:
0x80481a0
: PUSH% EBP
0x80481a1
: MOV% ESP,% EBP
0x80481a3
: Push $ 0x8071528
0x80481a8
: Call 0x804865c
0x80481ad
: Add $ 0x4,% ESP
0x80481B0
: Leave
0x80481b1
: RET
0x80481b2
: MOV% ESI,% ESI
End of assembler dump.
[alert7 @ redhat62 alert7] $ ldd test
NOT A DYNAMIC EXECUTABLE
-static code has no PLT, GOT is all 0.