目录
以下实验exe均放进IDA进行反编译。
lab6-1(Lab6-1.exe)
1. 由main函数调用的唯一子过程中发现的主要代码结构是什么?
一般看到的第一个流程图就是main函数,当然也可以直接在function name栏里直接搜索“main”来找到main函数。之后找到这个唯一的子子过程sub_401000,双击移动到该函数。分析后发现一个if语句,用于判断是否连接网络,代码如下:
图中loc_40103A是函数的结束部分。首先该函数调用了InternetGetConnectedState函数,该函数返回值存储于eax中,将eax值赋给var_4,然后与0进行对比,如果var_4=0,则ZF=1,jz就进行跳转,然后出现“Error”的字样。如果var_4!=0,则ZF=0,jz不跳转,则出现“Siccess”字样,一直执行到无条件跳转,跳过loc_40102B,到达函数结束点loc_40103A。类似代码结构如下:
if(a!=0){
printf("Success:...");
}else{
printf("Error:...");
}
2. 位于0x40105F的子过程是什么?
跳转到该地点后,粗略观察后并没有发现什么线索。按“X”键,查看其交叉引用,只在sub_401000函数中存在两次调用。两次调用的方式都是一样的,就只放一处。
很明显有一个字符串压栈的操作,一般是在printf函数处才会有这样的操作,但是也不一定,说不定是传入字符串进行其他操作。在这里看来,两处的字串都感觉像是反馈作用,似乎没有操作价值,因此猜测此处是printf函数,或者说这可能是一个有打印功能的函数。该函数汇编代码如下。
首先调用了__stbuf函数用来初始化缓冲区,之后调用了__ftbuf函数,用于打印在屏幕上,从该流程中,字符串首先存储在eax中,之后被赋值给了edi,在调用__ftbuf时,edi被压入栈中,作为__frbuf的输入参数,最后清理栈,函数结束。因此该函数就是一个输出函数,判断为(类)printf。
3. 这个程序的目的是什么?
该函数的目的是判断是否连接网络,sub_401000的返回值有1和0,如果连接网络则返回1,否则返回0,在main函数中对该返回值进行了判断,如果返回0则main返回0,如果返回1,则main函数返回1。
lab6-2(Lab6-2.exe)
1. main函数调用的第一个子过程执行了什么操作?
调用的第一个子过程是sub_401000,双击后查看了一下和lab6-1的sub_401000一毛一样,连代码都是一样的。该子过程检查了是否连接了网络。
2. 位于0x40117F的子过程是什么?
和lab6-1的0x40105F子过程一毛一样。该子过程是printf。
3. 被main函数调用的第二个子过程做了什么?
调用的第二个子过程是sub_401040。双击跳转过去看一眼。通篇看下来,各式各样的字符串和API,基本给出了提示,大致有访问网址,读取互联网文件等。接下来详细分析一下。
首先是压了一堆参数进去,其中一个字符串为“Internet Explore 7.5/pma”,调用InternetOpenA,并将返回值放进了hInternet中。
通过百度InternetOpenA函数,得出“Internet Explore...”字符串可以理解为,作为http请求的user-agent。该函数在官方文档的解释里是“初始化应用程序对WinINet函数的使用”。通过对WinNet的查询,得知是一个操作网络请求的函数集,其中就包括了InternetOpenA,也就是说是一个模块。这一步可以理解为准备发一个请求,user-agent设置为IE浏览器。该函数如果创建请求失败,则返回NULL,成功则返回一个句柄。
第二步又压了一堆参数进去,其中包括一个url和InternetOpenA函数返回的句柄。
着重看一下这个szurl和InternetOpenUrlA。szurl的完整内容如下图。
InternetOpenUrlA从字面意思可以猜出来就是打开一个url,因此这里很明确就是访问szurl这个网址。官方文档也这么说的(当然意思有一小点点偏差)。如果该函数访问URL成功则返回一个句柄,访问失败则返回NULL。访问完毕后,将返回值放入hFile中。
紧随其后就有一个返回值和0的对比(0就是Null)。如果是null,则输出提示,关闭句柄,退出函数,如果对比成功则跳转至loc_40109D,继续执行操作。printf的地方我进行了函数重命名,原名是sub_40117F。
假设url访问成功,我们看到loc_40109D点,同样的,压了几个参数进栈,然后调用了InternetReadFile,这其中的参数就有InternetOpenUrlA返回的句柄hFile。
直接查看InternetReadFile的官方说明。该函数是读取来自InternetOpenUrl、FtpOpenFile或者HttpOpenRequest返回句柄中的内容。也就说该函数获取访问完url的返回内容(response)。如果读取成功返回true,失败则返回false。从它后面的判断和输出字符串(Error 2.2)来看,此处应该是下载了一个文件如下图所示。如果读取失败,则直接函数返回。
假设下载成功,则进入到loc_4010E5。该部分代码如下图。
很明显可以理解成一连串的独立if,把他全拼起来是“<!--”,这是一个html注释的起始符。这段语句结合loc_40111D处的输出语句提示(Error 2.3),可以发现此处应该是解析html注释,获取其中的命令。
综合来说,这个子过程就是下载文件,然后解析html注释,然后获取其中的命令。
4. 在这个子过程中使用了什么类型的代码结构?
这个问题冷不丁的一下,我突然发现分析第三题的时候我也没发现有啥结构呀,期间还差点把一连串的独立if结构看成了switch。通过查看书中的答案得知,这里面有一个数组,数组中存储的就是“<!--”,书中给出的反编译代码比较直观,而我的不是很直观,需要结合IDA pro给出的参数提示。如下图:
在if语句中就比较明显了,首先从buffer中取出一个第一个值进行比较,然后取出第二个值进行比较,以此类推,结合参数提示,会发现buffer,var_20F,var_20E等偏移了1,而且内存位置在一起,结合数组在内存中情况(连续的存储空间),判断出存在一个数组,它的基地址就是buffer的地址。
5. 在这个子过程中有任何基于网络的指示吗?
从上面几道题的分析结果来看,看到的网络提示是:user-agent为Internet Explore 7.5/pma,访问了网址http://www.practicalmalwareanalysis.com/cc.htm。
6. 这个恶意代码的目的是什么?
结合main函数中最后一个提示:“Success:Parsed command is ...”,该函数的目的是从网络中获取htm页面,并解析出其中的命令,解析成功后休眠1分钟,然后退出程序。
lab6-3(Lab6-3.exe)
1. 比较在main函数与实验6-2的main函数的调用。从main中调用的新的函数是什么?
两个main中前面部分是相同的,也就是到“Success: Parsed command is...”之前都是一模一样的,包括其中调用的sub_401271都是printf函数。区别是从“Success”(0x401246)到“dwMilliseconds”(0x401260)这一段,代码如下图所示:
该实验比上一个实验多出的代码。很明显调用了sub_401130函数。所以从main中调用的新函数就是sub_401130。
2. 这个新的函数使用的参数是什么?
调用函数前,参数会先压到栈上,所以我们直接看压栈的参数就可以了。部分代码如下:
有两个push,说明这个函数需要两个参数,一个是存在eax中的内容分,一个是存在ecx中的内容。先看eax,在0x401251处,edx赋值给eax,0x40124E处,[ebp+argv]赋值给edx,简单一点就是argv给了edx,argv是main函数的参数,用于接收命令行传入的参数,是一个数组。此时没有出现argv偏移,所以此处是把argv[0]给了edx,而argv[0]就是该程序名称。最后看ecx,ecx被赋值的地方是0x40123C处,把var_8的值给了ecx,之后就没有操作过。结合上下文,var_8存放的内容是解析出来的命令。所以该函数接收的参数是命令(ecx)和程序文件名(eax)。
3. 这个函数包含的主要代码结构是啥?
该函数中主要的代码结构是switch结构,是跳转表形式的汇编。从其跳转表来看,共有5个case语句。跳转表如第二张图所示。
4. 这个函数能够做什么?
分析这个函数的流程,这个函数中两个参数表示,分别是arg_0和lpExistingFIlename。arg_0就是传入的解析出来的命令。部分代码如下:
将arg_0赋值给var_8,var_8赋值给ecx,减去0x61,也就是字符 “a”(因为很长时间没写代码,看到减“a”的时候比较懵,不知道减出来的结果是啥。其实就和整型加减相同,比如ecx=“a”,那么ecx-"a"=0,以此类推)。ecx减“a”后,赋值给了var_8,var_8和4进行比较。如果大于4,则跳转至switch的default处,输出报错“Error 3.2:Not a valid commad provided”,退出函数。
如果var_8<=4,则进入跳转表,然后根据跳转表索引进入合适的case代码中。我们看到case的汇编点。代码如下:
内容比较长,放了3张图,代码从上往下是case 1~4,逐个看一下。case1调用了CreateDirectiryA,所以这里是创建文件夹,创建的文件夹是C:\\Temp。第二个调用CopyFileA,它是一个复制文件操作,这部分是将lab6-3.exe复制到C:\\Temp\\cc.exe中。第三个调用DeleteFileA,这部分删除文件,这里是删除C:\\Temp\\cc.exe。第四个调用了RegOpenKeyExA和RegSetValueExA,很明显是在操作注册表,这里是打开了注册表键值“Software\Microsoft\Windows\CurrentVersion\Run”,然后将Malware设置为“C:\\Temp\\cc.exe”。第五个是睡眠100秒。
5. 在这个恶意代码中有什么本地特征吗?
结合上一题的分析,本地特征有C:\\Temp\\cc.exe文件,注册表键值Software\Microsoft\Windows\CurrentVersion\Run\Malware是C:\\Temp\\cc.exe。
6. 这个恶意代码的目的是什么?
集合第4题的分析,这个恶意代码的目的是:访问指定网址,获取网页,解析出命令,然后进行复制文件、创建文件、删除文件、修改注册表的操作。
lab6-4(Lab6-4.exe)
1. 在实验6-3和6-4的main函数中的调用之间的区别是什么?
在代码模式下看了一圈,没有发现新调用的函数。各函数功能一样,只是在sub_401267(解析命令函数)处,出现了参数传递,参数是循环的i值。
2. 什么新的代码结构已经被添加到main中?
在图形模式,有一个向上指的箭头,说明存在一个循环结构,经过识别是一个for循环。从0x401248处开始,对var_C赋值为0,可以理解为i=0,之后和0x5A0进行比较,如果var_C>=0x5A0,则跳转到0x4012AF处,然后函数运行结束,这里可以理解为如果i<0x5A0,则开始循环,在0x401251到0x401257处,出现了var_C的累加。等同于如下代码:
for(i=0,i<0x5A0,i++){...}
3. 这个实验的解析HTML的函数和前面实验中的那些有什么区别?
首先是出现了参数传递,这个参数是循环计数的var_C。进入到函数内部,其中的不同是user-agent出现了变化,在“Internet Explore 7.50/pma”的基础上加入了var_C的值(在函数中是arg_0),调用了_sprintf,将这个新字符串放入了szAgent局部遍历中。
4. 这个程序会运行多久?(假设他已经连接到互联网。)
如果一切正常,只计算sleep函数的睡眠时间,忽略其余时间的情况下,需要运行1440分钟。共循环1440次,每循环完一次睡眠1分钟。
5. 在这个恶意代码中有什么新的基于网络的迹象吗?
新的网络迹象就是user-agent的变化,字符串“Internet Explore 7.50/pma”随着循环的递增而增加不同的数字。如第一次循环出现“Internet Explore 7.50/pma0”,第二次为“Internet Explore 7.50/pma1”。
6. 这个恶意代码的目的是什么?
这段恶意代码的目的和 lab6-3是一样的,只是user-agent出现不同,且main函数出现循环结构,但是功能是一样的。