Introduction To Intel x86 Assembly, Architecture, Applications, & Alliteration
Introduction To Intel x86 Assembly, Architecture, Applications, & Alliteration
Introduction To Intel x86 Assembly, Architecture, Applications, & Alliteration
About Me
Security nerd - generalist, not specialist Realmz ~1996, Mac OS 8, BEQ->BNE FTW! x86 ~2002 Know or have known ~5 assembly languages(x86, SPARC, ARM, PPC, 68HC12). x86 is by far the most complex. Routinely read assembly when debugging my own code, reading exploit code, and reverse engineering things
4
About You?
Name & Department Why did you want to take the class? If you know you will be applying this knowledge, to which OS and/or development environment?
Agenda
Day 1 - Part 1 - Architecture Introduction, Windows tools Day 1 - Part 2 - Windows Tools & Analysis, Learning New Instructions Day 2 - Part 1 - Linux Tools & Analysis Day 2 - Part 2 - Inline Assembly, Read The Fun Manual, Choose Your Own Adventure
8
Miss Alaineous
Questions: Ask 'em if you got 'em
If you fall behind and get lost and try to tough it out until you understand, it's more likely that you will stay lost, so ask questions ASAP.
Browsing the web and/or checking email during class is a good way to get lost ;) Vote on class schedule. Benevolent dictator clause. It's called x86 because of the progression of Intel chips from 8086, 80186, 80286, etc. I just had to get that out of the way. :)
9
10
Is the same as
.text:00401730 main .text:00401730 .text:00401731 .text:00401733 .text:00401738 .text:0040173E .text:00401741 .text:00401746 .text:00401747
push ebp mov ebp, esp push offset aHelloWorld ; "Hello world\n" call ds:__imp__printf add esp, 4 mov eax, 1234h pop ebp retn
Windows Visual C++ 2005, /GS (buffer overflow protection) option turned off 11 Disassembled with IDA Pro 4.9 Free Version
Is the same as
08048374 <main>: 8048374: 8d 4c 24 04 8048378: 83 e4 f0 804837b: ff 71 fc 804837e: 55 804837f: 89 e5 8048381: 51 8048382: 83 ec 04 8048385: c7 04 24 60 84 04 08 804838c: e8 43 ff ff ff 8048391: b8 2a 00 00 00 8048396: 83 c4 04 8048399: 59 804839a: 5d 804839b: 8d 61 fc 804839e: c3 804839f: 90 nop lea 0x4(%esp),%ecx and $0xfffffff0,%esp pushl -0x4(%ecx) push %ebp mov %esp,%ebp push %ecx sub $0x4,%esp movl $0x8048460,(%esp) call 80482d4 <puts@plt> mov $0x1234,%eax add $0x4,%esp pop %ecx pop %ebp lea -0x4(%ecx),%esp ret
12
Is the same as
_main: 00001fca 00001fcb 00001fcd 00001fce 00001fd1 00001fd6 00001fd7 00001fdd 00001fe0 00001fe5 00001fea 00001fed 00001fee 00001fef
pushl movl pushl subl calll popl leal movl calll movl addl popl leave ret %ebp %esp,%ebp %ebx $0x14,%esp 0x00001fd6 %ebx 0x0000001a(%ebx),%eax %eax,(%esp) 0x00003005 ; symbol stub for: _puts $0x00001234,%eax $0x14,%esp %ebx
Mac OS 10.5.6, GCC 4.0.1 Disassembled from command line with otool -tV
13
Windows Visual C++ 2005, /GS (buffer overflow protection) option turned off Optimize for minimum size (/O1) turned on 14 Disassembled with IDA Pro 4.9 Free Version
Take Heart!
I think that knowing about 20-30 (not counting variations) is good enough that you will have the check the manual very infrequently You've already seen 11 instructions, just in the hello world variations!
15
09
10 11 12 13 14 15
1001b
1010b 1011b 1100b 1101b 1110b 1111b
0x09
0x0A 0x0B 0x0C 0x0D 0x0E 0x0F
17
10110000b : 0xB0 : -?
0x01 to 0x7F positive byte, 0x80 to 0xFF negative byte 0x00000001 to 0x7FFFFFFF positive dword 0x80000000 to 0xFFFFFFFF negative dword
18
Other major architectures are typically RISC Reduced Instruction Set Computer
Typically more registers, less and fixed-size instructions Examples: PowerPC, ARM, SPARC, MIPS
19
Architecture - Endian
Endianness comes from Jonathan Swift's Gulliver's Travels. It doesn't matter which way you eat your eggs :) Little Endian - 0x12345678 stored in RAM little end first. The least significant byte of a word or larger is stored in the lowest address. E.g. 0x78563412
Intel is Little Endian
Book p. 163
Book for this class is Professional Assembly Language by Blum
20
Endianess pictures
Big Endian (Others)
Register FE ED FA CE High Memory Addresses
00 00 CE FA ED FE
00 00 FE ED FA CE
FE ED FA CE
21
Architecture - Registers
Registers are small memory storage areas built into the processor (still volatile memory) 8 general purpose registers + the instruction pointer which points at the next instruction to execute
But two of the 8 are not that general
http://www.sandpile.org/ia32/reg.htm
26
http://www.sandpile.org/ia32/reg.htm
27
Architecture - EFLAGS
EFLAGS register holds many single bit flags. Will only ask you to remember the following for now.
Zero Flag (ZF) - Set if the result of some instruction is zero; cleared otherwise. Sign Flag (SF) - Set equal to the most-significant bit of the result, which is the sign bit of a signed integer. (0 indicates a positive value and 1 indicates a negative value.)
Intel Vol 1 Sec 3.4.3 - page 3-20
28
29
Every other person I had told this to had never heard it either. Thanks to Jon Erickson for cluing me in to this. XCHG instruction is not officially in this class. But if I hadn't just told you what it does, I bet you would have guessed right anyway.
30
The Stack
The stack is a conceptual area of main memory (RAM) which is designated by the OS when a program is started.
Different OS start it at different addresses by convention
A stack is a Last-In-First-Out (LIFO/FILO) data structure where data is "pushed" on to the top of the stack and "popped" off the top. By convention the stack grows toward lower memory addresses. Adding something to the stack means the top of the stack is now at a lower memory address.
31
The Stack 2
As already mentioned, esp points to the top of the stack, the lowest address which is being used
While data will exist at addresses beyond the top of the stack, it is considered undefined
The stack keeps track of which functions were called before the current one, it holds local variables and is frequently used to pass arguments to the next function to be called. A firm understanding of what is happening on the stack is *essential* to understanding a 32 program's operation.
Book p. 120
33
Registers Before
Registers After
eax esp
0x00000003 0x0012FF8C
push eax
Stack Before
eax esp
0x00000003 0x0012FF88
Stack After
0x0012FF90
0x00000001
esp
0x00000002
0x00000003 undef
0x0012FF80
undef
34
Book p. 120
35
Registers Before
eax
esp
0xFFFFFFFF
0x0012FF88
pop eax
Stack Before
Registers After
eax esp
0x00000003 0x0012FF8C
Stack After
0x00000001
esp
0x00000002
undef(0x00000003) undef
0x0012FF80
undef
36
Calling Conventions
How code calls a subroutine is compiler-dependent and configurable. But there are a few conventions. We will only deal with the cdecl and stdcall conventions. More info at
http://en.wikipedia.org/wiki/X86_calling_conventions http://www.programmersheaven.com/2/Calling-conventions
37
Then it changes eip to the address given in the instruction Destination address can be specified in multiple ways
Absolute address Relative address (relative to the end of the instruction)
40
Book p. 132
Pop the top of the stack into eip and add a constant number of bytes to esp
In this form, the instruction is written as ret 0x8, or ret 0x20, etc Typically used by stdcall functions
41
MOV - Move
Can move:
register to register memory to register, register to memory immediate to register, immediate to memory
Never memory to memory! Memory addresses are given in r/m32 form talked about later
Book p. 97
42
main() frame
undef
undef
stack top
Book p. 306
43
main() frame
undef
undef
stack top
44
stack bottom Local Variables Caller-Save Registers Arguments to Pass to Callee Caller's saved return address
main() frame
undef
undef
stack top
45
stack bottom Local Variables Caller-Save Registers Arguments to Pass to Callee Caller's saved return address Saved Frame Pointer
main() frame
foo()'s frame
undef
stack top
46
stack bottom Local Variables Caller-Save Registers Arguments to Pass to Callee Caller's saved return address Saved Frame Pointer
main() frame
foo()'s frame
undef
stack top
47
Callee-Save Registers
Local Variables
stack bottom Saved Frame Pointer Callee-Save Registers Local Variables Caller-Save Registers Arguments to Pass to Callee
main() frame
foo()'s frame
undef
stack top
48
stack bottom
undef
stack top
49
main() frame
foo()'s frame
bar()'s frame
stack top
50
Example1.c
The stack frames in this example will be very simple. Only saved frame pointer (ebp) and saved return addresses (eip).
//Example1 - using the stack //to call subroutines //New instructions: //push, pop, call, ret, mov int sub(){ return 0xbeef; } int main(){ sub(); return 0xf00d; }
sub: 00401000 push 00401001 mov 00401003 mov 00401008 pop 00401009 ret main: 00401010 push 00401011 mov 00401013 call 00401018 mov 0040101D pop 0040101E ret
51
Example1.c 1:
EIP = 00401010, but no instruction yet executed Key:
eax ebp esp
0x003435C0
0x0012FFB8
0x0012FF6C
sub: 00401000 push 00401001 mov 00401003 mov 00401008 pop 00401009 ret main: 00401010 push 00401011 mov 00401013 call 00401018 mov 0040101D pop 0040101E ret
undef undef
0x0012FF5C
0x0012FF58
undef
undef
52
Example1.c 2
eax ebp esp
sub: 00401000 push 00401001 mov 00401003 mov 00401008 pop 00401009 ret main: 00401010 push 00401011 mov 00401013 call 00401018 mov 0040101D pop 0040101E ret
0x0012FF5C
0x0012FF58
undef
undef
53
Example1.c 3
eax ebp esp
0x003435C0
0x0012FF68
0x0012FF68
sub: 00401000 push 00401001 mov 00401003 mov 00401008 pop 00401009 ret main: 00401010 push 00401011 mov 00401013 call 00401018 mov 0040101D pop 0040101E ret
0x0012FF5C
0x0012FF58
undef
undef
54
Example1.c 4
eax ebp esp
0x003435C0
0x0012FF68
0x0012FF64
sub: 00401000 push 00401001 mov 00401003 mov 00401008 pop 00401009 ret main: 00401010 push 00401011 mov 00401013 call 00401018 mov 0040101D pop 0040101E ret
0x0012FF5C
0x0012FF58
undef
undef
55
Example1.c 5
eax ebp esp
0x003435C0
0x0012FF68
0x0012FF60
sub: 00401000 push 00401001 mov 00401003 mov 00401008 pop 00401009 ret main: 00401010 push 00401011 mov 00401013 call 00401018 mov 0040101D pop 0040101E ret
0x0012FF5C
0x0012FF58
undef
undef
56
Example1.c 6
eax ebp esp
0x003435C0
0x0012FF60
0x0012FF60
sub: 00401000 push 00401001 mov 00401003 mov 00401008 pop 00401009 ret main: 00401010 push 00401011 mov 00401013 call 00401018 mov 0040101D pop 0040101E ret
0x0012FF5C
0x0012FF58
undef
undef
57
sub push ebp mov ebp, esp mov eax, 0BEEFh pop ebp retn main push ebp mov ebp, esp call _sub mov eax, 0F00Dh pop ebp retn
sub's frame
(only saved frame pointer, because it doesn't call anything else, and doesn't have local variables)
undef
undef
58
Example1.c 7
eax ebp esp
sub: 00401000 push 00401001 mov 00401003 mov 00401008 pop 00401009 ret main: 00401010 push 00401011 mov 00401013 call 00401018 mov 0040101D pop 0040101E ret
0x0012FF5C
0x0012FF58
undef
undef
59
Example1.c 8
eax ebp esp
0x0000BEEF
0x0012FF68
0x0012FF64
sub: 00401000 push 00401001 mov 00401003 mov 00401008 pop 00401009 ret main: 00401010 push 00401011 mov 00401013 call 00401018 mov 0040101D pop 0040101E ret
0x0012FF5C
0x0012FF58
undef
undef
60
Example1.c 9
eax ebp esp
0x0000BEEF
0x0012FF68
0x0012FF68
sub: 00401000 push 00401001 mov 00401003 mov 00401008 pop 00401009 ret main: 00401010 push 00401011 mov 00401013 call 00401018 mov 0040101D pop 0040101E ret
0x0012FF5C
0x0012FF58
undef
undef
61
Example1.c 9
eax ebp esp
0x0000F00D
0x0012FF68
0x0012FF68
sub: 00401000 push 00401001 mov 00401003 mov 00401008 pop 00401009 ret main: 00401010 push 00401011 mov 00401013 call 00401018 mov 0040101D pop 0040101E ret
0x0012FF5C
0x0012FF58
undef
undef
62
Example1.c 10
eax ebp esp
0x0000F00D
0x0012FFB8
0x0012FF6C
sub: 00401000 push 00401001 mov 00401003 mov 00401008 pop 00401009 ret main: 00401010 push 00401011 mov 00401013 call 00401018 mov 0040101D pop 0040101E ret
0x0012FF5C
0x0012FF58
undef
undef
63
Example1.c 11
eax ebp esp
0x0000F00D
0x0012FFB8
0x0012FF70
sub: 00401000 push 00401001 mov 00401003 mov 00401008 pop 00401009 ret main: 00401010 push 00401011 mov 00401013 call 00401018 mov 0040101D pop 0040101E ret
0x0012FF5C
0x0012FF58
undef
undef
64
Execution would continue at the value ret removed from the stack: 0x004012E8
Example1 Notes
sub() is deadcode - its return value is not used for anything, and main always returns 0xF00D. If optimizations are turned on in the compiler, it would remove sub() Because there are no input parameters to sub(), there is no difference whether we compile as cdecl vs stdcall calling conventions
65
67
68
69
70
71
72
Unfortunately the debug information format alters the code which gets generated too much, making it not as simple as I would like for this class.
73
This would just add extra complexity to the asm which we don't want for now
74
75
76
Another thing where I found out the hard way that it will increase the asm complexity
77
Building project
78
Building project 2
Information about whether the build succeeded will be here. If it fails, a separate error tab will open up
79
80
Step into
Step over
Step out
81
Showing assembly
Watching registers
Note that it knows the ebp register is going to be used in this instruction
83
Showing registers
85
Right click on the body of the data in the window and make sure everything's set like this
Set to 1
86
87
More info: Intel v2a, Section 2.1.5 page 2-4 in particular Tables 2-2 and 2-3
89
90
Adds or Subtracts, just as expected Destination operand can be r/m32 or register Source operand can be r/m32 or register or immediate No source and destination as r/m32s, because that could allow for memory to memory transfer, which isn't allowed on x86 Evaluates the operation as if it were on signed AND unsigned data, and sets flags as appropriate. Instructions modify OF, SF, ZF, AF, PF, and CF flags add esp, 8 sub eax, [ebx*2]
91
Example2.c - 1
.text:00000000 _sub: .text:00000001 .text:00000003 .text:00000006 .text:00000009 .text:0000000C .text:0000000D .text:00000010 _main: .text:00000011 .text:00000013 .text:00000014 .text:00000017 .text:0000001A .text:0000001B .text:00000021 .text:00000024 .text:00000027 .text:0000002A .text:0000002B .text:0000002E .text:0000002F .text:00000034 .text:00000037 .text:00000039 .text:0000003A push ebp mov ebp, esp mov eax, [ebp+8] mov ecx, [ebp+0Ch] lea eax, [ecx+eax*2] pop ebp retn push ebp mov ebp, esp push ecx mov eax, [ebp+0Ch] mov ecx, [eax+4] push ecx call dword ptr ds:__imp__atoi add esp, 4 mov [ebp-4], eax mov edx, [ebp-4] push edx mov eax, [ebp+8] push eax call _sub add esp, 8 mov esp, ebp pop ebp retn
eax
0xcafe
ecx
edx ebp esp
0xbabe
0xfeed 0x0012FF50 0x0012FF24
0x0012FF20
undef
undef
0x0012FF0C undef
92
Example2.c - 2
.text:00000000 _sub: .text:00000001 .text:00000003 .text:00000006 .text:00000009 .text:0000000C .text:0000000D .text:00000010 _main: .text:00000011 .text:00000013 .text:00000014 .text:00000017 .text:0000001A .text:0000001B .text:00000021 .text:00000024 .text:00000027 .text:0000002A .text:0000002B .text:0000002E .text:0000002F .text:00000034 .text:00000037 .text:00000039 .text:0000003A push ebp mov ebp, esp mov eax, [ebp+8] mov ecx, [ebp+0Ch] lea eax, [ecx+eax*2] pop ebp retn push ebp mov ebp, esp push ecx mov eax, [ebp+0Ch] mov ecx, [eax+4] push ecx call dword ptr ds:__imp__atoi add esp, 4 mov [ebp-4], eax mov edx, [ebp-4] push edx mov eax, [ebp+8] push eax call _sub add esp, 8 mov esp, ebp pop ebp retn
eax
0xcafe
ecx
edx ebp esp
0xbabe
0xfeed 0x0012FF24 0x0012FF24
0x0012FF20
undef
undef undef
undef
0x0012FF0C undef
93
Example2.c - 3
.text:00000000 _sub: .text:00000001 .text:00000003 .text:00000006 .text:00000009 .text:0000000C .text:0000000D .text:00000010 _main: .text:00000011 .text:00000013 .text:00000014 .text:00000017 Caller-save, or .text:0000001A space for local .text:0000001B var? This time it .text:00000021 turns out to be .text:00000024 space for local var .text:00000027 .text:0000002A since there is no .text:0000002B corresponding pop, .text:0000002E and the address is .text:0000002F used later to refer .text:00000034 to the value we .text:00000037 know is stored in a. .text:00000039 .text:0000003A push ebp mov ebp, esp mov eax, [ebp+8] mov ecx, [ebp+0Ch] lea eax, [ecx+eax*2] pop ebp retn push ebp mov ebp, esp push ecx mov eax, [ebp+0Ch] mov ecx, [eax+4] push ecx call dword ptr ds:__imp__atoi add esp, 4 mov [ebp-4], eax mov edx, [ebp-4] push edx mov eax, [ebp+8] push eax call _sub add esp, 8 mov esp, ebp pop ebp retn
eax
0xcafe
ecx
edx ebp esp
0xbabe
0xfeed 0x0012FF24 0x0012FF20
0x0012FF20
0xbabe (int a)
undef undef
undef
0x0012FF0C undef
94
Example2.c - 4
.text:00000000 _sub: .text:00000001 .text:00000003 .text:00000006 .text:00000009 .text:0000000C .text:0000000D .text:00000010 _main: .text:00000011 .text:00000013 .text:00000014 .text:00000017 .text:0000001A .text:0000001B .text:00000021 .text:00000024 .text:00000027 .text:0000002A .text:0000002B .text:0000002E .text:0000002F .text:00000034 .text:00000037 .text:00000039 .text:0000003A push ebp mov ebp, esp mov eax, [ebp+8] mov ecx, [ebp+0Ch] lea eax, [ecx+eax*2] pop ebp retn push ebp mov ebp, esp push ecx mov eax, [ebp+0Ch] mov ecx, [eax+4] push ecx call dword ptr ds:__imp__atoi add esp, 4 mov [ebp-4], eax mov edx, [ebp-4] push edx mov eax, [ebp+8] push eax call _sub add esp, 8 mov esp, ebp pop ebp retn
eax
0x12FFB0
ecx
edx ebp esp
0xbabe
0xfeed 0x0012FF24 0x0012FF20
0x0012FF20
0xbabe (int a)
undef undef
undef
0x0012FF0C undef
95
Example2 - 5
.text:00000000 _sub: .text:00000001 .text:00000003 .text:00000006 .text:00000009 .text:0000000C .text:0000000D .text:00000010 _main: .text:00000011 .text:00000013 .text:00000014 .text:00000017 .text:0000001A .text:0000001B .text:00000021 .text:00000024 .text:00000027 .text:0000002A (I chose .text:0000002B 0x12FFD4 .text:0000002E .text:0000002F arbitrarily since .text:00000034 it's out of the .text:00000037 stack scope .text:00000039 we're currently .text:0000003A push ebp mov ebp, esp mov eax, [ebp+8] mov ecx, [ebp+0Ch] lea eax, [ecx+eax*2] pop ebp retn push ebp mov ebp, esp push ecx mov eax, [ebp+0Ch] mov ecx, [eax+4] push ecx call dword ptr ds:__imp__atoi add esp, 4 mov [ebp-4], eax mov edx, [ebp-4] push edx mov eax, [ebp+8] push eax call _sub add esp, 8 mov esp, ebp pop ebp retn
eax
0x12FFB0
ecx
edx ebp esp
0x12FFD4(arbitrary)
0xfeed 0x0012FF24 0x0012FF20
0x0012FF20
0xbabe (int a)
undef undef
undef
0x0012FF0C undef
looking at)
96
Example2 - 6
.text:00000000 _sub: .text:00000001 .text:00000003 .text:00000006 .text:00000009 .text:0000000C Saving some .text:0000000D slides .text:00000010 _main: This will push the .text:00000011 address of the .text:00000013 string at argv[1] .text:00000014 (0x12FFD4). atoi() .text:00000017 will read the string .text:0000001A and turn in into an .text:0000001B int, put that int in .text:00000021 eax, and return. .text:00000024 Then the adding 4 .text:00000027 to esp will negate .text:0000002A the having pushed .text:0000002B the input parameter .text:0000002E and make .text:0000002F 0x12FF1C .text:00000034 undefined again .text:00000037 (this is indicative of .text:00000039 cdecl) .text:0000003A push ebp mov ebp, esp mov eax, [ebp+8] mov ecx, [ebp+0Ch] lea eax, [ecx+eax*2] pop ebp retn push ebp mov ebp, esp push ecx mov eax, [ebp+0Ch] mov ecx, [eax+4] push ecx call dword ptr ds:__imp__atoi add esp, 4 mov [ebp-4], eax mov edx, [ebp-4] push edx mov eax, [ebp+8] push eax call _sub add esp, 8 mov esp, ebp pop ebp retn
eax
0x100 (arbitrary)
ecx
edx ebp esp
0x12FFD4
0xfeed 0x0012FF24 0x0012FF20
0x0012FF20
0xbabe (int a)
undef undef
undef
0x0012FF0C undef
97
Example2 - 7
.text:00000000 _sub: .text:00000001 .text:00000003 .text:00000006 .text:00000009 .text:0000000C .text:0000000D .text:00000010 _main: .text:00000011 .text:00000013 .text:00000014 .text:00000017 First setting a .text:0000001A equal to the return .text:0000001B value. Then .text:00000021 pushing a as the .text:00000024 second parameter .text:00000027 in sub(). We can .text:0000002A see an obvious .text:0000002B optimization would .text:0000002E have been to .text:0000002F replace the last two .text:00000034 instructions with .text:00000037 push eax. .text:00000039 .text:0000003A push ebp mov ebp, esp mov eax, [ebp+8] mov ecx, [ebp+0Ch] lea eax, [ecx+eax*2] pop ebp retn push ebp mov ebp, esp push ecx mov eax, [ebp+0Ch] mov ecx, [eax+4] push ecx call dword ptr ds:__imp__atoi add esp, 4 mov [ebp-4], eax mov edx, [ebp-4] push edx mov eax, [ebp+8] push eax call _sub add esp, 8 mov esp, ebp pop ebp retn
eax
0x100
ecx
edx ebp esp
0x12FFD4
0x100 0x0012FF24 0x0012FF1C
0x0012FF20
0x100 (int a)
undef undef
undef
0x0012FF0C undef
98
Example2 - 8
.text:00000000 _sub: .text:00000001 .text:00000003 .text:00000006 .text:00000009 .text:0000000C .text:0000000D .text:00000010 _main: .text:00000011 .text:00000013 .text:00000014 .text:00000017 .text:0000001A .text:0000001B .text:00000021 .text:00000024 .text:00000027 .text:0000002A .text:0000002B Pushing argc .text:0000002E .text:0000002F as the first .text:00000034 parameter (int .text:00000037 x) to sub() .text:00000039 .text:0000003A push ebp mov ebp, esp mov eax, [ebp+8] mov ecx, [ebp+0Ch] lea eax, [ecx+eax*2] pop ebp retn push ebp mov ebp, esp push ecx mov eax, [ebp+0Ch] mov ecx, [eax+4] push ecx call dword ptr ds:__imp__atoi add esp, 4 mov [ebp-4], eax mov edx, [ebp-4] push edx mov eax, [ebp+8] push eax call _sub add esp, 8 mov esp, ebp pop ebp retn
eax
0x2
ecx
edx ebp esp
0x12FFD4
0x100 0x0012FF24 0x0012FF18
0x0012FF20
0x100 (int a)
0x2 (int x) undef
undef
0x0012FF0C undef
99
Example2 - 9
.text:00000000 _sub: .text:00000001 .text:00000003 .text:00000006 .text:00000009 .text:0000000C .text:0000000D .text:00000010 _main: .text:00000011 .text:00000013 .text:00000014 .text:00000017 .text:0000001A .text:0000001B .text:00000021 .text:00000024 .text:00000027 .text:0000002A .text:0000002B .text:0000002E .text:0000002F .text:00000034 .text:00000037 .text:00000039 .text:0000003A push mov mov mov lea pop retn push mov push mov mov push call add mov mov push mov push call add mov pop retn ebp ebp, esp eax, [ebp+8] ecx, [ebp+0Ch] eax, [ecx+eax*2] ebp ebp ebp, esp ecx eax, [ebp+0Ch] ecx, [eax+4] ecx dword ptr ds:__imp__atoi esp, 4 [ebp-4], eax edx, [ebp-4] edx eax, [ebp+8] eax _sub esp, 8 esp, ebp ebp
eax
0x2
ecx
edx ebp esp
0x12FFD4
0x100 0x0012FF24 0x0012FF14
0x0012FF20
0x100 (int a)
0x2 (int x) 0x00000034
undef
0x0012FF0C undef
100
Example2 - 10
.text:00000000 _sub: .text:00000001 .text:00000003 .text:00000006 .text:00000009 .text:0000000C .text:0000000D .text:00000010 _main: .text:00000011 .text:00000013 .text:00000014 .text:00000017 .text:0000001A .text:0000001B .text:00000021 .text:00000024 .text:00000027 .text:0000002A .text:0000002B .text:0000002E .text:0000002F .text:00000034 .text:00000037 .text:00000039 .text:0000003A push ebp mov ebp, esp mov eax, [ebp+8] mov ecx, [ebp+0Ch] lea eax, [ecx+eax*2] pop ebp retn push ebp mov ebp, esp push ecx mov eax, [ebp+0Ch] mov ecx, [eax+4] push ecx call dword ptr ds:__imp__atoi add esp, 4 mov [ebp-4], eax mov edx, [ebp-4] push edx mov eax, [ebp+8] push eax call _sub add esp, 8 mov esp, ebp pop ebp retn
eax
0x2
ecx
edx ebp esp
0x12FFD4
0x100 0x0012FF10 0x0012FF10
0x0012FF20
0x100 (int a)
0x2 (int x) 0x00000034
0x0012FF24(saved ebp)
0x0012FF0C undef
101
Example2 - 11
.text:00000000 _sub: .text:00000001 .text:00000003 .text:00000006 Move x into eax, .text:00000009 and y into ecx. .text:0000000C .text:0000000D .text:00000010 _main: .text:00000011 .text:00000013 .text:00000014 .text:00000017 .text:0000001A .text:0000001B .text:00000021 .text:00000024 .text:00000027 .text:0000002A .text:0000002B .text:0000002E .text:0000002F .text:00000034 .text:00000037 .text:00000039 .text:0000003A push ebp mov ebp, esp mov eax, [ebp+8] mov ecx, [ebp+0Ch] lea eax, [ecx+eax*2] pop ebp retn push ebp mov ebp, esp push ecx mov eax, [ebp+0Ch] mov ecx, [eax+4] push ecx call dword ptr ds:__imp__atoi add esp, 4 mov [ebp-4], eax mov edx, [ebp-4] push edx mov eax, [ebp+8] push eax call _sub add esp, 8 mov esp, ebp pop ebp retn
eax
ecx
edx ebp esp
0x100
0x100 0x0012FF10 0x0012FF10
0x0012FF20
0x100 (int a)
0x2 (int x) 0x00000034
0x0012FF0C undef
102
Example2 - 12
.text:00000000 _sub: .text:00000001 .text:00000003 .text:00000006 .text:00000009 Set the return value .text:0000000C (eax) to 2*x + y. .text:0000000D Note: neither .text:00000010 _main: pointer arith, nor an .text:00000011 address which .text:00000013 was loaded. Just an .text:00000014 afficient way to do a .text:00000017 calculation. .text:0000001A .text:0000001B .text:00000021 .text:00000024 .text:00000027 .text:0000002A .text:0000002B .text:0000002E .text:0000002F .text:00000034 .text:00000037 .text:00000039 .text:0000003A push ebp mov ebp, esp mov eax, [ebp+8] mov ecx, [ebp+0Ch] lea eax, [ecx+eax*2] pop ebp retn push ebp mov ebp, esp push ecx mov eax, [ebp+0Ch] mov ecx, [eax+4] push ecx call dword ptr ds:__imp__atoi add esp, 4 mov [ebp-4], eax mov edx, [ebp-4] push edx mov eax, [ebp+8] push eax call _sub add esp, 8 mov esp, ebp pop ebp retn
eax
0x104
ecx
edx ebp esp
0x100
0x100 0x0012FF10 0x0012FF10
0x0012FF20
0x100 (int a)
0x2 (int x) 0x00000034
0x0012FF0C undef
103
Example2 - 13
.text:00000000 _sub: .text:00000001 .text:00000003 .text:00000006 .text:00000009 .text:0000000C .text:0000000D .text:00000010 _main: .text:00000011 .text:00000013 .text:00000014 .text:00000017 .text:0000001A .text:0000001B .text:00000021 .text:00000024 .text:00000027 .text:0000002A .text:0000002B .text:0000002E .text:0000002F .text:00000034 .text:00000037 .text:00000039 .text:0000003A push ebp mov ebp, esp mov eax, [ebp+8] mov ecx, [ebp+0Ch] lea eax, [ecx+eax*2] pop ebp retn push ebp mov ebp, esp push ecx mov eax, [ebp+0Ch] mov ecx, [eax+4] push ecx call dword ptr ds:__imp__atoi add esp, 4 mov [ebp-4], eax mov edx, [ebp-4] push edx mov eax, [ebp+8] push eax call _sub add esp, 8 mov esp, ebp pop ebp retn
eax
0x104
ecx
edx ebp esp
0x100
0x100 0x0012FF24 0x0012FF14
0x0012FF20
0x100 (int a)
0x2 (int x) 0x00000034
undef
0x0012FF0C undef
104
Example2 - 14
.text:00000000 _sub: .text:00000001 .text:00000003 .text:00000006 .text:00000009 .text:0000000C .text:0000000D .text:00000010 _main: .text:00000011 .text:00000013 .text:00000014 .text:00000017 .text:0000001A .text:0000001B .text:00000021 .text:00000024 .text:00000027 .text:0000002A .text:0000002B .text:0000002E .text:0000002F .text:00000034 .text:00000037 .text:00000039 .text:0000003A push ebp mov ebp, esp mov eax, [ebp+8] mov ecx, [ebp+0Ch] lea eax, [ecx+eax*2] pop ebp retn push ebp mov ebp, esp push ecx mov eax, [ebp+0Ch] mov ecx, [eax+4] push ecx call dword ptr ds:__imp__atoi add esp, 4 mov [ebp-4], eax mov edx, [ebp-4] push edx mov eax, [ebp+8] push eax call _sub add esp, 8 mov esp, ebp pop ebp retn
eax
0x104
ecx
edx ebp esp
0x100
0x100 0x0012FF24 0x0012FF18
0x0012FF20
0x100 (int a)
0x2 (int x) undef
undef
0x0012FF0C undef
105
Example2 - 15
.text:00000000 _sub: .text:00000001 .text:00000003 .text:00000006 .text:00000009 .text:0000000C .text:0000000D .text:00000010 _main: .text:00000011 .text:00000013 .text:00000014 .text:00000017 .text:0000001A .text:0000001B .text:00000021 .text:00000024 .text:00000027 .text:0000002A .text:0000002B .text:0000002E .text:0000002F .text:00000034 .text:00000037 .text:00000039 .text:0000003A push ebp mov ebp, esp mov eax, [ebp+8] mov ecx, [ebp+0Ch] lea eax, [ecx+eax*2] pop ebp retn push ebp mov ebp, esp push ecx mov eax, [ebp+0Ch] mov ecx, [eax+4] push ecx call dword ptr ds:__imp__atoi add esp, 4 mov [ebp-4], eax mov edx, [ebp-4] push edx mov eax, [ebp+8] push eax call _sub add esp, 8 mov esp, ebp pop ebp retn
eax
0x104
ecx
edx ebp esp
0x100
0x100 0x0012FF24 0x0012FF20
0x0012FF20
0x100 (int a)
undef undef
undef
0x0012FF0C undef
106
Example2 - 16
.text:00000000 _sub: .text:00000001 .text:00000003 .text:00000006 .text:00000009 .text:0000000C .text:0000000D .text:00000010 _main: .text:00000011 .text:00000013 .text:00000014 .text:00000017 .text:0000001A .text:0000001B .text:00000021 .text:00000024 .text:00000027 .text:0000002A .text:0000002B .text:0000002E .text:0000002F .text:00000034 .text:00000037 .text:00000039 .text:0000003A push ebp mov ebp, esp mov eax, [ebp+8] mov ecx, [ebp+0Ch] lea eax, [ecx+eax*2] pop ebp retn push ebp mov ebp, esp push ecx mov eax, [ebp+0Ch] mov ecx, [eax+4] push ecx call dword ptr ds:__imp__atoi add esp, 4 mov [ebp-4], eax mov edx, [ebp-4] push edx mov eax, [ebp+8] push eax call _sub add esp, 8 mov esp, ebp pop ebp retn
eax
0x104
ecx
edx ebp esp
0x100
0x100 0x0012FF24 0x0012FF24
0x0012FF20
undef
undef undef
undef
0x0012FF0C undef
107
Example2 - 17
.text:00000000 _sub: .text:00000001 .text:00000003 .text:00000006 .text:00000009 .text:0000000C .text:0000000D .text:00000010 _main: .text:00000011 .text:00000013 .text:00000014 .text:00000017 .text:0000001A .text:0000001B .text:00000021 .text:00000024 .text:00000027 .text:0000002A .text:0000002B .text:0000002E .text:0000002F .text:00000034 .text:00000037 .text:00000039 .text:0000003A push ebp mov ebp, esp mov eax, [ebp+8] mov ecx, [ebp+0Ch] lea eax, [ecx+eax*2] pop ebp retn push ebp mov ebp, esp push ecx mov eax, [ebp+0Ch] mov ecx, [eax+4] push ecx call dword ptr ds:__imp__atoi add esp, 4 mov [ebp-4], eax mov edx, [ebp-4] push edx mov eax, [ebp+8] push eax call _sub add esp, 8 mov esp, ebp pop ebp retn
eax
0x104
ecx
edx ebp esp
0x100
0x100 0x0012FF50 0x0012FF28
0x0012FF20
undef
undef undef
undef
0x0012FF0C undef
108
109
110
111