CTF每日一题 | REVERSE练习之API定位

题目描述:

      主机C:\Reverse\2目录下有一个CrackMe2.exe程序,运行这个程序的时候会提示输入一个密码,当输入正确的密码时,会弹出过关提示消息框,请对CrackMe2.exe程序进行逆向分析和调试,找到正确的过关密码。

实验步骤:

1、外部行为分析

在随便输入字符和不输入字符时情况如下:

CTF每日一题 | REVERSE练习之API定位

CTF每日一题 | REVERSE练习之API定位

所以目的是找到一个正确的密码输入。

2、查看是否加壳

选中程序后单击右键,在右键菜单中选择“Scan with PEiD”选项,就可以查看加壳信息了。看到的是Microsoft Visual C++ 6.0,说明CrackMe2.exe没有加壳,且它是使用VC6编译的。

CTF每日一题 | REVERSE练习之API定位

3、使用OD动态调试

使用OD载入程序,如果继续使用实验CTF每日一题 | Reverse练习之初探中提到的方法查找字符串,提示找不到:

CTF每日一题 | REVERSE练习之API定位

在反汇编指令列表中单击右键,在右键菜单中依次选择“查找”——“当前模块中的名称(标签)”:

CTF每日一题 | REVERSE练习之API定位

 点击弹出的名称窗口,在键盘上敲下MESSAGEBOXA,就会自动定位到MessageBoxA,点击鼠标选中MessageBoxA这一行,单击右键,在弹出的右键菜单中选择“在每个参考上设置断点”:

CTF每日一题 | REVERSE练习之API定位

在OD最下方的状态栏上可以看到“已设置 2 个断点”的提示。(有对MessageBox两次的调用)

CTF每日一题 | REVERSE练习之API定位

现在按F9运行程序,随便给程序输入一个密码(如TEST),单击确定按钮后程序将在OD中断下,断下的位置为对MessageBoxA的调用的位置:

CTF每日一题 | REVERSE练习之API定位

这就是要找的关键函数,查看附近的代码,就找到了密码明文:

CTF每日一题 | REVERSE练习之API定位

4、使用IDA静态分析

使用IDA载入CrackMe2.exe程序进行分析,等待分析完毕后,选择主窗口面板上的Imports页面,然后在键盘上敲下MESSAGEBOXA,将自动定位到MessageBoxA函数:

CTF每日一题 | REVERSE练习之API定位

 双击这个条目,来到MessageBoxA定义的位置,选中后按下X键,弹出交叉引用列表窗口,看到一共有四个条目:

CTF每日一题 | REVERSE练习之API定位

不能直接看出哪一个引用就是要找的引用,所以需要一个一个进行查看,根据前面使用OD对程序的分析,知道在MessageBoxA之前有许多对LoadString的调用,通过对比几个交叉引用,可以断定sub_401450就是要找的函数。

CTF每日一题 | REVERSE练习之API定位

 使用F5还原sub_401450函数的伪代码,确定LoadString加载资源ID为0x6A的字符串就是要找的密码:

CTF每日一题 | REVERSE练习之API定位

使用Restorator打开CrackMe2.exe程序来查看字符串资源,0x6A的十进制即106(=10X16^0+6X16^1),因此可以知道密码就是HeeTianLab:

CTF每日一题 | REVERSE练习之API定位

5、总结:

Windows API:

ANSI的ASCII字符集及其派生字符集(也称多字节字符集)比较旧,而Unicode字符集比较新,固定以双字节表示一个字。Windows操作系统在声明一个API时,如果这个API存在字符串参数,便会指定字符集。每个含有字符串参数的API同时有两个版本:即ANSI,Unicode。尾部带A的API是ANSI版本,带W的API是Unicode版本。

      例如:我们在编程时使用的MessageBox实际上是一个宏,根据字符集的不同被定义为不同版本的MessageBox,如果是UNICODE字符集,则实际上为MessasgeBoxW,如果是ANSI字符集,则实际上为MessageBoxA:

 #ifdef UNICODE

 #define MessageBox  MessageBoxW

 #else

 #define MessageBox  MessageBoxA

 #endif // !UNICODE

交叉引用:

通过交叉引用(XREF)可以知道指令代码相互调用的关系,   在选的的函数上面按X键,可以打开交叉引用窗口,会列出所有调用了这个函数的地方。

十六进制转10进制:

十六进制数的第0位的权值为16的0次方,第1位的权值为16的1次方,第2位的权值为16的2次方……

假设有一个十六进数 2AF5, 那么如何换算成10进制?

用竖式计算:

2AF5换算成10进制:

第0位:

 CTF每日一题 | REVERSE练习之API定位

第1位:

 CTF每日一题 | REVERSE练习之API定位

第2位:

 CTF每日一题 | REVERSE练习之API定位

第3位:

 CTF每日一题 | REVERSE练习之API定位

直接计算就是:

 CTF每日一题 | REVERSE练习之API定位