<>逆向工程核心原理笔记(一)——Hello World-1

<>Ollydbg调试器指令

指令快捷键含义
Go toctrl + G移动到指定地址,用来查看代码或内存,运行时不可用
Execute till CursorF4执行到光标位置,也就是直接转到要调试的地址
Set/Reset Break PointF2设置或者取消断点
Comment;添加注释
Label:添加标签
Goto命令

如果要将光标定位到某处,可以执行Go to命令(ctrl + G)如果要将代码定位到 40104F 可以使用这个命令

之后配合F4可以将程序运行到此处。

设置断点

在调试代码的时候可以使用F2设置BP(断点)在设置断点之后,当程序运行到断点的时候,程序将会暂停

使用快捷键 ALT + B 可以调出断点框,列出设置的所有断点,双击这个位置就可以直接跳转到相应的设置断点的位置

添加注释

使用 ‘;’ 可以在相应的地址添加注释,并且添加后的注释可以通过查找命令找到,这里的命令必须在英文状态下

在调试代码的时候添加注释可以让调试过程变得较为简便,如果需要查找注释,可以在界面右键显示的菜单中选择 search for -> User-defined
comment 中查看所定义的注释,双击注释姐可以定位到相应位置:

添加标签

可以通过标签提供的功能在指定的地址添加特定的功能,通过 ‘:’ 符号添加标签,即 shift + ;

添加标签后,可以右键显示的菜单界面选择 search for -> User-defined label 查看添加的标签

<>快速查找指定代码

在逆向反编译代码的时候找到主函数是至关重要的,但是在反编译代码的时候 main() 函数并不直接位于可执行文件的 EP
位置上,首先出现的是开发工具自动生成的启动函数,因此可能真正需要的主函数距离开始的位置很远,因此,我们需要一些方法来快速的查找到主函数

1.代码执行法

我们来看下面的代码编译出的程序(根据原书程序重新编写的代码)

源代码如下:
#include<cstdio> #include<cstring> #include<iostream> #include<windows.h> using
namespace std; int main() { MessageBox(NULL, L"Hello World", L"Lpy_Now", 0);
return 0; }
运行程序后输出 MeaasgeBox:

接下来反编译代码,将代码放到 OD 里面运行,一直按 F8 跳过一些步骤,直到程序弹出这个MessageBox

程序到这一行 1111E2 这里调用了函数 111000 说明这里就是主函数,我们使用 ctrl + G 进入 111000 这个函数

这就是我们要找的主函数

在地址 111002 和 111007 这两个地方分别有一条 PUSH 语句,这两句分别将 Titlie = “Lpy_Now”, Text =
“Hello World” 保存到栈中,并作为参数传递给 MessageBox ,通过上面的方法也能成功的找到主函数。

2.字符串检索法

OD在第一次载入待调试的程序的时候,都会经历一个预分析的过程,在这个过程中会查看进程内存,程序中引用的字符串和调用的 API
都会被摘录出来,并被整理到另外的一个列表中,查找字符串对天十程序很有用。

右键,在弹出的窗口中点击 Search for -> All referenced text strings 可以看到如下窗口:

双击即可进入所对应的代码行,

通过上面的方式也成功的找到了主函数

3.API 检索法(1):在调用代码中设置断点

在 Windows 中,如果需要向显示器显示内容,需要使用 Win32 API 向 OS
请求显示输出,换言之,应用程序向显示器的画面输出内容的时候,需要在程序的内部调用 Win32 API
当我们观察一个程序的功能后,就可以大致得推测出程序运行时调用的 API ,如果能进一步查到调用的 Win32
API,就会为我们得程序调试带来很大的便利,上面的程序运行后会弹出一个消息窗口,那么我们就可以推断出这个程序运行时调用的是
user.MessageBoxW()API

在前面的描述中说过在 OD 对程序的预分析中不仅可以分析出程序使用的字符串,还能摘录出程序运行时调用的 API
函数列表。如果我们只想查看程序代码中调用了哪些 API 函数,我们可以直接使用 All intermodular calls 命令,即右键在出现的菜单中点击
Search for -> All intermodual calls 点击后

由于我们要找的是 MessageBox
这样的指令,因此在第一行就是这个指令,双击这里也可以找到主函数,因此观察一个程序的行为特征,如果我们能事先推测出代码使用的 API
,那么上面同样是一种不错的找到主函数的方法。

4. API 检索法(2):在 API 代码中设置断点

尽管在之前的介绍中有介绍 OD 可以为可执行文件列出 API
函数调用列表,但是如果使用压缩器/保护器对可执行文件进行压缩或者保护之后,可执行文件的结构就会发生高边,这时 OD 就无法列出 API
调用列表了(甚至会让调试过程变得十分困难)

压缩器(Run time
Packer,运行时压缩器):压缩器是一个实用压缩工具,能够压缩可执行文件的代码,数据,资源等等,与普通的压缩一样,经过压缩器压缩后的文件本身就是一个可执行文件

保护器:保护器不仅具有压缩功能,还添加了反调试,反模拟,反转储等功能,能够有效保护进程,如果想仔细分析保护器,那么分析者需要一些高级逆向分析知识

在这种情况下,DLL 代码库被加载到进程内存后,我么你可以直接想 DLL 代码库添加断点,API
是操作系用对用户的应用程序提供的一系列函数,用于实现一些文件。简言之,我们编写的应用程序执行某种操作的时候,必须使用 OS 提供的 API 向 OS
提供请求,然后与被调用的 API 对应的系统 dll 文件就会被加载到应用程序的进程内存

在 OD 中我们可以先尝试查看内存映射,在菜单栏中点击 View -> Memory(或 alt + M) 打开内存映射窗口

我们可以看到 USER32 库被加载到内存中,我们接下来右键的窗口中点击 Search for -> Name in all modules 可以打开
All names 窗口,点击 Name 栏目按名称进行排序

在这里搜索 MessageBoxW

在箭头所指的地方,双击这个函数,就会显示这里的代码,它在 USER32.dll 中实现。

观察这里的地址发现这里与我们的可执行文件的地址完全不同,我们尝试在这里设置断点(F2),之后继续执行代码(F9)

代码执行到这里就停了下来,在 1 处的箭头寄存器窗口中的 ESP 的值为 00EFF874 它是进程栈的地址,在 2
处的箭头的栈窗口中可以看到更为详细的信息 ESP 地址的 00EFFBB8 处对应一个地址 00FE1014 ,也就是主函数调用完 MessageBox
函数后,程序执行流将返回到这个地址,我们按 ctrl + G 到达这里

我们发现这段代码的上面就是我们要找的主函数

B8 处对应一个地址 00FE1014 ,也就是主函数调用完 MessageBox 函数后,程序执行流将返回到这个地址,我们按 ctrl + G 到达这里

我们发现这段代码的上面就是我们要找的主函数

以上就是快速查找代码的四种方式

技术
今日推荐
下载桌面版
GitHub
百度网盘(提取码:draw)
Gitee
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:766591547
关注微信