前言

每个人在调试中快速查找所需代码时都有不同的方法,但是最基本最常用的有下面几种。

学习这4种方法前我们需要思考一个问题。我们知道,运行HelloWorld.exe程序会弹出一个消息框,显示“Hello
World!”信息。固然是因为我们编写了代码,可在这种情形下,只要运行一下程序,不论是谁都能轻松意识到这一点。

如果你熟悉win32 api的开发,看到弹出的消息框就会想到,这是调用MessageBox()
API的结果。应用程序的功能非常明确,只要运行一下程序,就能大致推测出其内部结构。不过前提是你已经具备了开发和分析代码的经验。

一、代码执行法

我们需要查找的是main()函数中调用MessageBox()函数的代码。在调试器中调试HelloWorld.exe(F8)时,main()函数的MessageBox()函数在某个时刻就会被调用执行,弹出消息对话框,显示“Hello World!”这条信息。
上面就是代码执行法的基本原理,当程序功能非常明确时,我们可以逐条执行指令来查找需要查找的位置。但是代码执行法仅适用于被调试的代码量不大、且程序功能明确的情况。倘若被调试的代码量很大且比较复杂时,此种方法就不再适用了。下面使用代码执行法来查找代码中的main()函数。从“大本营”(40104F)开始,按F8键逐行执行命令,在某个时刻弹出消息对话框,显示“Hello World!”信息。按Ctrl+F2键再次载入待调试的可执行文件并重新调试,不断按F8键,某个时刻一定会弹出消息对话框。弹出消息对话框时调用的函数即为main()函数。如图2-20所示,地址401144处有一条函数调用指令“CALL00401000”,被调用的函数地址为401000,按F7键(Step Into)进入被调用的函数,可以发现该函数就是我们要查找的main()函数。


如上图,地址40100E处有一条调用MessageBox() API的语句。401002与401007处分别有一条PUSH语句,他把消息对话框的标题与显示字符串(Title = “www.reversecore.com”, Text = “Hello World!”)保存到栈(Stack)中,并作为参数传递给MessageBox W()函数。
这样我们就准确的查找到了main()函数。

win32应用程序中,API函数的参数是通过栈传递的。VC++中默认字符串是使用Unicode码表示的,并且,处理字符串的API函数也全部变更为Unicode系列函数。

二、字符串检索法

右键菜单-search for-all referenced text strings

OllyDbg初次载入待调试的程序时,都会先经历一个预分析过程。此过程中会查看进程内存,程序中引用的字符串和调用的API都会被摘录出来,整理到另外的一个列表中,这样的列表对调试时相当有用的。使用all referenced text strings命令会弹出一个窗口,其中列出了程序代码引用的字符串。

地址401007处有一条PUSH 004092A0命令,该命令中引用的004092A0处即是字符串“Hello World!”。双击字符串,光标定位到main()函数中调用MessageBox W()函数的代码处。

在OllyDbg的value窗口,然后按Ctrl+G命令,可以进一步查看位于内存4092A0地址处的字符串。首先使用鼠标单击value窗口,然后按Ctrl+G快捷键,打开Enter expression to follow in Dump窗口。(如果你的数据窗口不是这样的,右键单机选择HEX)

ascii前两行即使“Hello World!”字符串,它是以unicode码形式表示的,并且字符串的后面被填充上了NULL值(记住这块null值的区域,我们以后还会再讲的)。

VC++中,static字符串会被默认保存为Unicode码形式,static字符串是指在程序内部被硬编码的字符串。

上图我们还需要注意的是4092A0这个地址,它与我们之前看到的代码区域地址比如401XXX是不一样的。在HelloWorld进程中,409XXX地址空间被用来保存程序使用的数据。大家要清楚一点:代码和数据所在的区域是彼此分开的。

我们后面会慢慢学习代码和数据在文件里是怎么保存,以及怎么加载到内存的,这些是windows PE文件格式的相关内容,我们暂时先不管他。

三、API检索法

3.1在调用代码中设置断点

右键单击-search for-all intermodular calls

windows 编程中,如果想让显示器显示内容,则需要使用win32API向OS请求显示输出。换句话说,应用程序向显示器输出内容时,需要在程序内部调用win32 API。认真观察一个程序的功能后,我们能够大致推测出它在运行时调用的WIN32 API,则会为程序调式带来极大便利。以HelloWorld.exe为例,它在运行时会弹出一个消息窗口,由此我们可以推断出该程序调用了user_32.MessageBox W() API。(敏感词所以加了下划线)

在OllyDbg的预分析中,不仅可以分析出程序中使用的字符串,还可以摘录出程序运行时调用的API函数列表。如果只想查看程序代码中调用了哪些API函数,可以直接使用all intermodular calls命令。如下图窗口列出了程序中调用的所有API。

可以看到调用MessageBox W()的代码,该函数位于40100E地址处,他是user_32.MessageBox W() API。双击它,光标就会定位到调用它的地址处(40100E)。观察一个程序的行为特征,若能事先推测出代码中使用的API,则使用上述方法能够帮助我们快速查找到需要的部分。

对于程序中调用的API,OllyDbg如何准确摘录出他们的名称呢?首先,他不是通过查看源代码来摘取的,如果想要了解其中的原理,我们需要理解PE文件格式的IAT(Import
Address Table,导入地址表)结构。我们会在后面的文章中提到这些内容。

3.2在API代码中设置断点

鼠标右键菜单-search for - name in all calls

OllyDbg并不能为所有可执行文件都列出API函数调用列表。使用压缩器、保护器工具对可执行文件进行压缩或保护之后,文件结构就会改变,此时OllyDbg就无法列出API调用列表了(甚至连调试都会变得十分困难)。

压缩器(Run time Packer,运行时压缩器)

压缩器是一个实用压缩工具,能够压缩可执行文件的代码、数据、资源等,与普通压缩不同,它压缩后的文件本身就是一个可执行文件。

保护器

保护器不仅具有压缩功能,还添加了反调试、反模拟、反转储等功能,能够有效保护进程。如果想仔细分析保护器,我们还需要具有更高级的逆向知识。

这种情况下,DLL代码库被加载到进程内存后,我们可以直接向DLL代码库添加断点。API是操作系统对用户应用程序提供的一系列函数,他们实现于C:\Windows\system32文件夹中的 *.dll文件(如kernel32.dll、user_32.dll、gdi32.dll、advapi32.dll、ws2_32.dll等)内部。简单的说,我们编写的应用程序执行某种操作时(如各种I/O操作),必须使用OS提供的API向OS提出请求,然后与被调用API对应的系统DLL文件就会被加载到应用程序的进程内存。

在OllyDbg菜单中选择 View-Memory菜单(Alt+M),打开内存映射窗口。如下图,内存映射窗口中显示了一部分HelloWorld.exe进程内存。在图底部可以看到user_32库被加载到了内存。

使用OllyDbg中的Name in all modules命令可以列出被加载的DLL文件中提供的所有API。使用Name in all moudules命令打开All names窗口,单机Name栏目按名称排序,通过键盘敲出MessageBox W后,光标会自动定位到MessageBox W上。

USER_32模块中有一个Export类型的MessageBoxW函数(不同环境下函数地址不同)。双击MessageBoxW函数后就会显示其代码,它实现于USER_32.dll库中,如图

观察MessageBoxW函数的地址空间可以发现,它与HelloWorld.exe使用的地址空间完全不同。在函数起始地址上按F2键,设置好断点后按F9继续执行。

如果HelloWorld.exe应用程序中调用了MessageBoxW() API,则调试时程序运行到该处就会暂停。

与预测的一样,程序执行到MessageBoxW代码的断点处就停了下来,此时寄存器窗口中的ESP值为19FF18

它是进程栈的地址。在右下角的栈窗口中可以看到更详细的信息

我们会在后面的教程中详细说明函数调用以及站动作原理,现在可以暂时忽略

如上图,ESP值的12FF18处对应一个返回地址401014,HelloWorld.exe的main()函数调用完MessageBoxW函数后,程序执行流将返回到该地址处。按Ctrl+F9快捷键使程序运行到MessageBoxW函数的RETN命令处,然后按F7键也可以返回到401014地址处。地址401014的上方就是地址40100E,它正是调用MessageBoxW函数的地方。

以上是我所掌握的几种方法,大家还有其他的思路吗?

【逆向分析】快速查找指定代码的几种方法相关推荐

  1. php恶意代码,php快速查找数据库中恶意代码的方法,快速查找恶意代码_PHP教程...

    php快速查找数据库中恶意代码的方法,快速查找恶意代码 本文实例讲述了php快速查找数据库中恶意代码的方法.分享给大家供大家参考.具体如下: 数据库被输入恶意代码,为了保证你的数据库的安全,你必须得小 ...

  2. 5种快速查找容器文件系统中文件的方法

    5种快速查找容器文件系统中文件的方法 如果你经常使用容器,那么你很有可能希望在某个时刻查看正在运行的容器的文件系统.也许容器无法正常运行,你想读取一些日志,也许你想检查容器内部的一些配置文件-或者,你 ...

  3. Spring中Bean创建完成后执行指定代码的几种实现方式

    Spring中Bean创建完成后执行指定代码的几种实现方式 1. 实现ApplicationListener接口 2. 实现InitializingBean接口 3. 使用@PostConstruct ...

  4. android 漫画切换,Android逆向之路---让我们试试另一种方法看漫画-(2)

    前言 上次我们分析到了快看漫画的协议部分,这次我们根据他的协议来手动写个脚本,然后执行以后,可以把他的漫画自动下载到电脑上面, 然后自动拼接图片,这样就可以实现在电脑上当成一个长图来看漫画了,没有广告 ...

  5. VB创建超链接 打开指定网站的几种方法

    方法一:  Shell "Rundll32.exe url.dll, FileProtocolHandler  http://miaozk2006.blog.163.com", v ...

  6. 快速找到外贸客户的9种方法(建议收藏)

    所有外贸企业想要做好外贸出口的头等大事,就是要快速的找到优质的外贸客户和订单,没有订单的达成,所有的努力都是图劳,还有可能会陷入一种虚假的繁荣,每天都很忙,但是没有结果.今天,小编就来分享一下,快速找 ...

  7. 在Linux中查找文件系统类型的7种方法(ext2,ext3或ext4)

    文件系统是在存储磁盘或分区上命名,存储,检索和更新文件的方式.文件在磁盘上的组织方式. 文件系统分为两个部分:用户数据和元数据(文件名,创建时间,修改时间,大小和在目录层次结构中的位置等). 在本指南 ...

  8. 优化JS代码的34种方法(上)

    1. 含有多个条件的if语句 //longhand if(x === 'abc' || x === 'def' || x === 'ghi' || x == 'jkl'){//logic }//sho ...

  9. 查找Mac序列号的9种方法

    序列号包含与保修,维修和更换有关的详细信息,市场上有多种Mac型号,序列号可帮助维修中心找到修复Mac所需的相关零件. 今天小编给大家带来查找Mac序列号的9种方法,需要的朋友快收藏起来吧! 一 检查 ...

最新文章

  1. 从α到μ:DeepMind棋盘游戏AI进化史
  2. 创建试图 失败_导致微服务失败的 11 个原因
  3. 寻求最佳开发模式,免得落得“精”尽人亡
  4. Ice笔记---异步程序设计demo
  5. 洛谷出现RE(re)的情况
  6. MySQL联合查询介绍
  7. 安装jdk后出现bash: ./java: /lib/ld-linux.so.2: bad ELF interpreter: 没有那个文件或目录
  8. java session 数量_java中使用session监听实现同帐号登录限制、登录人数限制
  9. C# 中的数字分隔符 _
  10. Linux 安装之U盘引导
  11. 计算机在材料中的运用结课,计算机在材料科学工程中的应用的结课论文.doc
  12. 数学建模亚太赛优秀论文_2019亚太地区大学生数学建模竞赛志愿者等级评定结果公布!...
  13. java蓝桥杯算法训练 相l邻字母(题解)
  14. SyntaxHighlighter3.0.83 配置
  15. 【java面试经(架构师设计师)-第4课】java基础常识
  16. Java数组实现:一群人围成一圈从123报数 如果报到3就退出该圈中 直到最后一个人留下来!问其位置
  17. 响应式微服务_低风险整体式微服务演进第三部分
  18. sql server查询不显示结果_仅凭网上查询结果显示邮件由行政机关签收,能证明行政机关一定收到了当事人的申请吗?...
  19. Unity学习资源指南[精心整理]
  20. 军用软件概算计价规范_军用软件概算计价规范_关于举办军用软件功能点分析及计价规范讲解与交流会的通知......

热门文章

  1. 成功解决极其刁钻bug之SyntaxError: invalid character in identifier
  2. Interview:算法岗位面试—上海某公司算法岗位技术(偏机器学习,证券基金行业)面试考点之进程与线程区别、GD改进的算法、ROC和AUC
  3. CV之LabelImg:图片标注工具之LabelImg(图像标注工具)的简介、安装、使用方法详细攻略
  4. 基本数据结构—Hash哈希
  5. MVC案例——模糊查询
  6. MongoDB 征途
  7. 《大规模web服务开发技术》阅读笔记
  8. 不错的linux下通用的java程序启动脚本(转载)
  9. 重置SVN用户名与密码,修改SVN的IP地址
  10. STVD下配置Cosmic编译器