目录
0.前言
大学三年终于上到了最最最想学的课。
经历过买了很多相关书籍、看了很多相关视频,但是发现其中大部分讲的太过浅显,感觉并没有什么实际作用、不知道从哪里入手、讲的太难又看不懂的迷惘
曾经觉得“入门太简单,但要做的很好太难”
曾经怀疑过,为什么别人都可以自学,为什么自己这么差劲
在那一个个失落的夜晚之后,今天终于真的真的真的要入门了。
发现了原来在推开实现梦想的大门,踏上第一级阶梯之前,一切的失意都不值得一提。
甚至兴奋地颤抖。
所以在这里,将课堂的实验,以实验报告的形式发表博客,记录下自己学习的过程,也希望可以跟大家分享这个过程
如有不足、如果错误,还希望大家指正
1.实验环境搭建
本周的第一个实验是逆向分析三个简单的文件,不需要搭配什么特别的环境
需要的软件:IDA PRO
p.s PRO专业版和普通的版本打开文件后的默认窗口是略有差别的,提供的功能也是不一样的
2.IDA PRO简单介绍
打开IDA PRO会显示快速启动的界面
其中有三个选项:“New”、“Go”、“Previous”
这里我们选择第一个,解析一个新的文件
然后会默认打开一个“打开文件的窗口”
我们可以从这里选择要解析的文件,也可以直接拖动文件到IDA PRO里面进行解析
在加载文件时有多个选项
主要是在窗口最上方的选项
“Load file xxx as”(程序的类型)
这里我们选择默认的第一个,其他选项也按照默认的参数来,点击OK即可
我们选择的文件是Sample_1的可执行文件
OK后,开始Disassemble我们选择的文件,出现如下窗口
我们可以看到默认显示的有
“Function Name”窗口,即显示可执行文件所调用的函数
“IDA View-A”窗口,即可执行文件的反汇编窗口
“Output Window”,即可执行文件的输出
这里我们主要关注的是反汇编窗口,
其余的有关以十六进制显示的窗口还没有学到,在此先不做研究
在反汇编窗口点击鼠标右键,可以看到有多个选项,我们可以通过点击“Text View”来更改视图(默认以Graph View显示)
其余相关介绍可以参考其他的参考资料,本文仅粗略介绍本次实验需要用到的部分
3.Sample_01的逆向分析
打开Sample_01.exe后,跳过上面的文件信息的部分,我们就找到了这个可执行文件的Main函数的入口(黄色选中部分)
那么黑框里面的,就肯定是主函数的部分啦
前三行我们可以先不详细分析,因为本次实验的目的主要是通过逆向分析猜测可执行文件会执行一个怎么样的操作,并且解释相关函数的作用
那么我们从第四行开始看
我们可以看到,函数将“2012”,和lpString1 push入栈
接着就来到了
call表示调用了一个函数,这个函数的名称为“lstrcmpW”
通过参考微软的函数手册,我们可以看到
lstrcmpw函数比较了两个字符串lpString1和lpString2的值
如果lpString1小于lpString2,则函数返回一个负数
如果lpString大于lpString2,则函数返回一个正数
如果两个字符串相等,返回值为0
所以在这里我们就可以进行猜测了,这个程序首先将我们从命令行输入的值跟“2012”进行了比较,比较之后做了什么呢?让我们继续往下看
接下来test了两个值,通过查阅资料,我们知道了在反汇编中
test和jnz在这里是连用的
首先 test eax eax的含义是
if(EAX == 0)
ZF = 1
else
ZF = 0
而JNZ short loc_401035是
if(ZF == 0)
GOTO loc_401035
那么就是,首先test了一个值,看这个值是否为0
如果为0,则ZF = 1,如果不为0,ZF = 0
然后
如果ZF == 0
就跳转到loc_401035
那loc_401035是啥
还好当你选中这个值的时候,软件会自动帮你选中这个窗口中所有相同的值
那我们就可以猜测
比较了lstrcmpW函数的值是否为0
如果函数返回0,则ZF为1,则不会跳转
如果函数返回不为0,则ZF为0,则会跳转到loc_401035,执行他接下来的代码
接下来就很简单了,我们看到两边的代码(跳转 or 没有跳转)
分别有“Hello ! 2012”和“Hello!Windows”
然后都call了“GetActiveWindow”和“MessageBoxW”函数
那么可以猜测
如果没有跳转,则程序获取一个窗口句柄,并show了一个MessageBox,显示Hello!2012
如果跳转了,则程序获取一个窗口句柄,并show了一个MessageBox,显示Hello!Windows
最后程序return结束
我们可以来测试一下
打开命令行
如果不输入任何值,很明显,lstrcmpW返回肯定不为0,显示Hello!Windows
如果输入不为2012,同理可得,也是现实Hello!Windows
输入为2012呢?那当然会显示Hello!2012了
Sample_01总结(来自图灵社区相关文章)
http://www.ituring.com.cn/book/tupubarticle/9632
“和无参数的情况相比,这次显示出来的消息变成了 Hello! 2012。
可能有人要问:“那又如何?”我们发现了通过传递 2012 这个参数,程序的显示结果会发生变化,这很重要。因为我们在“完全没有源代码的情况下,搞清楚了程序的行为”。
这就是逆向工程。
刚才这个参数是我们猜测出来的,其实只要阅读汇编语言代码,就可以发现其中使用了 lstrcmpW 对字符串 2012 和命令行参数进行了比较操作。”
“我们没必要看懂全部的汇编语言代码。和刚才使用二进制编辑器的时候一样,只要一眼望去能大概理解这段代码做了什么事就可以了。”
“刚一听到“逆向工程”“汇编”这些词的时候,大家总会以为它们很难,但实际上并非如此。使用 IDA,我们就可以将可执行文件转换成像 C 语言一样容易理解(实际上还是有差距的)的汇编代码。尤其是它的 Graph view 十分强大,可以让我们十分清晰地看出程序的分支逻辑。
只要一定程度上掌握这些工具的使用方法,大家就可以完成很多软件分析工作了。”
这三句话,也恰恰好的解释了上文所说的“本次实验的目的主要是通过逆向分析猜测可执行文件会执行一个怎么样的操作,并且解释相关函数的作用”
4.Sample_02的逆向分析
实验要求:Sample_2分析范围:0x00401000至0x0040105E
所以我们同样把Sample_02的可执行文件拖入IDA PRO,并右键切换到Text View视图
方便我们按范围分析
首先我们还是找到文件的主函数入口
从0x00401000至0x0040105E的范围内,一共call了四个函数
分别查阅函数的作用
函数分析:
GetModuleFileNameA函数:
hModule参数为NULL时,函数获取当前进程的可执行文件的路径,复制到lpFilename指向的缓冲区中,如果lpFilename指向的缓冲区足够容纳该路径,则函数成功,path中存储了一个路径相关的字符串
SHGetSpecialFolderPathA函数:
获取一个指定的系统路径
lstrcatA函数:
返回了一个指向长度足以存储lpString1和lpString2的缓冲区的指针
可以理解为返回了一个LPTSTR形的字符串
此字符串为lpString1和lpString2的连接字符串
lstrcmpA函数:
如果lpString1小于lpString2,返回负数
如果大于,返回正数
如果相等,返回0
分析与验证
看到这里一度觉得十分的尴尬,从0x00401000至0x0040105E的范围,无非就是做了
获取文件名,获取一个路径,将路径和
"\\0.exe"拼接,然后做了一个比较
可以强行猜测一波,向这个路径复制了一个名为0的可执行文件
就没了啊,那我怎么继续逆向分析呢。。。
没办法,只好硬着头皮继续往下做
Sample_02拓展
发现做到这里再继续“正叙”写下去是根本一点也写不下去了
emmm可能这就是为什么只让我们分析到这里吧
因为后面的那些函数真是看不懂啊!
但是不能这么尴尬
所以我们偷偷懒,“倒叙”来看看程序是怎么走的
我们用Process Monitor来看看
看到Sample_02向
C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\startup
这个路径下Create了一个0.exe的File
而根据我们之前的分析和函数解释,大概可以猜到,这个0.exe跟Sample_02.exe是一样的
我们用Stirling来验证一下
发现确实如此
嗯。。。虽然没搞懂IDA里面的东西,但是通过借助其他工具的帮助,我们还是大致知道了,这个Sample_02会执行一个怎么样的操作
5.Sample_03逆向分析
实验要求:Sample_3分析范围:0x00401000至0x00401062
咦让我们分析的部分没有找到函数入口啊
没事,我们往下拉一点可以看到
程序的主函数上来讲就先call了我们要分析的这一部分
所以我们分析出来那一部分的子函数会做什么,也就可以知道这个程序会做什么了
函数分析:
GetModuleNameW函数:
与Sample_02中的GetModuleFileNameA相似
SHGetFolderPathW函数:
与Sample_02中的SHGetSpecialFolderPathA功能类似
CopyFileW函数:
复制一个文件,参数分别为现有文件名,目标文件名,和一个bool值
如果bool值为TRUE,且目标文件名已存在的话,函数失败
如果为FALSE,目标文件名已存在的话,函数将覆盖已有文件,并成功返回
分析与验证
这就比Sample_02容易猜测这个程序会执行一个什么操作了,毕竟有一个CopyFileW的存在嘛
所以在这里我们就已经大致可以猜测,这个程序
获取了一个系统的路径
并朝这个路径下复制了一个名为wsample01b的可执行文件,而这个可执行文件跟Sample_03应该是一样的
我们打开Process Monitor来查看一下
发现Sample_3在C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\startup这个路径下CreateFile
打开这个文件夹,发现
确实有wsample01b的可执行文件
用Stirling二进制编辑器,对比Sample3和wsample01b,发现他们是一样的
至此即可确定我们之前的分析是大致正确的
Sample_03拓展
在IDA中找了很久,都没有找到Sample_03.exe将获取到的系统路径存放在了哪里
提出疑问,如果不通过进程监视器来看,我们应该怎么知道程序向哪条路径CopyFile了呢
我们选择使用OllyDbg调试,将Sample_03拖入到OllyDbg中,如下显示
在00401000处设置断点,然后按下F8逐步执行指令
运行到0040103A处,显示如下
此处即将执行SHGetFolderPathW函数
运行到下一行后,显示如下
然后我们再确认一下Stack[0018DEE8]的内容
可以看到,虽然我们不知道SHGetFolderPathW函数设置了什么参数,但是我们知道了执行完这个函数之后,系统将获取到的路径push入栈,而我们的目的也达到了,寻找到了Sample_03.exe向哪一个路径复制了程序
最后我们用32位的IDA PRO查看我们分析范围0x00401000至0x00401062的这段子函数的代码,以确认之前逆向分析的结果(32位的可以按F5查看程序伪代码,64位的好像并没有这个功能)
int sub_401000()
{
WCHAR Filename; // [sp+0h] [bp-2004h]@1
WCHAR pszPath; // [sp+1000h] [bp-1004h]@1
GetModuleFileNameW(0, &Filename, 0x1000u);
SHGetFolderPathW(0, 7, 0, 0, &pszPath);
lstrcatW(&pszPath, L"\\wsample01b.exe");
CopyFileW(&Filename, &pszPath, 0);
return 0;
}
可以发现,是大致正确的
6.实验01总结
三个实验做下来,其实并没有“写下这篇实验报告类型的博客”看起来这么简单与轻描淡写
还是花费了许多时间的
三个实验中Sample_01和Sample_03还是比较让人满意的
Sample_02就真的,太打击人了
希望在日后的学习中可以继续好好努力,不耻下问
至少总有一天得搞懂Sample_02的函数吧(小声bb)
虽然不是第一次在优快云上发文了,(虽然以前也只发过一次)
但是这次有一点赶作业的嫌疑,并没有怎么认真排版,如果让大家阅读不便,敬请谅解!
附上三个Sample的IDA DATABASE文件和做作业时候的参考网址吧,原执行文件就不附上了
链接:https://pan.baidu.com/s/1v227QBImELFtbgMqmi8u5A
提取码:syll
http://www.ituring.com.cn/book/tupubarticle/9632