IDA使用 恶意代码分析实战 Lab 05 01
1.DllMain的地址是什么?
2.使用Imports窗口并浏览到gethostbyname,导入函数定位到什么地址?
3.有多少函数调用了gethostbyname?
4.将精力集中在位于0x1000757处的对gethostbyname的调用,你能找出哪个DNS请求将被触发吗?
5.IDA Pro识别了在0x16001656处的子过程中的多少个局部变量?
6.IDA Pro识别了在0x16001656处的子过程中的多少个参数?
7.使用Strings窗口,来在反汇编中定位字符串\cmd.exe/c。它位于哪?
8.在引用\cmd.exe/c的代码所在的区域发生了什么?
9.在同样的区域,在0x100101C8处,看起来好像dword_1008E5C4是一个全局变量,它帮助决定走哪条路径。那恶意代码是如何设置dword_1008E5C4的呢?(提示:使用dword_1008E5C4的交叉引用。)
10.在位于0x1000FF58处的子过程中的几百行指令中,一系列使用memcmp来比较字符串的比较如果对rootwork的字符串比较是成功的(当memcmp返回0),会发生什么?
11.PSLIST导出函数做了什么?
12.使用图模式来绘制出对sub_10004E79的交叉引用图。当进入这个函数时,哪个API函数可能被调用?仅仅基于这些API函数,你会如何重命名这个函数?
13.DllMain直接调用了多少个 Windows api?多少个在深度为2时被调用?
14.在0x10001358处,有一个对Sleep(一个使用一个包含要睡眠的毫秒数的参数的API函数)的调用。顺着代码向后看,如果这段代码执行,这个程序会睡眠多久?
15.在0x10001701处是一个对 socket的调用。它的3个参数是什么?
16.使用MSDN页面的 socket和 IDA Pro中的命名符号常量,你能使参数更加有意义吗?在你应用了修改以后,参数是什么?
17.搜索in指令( opcode 0xED)的使用。这个指令和一个魔术字符串VMXh用来进行 Vmware检测。这在这个恶意代码中被使用了吗?使用对执行in指令函数的交叉引用,能发现进一步检测Vmware的证据吗?
18.将你的光标跳转到0x1001D988处,你发现了什么?
19.如果你安装了 IDA Python插件(包括 IDA Pro的商业版本的插件),运行Lab0501py,一个本书中随恶意代码提供的 IDA Pro Python脚本,(确定光标是在0x1001D988处。)在你运行这个脚本后发生了什么?
20.将光标放在同一位置,你如何将这个数据转成一个单一的ASCI字符串?
21.使用一个文本编辑器打开这个脚本。它是如何工作的?
问题1:DllMain的地址
地址是1000D02E
问题2:使用Imports窗口浏览到gethostbyname,导入函数定位到什么地址
地址是100163CC
问题3:有多少函数调用了gethostbyname
r表示读,p表示调用,去掉重复的调用,一共5个!当然,另外一种方式:
gethostbyname函数名选择Xrefs graph to查看有多少函数调用它结果如图:五条线说明有五个函数调用他
问题4:在位于0x10001757处对于gethostbyname的调用,触发的是哪个DNS请求
如上图所示,1757的调用时图上的第六个,所以我们来分析1656这个函数即可
在函数中找到gethostbyname的调用,前后观察其重要的常量字符串
另外用汇编去看:
找到0x10001757(sub_10001656+101)双击到达代码处,分析如下,0x100019040处的全局变量地址赋值给eax,eax+0dh得到要请求的DNS名字,再压入栈作为gethostbyname的参数【eax寄存器内容就是函数实参】,所以双击查看10019040处代码,再双击跳转到1001994处看到字符串,[This is RDO]pics.praticalmalwareanalysis.com,去掉前头0dh个字符得到pics.praticalmalwareanalysis.com
问题5、6:IDA识别了1656函数的多少个局部变量和参数
这个问题其实没有太大意义,知道怎么操作就好。
当前版本的IDA,识别的是一个参数lpThreadParameter,以及62个参数
局部参数通常以var_
开头,偏移值为负值,看红色部分;参数的偏移为正,看蓝色部分。
问题7:定位\cmd.exe /c.
Shift + F12,查看Strings
问题8:在\cmd.exe /c的附近发生了什么
发现到了GetSystemDirectory的API函数调用
==》上述答案有错,标准答案是下面:
在上题处选中该局部变量,然后按x查看那个地方调用这个局部变量,可以发现只有 一个地方,双击跳转到该处
查看\cmd.exe/c
的交叉引用,定位到sub_1000FF58
函数,
这个函数的参数是SOCKET,是一个网络连接,还有很多字符串可以给出提示信息Encrypt Magic Number For This Remote Shell Session [0x%02x]\r\n
。根据不同系统打开了命令行,接下来就是很多比较,这部分代码在图形模式下更容易看懂,quit,exit,cd,enmagic。所以这部分代码是一个远程shell,可以执行cmd。==》看来还是要反汇编才好看懂!
问题9:在同样的区域里,在0x100101C8处,看起来好像dword_1008E5C4是一个全局变量,它帮助决定走那一条路径?恶意代码是如何设置dword_1008E5C4的?(提示:使用dword_1008E5C4的交叉引用)
先跳转到 这个位置上,然后选中这个变量,然后按“X”查看交叉引用,发现有3处交叉引用。
根据direction,双击第一个,进入第一次被引用的地方(从书本后面的答案来看,跳到这里的目的也是因为只有在这里被修改过)。
简单,在0x100101c处选中该局部变量按x可以看到就三个地方调用它,其中只有一个是mov指令其他都是比较,所以双击查看该mov指令,可以看到局部变量给赋予从函数10003695返回的值.再双击查看sub_10003695处的代码,可以看到如果得到的ID==2则al设为1否则为0,为2说明VER_PLATFORM_WIN32_NT win32nt平台
==》可以看到是eax给他的,而eax是sub_10003695函数调用的返回值!==》在恶意代码分析实战P65页专门说过!
所以看函数调用的功能就知道了:
看这个函数主要是要看它返回了什么东西。函数中eax首先赋值的是VersionInformation局部变量然后将94h这个内存空间(我个人理解)给了VersionInformation.dwOSVersionInfoSize,然后将eax压入栈中(这里只是将VersionInformation放入了栈中),然后调用GetVersionExA函数,这个函数是未来获取系统版本的,然后将eax置空,然后比较VersionInfomation.dwPlatformId是不是2。根据微软的文档,dwPlatformId是系统版本的标志位。而前面的dwOSVersionInfoSize有什么用呢,文档中说在调用GetVsersionExA前,必须要设置这个结构体成员,用来声明哪一种数据结构将被传递给函数。
函数判断为2的话,则zf将被置1,之后执行setz指令,setz指令是指当ZF被置位(置1),将al寄存器置1,否则为0。然后函数返回,该函数返回的就是al的值,所以就是将该全局变量直接置1。dwPlatformId为2,平台为VER_PLATFORM_WIN32_NT,具体系统有那些如下所示。
可以看到这个函数最终影响了al的值(eax的最低8位),实际上是确认系统是否是某个特定版本。
问题10:在位于0x1000FF58处的子过程中的几百行指令中,一系列使用memcmp来比较字符串的比较。如果对robotwork的字符串比较是成功的(当memcmp返回0),会发生什么?
先条状到0x1000FFF58,然后向下找到robotwork所在位置
如果memcmp比较返回0,所以不执行jnz指令,则调用sub_100052A2函数,然后跳转到loc_100103F6。直接双击该函数进行跳转,然后大致看了一下发现有一个注释(字符串),SOFTWARE//,双击该注释
成功则执行sub_100052A2函数双击跳转到该函数位置查看代码,看到两个关键的函数调用,打开一个注册表项成功跳转到10005309处,失败则关闭返回的注册表句柄,再看10005309处代码,还是几个关键函数调用,regqueryvalue和sprintf和100038EE,双击查看100038EE可以知道这是一个send函数,那么很明显了,得到某注册表值并且发送给某个远端.
有点复杂还是看图:
sub 38EE:
问题11:PSLIST导出函数
可见,其功能是完成注册表的新建
分析其中调用的几个函数
36C3:调用API函数GetVersionEx,在一个OSVERSIONINFO结构中载入与平台和操作系统有关的版本信息
664C:
在进程列表中搜索所有进程,其中Process32First是获取当前系统中运行的第一个进程,while中的Process32Next是获取下一个进程,形成的链表结构确保能够不重复不遗漏的遍历所有进程。从匹配进程名称来看,应该是恶意代码对于某种类型的系统进程实现了某种监听或者注入
6518:
和上面的664C框架结构类似
猜想:该导出函数实现的是对进程中的含有特殊字符串进程的监听或者是注入
==》和书中给的答案不一样。。。晕死。。。
这部分收集了一些进程信息,并通过Socket发送。
问题12:使用图模式来绘制出对sub_10004E79的交叉引用图。当进入这个函数时,哪个API将会被调用?仅仅基于这些API函数,你会如何重命名这个函数?
xrefs from截图如下:可以看到关键函数send,那么他send什么呢?看getsystemdefaultlangid和sprintf可以知道send的是和系统缺省语言ID,故命名为send_langID
问题13:DllMain直接调用了多少个Windows API?
直接右键xrefs from只能看到密密麻麻一片黑数不清多少个函数调用,选择view graphs user xrefs chart选择深度为1,为2的时候已经多的看不清楚了
问题14:0x10001358的Sleep时长
查看关键代码知道参数eax决定睡眠多长,可以看到一系列对eax的操作查看初始10019020处的数据得到30,30乘以3e8h(1000)得到30000毫秒
记得转换下1000!
问题15,16:1701处socket调用的参数
三个参数是2,1,6。这里需要注意参数的压栈顺序是从右到左的。
这里就是标准socket的使用。IDA已经有注释了,protocol,type,af
还是那句话,不加壳不加花的代码是很明显很好分析的,因为作者在写代码的时候是有逻辑的,找到那条主线结合正常的猜想,大致功能基本不会差太多的
根据网上的资料,protocol有如下常见的值:IPPROTO_TCP(6)。当内核向此raw socket交付数据包的时候,是包括整个IP头的,并且已经是重组好的IP包。protocol是IPPROTO_RAW(255),这时候,这个socket只能用来发送IP包,而不能接收任何的数据。protocol为0(IPPROTO_IP)的raw socket。用于接收任何的IP数据包。
type如下:SOCK_STREAM = 1 (stream connection socket),SOCK_DGRAM = 2, SOCK_RAW = 3,SOCK_RDM = 4,SOCK_SEQPACKET = 5,SOCK_DCCP = 6,SOCK_PACKET = 10
family如下:AF_INET = 2
函数调用形式为socket(int family,int type,int protocol)
问题17:搜索in指令的使用。程序是如何进行VMware检测的?
可以看到564D5868h,这就是小端存储的VMXh,也是检测恶意代码有反虚拟机行为的特征码。
https://www.cnblogs.com/FallenHWer/p/3409620.html
搜索指令可以使用search text,也可以使用Search -> Sequence of Bytes ,搜索in指令的opcode(ED)。
可以看到这个函数调用之后的比较中也出现了虚拟机相关的字符串,按时了这个函数有反虚拟机的功能。
之后发现有一个cmp指令,对比0x564D586,转化一下,选中该字符串,按“R”键,于是就看见了VMXh。
那说明这里确实使用in和VMXh进行了虚拟机检测。接下来看一看这函数的交叉引用。
查看每一个交叉引用,都会发现有一段“Found Virtual Machine,Install Cancel”。
说明确实存虚拟机检测。
问题18、19、20:在0x1001D988处运行IDA-py,并且修改显
示格式
19数值改变
21notepad++打开查看,获得光标位置将0-0x50个字节和0x55异或再重新写回去
根据提示运行脚本。File -> Script File
光标定位在1001D988
位置,A
可以转换位string
问题21:py代码如何工作的
简单的xor加密解密
sea = ScreenEA()
for i in range(0x00,0x50):
b = Byte(sea+i)
decoded_byte = b ^ 0x55
PatchByte(sea+i,decoded_byte)
py文件内容!