0% found this document useful (0 votes)
13 views33 pages

Lesson 2.1 - Intro + x86-x64 Assembly

This document provides an overview of x86 and x64 assembly architectures, highlighting their key features, including instruction sets, registers, and operational modes. It also compares these architectures with ARM and RISC-V, detailing differences in instruction length, memory access, and performance enhancements. Additionally, it covers data movement methods and arithmetic operations within x86 assembly language, providing examples and syntax variations.

Uploaded by

Braincain007
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views33 pages

Lesson 2.1 - Intro + x86-x64 Assembly

This document provides an overview of x86 and x64 assembly architectures, highlighting their key features, including instruction sets, registers, and operational modes. It also compares these architectures with ARM and RISC-V, detailing differences in instruction length, memory access, and performance enhancements. Additionally, it covers data movement methods and arithmetic operations within x86 assembly language, providing examples and syntax variations.

Uploaded by

Braincain007
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 33

Lesson 2.

1:
x86 + x64 Assembly
CSC448/548-CYEN404 – REVERSE ENGINEERING

DR. ANDREY TIMOFEYEV


OUTLINE
•Overview of computer architectures.
•x86 architecture & assembly.
•x64 architecture.
COMPUTER ARCHITECTURES (1)
•x86 (IA32) – 32-bit little-endian architecture based on Intel 8086 processor.
• Complex instruction set (CISC) architecture.
• Can address up to 4GB of physical memory.
• Intel syntax notation vs. AT&T syntax notation.
•x64 (x86-64) – 64-bit extension of x86 architecture.
• Expands on x86 registers amount and size.
• Expands x86 memory addressing to 16EB of physical memory.
• Servers & high-performance computing application.
COMPUTER ARCHITECTURES (2)
•ARM (Advanced RISC Machine) – 32-bit little-endian architecture.
• Proprietary reduced instruction set (RISC) architecture.
• Energy-efficient, relatively inexpensive, very powerful.
• ARMv8-A (AArch64) – 64-bit extension to 32-bit ARM.
•RISC-V (“risc-five”) – 32/64-bit bi-endian architecture.
• Open-source RISC architecture.
• RV32I & RV64I instruction sets.
• Simpler & more effective instructions than ARM.
• “Potentially” more energy efficiently than ARM.
COMPUTER ARCHITECTURES (3)
•Additional differences:
• Instruction length.
• x86 & x64 instructions are longer than ARM instructions.
• RISC-V instructions can be either longer or shorter than ARM instructions.
• Memory access.
• x86 & x64 processors can access memory directly.
• ARM & RISC-V processors must use load and store instructions to access memory.
• Branch prediction.
• x86, x64, ARM processors use branch prediction to improve performance. RISC-V processors typically do not.

•Estimated device shipments by architecture in 2022:


Architecture Devices Market share
x86/x64 1.39 billion (PCs / servers) 97.8% of PCs
ARM 6.4 billion (mobile devices, embedded systems) 90% of mobile devices
RISC-V <100 million (MCU, IoT, HPC) <1%
x86: INTRO
•Two modes of operation of x86 processor:
• Real mode. • Protected mode.
• Processor powered on to this mode. • Mode in which OS executes.
• Only supports 16-bit instruction set. • Supports virtual memory, paging, other OS features.

•Ring level – an abstraction that implements privilege separation.


• Ring 0 – the highest privilege level. Can modify all system setting.
• Kernel level.
• Ring 1 & Ring 2 – not commonly used.
• Ring 3 – the lowest privilege level. Can only read/modify a subset of system settings.
• User level.

•Registers – high-speed storage locations within the CPU.


• Holds data & instructions that are currently being processed.
• Short-term memory for quick access to frequently used data/instructions.
x86: REGISTERS (1)
•x86 register categories & purpose:
• General purpose registers (GPRs):
• EAX – accumulator register (AX)
• EBX – base register (BX)
• ECX – counter in loops (CX)
• EDX – data register (DX)
• ESI – source in string/memory operations (SI)
• EDI – destination in string/memory operations (DI)
• EBP – base frame pointer (BP)
• ESP – stack pointer (SP)
• Instruction pointer register:
• EIP – memory address of next instruction
x86: REGISTERS (2)
•x86 register categories & purpose (cont.):
• Flag register:
• CF (bit 0) – carry flag
• PF (bit 2) – parity flag
• ZF (bit 6) – zero flag
• SF (bit 7) – sign flag
• TF (bit 8) – trap flag
• OF (bit 11) – overflow flag
• Segment registers (16 bits each):
• SS – stack segment
• CS – code segment
• DS – data segment
• ES – extra segment
• FS/GS – F/G segment

Full flags reference


x86: REGISTERS (3)
•x86 register categories & purpose (cont.):
• Control registers (CRs):
• CR0 – controls memory paging, floating-point unit (FPU), write-protect bit.
• CR2 – contains physical address of the page fault that caused the processor to trap to the OS
• CR3 – contains base address of the page directory (data structure for virtual memory management)
• CR4 – controls hardware virtualization settings
• Debug registers (DRs):
• DR0-DR3 – hardware breakpoints
• DR4-DR5 – not used in practice
• DR6 – debug status register
• DR7 – debug control register
• CRs & DRs are not directly accessible by user-level instructions.
• Used by OS and hardware-specific code.
x86: INSTRUCTION SET BASICS (1)
•x86 instruction syntax:

• Label/address – defines location of instruction line.


• Mnemonic – human-readable instruction. Every instruction has equivalent opcode byte.
• Operands – instruction arguments: destination, source.
• Comments – denoted by semicolon.

•Example:
Address Opcode Instructions
00A92D7C B8 00000080 MOV EAX,80000000h
00A92D81 B9 02000000 MOV ECX,2
00A92D86 F7E1 MUL ECX
In memory:
00A92D7C B8 00 00 00 80 B9 02 00 00 00 F7 E1
x86: INSTRUCTION SET BASICS (2)
•x86 has two syntax notations:
• Intel • AT&T
mov ecx, AABBCCDDh movl $0xAABBCCDD, %ecx
mov ecx,[eax] movl (%eax), %ecx
mov ecx, eax movl %eax, %ecx

•Differences:
• AT&T prefixes registers with %, immediates with $. Intel does not.
• AT&T adds prefix to indicate operation width. Intel does not.
• AT&T puts source operand then destination. Intel reverses the order.
x86: DATA MOVEMENT (1)
•x86 data movement methods:
• Register to register.
• Register to memory.
• Immediate to register.
• Immediate to memory.
• Memory to register.
• Memory to memory.
•Memory to memory is not supported by RISC architectures.
ARM:
01: 1B 68 LDR R3, [R3] ; read the value at address R3
02: 5A 1C ADDS R2, R3, #1 ; add 1 to it
03: 1A 60 STR R2, [R3] ; write updated value back to address R3
x86:
01: FF 00 inc dword ptr [eax] ; directly increment value at address EAX
x86: DATA MOVEMENT (2)
•MOV instruction:
• Data to registers.
01: BE 3F 00 0F 00 mov esi, 0F003h ; set ESI = 0xF003
02: 8B F1 mov esi, ecx ; set ESI = ECX
• Data to/from memory.
• Method: [base register + offset]
Example 1: simple data moves
Assembly Pseudo C
01: C7 00 01 00 00+ mov dword ptr [eax], 1 01: *eax = 1;
02: 8B 08 mov ecx, [eax] 02: ecx = *eax;
03: 89 18 mov [eax], ebx 03: *eax = ebx;
04: 89 46 34 mov [esi+34h], eax 04: *(esi+34) = eax;
05: 8B 46 34 mov eax, [esi+34h] 05: eax = *(esi+34);
06: 8B 14 01 mov edx, [ecx+eax] 06: edx = *(ecx+eax);
x86: DATA MOVEMENT (3)
•MOV instruction (cont.):
• Data to/from memory.
• Method: [base register + offset]
Example 2: access structure members at location computed at runtime
Pseudo C
struct ExampleStruct {
int integer;
Assembly
char character;
; Assuming struct starts at ebp-0xC
float floating;
01: C7 45 F4 0A 00 00 00 mov dword [ebp-0xC], 10
};
02: C6 45 F8 41 mov byte [ebp-0x8], ‘A‘
03: C7 45 FC CD CC 04 40 mov dword [ebp-0x4], 0x4044CCCD
int main() {
04: 8A 45 F8 mov al, [ebp-0x8]
struct ExampleStruct myStruct = {10, 'A', 3.14f};
05: C7 45 FC AE 47 E1 3F mov dword [ebp-0x4], 0x3FE147AE
char value_char = myStruct.character;
06: 81 25 F4 FF FF FF 00 and dword [ebp-0xC], 0
myStruct.floating = 2.718f;
myStruct.integer = 0;
return 0;
}
x86: DATA MOVEMENT (4)
•MOV instruction (cont.):
• Data to/from memory.
• Method: [base + index * scale]
Example: access array-type objects
Assembly
Pseudo Java
01: B9 00 00 00 00 mov ecx, 0
public class ArrayAccess {
02: BE 00 00 00 00 mov esi, array
public static void main(String[] args) {
loop_start:
int[] array = {10, 20, 30};
03: 83 F9 03 cmp ecx, 3
for (int i = 0; i < 3; i++) {
04: 7D 0D jge loop_end
int value = array[i];
05: 8B 04 8E mov eax, [esi + ecx * 4]
}
06: 41 inc ecx
}
07: EB F4 jmp loop_start
}
loop_end:
x86: DATA MOVEMENT (5)
•MOVS(B/W/D) instructions:
• Move 1/2/4-byte data between memory addresses.
• EDI = destination / ESI = source.
• Usage: string/memory copy function when the length is known at compile time.
• Example: string & memcpy
Assembly
_start:
Pseudo C
01: Bf, source mov esi, source
int main() {
02: B7, destination mov edi, destination
char source[] = "Hello, Assembly!";
copy_loop:
char destination[20];
03: A4 movsb
memcpy(destination, source, strlen(source) + 1);
04: A8, 00 test al, al
return 0;
05: 74, 06 jz end_copy
}
06: EB, F9 jmp copy_loop
end_copy:
x86: ARITHMETIC OPERATIONS (1)
•x86 fundamental arithmetic / bit-level operations:
• ADD, SUB, INC, DEC, AND, OR, XOR, NOT, SHL, SHR.
• Examples:
01: 83 C4 14 add esp, 14h ; esp = esp + 0x14
02: 2B C8 sub ecx, eax ; ecx = ecx – eax
03: 83 EC 0C sub esp, 0Ch ; esp = esp - 0xC
04: 41 inc ecx ; ecx = ecx + 1
05: 4F dec edi ; edi = edi – 1
06: 83 C8 FF or eax, 0FFFFFFFFh ; eax = eax | 0xFFFFFFFF
07: 83 E1 07 and ecx, 7 ; ecx = ecx & 7
08: 33 C0 xor eax, eax ; eax = eax ^ eax
09: F7 D7 not edi ; edi = ~edi
10: C0 E1 04 shl cl, 4 ; cl = cl << 4
11: D1 E9 shr ecx, 1 ; ecx = ecx >> 1

• SHL/SHR optimize mul & div.


• If multiplicand/divisors are power of 2.
• 1002/2 = 100>>1
• 1002*2 = 100<<1
x86: ARITHMETIC OPERATIONS (2)
•x86 fundamental arithmetic and bit-level operations (cont.):
• MUL reg/mem
• Operand multiplied with AL/AX/EAX. Result stored in AX/DX:AX/EDX:EAX.
• Examples:
01: F7 E1 mul ecx ; EDX:EAX = EAX * ECX
02: F7 66 04 mul dword ptr [esi+4] ; EDX:EAX = EAX * dword_at(ESI+4)
03: F6 E1 mul cl ; AX = AL * CL
04: 66 F7 E2 mul dx ; DX:AX = AX * DX
05: B8 03 00 00 00 mov eax, 3 ; set EAX=3
06: B9 22 22 22 22 mov ecx, 22222222h ; set ECX=0x22222222
07: F7 E1 mul ecx ; EDX:EAX = 3 * 0x22222222 = 0x66666666
; hence, EDX=0, EAX=0x66666666
08: B8 03 00 00 00 mov eax, 3 ; set EAX=3
09: B9 00 00 00 80 mov ecx, 80000000h ; set ECX=0x80000000
10: F7 E1 mul ecx ; EDX:EAX = 3 * 0x80000000 = 0x180000000
; hence, EDX=1, EAX=0x80000000
x86: ARITHMETIC OPERATIONS (3)
•x86 fundamental arithmetic and bit-level operations (cont.):
• IMUL has three forms:
• IMUL reg/mem
• IMUL reg1, reg2/mem
• reg1 = reg1 * reg2/mem
• IMUL reg1, reg2/mem, imm
• reg1 = reg2 * imm
• Examples:
01: F7 E9 imul ecx ; EDX:EAX = EAX * ECX
02: 69 F6 A0 01 00+ imul esi, 1A0h ; ESI = ESI * 0x1A0
03: 0F AF CE imul ecx, esi ; ECX = ECX * ESI
x86: ARITHMETIC OPERATIONS (4)
•x86 fundamental arithmetic and bit-level operations (cont.):
• DIV/IDIV reg/mem
• Dividend – AX/DX:AX/EDX:EAX. Quotient/remainder – AL/AH, AX/DX, EAX/EDX
• Examples:
01: F7 F1 div ecx ; EDX:EAX / ECX, quotient in EAX
02: F6 F1 div cl ; AX / CL, quotient in AL, remainder in AH
03: F7 76 24 div dword ptr [esi+24h] ; see line 1
04: B1 02 mov cl, 2 ; set CL = 2
05: B8 0A 00 00 00 mov eax, 0Ah ; set EAX = 0xA
06: F6 F1 div cl ; AX/CL = A/2 = 5 in AL (quotient),
; AH = 0 (remainder)
07: B1 02 mov cl, 2 ; set CL = 2
08: B8 09 00 00 00 mov eax, 09h ; set EAX = 0x9
09: F6 F1 div cl ; AX/CL = 9/2 = 4 in AL (quotient),
; AH = 1 (remainder)
x86: STACK OPERATIONS (1)
•In x86, stack - contiguous memory region pointed by ESP & growing downward.
• PUSH decrements ESP by 4 & writes data at location pointed by ESP.
• POP reads data & incrementes ESP by 4.
• ESP can be directly modified by ADD/SUB.

• Example:
; initial ESP = 0xb20000
01: B8 AA AA AA AA mov eax, 0AAAAAAAAh
02: BB BB BB BB BB mov ebx, 0BBBBBBBBh
03: B9 CC CC CC CC mov ecx, 0CCCCCCCCh
04: BA DD DD DD DD mov edx, 0DDDDDDDDh
05: 50 push eax ; address 0xb1fffc will contain the value 0xAAAAAAAA
; ESP will be 0xb1fffc (=0xb20000-4)
06: 53 push ebx ; address 0xb1fff8 will contain the value 0xBBBBBBBB
; ESP will be 0xb1fff8 (=0xb1fffc-4)
07: 5E pop esi ; ESI will contain the value 0xBBBBBBBB
; ESP will be 0xb1fffc ; (=0xb1fff8+4)
08: 5F pop edi ; EDI will contain the value 0xAAAAAAAA
; ESP will be 0xb20000 ; (=0xb1fffc+4)
x86: STACK OPERATIONS (2)
•x86 uses stack & CALL/RET operations to implement function calls.
• CALL perfoms two operations:
• Pushes return address to the stack.
• Address immediately after CALL instruction.
• Changes EIP to the call destination.
• Transfers control to the call target & begins execution.
• RET pops address stored on stack into EIP & transfers control to it.
• Calling convention - set of rules dictating how function calls work at the machine level.
• Defined by Application Binary Interface (ABI) for a particular system.
CDECL STDCALL FASTCALL

Pushed on the stack from right-to- Same as CDECL except that the callee First two parameters are passed in
Parameters left. Caller must clean up the stack must clean the stack. ECX and EDX. The rest are on the
after the call. stack.

Return value Stored in EAX.

Non-volatile registers EBP, ESP, EBX, ESI, EDI.


x86: STACK OPERATIONS (3)
•x86 uses stack & CALL/RET operations to implement function calls.
• Example:
Pseudo C Assembly
int 01: 004113A0 55 push ebp
__cdecl addme(short a, short b) 02: 004113A1 8B EC mov ebp, esp
{ 03: ...
return a+b; 04: 004113BE 0F BF 45 08 movsx eax, word ptr [ebp+8]
} 05: 004113C2 0F BF 4D 0C movsx ecx, word ptr [ebp+0Ch]
06: 004113C6 03 C1 add eax, ecx
07: ...
08: 004113CB 8B E5 mov esp, ebp
09: 004113CD 5D pop ebp
10: 004113CE C3 ret

sum = addme(x, y); 01: 004129F3 50 push eax


02: ...
03: 004129F8 51 push ecx
04: 004129F9 E8 F1 E7 FF FF call addme
05: 004129FE 83 C4 08 add esp, 8
x86: CONTROL FLOW (1)
•x86 conditional execution of if/else, switch/case, while/for is implemented through:
• CMP, TEST, JMP, Jcc instructions + EFLAG register.
• Arithmetic instructions update flags based on result.
• Jcc instruction (“cc” = conditional code) changes flow based on flags.

•Common conditional codes:


CC Description Machine description
B/NAE Below/Neither Above nor Equal. Used for unsigned operations. CF=1
NB/AE Not Below/Above or Equal. Used for unsigned operations. CF=0
E/Z Equal/Zero ZF=1
NE/NZ Not Equal/Not Zero ZF=0
L Less than/Neither Greater nor Equal. Used for signed operations. (SF ^ OF) = 1
GE/NL Greater or Equal/Not Less than. Used for signed operations. (SF ^ OF) = 0
G/NLE Greater/Not Less nor Equal. Used for signed operations. ((SF ^ OF) | ZF) = 0
x86: CONTROL FLOW (2)
Assembly
•If/else = compare/test followed by Jcc. simpleFunction:
• Example: ; Function prologue: allocating space for local variables
push ebp ; Save old base pointer
Pseudo C mov ebp, esp ; Set base pointer to current stack pointer
int simpleFunction(int x) { sub esp, 4 ; Reserve space for local variables (int result)
int result;
; Compare x with 0 and x with 10
if (x > 0 && x == 10) { mov eax, [ebp+8] ; Move 'x' into eax
result = 11; cmp eax, 0 ; Compare with 0
} else { jle elseBlock ; Jump to else block if x <= 0
result = -5; cmp eax, 10 ; Compare with 10
} jne elseBlock ; Jump to else block if x != 10

return result; ; If block: x > 0 and x == 10


} mov DWORD [ebp-4], 11 ; Set result = 11
jmp endFunction ; Jump to end of function

elseBlock: ; Else block: !(x > 0 && x == 10)


mov DWORD [ebp-4], -5 ; Set result = -5

endFunction: ; Function epilogue: restoring stack & returning result


mov eax, [ebp-4] ; Move result to eax
leave ; Restore the stack frame
ret ; Return with the result in eax
x86: CONTROL FLOW (3)
Assembly
•switch-case = sequence of if/else statements 01: 55 push ebp
• Example 1: simple case 02: 8B EC
03: 8B 45 08
mov ebp, esp
mov eax, [ebp+8]
Pseudo C 04: 83 E8 41 sub eax, 41h
05: 74 05 jz short loc_caseA
unsigned char switchme(int a)
06: 48 dec eax
{
07: 74 05 jz short loc_caseB
unsigned char res; 08: 48 dec eax
switch(a) { 09: 74 07 jz short loc_caseC
case 0x41: 10: B0 5A mov al, 5Ah
res = 'A'; 11: 0F B6 C0 movzx eax, al
break; 12: 5D pop ebp
case 0x42: 13: C3 retn
res = 'B'; 14: loc_caseC:
break; 15: B0 43 mov al, 43h
case 0x43: 16: 0F B6 C0 movzx eax, al
res = 'C'; 17: 5D pop ebp
break; 18: C3 retn
19: loc_caseB:
default:
20: B0 42 mov al, 42h
res = 'Z';
21: 0F B6 C0 movzx eax, al
break; 22: 5D pop ebp
} 23: C3 retn
return res; 24: loc_caseA:
} 25: B0 41 mov al, 41h
26: 0F B6 C0 movzx eax, al
27: 5D pop ebp
28: C3 retn
x86: CONTROL FLOW (4)
•switch-case = sequence of if/else statements
• Example 2: jump table Assembly
01: 81 FF 05 00 00 00 cmp edi, 5
Pseudo C 02: 77 0A ja short loc_10001141
switch(edi) { 03: FF 24 B5 A4 11 00 10 jmp ds:off_100011A4[edi*4]
case 0: 04: loc_10001125:
05: C7 06 40 00 00 00 mov esi, 40h
case 1: // goto loc_10001125;
06: EB 0E jmp short loc_10001145
esi = 0x40;
07: loc_1000112C:
break; 08: C7 06 20 00 00 00 mov esi, 20h
case 2: 09: EB 0E jmp short loc_10001145
case 5: // goto loc_1000113A; 10: loc_10001133:
esi = 0x30; 11: C7 06 38 00 00 00 mov esi, 38h
break; 12: EB 0E jmp short loc_10001145
case 3: // goto loc_1000112C; 13: loc_1000113A:
esi = 0x20; 14: C7 06 30 00 00 00 mov esi, 30h
break; 15: EB 08 jmp short loc_10001145
case 4: // goto loc_10001133; 16: loc_10001141:
esi = 0x38; 17: 8B 74 24 0C mov esi, [esp+0Ch]
break; 18: ...
19: A4 11 00 10 off_100011A4 dd offset loc_10001125
default: // goto loc_10001141;
20: A4 11 00 10 dd offset loc_10001125
esi = *(esp+0xC)
21: 3A 11 00 10 dd offset loc_1000113A
break; 22: 2C 11 00 10 dd offset loc_1000112C
} 23: 33 11 00 10 dd offset loc_10001133
... 24: 3A 11 00 10 dd offset loc_1000113A
x86: CONTROL FLOW (5)
•loop = Jcc + JMP instructions
• Example 1: for loop -> if/else+goto
Pseudo C (for loop): Assembly:
for (int i=0; i<10; i++) { 01: B8 00 00 00 mov edi, ds:__imp__printf
; Move the address of "__imp__printf" to register EDI
printf("%d\n", i);
02: 33 F6 xor esi, esi ; Clear register ESI
} 03: 8D 8B 00 lea ebx, [ebx+0] ; Load the address of EBX into itself
printf("done!\n"); 04: loc_401010:
05: 50 push esi ; Push the loop counter (ESI) onto the stack
06: 68 40 00 00 00 push offset Format
Pseudo C (if/else+goto):
; Push the address of "Format" string onto the stack
int i = 0; 07: FF D7 call edi ; Call the "printf" function
loop_start: 08: 40 inc esi ; Increment the loop counter
if (i < 10) { 09: 83 C4 08 add esp, 8 ; Add 8 to stack pointer (clean up arguments)
printf("%d\n", i); 10: 83 7E 0A cmp esi, 0Ah ; Compare ESI with 10 (loop limit)
i++; 11: 7C 00 F8 jl short loc_401010 ; Jump to "loc_401010" if ESI < 10
12: 68 44 00 00 00 push offset aDone
goto loop_start;
; Push the address of "aDone" string onto the stack
} 13: FF D7 call edi ; Call the "printf" function
printf("done!\n"); 14: 83 C4 04 add esp, 4 ; Add 4 to stack pointer (clean up argument)
x86: CONTROL FLOW (6)
Assembly:
•loop = Jcc + JMP instructions 01: sub_1000AE3B proc near ; Declare fxn sub_1000AE3B as a near procedure.
02: push edi ; Save value of register EDI on the stack.
• Example 2: while loop 03: push esi ; Save value of register ESI on the stack.
Pseudo C: 04: call ds:lstrlenA
char *sub_1000AE3B (char *str) ; Call the function lstrlenA located at address stored in EDI.
05: mov edi, eax ; Move return value of lstrlenA to EDI.
{ 06: xor ecx, ecx ; Clear register ECX to 0 (loop counter).
int len, i=0, j=0; 07: xor edx, edx ; Clear register EDX to 0 (pointer).
len = lstrlenA(str); 08: test edi, edi ; Check if string length in EDI is zero.
if (len <= 0) { 09: jle short loc_1000AE5B ; If string length = zero/negative, jump to end label.
str[j] = 0; 10: loc_1000AE4D: ; Loop start label.
return str; 11: mov al, [edx+esi]
; Load byte at current memory location (pointed to by EDX+ESI) into AL.
} 12: mov [ecx+esi], al
while (j < len) { ; Store byte from AL into memory location pointed to by ECX+ESI.
str[i] = str[j]; 13: add edx, 3 ; Increment memory pointer EDX by (skip null terminator).
j = j+3; 14: inc ecx ; Increment the loop counter ECX.
i = i+1; } 15: cmp edx, edi ; Compare current memory location with string length in EDI.
str[i] = 0; 16: jl short loc_1000AE4D
; If current memory location is less than string length, jump back to the loop.
return str; 17: loc_1000AE5B: ; Loop end label.
} 18: mov byte ptr [ecx+esi], 0 ; Store null terminator (0) at the end of copied string.
19: mov eax, esi ; Move value of ESI (original string pointer) to EAX.
20: pop edi ; Restore saved value of EDI from stack.
21: retn
; Return from function, returning original string pointer in EAX.
22: sub_1000AE3B endp ; End of function declaration.
x86: CONTROL FLOW (7)
•loop = Jcc + JMP instructions
• Example 3: LOOP instruction
Pseudo C: Assembly:
while (ecx != 0) { 01: 8B CA mov ecx, edx ; Move register edx value to register ecx
eax = *edi; 02: loc_CFB8F: ; Label: loc_CFB8F
edi++; 03: AD lodsd ; Load doubleword from memory into register eax
*esi = ~eax; ; increment the memory pointer
esi++; 04: F7 D0 not eax ; Bitwise NOT the value in register eax
ecx--; 05: AB stosd ; Store doubleword from register eax to memory
} ; increment the memory pointer
06: E2 FA loop loc_CFB8F ; Loop back to the label while ecx is not zero
x64: REGISTERS (1)
•x64 register set:
• General Purpose Registers (GPRs).
• Eighteen 64-bit GPRs with prefix R.
• 64-bit R0-R7 = RAX, RCX, RBX, RDX, RSP, RBP, RSI, RDI.
• 32-bit R0D-R7D = EAX, ECX, EBX, EDX, ESP, EBP, ESI, EDI.
• 16-bit R0W-R7W = AX, CX, BX, DX, SP, BP, SI, DI.
• 8-bit R0B-R7B = AL, CL, BL, DL, SPL, BPL, SIL, DIL.
• RIP & RFLAGS.
• Instruction pointer and flags.
• Segment Registers.
• CS, DS, SS, ES, FS, GS.
• XMM Registers.
• Sixteen 128-bit registers XMM0-XMM15.
• Floating-point & integer arithmetic.
• 128-bit operations or parallel operations.
• Two 64-bit integer operations, four 32-bit integer operations, etc.
x64: REGISTERS (2)
•x64 register set (cont.):
• YMM Registers.
• Sixteen 256-bit registers YMM0-YMM15.
• Direct or parallel floating-point arithmetic.
• Four 64-bit floating-point operations.
• FPU Registers.
• Eight registers for computing with 80-bit floating point values.
• Other Registers.
• Eight 32-bit processor control registers: CR0-CR7.
• Four 16-bit table registers: GDTR, IDTR, LDTR and TR.
• Memory management, interrupt handling, multitasking.
• Eight 32-bit debug registers: DR0-DR7.
• Five test registers: TR3-TR7.
• Memory type range registers.
• Machine specific registers.
• Machine check registers.
x64: OPERATIONS
•x64 data movement.
• RIP-relative addressing – instructions reference data at a relative position to RIP.
Assembly
01: 48 8B 05 00 00+ mov rax, qword ptr cs:loc_A
; originally written as "mov rax, [rip]“
02: loc_A:
03: 48 31 C0 xor rax, rax
04: 90 nop
•x64 arithmetic operations automatically promoted to 64-bits.
Assembly
01: 48 B8 88 77 66+ mov rax, 1122334455667788h
02: 31 C0 xor eax, eax ; will also clear the upper 32 bits of RAX.
; i.e., RAX=0 after this
03: 48 C7 C0 FF FF+ mov rax,0FFFFFFFFFFFFFFFFh
04: FF C0 inc eax ; RAX=0 after this

•x64 function invocation - parameters are passed through registers.


• Windows calling convention.
• First four parameters passed through RCX, RDX, R8, R9. Remaining pushed on the stack right-to-left.
• Linux calling convention.
• First six parameters are passed through RDI, RSI, RDX, RCX, R8, R9. Remaining pushed on the stack right-to-left.

You might also like