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

http://bbs.pediy.com/showthread.php?p=1354999

标 题: 【原创】使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函数的调用过程。
作 者: shayi
时 间: 2015-02-12,05:19:54
链 接: http://bbs.pediy.com/showthread.php?t=197829

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

*转载请注明来自看雪论坛@PEdiy.com

 

此帖于 2015-02-12 16:03:59 被 shayi 最后编辑


[公告]如果你觉得有人语言挑衅,请点每帖右上角的“举报”按钮!

 

共 8 位会员
感谢 shayi 发表的文章:
dolphinzhu (2015-03-03), hbcld (2015-02-27), hrpirip (2015-02-26), Lnairan (2015-02-25), springkang[DFCG (2015-03-14), 学gg (2015-02-23), 雪衫 (2015-03-04), 马来 (2015-06-07)

lihuakx

初级会员

资 料:

注册日期: Feb 2015

帖子: 1 

精华: 0

现金: 50 Kx

致谢数: 0

获感谢文章数:0
获会员感谢数:0


2  2015-02-12, 07:31:13 

写的很清楚哦。

 


[招生]15PB软件安全培训开始接受第009期报名(10.06开课)!

 


shayi

普通会员

资 料:

注册日期: Jul 2012

帖子: 99 

精华: 1

现金: 93 Kx

致谢数: 0

获感谢文章数:7
获会员感谢数:28


3  2015-02-14, 00:05:54 

补充一下,前面在查看绝大部分使用静态链接的程序中,整个函数的调用拓扑,非常凌乱,我们甚至找不到main函数与最终的DLL函数入口
下面这张来自于 IDA PRO 的函数递归调用图,把范围缩小到了我们追踪的从main()到 EnterCriticalSection() 的整个过程,验证了前面在StackFrame的代码节中的查找工作:

 

此帖于 2015-02-14 00:16:50 被 shayi 最后编辑


[招生]15PB软件安全培训开始接受第009期报名(10.06开课)!

 


shayi

普通会员

资 料:

注册日期: Jul 2012

帖子: 99 

精华: 1

现金: 93 Kx

致谢数: 0

获感谢文章数:7
获会员感谢数:28


4  2015-02-14, 00:20:10 

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

时间: 2024-10-11 19:30:20

使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函数的调用过程的相关文章

[Android Pro] 深入理解函数的调用过程——栈帧

cp :http://blog.csdn.net/x_perseverance/article/details/78897637 每一个函数被调用时,都会为函数开辟一块空间,这块空间就称为栈帧. 首先,我们了解一下不同种类的寄存器: (1)eax,ebx,ecx,edx :通用寄存器 (2)ebp:存放指向函数栈帧栈底的地址 (3)esp:存放指向函数栈帧栈顶的地址 (4)eip:程序计数器——保存程序当前正在执行指令的下一个指令的地址 接着我们以下面这段代码为例,深入到函数的调用过程中去: #

Windows API常用函数

转自:http://www.cnblogs.com/xiashengwang/p/4026259.html .NET中虽然类库很强,但还是有些时候功能有限,掌握常用的api函数, 会给我们解决问题提供另一种思路. 1.SetForegroundWindow 将窗口显示到最前面,前提是窗口没有最小化. [DIIImport("User32.dll")] public static extern bool SetForegroundWindow(IntPtrh Wnd); 2.ShowWi

Windows API CreateEvent函数用法

CreateEvent是创建windows事件对象,作用主要用在判断线程退出和锁定方面. HANDLE CreateEvent(   LPSECURITY_ATTRIBUTES lpEventAttributes, // SD    BOOL bManualReset, // reset type    BOOL bInitialState, // initial state    LPCTSTR lpName // object name); 参数说明: lpEventAttributes:

c运行库、c标准库、windows API的区别和联系

C运行时库函数C运行时库函数是指C语言本身支持的一些基本函数,通常是汇编直接实现的.  API函数API函数是操作系统为方便用户设计应用程序而提供的实现特定功能的函数,API函数也是C语言的函数实现的. 区别他们之间区别是:API函数是针对操作系统的,C语言运行时函数则是针对C语言本身的. ·1.运行时库就是 C run-time library,是C而非C++语言世界的概念.     取这个名字就是因为你的C程序运行时需要这些库中的函数. ·2.C语言是所谓的“小内核”语言,就其语言本身来说很

(转)c运行库、c标准库、windows API的区别和联系

C运行时库函数C运行时库函数是指C语言本身支持的一些基本函数,通常是汇编直接实现的.  API函数API函数是操作系统为方便用户设计应用程序而提供的实现特定功能的函数,API函数也是C语言的函数实现的. 区别他们之间区别是:API函数是针对操作系统的,C语言运行时函数则是针对C语言本身的. ·1.运行时库就是 C run-time library,是C而非C++语言世界的概念.     取这个名字就是因为你的C程序运行时需要这些库中的函数. ·2.C语言是所谓的“小内核”语言,就其语言本身来说很

windows API之控制台界面

windows API之控制台界面 tkorays ([email protected]) 在windows里面,用户界面包括控制台(Console)形式的和窗口(Window)形式的.控制台形式的界面我们也是经常接触的,不就是那个黑色的框框吗?但是我们并没有直接使用Windows API,通常我们调用printf来输出.scanf来输入.实际上,这个c语言函数也是通过Windows API来实现的.不信的话,可以打开crtdll.dll查看里面的字符串. 关于Console的API不是很多,主

IDA Pro Disassembler 6.8.15.413 (Windows, Linux, Mac)

IDA: What's new in 6.8 Highlights This is mainly a maintenance release, so our focus was on fixing bugs. However, there are some improvements too: Support for long names. In previous versions of IDA names were limited to 511 bytes. This was causing p

IDA.Pro权威指南 读书笔记

http://www.pediy.com/kssd/pediy12/142766.html 标 题:IDA.Pro权威指南 读书笔记[Made By C_lemon] 作 者:Dstlemoner 时 间:2011-11-14 11:56:17 链 接:http://bbs.pediy.com/showthread.php?t=142766    IDA为反汇编 和逆向破解的 静态分析利器 ! 虽然是利器,但是你不会用的话~那就另当别论了. →     唉.对于刚入门的新手来说,看前人走过的路程

IDA Pro使用技巧

DA Pro基本简介 IDA加载完程序后,3个立即可见的窗口分别为IDA-View,Named,和消息输出窗口(output Window). IDA图形视图会有执行流,Yes箭头默认为绿色,No箭头默认为红色,蓝色表示默认下一个执行块. 在寄存器窗口中显示着每个寄存器当前的值和对应在反汇编窗口中的内存地址.函数在进入时都会保存堆栈地址EBP和ESP,退出函数时恢复. 选择菜单Debugger下的Start process(也可以按F9键)来开始调试.调试会让程序在电脑中执行,所以IDA会提示注