x86
#include <stdio.h>
#include <stdint.h>
#ifdef _MSC_VER
#define MOVE_REGISTER_VALUE_TO_VARIABLE(reg, var) \
\
__asm mov var, reg;
#elif defined __GNUC__
#define MOVE_REGISTER_VALUE_TO_VARIABLE(reg, var) \
\
asm("movl %%" #reg ", %0\n" : \
"=r"( var ));
#else
#error "Neither Microsoft nor GNU compiler"
#endif
uint32_t retVal;
uint32_t* basePointer;
int __cdecl func(int param_1, char* param_2, int param_3) {
int local_1;
int local_2;
MOVE_REGISTER_VALUE_TO_VARIABLE(ebp, basePointer)
local_1 = 101;
local_2 = 102;
#ifdef __GNUC__
printf("EBP -4: Local 2 (gcc) = %d\n", basePointer[- 4]);
printf("EBP -3: Local 1 (gcc) = %d\n", basePointer[- 3]);
#elif defined _MSC_VER
printf("EBP -2: Local 2 (cl ) = %d\n", basePointer[- 2]);
printf("EBP -1: Local 1 (cl ) = %d\n", basePointer[- 1]);
#else
#error "Use Microsoft cl or gcc"
#endif
printf("EBP 0: ? = %d\n", basePointer[ 0]);
printf("EBP 1: Return address = %d\n", basePointer[ 1]);
printf("EBP 2: Parameter 1 = %d\n", basePointer[ 2]);
printf("EBP 3: Parameter 2 = %s\n", basePointer[ 3]);
printf("EBP 4: Parameter 3 = %d\n", basePointer[ 4]);
return 42;
}
int main() {
printf("Address of func = %d\n", &func);
// printf("ESP before call: %d\n", basePointer[0]);
// MOVE_REGISTER_VALUE_TO_VARIABLE(esp, basePointer)
func(1, "hello world", 3);
MOVE_REGISTER_VALUE_TO_VARIABLE(eax, retVal)
printf("EAX : Return value = %d\n", retVal);
return 0;
}
Compile
gcc -c -O0 prog.c
gcc prog.o
# objdump -d -S prog.o
cl /nologo /c prog.c
cl /nologo prog.obj
Output
.\a.exe
Address of func = 4199760
EBP -4: Local 2 (gcc) = 102
EBP -3: Local 1 (gcc) = 101
EBP 0: ? = 2686664
EBP 1: Return address = 4200043
EBP 2: Parameter 1 = 1
EBP 3: Parameter 2 = hello world
EBP 4: Parameter 3 = 3
EAX : Return value = 42
prog.exe
Address of func = 19730432
EBP -2: Local 2 (cl ) = 102
EBP -1: Local 1 (cl ) = 101
EBP 0: ? = 3931604
EBP 1: Return address = 19730659
EBP 2: Parameter 1 = 1
EBP 3: Parameter 2 = hello world
EBP 4: Parameter 3 = 3
EAX : Return value = 42
x64
#include <stdio.h>
#include <stdint.h>
#ifdef _MSC_VER
#todo ...
#define MOVE_REGISTER_VALUE_TO_VARIABLE(reg, var) \
\
__asm mov var, reg;
#elif defined __GNUC__
#define MOVE_REGISTER_VALUE_TO_VARIABLE(reg, var) \
\
asm("movq %%" #reg ", %0\n" : \
"=r"( var ));
#else
#error "Neither Microsoft nor GNU compiler"
#endif
uint64_t retVal;
uint64_t* basePointer;
uint64_t RDI, RSI, RDX;
int func(int param_1, char* param_2, int param_3) {
uint64_t local_1;
uint64_t local_2;
MOVE_REGISTER_VALUE_TO_VARIABLE(rbp, basePointer)
MOVE_REGISTER_VALUE_TO_VARIABLE(rdi, RDI )
MOVE_REGISTER_VALUE_TO_VARIABLE(rsi, RSI )
MOVE_REGISTER_VALUE_TO_VARIABLE(rdx, RDX )
local_1 = 101;
local_2 = 102;
#ifdef __GNUC__
printf("RBP -2: Local 2 (gcc) = %d\n", basePointer[- 2]);
printf("RBP -1: Local 1 (gcc) = %d\n", basePointer[- 1]);
#elif defined _MSC_VER
# todo
printf("RBP -2: Local 2 (cl ) = %d\n", basePointer[- 2]);
printf("RBP -1: Local 1 (cl ) = %d\n", basePointer[- 1]);
#else
#error "Use Microsoft cl or gcc"
#endif
printf("RBP 0: ? = %d\n", basePointer[ 0]);
printf("RBP 1: Return address = %ld\n", basePointer[ 1]);
printf("RDI : Parameter 1 = %d\n", RDI );
printf("RSI : Parameter 2 = %s\n", RSI );
printf("RDX : Parameter 3 = %d\n", RDX );
return 42;
}
int main() {
printf("Address of func = %ld\n", &func);
// printf("ESP before call: %d\n", basePointer[0]);
// MOVE_REGISTER_VALUE_TO_VARIABLE(esp, basePointer)
func(1, "hello world", 3);
MOVE_REGISTER_VALUE_TO_VARIABLE(rax, retVal)
printf("RAX : Return value = %ld\n", retVal);
return 0;
}