首页
社区
课程
招聘
[原创]使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函数的调用过程。
2015-2-12 05:19 37453

[原创]使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函数的调用过程。

2015-2-12 05:19
37453
使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函数的调用过程。

(本文同步更新至我的51blog上,我最初是在那里发布的,由于引用该处的图片,因此带有水印,该贴原始出处如下:
http://shayi1983.blog.51cto.com/4681835/1613615


首先用文本编辑器写一个C++源程序名为StackFrame.cpp ,代码如下:

#include "stdio.h"

long add(long a, long b)
{
    long x = a, y = b;
    return (x + y);
}

int main(int argc, char* argv[])
{
    long a = 1, b = 2;
    
    printf("%d\n", add(a, b));

    return 0;
}


使用visual C++ IDE 对该源文件执行编译,汇编,链接一系列的操作后,最终生成的二进制可执行文件(PE格式)名为StackFrame.exe
回顾上述源码,main函数调用了标准C库函数printf打印信息,我们想要知道,
visual C++ 编译器是如何实现printf库函数的,并且StackFrame.exe采用的是静态链接还是动态链接,如果是后者,那么printf又调用了哪些位于动态链接库中的windows API函数?抑或是“动静”兼用?
要解答这些疑问,首先使用IDA PRO打开StackFrame.exe ,它会自动查找程序入口点,这是由编译器自动生成的启动代码,用于初始化我们编写的main函数执行前的环境,以及执行main函数退出后的收尾工作。
一般而言,只要反汇编的对象不是经过加壳或者插入了模糊代码,IDA PRO可以轻松识别程序入口点与main函数,这里为了简化分析流程,我们直接进入main函数的反汇编代码段,如下所示:











我们通过上面一系列的IDA PRO截图可以看到,地址 0x00404063处的call指令想要调用EnterCriticalSection函数,后者的地址尝试以call的操作数0x0040A018给出,但是这个地址处的值,即EnterCriticalSection函数的最终地址,需要操作系统加载器加载StackFrame.exe文件时才能确定,因此我们对磁盘上的文件反汇编时,无法确定动态链接库中函数的地址。
下面以PEview工具查看StackFrame.exe在磁盘上的“真实”面貌(而不是由IDA PRO “模拟”的运行时地址空间面貌)
之所以要先使用PEview工具,是因为后面的动态调试中,会与此处的信息对比,来加深理解程序在磁盘上与在内存中的异同。
使用PEview工具打开StackFrame.exe ,我们的重点是定位到PE文件中的导入表,因为无论是操作系统加载器,反汇编器,还是动态调试器,都依赖该表来解析导入的动态链接库与其中的函数。





我们尝试在原始PE文件中,计算并找出call ds:EnterCriticalSection 指令对应的字节序列,其实这没有想象中困难,而且在这里提出计算方法的原因是,后面会用同样的计算手法来判断Ollydbg中追踪到的EnterCriticalSection函数的实际地址,
该地址究竟属于kernel32.dll还是ntdll.dll?(因为有时Ollydbg给出的信息并不十分准确)届时会用到下面的计算方法。

首先,回到IDA PRO,打开StackFrame.exe的程序段窗口,如下所示:





前面指出,地址 0x00404063处的call指令想要调用EnterCriticalSection函数,因此计算 404063 - 401000 = 3063 , 3063 + 400 = 3463
3463这个值就是该指令字节码在StackFrame.exe的位置,下面验证:



接下来,使用Ollydbg打开StackFrame.exe进行动态调试,我们的目标在于定位EnterCriticalSection函数的入口处,并且单步跟进,查看其中的机器码,然后使用PEview工具,以上面的计算方法,验证Ollydbg给出的该函数所属的动态链接库文件信息是否准确,如下截图所示:











上面验证了StackFrame.exe 在运行时调用的共享库函数,与它在磁盘文件上的导入表中描述的行为一致。
最后,我们验证EnterCriticalSection这个 windows API函确实位于ntdll.dll这个动态链接库中,作为本案例的结尾。
首先,可以访问微软MSDN站点,查找关于EnterCriticalSection函数的信息:
https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms682608(v=vs.85).aspx











最后总结一下:
stack.exe使用“部分”静态链接,其中多数的代码为库代码,
这包含由“编译器库”添加的,处理程序初始化的启动代码与程序退出善后的结束代码,
以及程序中调用的库函数,如printf等函数的代码。
由于 printf 函数需要在屏幕打印信息,涉及更底层的系统I/O操作,因此它需要调用封装这些系统功能的 windows API 函数,
除了windows API 函数所在的DLL(kernel32.dll,ntdll.dll)作为动态链接库在运行时加载以外,
所有其它被调用函数的二进制目标代码都被链接器复制一份副本,然后链接到最终的可执行文件stack.exe中,
因此,stack.exe包含的库代码数量远多于程序员自行编写的代码数量。
使用静态链接的程序,很容易通过IDA PRO的全局函数调用拓扑图识别出来,如下所示:



上面只是抛砖引玉,类似的将IDA PRO,Ollydbg,PEview,甚至WinHex,PEiD等工具结合起来应用,交叉验证的例子不胜枚举,通过熟练使用这些工具,不仅能提高逆向工程的效率与准确度,更重要的是,我们对处理器指令集体系结构,操作系统内存管理,以及动态链接的机制,编译器,链接器的运行原理等等系统底层机理的认识又提升了一个档次。
最后,限于个人知识水平有限,文中若有错误以及误导之处,还请提出指正,不胜感激。
有任何问题,看法,也欢迎提出讨论。


[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

收藏
点赞1
打赏
分享
最新回复 (28)
雪    币: 34
活跃值: (930)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lihuakx 2015-2-12 07:31
2
0
写的很清楚哦。
雪    币: 1604
活跃值: (640)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
shayi 9 2015-2-14 00:05
3
0
补充一下,前面在查看绝大部分使用静态链接的程序中,整个函数的调用拓扑,非常凌乱,我们甚至找不到main函数与最终的DLL函数入口
下面这张来自于 IDA PRO 的函数递归调用图,把范围缩小到了我们追踪的从main()到 EnterCriticalSection() 的整个过程,验证了前面在StackFrame的代码节中的查找工作:



雪    币: 1604
活跃值: (640)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
shayi 9 2015-2-14 00:20
4
0


下面这张图是用于生成上图的函数调用设置:



雪    币: 1844
活跃值: (35)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
yingyue 2015-2-14 04:38
5
0
不错 。。。。。。。。。。。。。。。。。。。。
雪    币: 1604
活跃值: (640)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
shayi 9 2015-2-23 19:44
6
0
帖子中使用的测试程序,实际上是《逆向工程核心原理》一书中,第7章的实例程序
StackFrame.exe
各位若要使用IDA或者OD对其进行分析,可以在这里下载该文件,解压后以OD加载或IDA加载即可

StackFrame.rar

或者,也可以去该书作者的博客下载配书资源,里面的第7章文件夹中的文件与这里的相同
上传的附件:
雪    币: 78
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
whypro 2015-2-23 20:16
7
0
写的很清楚哦。
雪    币: 15
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
寒江孤影 2015-2-24 11:09
8
0
你这IDA界面是主题吗?哪里下载的。可以给一份吗
雪    币: 11278
活跃值: (4018)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xie风腾 2015-2-24 11:28
9
0
好强大的呢,来学习
雪    币: 1604
活跃值: (640)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
shayi 9 2015-2-24 15:37
10
0
这是开启windows 7 的Aero 特效桌面主题后,启动放大镜,再启用"颜色反转"时,截的图,不是IDA的主题界面
雪    币: 346
活跃值: (25)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
OnlyForU 2015-2-25 00:09
11
0
已拜读!!!!
雪    币: 15893
活跃值: (1090)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
killbr 2015-2-25 20:34
12
0
走迷宫高手……
雪    币: 52
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
kuty 2015-2-26 10:12
13
0
LZ介绍的很详细,支持一个。
雪    币: 111
活跃值: (100)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
ronging 2015-2-26 11:19
14
0
基础的文章越来越少,顶下。
雪    币: 43
活跃值: (30)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hbcld 2015-2-27 15:24
15
0
先mark,慢慢学些看
雪    币: 27
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
小鸡炖蘑菇 2015-3-4 14:04
16
0
不错 类似于教材性质的文章  适合新人
雪    币: 788
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Nekoxiaoji 2015-3-6 16:11
17
0
楼主使用的OD 是什么版本的?能否提供一下?
雪    币: 22
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
checkmate 2015-3-6 23:05
18
0
看完了。不过这里使用IDA的意义在哪?直接用OD不也可以完成分析吗?
雪    币: 1604
活跃值: (640)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
shayi 9 2015-3-6 23:42
19
0
如果LZ仅用OD分析,就不会有这篇文章了,IDA的强大之处在于,可以迅速准确地区分库代码与程序员代码,而且这里也用到了IDA绘制函数调用流程图的功能,可以这么讲,在OD动态调试时,IDA就是我们的灯塔,以至于不会在代码的汪洋中迷失方向,
代码行数量越大的软件,IDA的作用越明显。
雪    币: 87
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
TOMsc 2015-3-13 10:44
20
0
写的很详细
雪    币: 1644
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yodamaster 2015-6-4 22:47
21
0
感谢分享。
雪    币: 90
活跃值: (80)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
hulucc 2015-6-5 16:25
22
1
然而IDA并不能,你这里能区分是因为你并没有调用什么奇怪的库
如果用了boost,openssl之类的除非自己制作sig,然后你又不知道对方的版本,就算知道了版本,你还要猜对方的编译优化选项,一些游戏的库会用非常多的优化手段

然而有些库你虽然知道名字,但是你拿不到lib,制作不了sig,IDA什么都帮不了你
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yalohalo 2015-9-1 15:53
23
0
学习了,谢谢。
雪    币: 79
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lzq李志强 2015-10-18 23:31
24
0
mark thanks
雪    币: 22
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qqv 2016-7-1 13:34
25
0
多谢楼主, 非常适合我这样的汇编菜比
游客
登录 | 注册 方可回帖
返回