Reverse Engineering for Beginners

(avery) #1

CHAPTER 8. ACCESSING PASSED ARGUMENTS CHAPTER 8. ACCESSING PASSED ARGUMENTS


; EDX - 3rd argument
imul esi, edi
lea eax, [rdx+rsi]
ret

main:
sub rsp, 8
mov edx, 3
mov esi, 2
mov edi, 1
call f
mov edi, OFFSET FLAT:.LC0 ; "%d\n"
mov esi, eax
xor eax, eax ; number of vector registers passed
call printf
xor eax, eax
add rsp, 8
ret


Non-optimizing GCC:


Listing 8.7: GCC 4.4.6 x64

f:
; EDI - 1st argument
; ESI - 2nd argument
; EDX - 3rd argument
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], edi
mov DWORD PTR [rbp-8], esi
mov DWORD PTR [rbp-12], edx
mov eax, DWORD PTR [rbp-4]
imul eax, DWORD PTR [rbp-8]
add eax, DWORD PTR [rbp-12]
leave
ret
main:
push rbp
mov rbp, rsp
mov edx, 3
mov esi, 2
mov edi, 1
call f
mov edx, eax
mov eax, OFFSET FLAT:.LC0 ; "%d\n"
mov esi, edx
mov rdi, rax
mov eax, 0 ; number of vector registers passed
call printf
mov eax, 0
leave
ret


There are no “shadow space” requirements in System V *NIX[Mit13], but thecalleemay need to save its arguments somewhere
in case of registers shortage.


8.2.3 GCC: uint64_t instead of int


Our example works with 32-bitint, that is why 32-bit register parts are used (prefixed byE-).


It can be altered slightly in order to use 64-bit values:


#include <stdio.h>
#include <stdint.h>


uint64_t f (uint64_t a, uint64_t b, uint64_t c)
{
return a*b+c;

Free download pdf