2016defcon Intro To Disassembly Workshop PDF
2016defcon Intro To Disassembly Workshop PDF
Defcon 24
2016
DazzleCat Duo
Architecture Overview
2
Computer Architecture
System Memory
CPU Bus Bus
ALU
Bridge Memory
Registers
Control Unit
I/O Bus
4
Computer Architecture
CPU (Central Processing Unit)
Processes information
ALU (Arithmetic logic unit)
Does math
Registers
Store data (very fast)
Register size: 1 word
Generally named, rather than addressed
Control unit
Executes code
5
Computer Architecture
Registers vs. Memory
Registers serve the same purpose as memory
They store data
Memory
Moderate access speed
Cheap
Lots
Registers
Fast
Expensive
Few
Your program/data/etc sit in memory, while registers
are used to process very small pieces at a time
6
Abstractions
All of this is normally abstracted away from
the programmer
The Operating System manages
Processes
Makes it look like your program has control of the
processor
Memory
Makes it look like your process has it
Files
Makes them look like a sequence of bytes
7
Abstractions
But none of these things are true
Goal of learning assembly is to start seeing the
world as it really is
Source: http://www.einstorm-xp1-home-biz.com/Morpheus.jpg
Assembly
Everything the CPU does is through digital
logic
On/Off, 1/0
Including running your program
The series of bits that control the CPU is
machine code
A bunch of numbers
Define a set of instructions to run
9
Assembly
The machine code for a standard hello world :
55 89 e5 83 e4 f0 83 ec 10 b8 b0 84 04 08 89 04
24 e8 1a ff ff ff b8 00 00 00 00 c9 c3 90
This is a series of instructions for the processor to
execute
It flips the right transistors to calculate
information, fetch data from memory, send
signals to the system buses, communicate with
the graphics card, and print out hello world
With help from additional machine code
10
Assembly
Machine code controls the processor on the
most detailed possible level
Moves information in and out of memory
Moves information to and from registers
Controls the system bus
Controls the ALU, control unit, etc
11
Assembly
We want to directly control the CPU to leverage
its full power
But we dont want to write a bunch of numbers that
we cant hope to understand
Assembly is a shorthand, more legible version of
machine code
Uses mnemonics to save us from memorizing which
numbers do what
sub (subtract) instead of 0x83
add (add) instead of 0x81
12
Assembly
Machine Code Assembly
55 push %ebp
89 e5 mov %esp,%ebp
83 e4 f0 and $0xfffffff0,%esp
83 ec 10 sub $0x10,%esp
b8 b0 84 04 08 mov $0x80484b0,%eax
89 04 24 mov %eax,(%esp)
e8 1a ff ff ff call 80482f4
b8 00 00 00 00 mov $0x0,%eax
c9 leave
c3 ret
90 nop
13
Assembly
Writing in pure machine code is fun, and has
its uses, but is difficult and uncommon
Much more practical to write in assembly
An assembler is a tool that translates from
assembly to machine code; this process is
called assembling
A disassembler is a tool that translates from
machine code to assembly; this process is
called disassembling
14
Assembly
C code:
int x=1, y=2, z=x+y;
Assembly code:
mov [ebp-4], 0x1
mov [ebp-8], 0x2
mov eax, [ebp-8]
mov edx, [ebp-4]
lea eax, [edx+1*eax]
mov [ebp-0xc], eax
Machine code:
c7 45 fc 01 00 00 00 c7 45 f8 02 00 00
00 8b 45 f8 8b 55 fc 8d 04 02 89 45 f4
15
Compilation Process
Source code is compiled into assembly code
Assembly code is assembled into machine
code
Compilers have been doing all this for you
16
Instruction Set Architecture
The Instruction Set Architecture (ISA) defines
Processor registers
One register, or 200? 8 bits, or 128?
Address and data format
Do I grab a byte from memory at a time? Or 500?
Machine instructions
Can I add and subtract? Check for equality? Halt?
Indirectly defines the assembly language
What low level instructions we have available, what
those instructions do
17
Microarchitecture
A microarchitecture
is the way a given
instruction set is
implemented on a
processor
18
Source: http://en.wikipedia.org/wiki/File:Intel_Core2_arch.svg
Computer Architecture
Collectively, the instruction set architecture
and microarchitecture define the computer
architecture
19
Computer Architecture
There are
Thousands of instruction set architectures
Thousands of microarchitectures
Thousands of computer architectures
20
Computer Architecture
Architectures can usually be broadly divided
into two categories
Reduced Instruction Set Computing (RISC)
Complex Instruction Set Computing (CISC)
21
RISC vs. CISC
RISC
Small set of simple instructions
Generally
Cheaper to create
Easier to design
Lower power consumption
Physically smaller
CISC
Large set of powerful instructions
Generally
More expensive
Hard to design
Higher power requirements
Pysically larger
22
RISC vs. CISC
Hypothetical example
Multiply by 5, RISC vs. CISC
CISC:
mul [100], 5
RISC:
load r0, [100]
mov r1, r0
add r1, r0
add r1, r0
add r1, r0
add r1, r0
mov [100], r1
23
RISC vs. CISC
Neither RISC nor CISC is better or worse than
the other
Both have advantages, and disadvantages
A CISC instruction may take 100 RISC instructions
to implement
But a CISC instruction may run at 1/200th the
speed of the RISC instructions
Or consume 1000x the power
Or take a year to design
24
(Some of) The Major Players
RISC
ARM (examples: phones, tablets)
MIPS (examples: embedded systems, routers)
PowerPC (examples: original Macs, Xbox)
CISC
x86 (examples: consumer computers)
Motorola 68k (examples: early PCs, consoles)
25
Introduction to x86
26
Introduction to x86
Why x86?
Can build, run, and play with on your own
computer
Extremely popular, billions of systems, market
dominance
Core of familiar operating systems (Windows,
Mac, Linux)
27
x86
Your laptops, desktops, workstations, servers,
etc, all use the x86 architecture
When you buy a new processor to upgrade
your computer, thats an x86 processor
Makes it an ideal choice for studying assembly
and computer architecture
28
History of x86
Intel 8080
8 bit microprocessor, introduced in 1974
Intel 8086
16 bit microprocessor, introduced in 1978
Intel 80386
32 bit microprocessor, introduced in 1985
Intel Prescott, AMD Opteron and Athlon 64
64 bit microprocessor, introduced in 2003/2004
29
Source: http://en.wikipedia.org/wiki/File:KL_Intel_D8086.jpg
History of x86
Goal of design: backwards compatibility
Every generation adds new features
But doesnt break or remove any of the old
Even when the old features were later determined to
be useless/broken/etc
Code that runs on the original 8086 processor can
run unmodified on the latest 9th generation
architectures
Has resulted in an immense, complex,
interesting architecture
30
31
Source: http://gigaom.files.wordpress.com/2010/06/aubrey_isle_die.jpg
A Complex Architecture
Intel Software Developers manual
http://www.intel.com/content/dam/www/public/
us/en/documents/manuals/64-ia-32-
architectures-software-developer-manual-
325462.pdf
4000 pages, doesnt even begin to scratch the
surface
Goal in class: give you the basics
32
x86
Today, x86 generally refers to all architectures
based off of the original 8086
The 8086, which contains the 16 bit architecture
The 80286, which contains the 32 bit architecture and
the 16 bit architecture
The 80886, which contain a 64 bit architecture, 32 bit
architecture, and 16 bit architecture
The term x64 refers specifically to the 64 bit
version of the x86 architecture
We will study the 32 bit x86, since it is the most
universal
33
x86
CISC
Little Endian
34
Assembly Syntax
35
Assembly Syntax
The ISA defines registers, data format,
machine instructions, etc
But it doesnt actually define what code
should look like
It might define a multiply instruction, and how it
works
But it doesnt say anything about how we would
write such an instruction in assembly
multiply, mul, MUL, etc
36
Assembly Syntax
There is no standard syntax for assembly
Not even a standard syntax for a particular
architectures assembly language
Entirely defined by the assembler
Hundreds of variations
37
Rivals
Two main branches of x86 syntax
AT&T
Used by gcc
Intel
Used by Intel
They both have their pros and cons
Then hundreds of smaller variations specific to
an assembler
38
Assembler Syntax
In this class:
The assembler is NASM
The netwide assembler
Extremely popular
Very powerful
Very flexible
So well teach NASMs x86 syntax
Uses Intel syntax
39
Assembler Syntax
Almost universally true in assembly, and with
NASM
Lines do not end in a semi-colon
Semi-colons are used to start a single line
comment
instruction ; comment
40
x86 Registers
41
Registers
Registers are how the processor stores
information
The processor can access memory, but since
the systems memory is not part of the actual
processor, this is extremely slow
Registers are contained in the actual
processor, they are very fast (access at the
same speed as the processor)
42
Registers
You can think of registers as 32 bit variables
Each register has its own name
Can be modified, etc
But there are a very limited number of registers
They must be shared by the whole program
When they run out, they need to store their
information back to memory
Typical execution:
Fetch data from memory, store in registers
Work with data
Save data back to memory
Repeat
43
Registers
Registers are generally divided into two
categories
General Purpose Registers (GPRs)
Used for general things
Store data, addresses, etc
Special Purpose Registers (SPRs)
Store program state
44
x86 Registers
45
Source: http://en.wikipedia.org/wiki/File:Table_of_x86_Registers.png
x86 Registers
Fortunately, you do not need to know all
those
The ones you will need to know
x86 GPRs:
eax, ebx, ecx, edx, esi, edi, ebp, esp
x86 SPRs:
eip, eflags
46
x86 Registers
The registers we will discuss are 32 bit
registers
Notice that these register names begin with
e
This is for extended the latest 32 bit
processors extended their 16 bit predecessors
47
x86 Registers
You can access the low order 16 bits of the
register by removing the e from the register
name (for example, ax is the low 16 bit of
eax)
For the register names that end in x (eax,
ebx, ecx, edx), you can access the low order 8
bits of the 16 bit register using l (al, bl, cl,
dl), and the high order 8 bits of the 16 bit
register using h (ah, bh, ch, dh)
48
x86 Registers
Example, accessing pieces of the eax register
AH AL
MSB LSB
(8 bits) (8 bits)
AX (16 bits)
49
x86 Registers
eax, ebx, ecx, edx
Registers can be accessed in parts
erx Refers to 32 bit register
rx Referes to the lower 16 bits of erx
rh Refers to the top 8 bits of the rx bit
register
rl Refers to the lower 8 bits of the rx register
EAX
32 bit GPR
The accumulator register
Traditionally used to accumulate results of arithmetic
operations
e.g. eax+=ebx; eax+=ecx; eax+=edx;
ax: low 16 bits of eax
al: low 8 bits of ax
ah: high 8 bits of ax
52
EBX
32 bit GPR
The base register
Traditionally used to store the base of an address
e.g. accessing array index 5: [ebx + 5]
bx: low 16 bits of ebx
bl: low 8 bits of bx
bh: high 8 bits of bx
53
ECX
32 bit GPR
The counter register
Traditionally used to count
e.g. for (i=0; i<10; i++) i might be assembled to the
ecx register
cx: low 16 bits of ecx
cl: low 8 bits of cx
ch: high 8 bits of cx
54
EDX
32 bit GPR
The data register
Traditionally used to store and work with data
e.g. sub edx, 7
dx: low 16 bits of edx
dl: low 8 bits of dx
dh: high 8 bits of dx
55
EBP
32 bit GPR
The base pointer register
Stores the address of the base of the stack
frame
bp: low 16 bits of ebp
56
ESP
32 bit GPR
The stack pointer register
Stores the address of the top of the stack
frame
sp: low 16 bits of esp
57
EBP/ESP
Intel classifies EBP and ESP as GPRs
But many people would consider them SPRs
GPRs are used in arithmetic, memory accesses,
etc
SPRs have some other special purpose
EBP/ESP control the stack, so they have another
special purpose
You would generally not modify them like you
would EAX/EBX/ECX/EDX
58
EIP
32 bit SPR
The instruction pointer register
Stores the address of the next instruction to
execute
ip: low 16 bits of eip
59
EFLAGS
32 bit SPR
The flags register
Stores flags (bits specifically indicating
true/false) about system state and
information about the results of previously
executed instructions
flags: low 16 bits of eflags
60
Accessing Registers
When you write C code
int x = 5;
int y = 2;
int z = x + y;
x, y, and z are variables stored in memory.
But to work with them, they need to be
moved into registers first. The compiler
chooses which registers to use for this.
61
Accessing Registers
The EFLAGS and EIP registers cannot be
accessed directly this way
This is because they store and track system state
for you, you are not supposed to need to set them
yourself
mov eip, 1 ; does not assemble
62
Initializing Registers
registers are not initialized to any specific
values when your function begins
You must first set them to be the values you
need
Be careful:
Setting low bits (e.g. al) does not initialize the high
bits
63
x86 Memory Access
64
Accessing Memory
Registers used in this class:
eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags
ebp, esp track the stack, and shouldnt be used
(in this class) for computation
eip and eflags are special purpose registers that
cant be used for general computation
That leaves only eax, ebx, ecx, edx, esi, edi
This isnt enough to do much
At some point, the program needs to access
memory
65
Accessing Memory
In assembly, memory is accessed using [ ]
notation
Examples:
[ 0x12345678 ]
Access the value stored at memory address
0x12345678
[ eax ]
Access the value stored at the memory pointed to by
eax
66
Accessing Memory
[ 0x12345678 ]
I am accessing memory at address 0x12345678
But how much am I accessing?
A byte? A word? A double word?
In some cases, the size of the access is implicit
mov eax, [ 0x1234567 ]
Since I am moving memory into the eax register, and
eax is 32 bits, I must be accessing 32 bits of memory
But in other cases, it is not
mov [ 0x1234567 ], 1
Am I trying to set a byte, word, or doubleword?
67
Accessing Memory
If the size of the memory access is not implied
by the instruction, it must be explicitly
specified with either byte, word, or
dword
Examples:
byte [ 100 ]
Access the single byte at address 100
dword [ ax ]
Access the doubleword pointed to by ax
68
x86 Word Size
A quirk
Traditionally, the word size of an architecture is the
size of data that architecture is natively built for
A 32 bit architecture like x86 is designed to work with 32 bit
data this would be its word size
But the original x86 was 16 bits
Had a 16 bit word
We still use this definition
Even though the architecture works with 32 bit data,
32 bit registers, etc
At least when writing assembly, we say a word is 16 bits
69
x86 Word Size
byte: 8 bits
word: 16 bits Only 3 you need for this class
dword: 32 bits
qword: 64 bits
fword: (not what you think) 48 bits
tword: 80 bits
70
Accessing Registers & Memory
Most x86 instructions take operands
The instruction mnemonic indicates the
operation the processor is supposed to perform
The instruction operands indicate what is used in
the operation
Example: add eax, ebx
Add ebx to eax
add is the mnemonic
eax and ebx are the operands
71
Accessing Registers & Memory
Instructions (mnemonics) typically accept 0, 1, 2, or 3
operands (depends on the instruction)
In general, x86 instructions can access any number of
registers at once, but at most one memory location at
once
add eax, ebx
Accesses two registers at once, valid
add eax, [ 0x12345678 ]
Accesses one register, and one memory address, valid
add [ 0x12345678 ], [ 0x87654321 ]
Accesses two memory addresses at once, not valid
72
x86 Instructions
73
x86 Instructions
Arithmetic
add Data movement:
sub mov
mul
inc Execution flow
dec jmp
and Conditional jumps
or
xor Comparison
Not test
cmp
Stack
call Other
return lea
push nop
pop
74
x86 Instructions
There are hundreds more, but those are the
basics we need for this class
Even this might seem like a lot, but when you
think of all the operators (+, -, *, /, %, &&, ||,
&, |, ^, !, ~, <, >, >=, <=, ==, ., ->, etc) and
keywords (if, else, switch, while, do, case,
break, continue, for, etc) you know for any
other language, this is trivial
75
mov
Move data from one location (memory,
register, etc) to another
Syntax: mov destination, source
76
mov Examples
mov eax, 5
Store the value 5 into eax
mov eax, [ 1 ]
Copy the 32 bit value at memory address 1 into eax
mov dx, [ 0x100 ]
Copy the 16 bit value at memory address 0x100 into dx
mov ecx, eax
Copy the contents of eax into ecx
mov [ 1984 ], bl
Store the 8 bit value in bl to memory address 1984
mov [ eax ], cx
Store the 16 bit value in cx to the memory pointed to by eax;
e.g. if eax is 0x777, store cx to location 0x777 in memory
77
inc, dec
Increment, decrement by 1
Syntax:
inc register
inc [ memory ]
dec register
dec [ memory ]
78
inc, dec Examples
inc eax
Increment the eax register by 1
dec dx
Decrement the dx register by 1
dec dword [ 0x11223344 ]
Decrement the 32 bit value at 0x11223344 by 1
inc word [ ecx ]
Increment the 16 bit value pointed to by ecx by 1
79
add, sub
Add and subtract
Syntax
add destination, value
sub destination, value
Destination can be a register or memory
Value can be a register, memory, or immediate
Note: operands must all be same size
add eax, bx is invalid
80
add, sub Examples
add eax, ebx
Add ebx to eax, store result in eax
sub ecx, [ 100 ]
Subtract the 32 bit value at address 100 from ecx,
store the result in ecx
Note that the memory access is implied to be 32 bits,
there is no need to specify dword
add dword [ edx ], 100
Add 100 to the 32 bit value pointed by edx
Note that the address is implied to be 32 bits (edx),
but the data size must be specified
81
mul
Multiply eax by operand, store result in
edx:eax
edx: high 32 bits of result
eax: low 32 bits of result
Syntax:
mul [ memory ]
mul register
mul always uses the eax register as a source
And always stores the result in edx:eax
82
mul Examples
mul eax
edx:eax = eax * eax; (Square eax)
mul ebx
edx:eax = eax * ebx;
mul dword [ 0x555 ]
edx:eax = eax * (32 bit value at address 0x555)
mul byte [ 0x123 ]
edx:eax = eax * (8 bit value at address 0x123)
83
and, or, xor
Binary AND, OR, and XOR
Syntax:
and destination, source
or destination, source
xor destination, source
Destination can be a register or memory
address
Source can be a register, memory address, or
immediate
84
and, or, xor Examples
or eax, 0xffffffff
Set eax to all 1s
and dword [ 0xdeadbeef ], 0x1
Mask off low bit of 32 bit value at 0xdeadbeef
xor ecx, eax
ecx = ecx ^ eax
Evaluate exclusive or of bits in ecx and eax, store
result in ecx
85
and, or, xor Examples
xor eax, eax
Fastest way to clear a register in x86
Other ways
mov eax, 0
and eax, 0
sub eax, eax
Involve extra computation or longer machine
encodings, which slow them down
86
not
Binary NOT
Syntax:
not register
not [ memory ]
Retrieves the value of the operand, computes
its ones complement, and stores it back to the
operand
87
not Examples
not ch
Inverts all the bits of ch
not dword [ 2020 ]
Inverts all the bits of 32 bit value at address 2020
88
nop
No operation
Literally does nothing
Syntax: nop
Compiles to exactly one byte in machine code (0x90)
Commonly used for
Timing
Memory alignment
Hazard prevention
Branch delay slot (RISC architectures)
A placeholder to be replaced later
Hacking (nop sleds)
Cracking (nop outs)
89
lea
Load Effective Address
Syntax: lea destination, [ source ]
Computes the address of the source operand,
and places it in the destination operand
Similar to the & operator in C
Often used for simple math, rather than
anything to do with addresses
90
lea examples
lea eax, [ 100 ]
Computes the effective address of [ 100 ] (which is
100) and stores it in eax
lea ecx, [ ebx ]
Computes the effective address of [ ebx ] (which is
ebx) and stores it in ecx
91
Examples
Evaluate 0x13 * 0x100 + 0x37 using assembly
92
Conclusion
Always a similar pattern
Load data from memory into registers
Work with the data
Store back to memory
93
x86 reference
One of my favorite x86 references
http://ref.x86asm.net/coder32.html
x86
8 32 bit registers
General Purpose Registers
eax
ebx
ecx
edx
esi
edi
Stack Register
esp
Base Register
ebp
Conditional Codes
Eflags register contains the current state of
flags AKA conditional codes
There are 9 conditional codes on x86
Flags are used to track the outcome of
operations
Flags are used to conditional execute code
101
lea examples
Why is this useful?
Variables are often stored at offsets from a register
Example: char s[5];
eax may contain the address of s
lea ebx, [eax + 2] gives me the address of element 2
We could do that with
mov ebx, eax
add ebx, 2
But this is an extra instruction
102
lea examples
Why is this useful?
Variables are often stored at offsets from a register
Example: char s[5];
eax may contain the address of s
lea ebx, [eax + 2] gives me the address of element 2
We could do that with
mov ebx, eax
add ebx, 2
But this is an extra instruction
103
Data Movement
leave
Sets stack pointer to the base frame address
Syntax
leave
Examples
leave equivalent to:
mov esp,ebp
pop ebp
Arithmetic and Logic
add op1, op2
adds together the two operands and stores result in
the first operand
Flags
o..szapc
Syntax
add <reg>,<reg>
add <reg>,<mem>
add <mem>,<reg>
add <reg>,<con>
add <mem>,<con>
Examples
add eax, 10 add 10 to the current value in eax,
and store result in eax
Arithmetic and Logic
sub op1, op2
subtracts the two operands and stores result in the first
operand
Flags
o..szapc
Syntax
sub <reg>,<reg>
sub <reg>,<mem>
sub <mem>,<reg>
sub <reg>,<con>
sub <mem>,<con>
Examples
sub al, ah AL AL - AH
sub eax, 216 subtract 216 from the value stored in
EAX
Arithmetic and Logic
inc op1
increments contents of operand1 by 1
Flags
o..szap.
Syntax
inc <reg>
inc <mem>
Examples
inc eax - adds one to the contents of eax
inc DWORD PTR [var]- add one to the 32-
bit integer stored at location var
Arithmetic and Logic
dec op1
decrements contents of operand1 by 1
Flags
o..szap.
Syntax
dec <reg>
dec <mem>
Examples
dec eax subtracts one from the contents of eax
dec DWORD PTR [var]- subtracts one from the
32-bit integer stored at location var
Arithmetic and Logic
imul
2 operand multiplies op1 and op2 together and stores result in op1.
op1 must be a register
3 operand multiplies op2 and op3 together and stores results in op1.
op1 must be a register, op3 must be a constant
Flags
o..szap.
Syntax
imul <reg32>,<reg32>
imul <reg32>,<mem>
imul <reg32>,<reg32>,<con>
imul <reg32>,<mem>,<con>
Examples
imul eax, [var]- multiply the contents of EAX by the 32-bit
contents of the memory location var. Store the result in EAX.
imul esi, edi, 25 - ESI = EDI * 25
idiv
Arithmetic and Logic
Divides the contents of the 64 bit integer EDX:EAX by
op1. Quotient stored in EAX, remained in EDX
Flags
o..szapc
Syntax
idiv <reg32>
idiv <mem>
Examples
idiv ebx - divide the contents of EDX:EAX by the
contents of EBX.
idiv DWORD PTR [var] - divide the contents of
EDX:EAX by the 32-bit value stored at memory location
var.
Arithmetic and Logic
and op1, op2
bitwise and, save results in op1
Flags
o..szapc
Syntax
and <reg>,<reg>
and <reg>,<mem>
and <mem>,<reg>
and <reg>,<con>
and <mem>,<con>
Examples
and eax, 0fH clear all but the last 4 bits of EAX
Arithmetic and Logic
or op1, op2
bitwise or, save results in op1
Flags
o..szapc
Syntax
or <reg>,<reg>
or <reg>,<mem>
or <mem>,<reg>
or <reg>,<con>
or <mem>,<con>
Examples
or eax, 0fH set the last 4 bits of EAX
Arithmetic and Logic
xor op1, op2
bitwise xor, save results in op1
Flags
o..szapc
Syntax
xor <reg>,<reg>
xor <reg>,<mem>
xor <mem>,<reg>
xor <reg>,<con>
xor <mem>,<con>
Examples
xor eax, eax set eax to 0
Arithmetic and Logic
not op1
bitwise not of op1, save results in op1
Syntax
not <reg>
not <mem>
Examples
not BYTE PTR [var] negate all bits
in the byte at the memory location var.
Arithmetic and Logic
neg op1
twos complement on op1, save results in op1
Flags
o..szapc
Syntax
neg <reg>
neg <mem>
Examples
neg eax EAX - EAX
Arithmetic and Logic
shl op1, op2
logical shift left op1, op2 times
Flags
o..szapc
Syntax
shl <reg>,<con8>
shl <mem>,<con8>
shl <reg>,<cl>
shl <mem>,<cl>
Examples
shl eax, 1 Multiply the value of EAX by 2
Arithmetic and Logic
sal op1, op2
arithmetic shift left op1, op2 times
Flags
o..szapc
Syntax
shl <reg>,<con8>
shl <mem>,<con8>
shl <reg>,<cl>
shl <mem>,<cl>
Examples
sal eax, 1 shift the value of EAX by 1
Arithmetic and Logic
shr op1, op2
logical shift right op1, op2 times
Flags
o..szapc
Syntax
shr <reg>,<con8>
shr <mem>,<con8>
shr <reg>,<cl>
shr <mem>,<cl>
Examples
shr eax, 2 Divide the value of EAX by 4
bits
Arithmetic and Logic
sar op1, op2
arithmetic shift right op1, op2 times
Flags
o..szapc
Syntax
sar<reg>,<con8>
sar<mem>,<con8>
sar<reg>,<cl>
sar<mem>,<cl>
Examples
sar eax, 1 shift eax right 1, duplicating
the sign bit with each shift
Arithmetic and Logic
test op1, op2
logical and of op1 and op2, result is discarded
Flags
o..szapc
Syntax
test <reg>,<reg>
test <con>,<reg>
test <reg>,<mem>
test <con>,<mem>
Examples
test ax, 5 sets ZF, PF, and SF to
appropriate state based on value in ax
Arithmetic and Logic
cmp op1, op2
subtracts op2 from op1, result is discarded
Flags
o..szapc
Syntax
cmp <reg>,<reg>
cmp <reg>,<con>
cmp <reg>,<mem>
cmp <mem>,<mem>
cmp <mem>,<reg>
cmp <mem>,<con>
Examples
cmp ax, 5 sets ZF, OF, PF, and SF to
appropriate state based on value in ax
Examples
Rewrite the following C code in assembly:
int i = 7; char j = 5; int k = i + j;
Assume:
i is at address 100
j is at address 200
k is at address 300
122
int i = 7; char j = 5; int k = i + j;
123
Examples
Rewrite the following C code in assembly:
int i = 7; char j = 5; int k = i * i + j * j;
Assume:
i is at address 100
j is at address 200
k is at address 300
124
int i = 7; char j = 5; int k = i * i + j * j;
mov dword [ 100 ], 7 ; set i
mov byte [ 200 ], 5 ; set j
myasm.o: myasm.asm
nasm -f elf myasm.asm
ld -melf_i386 myasm.o
clean:
rm myasm.o a.out
Makefile
all: printreg-shift.o
printreg-shift.o: printreg-shift.asm
nasm -f elf32 -g printreg-shift.asm
ld -melf_i386 -g printreg-shift.o -o printreg-
shift.out
Add debugging
symbols
clean:
rm printreg-shift.o printreg-shift.out
Once we get into more complicated assembly you wont be able to do much
debugging if you dont include extra debug symbols
NASM sections
section .text;Section for all
code
global _start ;Exports start
method
_start: ;Linker entry point. ld by
default looks for _start
CODE HERE
section .data
v1 db 0x55 ; just the byte 0x55
v2 db 0x55,0x56,0x57 ; three bytes in succession
v3 db 'a',0x55 ; character constants are
OK
v4 db 'hello',13,10,'$' ; so are string constants
v5 dw 0x1234 ; 0x34 0x12
v6 dw 'a' ; 0x61 0x00
v7 dw 'ab' ; 0x61 0x62
Declaring Variables
General form: Name <granularity> <initial value>
db = 1 byte
dw = 2 bytes
dd = 4 bytes
dq = 8 bytes
section .data
v8 dw 'abc' ; 0x61 0x62 0x63 0x00 (string)
v9 dd 0x12345678 ; 0x78 0x56 0x34 0x12
v10 dd 1.234567e20 ; floating-point constant
v11 dq 0x123456789abcdef0 ; eight byte constant
v12 dq 1.234567e20 ; double-precision float
v13 dt 1.234567e20 ; extended-precision float
Debugging x86 with GDB
Run gdb <executable_name>
Debugging x86 with GDB
Tell gdb we want to look at intel assembly
(gbd) set disassembly-flavor intel
Debugging x86 with GDB
Show the different parts of the file
(gdb) info files
Debugging x86 with GDB
disassemble
disassembles where IP currently is
disassemble address
disassemble 0x8048080
disassemble label
disassemble loop
disassemble main
Decimal Value
Hex Value
Debugging x86 with GDB
You can print individual registers
print $reg
Debugging x86 with GDB
Step 1 instruction at a time
stepi
libc calls
GDB Summary Slide
159
Lab
SharkSim 3000
In the linux VM (dazzlecat/dazzleme)
cd ~/training/sharksim
READ sharksim3000.pdf
you've spent thousands of hours crafting the most
terrifying, realistic shark simulation the world has
ever seen all in x86 assembly!
There's just one problem the program is seg
faulting!!!
You'll need to debug the code to save your reputation
and unleash the greatest game of all time Shark Sim
3000!
Control Flow Instructions
ip register (instruction pointer)
Holds the address of the current instruction
ip register cannot be manipulated directly
Updated by control flow instructions
mov eax, 0
loop: inc eax
jmp loop
Conditional Jumps
Conditional jumps take into consideration the
current state of the flags to determine if a
jump is taken or not
Jumps
Control Flow Instructions
Syntax
je <label> (jump when equal)
jne <label> (jump when not equal)
jz <label> (jump when last result was zero)
jg <label> (jump when greater than)
jge <label> (jump when greater than or equal to)
jl <label> (jump when less than)
jle <label> (jump when less than or equal to)
Example
cmp eax, ebx
jle done - If the contents of EAX are less than or
equal to the contents of EBX, jump to the label done.
Otherwise, continue to the next instruction.
je
jge - jump when greater than or equal to
Conditions: SF = 0 || ZF = 1
jl - jump when less than
Conditions: SF = 1
jle - jump when less than or equal to
Conditions: SF = 1 || ZF = 1
je
je - jump equals
Conditions: ZF = 1
jne - jump when not equal
Conditions: ZF = 0
jz - jump when last result was zero
Conditions: ZF = 1
jg - jump when greater than
Conditions: SF = 0 && ZF = 0
Arithmetic and Logic
test
Bitwise AND of op1 and op2, result is discarded
Flags
o..szapc
Syntax
test <reg>,<reg>
test <con>,<reg>
test <reg>,<mem>
test <con>,<mem>
Examples
test ax, 5 Check if bits 0 and 2
are set
test example
Why is this useful?
Test can be used to see if a particular bit is set by looking
at ZF
void main(){
func();
}
Calling
Addr Value
;C func()
0x15423 main: ip 0xF0
0xF4 ?
0x16745 func:
esp 0x100
;C func()
0x15423 main: 0xF0
0xF4 ?
0x16745 func:
esp 0x100
;C func()
0x15423 main: 0xF0
0xF4 ?
0x16745 func: ip
esp 0xFC
;C func()
0x15423 main: 0xF0
0xF4 ?
0x16745 func:
esp 0xFC
;C func()
0x15423 main: 0xF0
0xF4 ?
0x16745 func:
esp 0x100
void callee()
{
//was called
}
Calling Conventions
Other calling conventions
caller clean-up
cdecl
syscall
optlink
Calle clean-up
pascal
register
stdcall
fastcall
safecall
CDECL
Arguments are passed on the stack
pushed from right to left
pushed third
Passing Parameters
;void function(int a, int b, int c)
addr value
0x64E8 ?
_start: 0x64EC ?
;assume a is in eax 0x64F0 ?
push ebx
push eax esp 0x6500
call function
Passing Parameters
;void function(int a, int b, int c)
addr value
_start: 0x64E8 ?
;assume a is in eax 0x64EC ?
0x64F0 ?
;assume b is in ebx
0x64F4 ?
;assume c is in ecx 0x64F8 ?
push ecx 0x64FC c
ip 0x6500 ?
push ebx
push eax
esp 0x65FC
call function
Passing Parameters
;void function(int a, int b, int c)
addr value
_start: 0x64E8 ?
;assume a is in eax 0x64EC ?
0x64F0 ?
;assume b is in ebx
0x64F4 ?
;assume c is in ecx 0x64F8 b
push ecx 0x64FC c
0x6500 ?
push ebx
push eax ip
esp 0x65F8
call function
;void
Passing Parameters
function(int a, int b, int c)
addr value
_start: 0x64E8 ?
esp 0x65F0
Parameter Passing
instead of pushing parameters onto the
stack, pre-allocate enough space on the stack
and moved to appropriate places
Compiler specific, both ways achieve the same
thing
Passing Parameters
;void function(int a, int b, int c)
esp 0x65F0
CDECL
eax, ecx, edx are caller-saved
Other registers are callee-saved
//C
int function()
{ //assembly
return 0; function:
} mov eax, 0
ret
CDECL
Return value is in eax
//C
int function()
{ //assembly
return 1; function:
} mov eax, 1
ret
push ebp Callee Rules
mov ebp, esp
void main(){
m = func(a,b,c);
}
cdecl parameter example
Addr Value
;C m = func(a,b,c)
main: 0xF0
esp 0xF4 retaddr
push c 0xF8 a
0xFC b
push b 0x100 c
push a
call _func ;stack shown here
add esp, 12;cleaning up the stack
mov m, eax ;save the result
Addr Value
esp 0xE4 ebx
0xE8 esi
;C uint32_t func(uint32_t a,uint32_t b,uint32_t c) 0xEC edi
ebp 0xF0 caller ebp
_func: 0xF4 retaddr
PUSH EBP
0xF8 a
MOV EBP, ESP
PUSH EDI 0xFC b
PUSH ESI 0x100 c
PUSH EBX ;stack shown here
.
. MOV EBX, [EBP + 12] ; (+0xc) Load b into EBX
.
.
XOR EAX, EAX ; Zero the return value
POP EBX ; Restore the saved registers
POP ESI
POP EDI
LEAVE ; Equivalent to MOV ESP, EBP
; POP EBP
RET
cdecl example 2
Consider the following c code
int MyFunc1(int a, int b)
{
return a + b;
}
And the following function call
x = MyFunc1(2, 3);
cdecl example 2
Caller address value
0xF0
push 3 0x100 3
push 2
call _MyFunc1 ;stack shown here
add esp, 8
addr value
cdecl example 2
esp/ebp
0xF0
0xF4 caller ebp
0xF8 ret addr
Callee 0xFC 2
;int MyFunc1(int a, int b) {
0x100 3
; return a + b;
;}
_MyFunc1:
push ebp
mov ebp, esp ;stack shown here
mov eax, [ebp + 8] ;loads 2
mov edx, [ebp + 12] ;loads 3
add eax, edx
pop ebp
ret
CDECL
Parameter Passing is always right to left
Return address is always pushed
Callee pushes ebp to preserve callers value
increasing addr value
address ebp Caller ebp
ebp+4 Return Addr
ebp+8 Argument 1
ebp+4+4n Argument n
CDECL
int function(int a, int b)
[ebp+8] = a
[ebp+0xc] = b
void main(){
m = func(a,b,c);
}
cdecl example 3
Addr Value
;C m = func(a,b,c)
main: 0xF0
esp 0xF4 retaddr
push c 0xF8 a
0xFC b
push b 0x100 c
push a
call _func ;stack shown here
add esp, 12;cleaning up the stack
mov m, eax ;save the result
Addr Value
;C uint32_t func(uint32_t a,uint32_t b,uint32_t c)
0xDC
_func: 0xE0
PUSH EBP 0xE4
MOV EBP, ESP ; 8 bytes for two
SUB ESP, 08H ; local variables. esp 0xE8 y
;(Stack shown at this point) 0xEC x
ebp 0xF0 caller ebp
PUSH EDI ; These would only be
PUSH ESI ; pushed if they were used 0xF4 retaddr
PUSH EBX ; in this function. 0xF8 a
. .
MOV EAX, [EBP - 8] ; Load y into EAX 0xFC b
MOV EBX, [EBP + 12] ; Load b into EBX 0x100 c
.
.
XOR EAX, EAX ; Zero the return value
POP EBX ; Restore saved registers
POP ESI
POP EDI
LEAVE ; Equivalent to MOV ESP, EBP
; POP EBP
RET
Addr Value
;C uint32_t func(uint32_t a,uint32_t b,uint32_t c)
esp 0xDC ebx
_func:
0xE0 esi
PUSH EBP 0xE4 edi
MOV EBP, ESP ; Allocating 8 bytes of storage 0xE8 y
SUB ESP, 08H ; for two local variables.
0xEC x
PUSH EDI ; These would only be
PUSH ESI ebp
; pushed if they were used 0xF0 caller ebp
PUSH EBX ; in this function. 0xF4 retaddr
. ;(Stack shown at this point) 0xF8 a
.
0xFC b
MOV EAX, [EBP - 8] ; Load y into EAX
MOV EBX, [EBP + 12] ; Load b into EBX 0x100 c
.
.
XOR EAX, EAX ; Zero the return value
POP EBX ; Restore saved registers
POP ESI
POP EDI
LEAVE ; Equivalent to MOV ESP, EBP
; POP EBP
RET
Local Parameters
If the method is simple enough local
parameters will simply use a register
Stack Alignment
Some compilers will enforce 16 byte
alignment for entering methods
What does this look like?
When allocating space for local parameters
allocate enough to align frame to 16 byte
boundary
Often leads to unused space in the functions
stack frame
You dont have to do this in your code
C constructs in x86
251
C constructs in x86
if (...) { ... }
if (...) { ... } else { ... }
if (...) { ... } else if (...) { ... } else { ... }
while (...) { ... }
do { ... } while (...);
for (...; ...; ...) { ... }
switch (...) { ... }
252
C constructs in x86
All of these can be written using comparisons
(cmp) and jumps (jmp, je, jne, jl, jle, jg, jge)
When compiling your program, the compiler
does this translation for you
When writing your own assembly, you need to
figure out the translation
253
Translation: C to Assembly
Assembly does not have concepts of code
blocks {} like higher level languages do
Everything is just a stream of instructions
Translation step 1: remove code blocks
Requires you to rewrite code using goto
statements
Translation step 2: rewrite as assembly
254
if (...) { ... }
With blocks: Without blocks:
if (condition) if (!condition)
{ goto skip_block;
code_if_true;
} code_if_true;
skip_block:
255
if (...) { ... }
With blocks: Without blocks:
if (x==5) if (x!=5)
{ goto skip_block;
x++;
y=x; x++;
} y=x;
skip_block:
256
if (...) { ... }
C: x86:
257
if (...) { ... } else { ... }
With blocks: Without blocks:
if (condition) if (!condition)
{ goto false_block;
code_if_true;
} code_if_true;
else goto skip_block;
{
code_if_false; false_block:
} code_if_false;
skip_block:
258
if (...) { ... } else { ... }
With blocks: Without blocks:
if (x) if (!x)
{ goto false_block;
x++;
} x++;
else goto skip_block;
{
x--; false_block:
} x--;
skip_block:
259
if (...) { ... } else { ... }
C: x86:
if (!x) cmp dword [x], 0
goto false_block; je false_block
false_block: false_block:
x--; dec dword [x]
skip_block: skip_block:
260
if (...) { ... } else if { ... } else { ... }
With blocks: Without blocks:
if (condition_1) if (!condition_1)
{ goto test_2;
code_if_1; code_if_1;
} goto skip_block;
else if (condition_2)
{ test_2:
code_if_2; if (!condition_2)
} goto false_block;
else code_if_2;
{ goto skip_block;
code_if_false;
} false_block:
code_if_false;
skip_block:
261
if (...) { ... } else if { ... } else { ... }
With blocks: Without blocks:
if (score>70) if (score<=70)
{ goto test_2;
grade=a; grade=a;
} goto skip_block;
else if (score>50)
{ test_2:
grade=b; if (score<=50)
} goto false_block;
else grade=b;
{ goto skip_block;
grade=c;
} false_block:
grade=c;
skip_block:
262
if (...) { ... } else if { ... } else { ... }
C: x86:
if (score<=70) cmp dword [score], 70
goto test_2; jle test_2
grade=a; mov byte [grade], 'a'
goto skip_block; jmp skip_block
test_2: test_2:
if (score<=50) cmp dword [score], 50
goto false_block; jle false_block
grade=b; mov byte [grade], 'b'
goto skip_block; jmp skip_block
false_block: false_block:
grade=c; mov byte [grade], 'c'
skip_block: skip_block:
263
do { ... } while (...);
With blocks: Without blocks:
do loop:
{
code; code;
}
while (condition); if (condition)
goto loop;
264
do { ... } while (...);
With blocks: Without blocks:
do loop:
{
y*=x; y*=x;
x--; x--;
}
while (x); if (x)
goto loop;
265
do { ... } while (...);
C: x86:
loop: loop:
done:
267
while (...) { ... }
With blocks: Without blocks:
done:
268
while (...) { ... }
C: x86:
loop: loop:
if (!tired) cmp dword [tired], 0
goto done; je done
done: done:
269
for (...; ...; ...) { ... }
With blocks: Without blocks:
for (expr_1; expr_2; expr_3) expr_1;
{
code; loop:
} if (!expr_2)
goto done;
code;
expr_3;
goto loop;
done:
270
for (...; ...; ...) { ... }
With blocks: Without blocks:
for (i=0; i<100; i++) i=0;
{
sum+=i; loop:
} if (i>=100)
goto done;
sum+=i;
i++;
goto loop;
done:
271
for (...; ...; ...) { ... }
C: x86:
mov dword [i], 0
i=0;
loop:
loop: cmp dword [i], 100
if (i>=100) jge done
goto done;
mov eax,[i]
sum+=i; add [sum],eax
i++; inc dword [i]
goto loop;
jmp loop
done:
done:
272
A Simple Function
int factorial(int n)
{
if (n <= 1)
return n;
else
return n * factorial(n-1);
}
273
factorial: int f(int n)
push ebp {
mov ebp, esp
if (n <= 1)
return n;
mov eax, [ebp+8]
cmp eax, 1 else
jle done return n * f(n-1);
}
sub eax, 1
push eax
call factorial
mul dword [ebp+8]
done:
mov esp, ebp
pop ebp
ret
274
00008000 6655 push ebp
00008002 6689E5 mov ebp,esp
00008005 67668B4508 mov eax,[ebp+0x8]
0000800A 6683F801 cmp eax,byte +0x1
0000800E 7E0E jng 0x1e
00008010 6683E801 sub eax,byte +0x1
00008014 6650 push eax
00008016 E8E7FF call word 0x0
00008019 6766F76508 mul dword [ebp+0x8]
0000801E 6689EC mov esp,ebp
00008021 665D pop ebp
00008023 C3 ret
275
Run Trace
Lets evaluate a call to factorial with n = 2
push 2
call factorial
276
factorial:
8000 push ebp eax ??
8002 mov ebp, esp
Address Value
8005 mov eax, [ebp+8]
800A cmp eax, 1 0x0ec
800E jle done 0x0f0
0x0f4
8010 sub eax, 1
8014 push eax 0x0f8
8016 call factorial 0x0fc
8019 mul dword [ebp+8]
esp 0x100 Ret. Addr
done: 0x104 2
801E mov esp, ebp ebp 0x108 ??
8021 pop ebp
8023 ret
277
factorial:
8000 push ebp eax ??
8002 mov ebp, esp
Address Value
8005 mov eax, [ebp+8]
800A cmp eax, 1 0x0ec
800E jle done 0x0f0
0x0f4
8010 sub eax, 1
8014 push eax 0x0f8
8016 call factorial 0x0fc
8019 mul dword [ebp+8]
esp 0x100 Ret. Addr
done: 0x104 2
801E mov esp, ebp ebp 0x108 ??
8021 pop ebp
8023 ret
278
factorial:
8000 push ebp eax ??
8002 mov ebp, esp
Address Value
8005 mov eax, [ebp+8]
800A cmp eax, 1 0x0ec
800E jle done 0x0f0
0x0f4
8010 sub eax, 1
8014 push eax 0x0f8
8016 call factorial esp 0x0fc 0x108
8019 mul dword [ebp+8]
0x100 Ret. Addr
done: 0x104 2
801E mov esp, ebp ebp 0x108 ??
8021 pop ebp
8023 ret
279
factorial:
8000 push ebp eax ??
8002 mov ebp, esp
Address Value
8005 mov eax, [ebp+8]
800A cmp eax, 1 0x0ec
800E jle done 0x0f0
0x0f4
8010 sub eax, 1
8014 push eax 0x0f8
8016 call factorial esp 0x0fc 0x108
8019 mul dword [ebp+8]
ebp 0x100 Ret. Addr
done: 0x104 2
801E mov esp, ebp 0x108 ??
8021 pop ebp
8023 ret
280
factorial:
8000 push ebp eax 2
8002 mov ebp, esp
Address Value
8005 mov eax, [ebp+8]
800A cmp eax, 1 0x0ec
800E jle done 0x0f0
0x0f4
8010 sub eax, 1
8014 push eax 0x0f8
8016 call factorial esp 0x0fc 0x108
8019 mul dword [ebp+8]
ebp 0x100 Ret. Addr
done: 0x104 2
801E mov esp, ebp 0x108 ??
8021 pop ebp
8023 ret
281
factorial:
8000 push ebp eax 2
8002 mov ebp, esp
Address Value
8005 mov eax, [ebp+8]
800A cmp eax, 1 0x0ec
800E jle done 0x0f0
0x0f4
8010 sub eax, 1
8014 push eax 0x0f8
8016 call factorial esp 0x0fc 0x108
8019 mul dword [ebp+8]
ebp 0x100 Ret. Addr
done: 0x104 2
801E mov esp, ebp 0x108 ??
8021 pop ebp
8023 ret
282
factorial:
8000 push ebp eax 2
8002 mov ebp, esp
Address Value
8005 mov eax, [ebp+8]
800A cmp eax, 1 0x0ec
800E jle done 0x0f0
0x0f4
8010 sub eax, 1
8014 push eax 0x0f8
8016 call factorial esp 0x0fc 0x108
8019 mul dword [ebp+8]
ebp 0x100 Ret. Addr
done: 0x104 2
801E mov esp, ebp 0x108 ??
8021 pop ebp
8023 ret
283
factorial:
8000 push ebp eax 1
8002 mov ebp, esp
Address Value
8005 mov eax, [ebp+8]
800A cmp eax, 1 0x0ec
800E jle done 0x0f0
0x0f4
8010 sub eax, 1
8014 push eax 0x0f8
8016 call factorial esp 0x0fc 0x108
8019 mul dword [ebp+8]
ebp 0x100 Ret. Addr
done: 0x104 2
801E mov esp, ebp 0x108 ??
8021 pop ebp
8023 ret
284
factorial:
8000 push ebp eax 1
8002 mov ebp, esp
Address Value
8005 mov eax, [ebp+8]
800A cmp eax, 1 0x0ec
800E jle done 0x0f0
0x0f4
8010 sub eax, 1
8014 push eax esp 0x0f8 1
8016 call factorial ebp 0x0fc 0x108
8019 mul dword [ebp+8]
0x100 Ret. Addr
done: 0x104 2
801E mov esp, ebp 0x108 ??
8021 pop ebp
8023 ret
285
factorial:
8000 push ebp eax 1
8002 mov ebp, esp
Address Value
8005 mov eax, [ebp+8]
800A cmp eax, 1 0x0ec
800E jle done 0x0f0
301
IDA
IDA Interactive Disassembler
Allows for binary visualization of disassembly
About
https://hex-rays.com/products/ida/index.shtml
Download
https://hex-
rays.com/products/ida/support/download.shtml
Free version supports x86
IDA
IDA recognizes
many common file
formats
If it gets it wrong
you can select
generic binary file
Processor type
drop down to
change
architectures
Memory map of
executable
Function
window
Graph window,
overall logic
block view
IDA
IDA shows code in Basic Blocks
basic block has:
one entry point, meaning no code within it is the
destination of a jump instruction anywhere in the
program;
one exit point, meaning only the last instruction
can cause the program to begin executing code in
a different basic block.
IDA Basic Block
int main(int argc, char* argv[])
{
return argc;
}
IDA Basic Block
IDA is smart enough to know
that the first argument
always starts at ebp+8, so it
renames that offset to arg_0
to make it easier to read
IDA Paths
IDA shows 3 different types of paths between
basic blocks
RED Path taken if conditional jump is not
taken
GREEN Path taken if conditional jump is
taken
BLUE Guaranteed path
C If Example
return argc;
}
C If Example
C If Example
Taken if arg_0
greater than 1
Taken if arg_0 less
than or equal to 1
cmp [ebp+arg_0], 1
Compares argc to 1
return 0;
}
IDA If And Example
Objdump view - Hard to read!
000000000040051c <main>:
40051c: 55 push rbp
40051d: 48 89 e5 mov rbp,rsp
400520: 48 83 ec 10 sub rsp,0x10
400524: 89 7d fc mov DWORD PTR [rbp-0x4],edi
400527: 48 89 75 f0 mov QWORD PTR [rbp-0x10],rsi
40052b: 83 7d fc 02 cmp DWORD PTR [rbp-0x4],0x2
40052f: 7e 10 jle 400541 <main+0x25>
400531: 83 7d fc 08 cmp DWORD PTR [rbp-0x4],0x8
400535: 7f 0a jg 400541 <main+0x25>
400537: bf f4 05 40 00 mov edi,0x4005f4
40053c: e8 af fe ff ff call 4003f0 <puts@plt>
400541: b8 00 00 00 00 mov eax,0x0
400546: c9 leave
400547: c3 ret
IDA View If And Example
IDA- While Example
#include <stdio.h>
i = 0;
while (i < 10)
{
printf("i: %i\n", i);
i += 2;
}
return 0;
}
IDA While Example
IDA While/While
#include <stdio.h>
int main(int argc, char* argv[]){
int i, j;
i = 0;
while (i < 10)
{
j = 0;
while (j < 5)
{
printf("i: %i, j: %i\n", i, j);
j++;
}
i++;
}
return 0;
}
IDA For Loop Example
#include <stdio.h>
return 0;
}
IDA For Loop Example
Goodies
Windows VM (dazzlecat/dazzleme)
~Desktop/training/assembly_samples
src Contains simple c programs that incorporate
a basic logic flow (if/else/etc)
bin compiled programs of the src with different
optimization levels
-O0 optimization for compilation time (default)
-O2 optimization more for code size and execution
time
-Os optimization for code size
IDA Example
IDA Patching- Demo
dazzlecatduo on github
[email protected]