x86 notes

calculate a relocatable offset

-> instructions
0x109a: lea     rcx, [rip + 0x1af]
0x10a1: lea     rdi, [rip + 0xd1]
0x10a8: call    qword ptr [rip + 0x2f32]
0x10ae: hlt
0x10af: nop

-> relocation entries
%s: .rela.dyn
        0x3de8
        0x3df0
        0x4048
_ITM_deregisterTMCloneTable     0x3fd8
__libc_start_main       0x3fe0
__gmon_start__  0x3fe8
_ITM_registerTMCloneTable       0x3ff0
__cxa_finalize  0x3ff8
stdin   0x4050
%s: .rela.plt
puts    0x4018
printf  0x4020
fgets   0x4028
strcmp  0x4030
malloc  0x4038

as soon as the processor executes the next instruction
the instruction pointer points to the next instruction
in line...

0x10a8: call    qword ptr [rip + 0x2f32]
0x10ae: hlt

Thus [rip + 0x2f32] is equvivalent to [0x10ae + 0x2f32] which evaluates to 0x3fe0


https://medium.com/sector443/python-for-reverse-engineering-1-elf-binaries-e31e92c33732 .got -> Global Offset Table .ptl -> Procedure Linkage Table # https://stackoverflow.com/a/5469334 system@plt --> variable address for system syscall

32 bit register layout

+---------+------+------+------+------+------+------+------+------+
| syscall | arg0 | arg1 | arg2 | arg3 | arg4 | arg5 |      |      |
+---------+------+------+------+------+------+------+------+------+
|   %eax  | %ebx | %ecx | %edx | %esi | %edi | %ebp | %eip | %esp |
+---------+------+------+------+------+------+------+------+------+

64 bit register layout

+---------+------+------+------+------+------+------+
| syscall | arg0 | arg1 | arg2 | arg3 | arg4 | arg5 |
+---------+------+------+------+------+------+------+
|   %rax  | %rdi | %rsi | %rdx | %r10 | %r8  | %r9  |
+---------+------+------+------+------+------+------+

%rbp - %rip  - %rsp
  8  -   8  -  8

For 64 bit, the argument needs to be passed into CPU register instead of the stack. (https://arvandy.com/rop-emporium-split/)

x64 NASM cheat sheet

FROM https://gist.github.com/justinian/385c70347db8aca7ba93e87db90fc9a6#file-linux-x64-nasm-cheatsheet-md

Registers

|                         | 64 bit | 32 bit | 16 bit | 8 bit |
|-------------------------|--------|--------|--------|-------|
| A (accumulator)         | `RAX`  | `EAX`  | `AX`   | `AL`  |
| B (base, addressing)    | `RBX`  | `EBX`  | `BX`   | `BL`  |
| C (counter, iterations) | `RCX`  | `ECX`  | `CX`   | `CL`  |
| D (data)                | `RDX`  | `EDX`  | `DX`   | `DL`  |
|                         | `RDI`  | `EDI`  | `DI`   | `DIL` |
|                         | `RSI`  | `ESI`  | `SI`   | `SIL` |
| Numbered (n=8..15)      | `Rn`   | `RnD`  | `RnW`  | `RnB` |
| Stack pointer           | `RSP`  | `ESP`  | `SP`   | `SPL` |
| Frame pointer           | `RBP`  | `EBP`  | `BP`   | `BPL` |

As well as XMM0 .. XMM15 for 128 bit floating point numbers.

Calling Conventions

Put function arguments (first to last) in the following registers (64 bit representations): RDI, RSI, RDX, RCX, R8, R9, then push to stack (in reverse, has to be cleaned up by the caller!) XMM0 - XMM7 for floats

Return values are stored in RAX (int) or XMM0 (float)

RBP, RBX, R12, R13, R14, R15 will not be changed by the called function, all others may be

Align stack pointer (RSP) to 16 byte, calling pushes 8 bytes!

Keep in mind that strings (in C) are 0-terminated

Like in a normal C program, the label that is (de facto) called first is main, with the args argc (argcount) in RDI, and the char** argv in RSI (the commandline arguments as in C's main function).