现在的位置: 首页 > 综合 > 正文

用指针来"爬栈"

2014年10月04日 ⁄ 综合 ⁄ 共 2121字 ⁄ 字号 评论关闭
文章目录

用指针来"爬栈"

转自:http://dododododo.blog.sohu.com/4627612.html

 

分类: Programing 2006-06-16 13:04

指针是个好东西,她能在内存中随意的游走.下面来介绍一个有趣的应用--爬栈.

爬栈就是用指针,从子函数开始,顺着堆栈向下找母函数的过程.

先给出一段代码:

/////////////////////////////////////////

int papa(int a)
{

 int i = 2;
 int *ptr ;
 int EBP;
 i = a;
 ptr = &i;
 EBP = *(ptr+1);
 return 1;
}

int main(int argc, char* argv[])
{
 int ret = 0;
 int e = 3;

 ret = papa(e);

 return ret;
}

/////////////////////////////////////////

运行起来,跟到papa()里面,单步运行,ebp = 0x12ff20 看堆栈:

/////////////////////////////////////////

0x12ff1c:02 00 00 00 //变量i

0x12ff20:80 ff 12 00 //main()的EBP;

0x12ff24:df 84 40 00 //main()中下一条指令地址

0x12ff28:03 00 00 00 //传递给papa()的参数e

.....................

/////////////////////////////////////////

我们用"ptr = &i" 来得到变量i的地址,也就是0x12ff1c,然后ptr+1就可以得到papa()的EBP值,也就是0x12ff20;然后mian()的EBP就是存放在0x12ff20里面的值;然后存放在0x12ff28中的就是main()函数中下一条指令的地址.简单吧.......

然后,顺着EBP看:

/////////////////////////////////////////

0x12ff80:c0 ff 12 00 //mainCRTStartup 的 EBP

         49 11 40 00

.....................

0x12ffc0:f0 ff 12 00 //这里就没有了,新进程吗,与主进程(比如explorer.exe)没关系了

         4f 6d 81 7c //顺着这个再向上找

.....................

0x12fff0:00 00 00 00

         00 00 00 00

.....................

/////////////////////////////////////////

顺着0x7c816d4f向上找的话,你会进入到kernel32.dll,哈哈,好,我们来看看这段代码:

////////////////////////////////////////

7C816D2A   90               NOP
7C816D2B   90               NOP
7C816D2C   6A 0C            PUSH 0C
7C816D2E   68 586D817C      PUSH kernel32.7C816D58
7C816D33   E8 93B7FEFF      CALL kernel32.7C8024CB
7C816D38   8365 FC 00       AND DWORD PTR SS:[EBP-4],0
7C816D3C   6A 04            PUSH 4
7C816D3E   8D45 08          LEA EAX,DWORD PTR SS:[EBP+8]
7C816D41   50               PUSH EAX
7C816D42   6A 09            PUSH 9
7C816D44   6A FE            PUSH -2
7C816D46   FF15 A013807C    CALL DWORD PTR DS:[<&ntdll.NtSetInformat>; ntdll.ZwSetInformationThread
7C816D4C   FF55 08          CALL DWORD PTR SS:[EBP+8]  //喂,在这里!!
7C816D4F   50               PUSH EAX
7C816D50   E8 545FFFFF      CALL kernel32.ExitThread
7C816D55   90               NOP
7C816D56   90               NOP
7C816D57   90               NOP

///////////////////////////////////////

再向上走的话,你会发现,一个你很熟悉的函数CreateRemoteThread,最后是CreateThread!;

它由运行该exe的父进程调用!.

以上这些意味着,我用子函数的指针就可以对母函数的数据进行任意操作,如改改父函数的局部变量,从父函数偷点子函数不能获得的数据,甚至直接跳到父函数去执行都是可以的......

抱歉!评论已关闭.