找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 42355|回复: 67

[原创科普]一份标准的栈回溯代码[32/64/R3/R0全通用]

 火... [复制链接]

857

主题

2632

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36130
发表于 2013-12-27 22:54:43 | 显示全部楼层 |阅读模式
今天忽然间对栈回溯产生了兴趣,因为有人说WIN64AST的的行为监视器看不到调用堆栈,于是打算实现相关功能。

无意中上网搜索关于栈回溯的知识,结果震惊了,这么标准的东西,竟然被那些所谓的“大牛”写得繁杂无比,还要内联汇编,还只支持STDCALL!

于是怀着“帮助后人”的想法,写下了这份简单的代码,通用于R3和R0,支持WIN32/WIN64,因为没有内嵌汇编和使用硬编码,相信能支持所有的架构,包括ARM、MIPS、IA64等。

  1. #include <stdio.h>
  2. #include <Windows.h>

  3. typedef ULONG (WINAPI *RTLWALKFRAMECHAIN)(OUT PVOID *Callers, IN ULONG Count, IN ULONG Flags);

  4. RTLWALKFRAMECHAIN RtlWalkFrameChain=(RTLWALKFRAMECHAIN)GetProcAddress(GetModuleHandleW(L"ntdll.dll"),"RtlWalkFrameChain");

  5. void PrintStack()
  6. {
  7.         PVOID ary[MAX_PATH]={0}; //这里应该动态分配内存实现,直接用数组是偷懒的办法。
  8.         ULONG StackCount;
  9.         StackCount=RtlWalkFrameChain(ary,MAX_PATH,0);
  10.         printf("\nStackCount=%ld\n",StackCount);
  11.         for(ULONG i=0;i<StackCount;i++)
  12.                 printf("Stack[%d]=%p\n",i,ary[i]);
  13.         DebugBreak();
  14. }

  15. void funD()
  16. {
  17.         PrintStack();        
  18. }

  19. void funC()
  20. {
  21.         funD();
  22. }

  23. void funB()
  24. {
  25.         funC();
  26. }

  27. void funA()
  28. {
  29.         funB();
  30. }

  31. int main()
  32. {
  33.         funA();
  34.         getchar();
  35.         return 0;
  36. }
复制代码

使用方法:
用WINDBG运行程序,按下F5,然后用WINDBG查看栈信息即可。
32.png
64.png

思考题:
为什么WINDBG里显示的数据和程序打印的数据有一个不同呢?

附件:
游客,如果您要查看本帖隐藏内容请回复

12

主题

144

回帖

0

精华

铜牌会员

积分
281
发表于 2014-1-5 18:10:03 | 显示全部楼层
下载附件回复主题

0

主题

38

回帖

0

精华

铜牌会员

积分
102
发表于 2014-2-27 15:53:23 | 显示全部楼层
老规矩,先回后下!!!!!!!

0

主题

14

回帖

0

精华

铂金会员

积分
2276
发表于 2014-3-22 10:44:52 | 显示全部楼层
回复主题,下载附件

1

主题

29

回帖

0

精华

铜牌会员

积分
94
发表于 2014-5-7 13:43:50 | 显示全部楼层
看看事实!!!!

0

主题

6

回帖

0

精华

铜牌会员

积分
32
发表于 2014-7-9 13:38:02 | 显示全部楼层
一份标准的栈回溯代码

0

主题

10

回帖

0

精华

铜牌会员

积分
80
发表于 2014-9-4 15:00:24 | 显示全部楼层
学习知识,回复一下

0

主题

33

回帖

0

精华

铂金会员

积分
1827
发表于 2014-9-21 00:39:06 | 显示全部楼层
通用的  赞一个

1

主题

77

回帖

0

精华

铂金会员

积分
1972
发表于 2014-10-31 00:12:28 | 显示全部楼层
学习了

0

主题

13

回帖

0

精华

铜牌会员

积分
47
发表于 2014-10-31 11:51:59 | 显示全部楼层
不晓得

0

主题

5

回帖

0

精华

初来乍到

积分
21
发表于 2014-11-21 18:18:55 | 显示全部楼层
0126103D是RtlWalkFrameChain的返回地址
DebugBreak() 异常分发到调试器,所以调试器显示的是引起异常的地址  这样解释对吧

5

主题

52

回帖

0

精华

钻石会员

积分
4275
发表于 2014-11-23 22:27:36 | 显示全部楼层
老大我来学习了~

0

主题

62

回帖

0

精华

银牌会员

积分
341
发表于 2014-11-26 10:28:18 | 显示全部楼层
不错,这个实用哈哈

1

主题

82

回帖

0

精华

铜牌会员

积分
156
发表于 2014-12-17 13:49:12 | 显示全部楼层
哈哈哈好东西哈哈哈

0

主题

8

回帖

0

精华

铜牌会员

积分
36
发表于 2015-1-5 09:34:34 | 显示全部楼层
感谢分享!

0

主题

8

回帖

0

精华

铜牌会员

积分
36
发表于 2015-1-5 09:34:51 | 显示全部楼层
感谢分享

1

主题

19

回帖

0

精华

铜牌会员

积分
43
发表于 2015-1-12 12:54:16 | 显示全部楼层
回复主题,下载附件

0

主题

3

回帖

0

精华

初来乍到

积分
19
发表于 2015-5-4 10:11:56 | 显示全部楼层
支持一个!

0

主题

15

回帖

0

精华

贵宾会员

积分
930
发表于 2015-6-10 02:31:13 | 显示全部楼层
不错
头像被屏蔽

0

主题

10

回帖

0

精华

铂金会员

积分
1934
发表于 2015-6-10 16:18:48 | 显示全部楼层
提示: 该帖被管理员或版主屏蔽

30

主题

693

回帖

0

精华

钻石会员

积分
2815
发表于 2015-6-10 22:00:43 | 显示全部楼层
学习了 谢谢分享哈

0

主题

10

回帖

0

精华

初来乍到

积分
30
发表于 2015-9-16 10:59:51 | 显示全部楼层
叮叮叮

2

主题

165

回帖

0

精华

金牌会员

积分
944
发表于 2015-9-16 22:05:45 | 显示全部楼层
来看看栈回溯

5

主题

103

回帖

0

精华

铜牌会员

积分
252
发表于 2015-9-30 19:30:48 | 显示全部楼层
线性分析,谢谢分享。

0

主题

65

回帖

0

精华

金牌会员

积分
1011
发表于 2015-10-1 04:25:02 | 显示全部楼层
学习了 感谢分享

0

主题

17

回帖

0

精华

贵宾会员

积分
204
发表于 2015-10-17 13:42:30 | 显示全部楼层
这个貌似很强大啊。支持

2

主题

72

回帖

0

精华

银牌会员

积分
597
发表于 2015-10-19 16:07:11 | 显示全部楼层
前些天看到栈回溯好像可以欺骗父进程检测,请问楼主是否有研究过?

0

主题

5

回帖

0

精华

初来乍到

积分
15
发表于 2015-10-21 19:10:48 | 显示全部楼层
下来看看

0

主题

10

回帖

0

精华

铜牌会员

积分
160
发表于 2015-10-22 09:17:13 | 显示全部楼层
确实是非常的受用  不错

0

主题

26

回帖

0

精华

铜牌会员

积分
129
发表于 2015-10-31 23:56:04 | 显示全部楼层
how it possible

0

主题

41

回帖

0

精华

铜牌会员

积分
116
发表于 2015-11-30 08:26:30 | 显示全部楼层
学习下~
头像被屏蔽

0

主题

29

回帖

0

精华

金牌会员

积分
976
发表于 2016-1-8 22:57:16 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表