这里可以简单的修改任意函数的返回地址,可以做到自定义EIP的指向,即可执行当前进程空间的任意指令,这里只是让大家更清楚栈帧结构,没有涉及跨进程的inline HOOK 等,后面会陆续讲下读取任意进程内存,修改任意进程函数执行流程等方法。
废话不多说了,直接上菜:
#include <stdio.h>
#include <windows.h>
/*
打印 main函数的返回地址的值(用途,你懂得!)
所需知识:函数栈帧结构
C调用约定,自右向左压栈
push argv
push argc
call main ; jmp main
main:
push ebp
mov ebp, esp
sub esp, 0x4 ; 0x4 == sum (sizeof(type) * count)
栈中:
argv
argc ; new ebp + 8
eip ; main ret 地址 == new ebp + 4
ebp ; old ebp value, new ebp postation
i ; i 局部变量 == new ebp - 4
*/
int main(int argc, char* argv[])
{
int i = 0; // ebp - 4
__asm {
mov eax, [ebp + 4]
mov i, eax
}
printf("%08x\n",i);
printf("%p\n", *(DWORD*)(((DWORD)&argc) - 4));
printf("%p\n", *(DWORD*)(((DWORD)&i) + 8));
return 0;
}
还有下面的调试图,一目了然: