# 第 6 章：识别汇编中的 C 代码结构

## Lab 6-1

在这个实验中，你将分析在文件 Lab06-01.exe 中发现的恶意代码。

### 1、由 main 函数调用的唯一子过程中发现的主要代码结构是什么？

答案：**首先进行基础静态分析。**

二话不说，先上 VirusTotal。OK，无毒。其 Behavior 的说明为 “Network Communication”，也即存在网络通信行为：

* &#x20;<https://www.virustotal.com/gui/file/fe30f280b1d0a5e9cef3324c2e8677f55a6202599d489170ece125f3cd843a03/detection>

PEiD 表明是 VC 6.0 编译链接。使用 Dependency Walker 查看导入表。注意到 wininet.dll 中的 InternetGetConeectedState，该函数的作用是获得本地系统的网络连接状态（Retrieves the connected state of the local system）。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MLwdAYssKFCuV-5PoYS%2F-MLwnlISq-gr0kOrYgho%2FV%5BFZ1\(D%7DYSJU4V\(%25JB%25XNWM.png?alt=media\&token=7836b14c-a2c6-460e-a95b-1aaf76b70348)

* InternetGetConnectedState function (wininet.h) - Win32 apps | Microsoft Docs
  * <https://docs.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetgetconnectedstate>

当然，wininet.dll 本身还提供了很多其他联网的功能。

再解析下字符串。除了各种 API 函数外，还注意到包含 “Error 1.1L No Internet” 和 “Success: Internet Connection” 等字符串，推测该程序会检测系统中是否存在可用的 Internet 连接。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MLwoYUv-7l1Jt91b_tZ%2F-MLwowHxukNXjeOnmlRN%2F8%24%7B%7D~~_0\(%60LKPJ3\(7C11%24TJ.png?alt=media\&token=104b9683-e7a6-464f-ae77-ef401a787ab1)

**接下来进行基础动态分析。**

打开 Process Monitor，关闭捕获，清空历史，开启捕获，添加过滤规则 Process Name is Lab06-01.exe。在命令行运行，打印字符串 “Success: Internet Connection” 后就关闭了。Process Explorer 里没有任何驻留的进程或服务。Process Monitor 里也没有什么异样的信息。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MLwpzpIvfe3Jq_QlIfI%2F-MLwq0ZpU8GH4auG8OKy%2FZ60%5B%2459_4ZX2O%60\(%7DV6TOZRB.png?alt=media\&token=455c9255-0d5b-4e54-b201-5d8d062604e6)

**再进行高级静态分析。**

使用 IDA Pro 打开 Lab06-01.exe。main 函数的起始地址是 00401040。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM-rM9nmVcHtgdJvzvD%2F-MM0g7UiDSb-4wFL2z83%2F_DD%25ENHWDX0%409\(B%5BBC1TS%40Q.png?alt=media\&token=da659916-007f-4840-898a-02c50f9e555e)

该函数主要调用了函数 sub\_401000（上图粉色）。双击点开如下图。可以看到根据 InternetGetConnectedState 的结果来进行分支。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM-rM9nmVcHtgdJvzvD%2F-MM0mHLY8QlK-g6wSYGs%2FQ15%40EW_98%60UUQGYT%40THV%7BQ3.png?alt=media\&token=dffa4406-9a5e-4c0a-aec6-dd4b95732a96)

切换成图模式看得更直观一些。猜测含义是，若存在网络连接，则将字符串 “Sucess: ...” 传给 sub\_40105F，若不存在，则将字符串 “Error: ...” 传给 sub\_40105F。由于我们之前运行过该程序，运行结果是打印出了上面的字符串，因此我们推测 0x40105F 的作用是打印字符串。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM-rM9nmVcHtgdJvzvD%2F-MM0mIo9zsObytsuISLo%2FN7IQYPN%5BS%25F%7D7JAAL%24CY%60NG.png?alt=media\&token=41dba5e3-7d15-40dd-a4e3-025c596f719c)

### 2、位于 0x40105F 的子过程是什么？

在前一问中我们推测该子过程的作用是打印字符串。更详细的分析可以看参考链接中的说明。

能深入 C 源码分析其和汇编代码的相似性，固然最好。如果一时半会找不到，也不用担心，我们应当具备高层次的猜测和抽象思维，从而更快地分析出程序的意图。

### 3、这个程序的目的是什么？

该函数会检查是否存在一个可用的 Internet 连接，如果存在，打印结果并返回 1， 否则返回 0。恶意代码经常做类似于这样的检查以确定是否可以联网 。

### 参考链接

* 恶意代码分析实战 Lab 6-1 习题笔记\_isinstance的博客-CSDN博客&#x20;
  * <https://blog.csdn.net/isinstance/article/details/77948111>

## Lab 6-2

分析在文件 Lab06-02.exe 中发现的恶意代码。

VirusTotal 报告，报毒。有访问远程主机的恶意行为：

* &#x20;<https://www.virustotal.com/gui/file/b71777edbf21167c96d20ff803cbcb25d24b94b3652db2f286dcd6efd3d8416a/behavior/VirusTotal%20Jujubox>

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM0wbfFyidpJn2kAvuV%2F-MM10woQTOi9nX9QQwxp%2F6EYPVS~H%409KCQ0CVWU3K%5DQO.png?alt=media\&token=1b01bd89-d20e-4b95-bd65-20878e14c520)

PEiD 显示为 VC 6.0 编译链接。Dependency Walker 显示调用了 wininet.dll，其中导入函数均为联网相关操作。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM0wbfFyidpJn2kAvuV%2F-MM11JxWNdE1Zjfi36aP%2FR8QX07O1P%25F%247%60BY2AJL%7BGP.png?alt=media\&token=ffc628f9-f3dc-458a-bf05-730fd883d918)

用 IDA Pro 打开，切换到 Strings 窗口。可以看到很多和联网相关的字符串：

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM0wbfFyidpJn2kAvuV%2F-MM11nURZnaAdA9HUrsW%2F3LGY~AT6QJR%605TPSI%25%24%40ZKN.png?alt=media\&token=a42d714b-4609-434e-9a3a-ff476e65355d)

运行 Lab06-02.exe，得到 “Error 2.1: Fail to OpenUrl”。可能是虚拟机的网络配置问题。并且 netcat 也没有监听到书中所说的报文。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM11uIjHs0pHpcxMB_T%2F-MM135B9GAX7fctqe7i_%2F2%7DNOI6XW9S2L2%5B%5BG75CG1RE.png?alt=media\&token=3617125f-24f8-4b52-91f6-35fe65735217)

### 1、main 函数调用的第一个子过程执行了什么操作？

答案：首先查看一下 main 函数（红色）的结构。调用的第一个子过程为 sub\_401000（粉色）。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM13QmBFi6NurGsR15v%2F-MM1534tMYJQofYaoBzD%2FJQR%5D45BP2GY5Z%251J%5D2%251XVP.png?alt=media\&token=507e7100-d60a-4b7d-8e1b-026b5f61360a)

图模式看得更清晰一些：

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM13QmBFi6NurGsR15v%2F-MM154kXYLYaQtW0x2f_%2FX%40%25RM%5BL66B3%25%25X9AQ%7DV\)5X6.png?alt=media\&token=0593c1d7-2d56-458b-bbb8-99342d249f3d)

点开 sub\_401000，和 Lab 6-1 的很像，所以第一个子过程应该是判断本地系统是否有网络连接，有就打印 “Sucess…” 并返回 1，没有就打印 “Error…” 并返回 0。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM13QmBFi6NurGsR15v%2F-MM15k_op0HlXJyG7j2_%2F%5DS\)\)6W~AWY~4YD%5BX%60E_27R9.png?alt=media\&token=50b1dfab-2194-4b2c-80b8-3f5b4bb54345)

### 2、位于 0x40117F 的子过程是什么？

答案：看着眼熟，实际上在 Lab 6-1 中已经分析过，该子过程作用是打印字符串，相当于 printf。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM167gwOBLfJQU86av8%2F-MM16psuu2q7EAVNBSqO%2F\)VA320874%7BSHM%7BSF102J4C5.png?alt=media\&token=99cabb81-f378-4aa6-9d04-d5246f59ce1f)

### 3、被 main 函数调用的第二个子过程做了什么？

答案：第 2 个子过程是 sub\_401040。该子过程中调用了：

* InternetOpen（粉色）：初始化应用程序对 WinINet 函数的使用，“Internet Explorer 7.5/pma”
* InternetOpenUrl（蓝色）：打开静态网页，“<http://www.practicalmalwareanalysis.com/cc.htm”>
* printf（绿色）：打印出错信息，“Error 2.1: Fail to OpenUrl\n”
* InternetCloseHandle（橙色）：关闭一个网络句柄

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM16xhtgRyPaSunWxEi%2F-MM17vc8XBGDjwhrxA4L%2F3V%258G%7BI%5B%7DZ3ZA%60\)NN1ENI02.png?alt=media\&token=f92b4920-e57d-4c12-8c4c-f126535e470f)

* InternetReadFile（绿色）：从前面 InternetOpenUrl 打开的句柄中读取数据

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM1JkAuCCrcjQcVTKaV%2F-MM1K5S1QFDovAhUReuw%2F%24%24VY7E%24WIAOU%603K%7B\(WISC8D.png?alt=media\&token=bf09d7c2-35ed-4a60-a72c-a1ed98b1213d)

继续往下看，粉色部分标出了程序在比较字符串是否为 “\<!--”（在原本的十六进制数上按下 R 键切换显示成对应的 ASCII 字符），也就是 HTML 代码中的注释开头。

同时注意到 Buffer（蓝色），以及后面的几个 var\_\*（青色），事实上 var\_\* 应当是一个偏移量，但是 IDA Pro 没有识别出来 Buffer 是 512 字节。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM1MYug0Tr2Ks9Sa2g2%2F-MM1NNLWkaPdKAb5JPwu%2F%7B%5B4Z%5D%40US~HWMH%25%2527K2P0%5DR.png?alt=media\&token=a43f4999-9c48-4040-8405-3c55b1e1f830)

在函数中的任意位置，Edit > Functions >Stack variables（Ctrl+K），可以看到栈变量中的数据。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM1MYug0Tr2Ks9Sa2g2%2F-MM1OevIeFYW7FzNCVm0%2FG8N\)4MVSR%7B3B\(%24OLFLOC%5DVP.png?alt=media\&token=4d3d9258-9cf3-44ff-a46a-ae0cc1e54688)

在 Buffer 出右键，Array，设置 Array size 为 512，可以看到栈变成了下面的内容，这样就能看出有意义的参数信息了。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM1MYug0Tr2Ks9Sa2g2%2F-MM1PNaWkFFgCUyLIGss%2FY\(BA4%60D%7BR%25QFC%258~5W\(%7B%7DYE.png?alt=media\&token=072bd699-ebbf-430d-9181-cf91a090449b)

原来的 var\_\* 也自动变成了 Buffer 加上一个偏移量。所以图中这段内容就是比较 Buffer\[0:3] 的内容是否为注释开头 “\<!--”，如果是，则将 Buffer\[4] 的内容写入 al。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM1PXdrL3Mzrqjgxj5b%2F-MM1PbJONy8l2dOdMh2T%2FURHUA3O27%24%5DMXZ%5DN0%5DP1Y6Y.png?alt=media\&token=7dfffab2-7d38-494c-b448-fe688665ca2e)

接着回到主函数中 sub\_401040 处，继续向下执行，可以看到 al 的值赋给了 eax，并判断 eax 是否为 0，若非 0（也即 Buffer\[4] 的字符有意义），则跳到 loc\_40115C。然后打印 eax 对应的字符 “Success: Parsed command is %c\n”，其中 “%c” 就是 Buffer\[4] 转换得到的字符。最后休眠（Sleep）0EA60h=60000 毫秒，也即 60 秒。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM1Q4reHsiZ0sfqSVbD%2F-MM1R0PcqJsO58R9AeDO%2FL%5D%25LV\(SBJL%5DZ6K88%7BL%24%25T%7B3.png?alt=media\&token=812979f9-4ed8-4309-a10d-d00b57d015c1)

**最后总结一下，该程序检查是否有一个可用的 Internet 连接，然后下载一个包含 “\<!--” 的网页，这是 HTML 注释的开头部分，在网页浏览器中 HTML 注释不会被显示，但可以通过查看 HTML 页面源码看到。这种通过 HTML 注释隐藏指令的方法经常被攻击者用于向恶意代码发送指令，这让恶意代码看起来就像是在访问一个正常网页 。**

### 4、在这个子过程中使用了什么类型的代码结构？

答案：字符数组。

### 5、在这个程序中有任何基于网络的指示吗？

答案：有。

* InternetOpen 中 使用 User-Agent：“Internet Explorer 7.5/pma”
* InternetOpenUrl 从远程主机下载文件：<http://www.practicalmalwareanalysis.com/cc.htm>

### 6、这个恶意代码的目的是什么？

答案：程序首先判断是否存在一个可用的 Internet 连接，如果不存在就终止运行，如果存在，则使用一个独特的用户代理尝试下载一个网页。该网页包含了一段由 “\<!--” 开始的 HTML 注释，程序解析之后的那个字符，并打印 “Success: Parsedcommand is %c\n”，其中 %c 就是从该字符。如果解析成功，程序会休眠 60 秒，然后终止运行。

### 参考链接

* 恶意代码分析实战 Lab 6-2 习题笔记\_isinstance的博客-CSDN博客&#x20;
  * <https://blog.csdn.net/isinstance/article/details/77968330>

## Lab 6-3

在这个实验中，我们会分析在文件 Lab06-03.exe 中发现的恶意代码。

先一波静态分析。

VirusTotal，报毒，依旧是向远程主机请求下载文件：

* &#x20;<https://www.virustotal.com/gui/file/75eb05679a0a988dddf8badfc6d5996cc7e372c73e1023dde59efbaab6ece655/behavior/VirusTotal%20Jujubox>

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM1VaETcKtIJKXSx64c%2F-MM1ppoYjshDIRLBgJPE%2F92XI~TSL\(SON\)26Y\)M5M6XC.png?alt=media\&token=5953145e-40e9-4413-88c4-bac94a69ae10)

Dependency Walker 看一下导入函数，wininet.dll 中有 InternetGetConnectedState、InternetOpen、InternetOpenUrl、InternetReadFile 和 InternetCloseHandle，同 Lab 6-2 类似。多了一个 advapi32.dll，有 RegOpenKeyEx 和 RegSetValueEx，有写注册表操作。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM1pxvBOS96BMqPGv21%2F-MM1qanEYybMvvu8ZAbi%2FA0GQPANGQDJ717CD%25O9_CGU.png?alt=media\&token=f18da34d-41d8-4df2-be89-914bfefcddea)

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM1pxvBOS96BMqPGv21%2F-MM1qc8RxffUlxiSBUkt%2FELPK3V1B%60%7D\)K%60A%5D49NS2_%60U.png?alt=media\&token=f8fb6ac1-c913-4c18-b9eb-8c3479ebc816)

用 IDA Pro 打开，查看 Strings，除了 Lab 6-2 中出现的和网络请求相关的部分，还多出了注册表和命令：

* Software\Microsoft\Windows\CurrentVersion\Run
* C:\Temp\cc.exe
* C:\Temp

猜测可能要读写注册表，并执行远程下载的恶意程序。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM1r4w3c2qv7V7XyFS1%2F-MM1rPQIuG_cy4RB23Kp%2F9A3%24%403AXIYCG%60R%7DR0TUNW_G.png?alt=media\&token=1410a393-52c5-4e27-8280-81eef94c88ab)

### 1、比较在 main 函数与实验 6-2 的 main 函数的调用。从 main 中调用的新的函数是什么？

答案：其他基本一致，只出现了一个新函数 sub\_401130（粉色）。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM1roxsZCQhzVFkr07d%2F-MM1s_6QiQaZcd2NyFbI%2FGP5%25P%5D%7BNQD76FXIX5C9%5BHHM.png?alt=media\&token=8416d967-bee2-466b-a434-a41af36539bc)

### 2、这个新的函数使用的参数是什么？

答案：传入的第一个参数是 char 类型，其实就是此前读出的 HTML 字符。第二个参数是指向文件名字符串的指针（实际上是标准 main 函数的 argv\[0]，也即该程序自己的文件名）：

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM1siZvoe11mMkgpBft%2F-MM1txBeR5UZh8bsPzjD%2FP%5BO%406BMSAB1JJG83YW2%60WW4.png?alt=media\&token=aa5bad67-d937-4134-a2a4-4bf0b974b004)

### 3、这个函数包含的主要代码结构是什么？

答案：双击进入函数，进一步查看。arg\_0 是 IDA 自动生成的标签，表示第一个参数（或者说，最后一个压入栈中的参数）。粉色的两行语句表示将 arg\_0 的值赋给 var\_8。绿色的前 3 行语句表示将 var\_8 自减 61h（对应 ASCII 字符 ‘a’），第 4\~5 行表示，若该字符减 ‘a’ 大于 4（非 ‘a’、‘b’、‘c’、‘d’、‘e’），则跳到 loc\_4011E1（打印 “Error 3.2 …” 并终止 ），否则，将该值赋给 edx，进入 switch 语句。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM1vuHZWxC7VfpQtfIf%2F-MM1wLH9ad_dJozrQjOh%2FZ%7BGTGM0H7O7%25F%607T_B~_P_M.png?alt=media\&token=edf3450f-27e7-42b6-8299-dbcb5038926d)

切换到图模式看得更直观一些（粉色即为 switch 的判断语句）：

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM1xYZ-2qRv0LAZQdyV%2F-MM1yLCOlruKN32cnnHZ%2FM%60DI86G24QB_%7D0ULC_L7DDM.png?alt=media\&token=8dc40592-4709-4b91-a2fe-8ce981638a6d)

off\_4011F2 对应一张跳转表（‘a’\~‘e’ 的分支），加上 loc\_4011E1（default 分支），共有 6 个分支，和上图橙色部分正好对应。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM1xYZ-2qRv0LAZQdyV%2F-MM1xnL-pW7vJYZllkwG%2FUA%5B%40%60V_%25TPF3ND2L9%248%24C84.png?alt=media\&token=4e28f2e5-1230-4d3b-aa88-b958f0d5d369)

### 4、这个函数能够做什么？

答案：函数的重点是整个 switch 语句的作用。下面逐一剖析。

case 0，也就是字符为 ‘a’。调用 CreateDirectory 创建了一个文件夹 “C:\Temp”。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM44SMWb9xxThD3ED-N%2F-MM4m6JjM_lLN3bOetCD%2FRWRHDIS5F%60JI~910WC7M5%7BK.png?alt=media\&token=fb610437-2f85-41b0-bd15-fc6a3478e481)

case 1，也就是字符串为 ‘b’。调用 CopyFile 复制文件：源文件是 lpExistingFileName，前文提过是 argv\[0]，也即该程序自己的文件名 “Lab06-03.exe”；目标文件是是 “C:\Temp\cc.exe”。也即该分支将 Lab06-03.exe 复制到 C:\Temp\cc.exe。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM44SMWb9xxThD3ED-N%2F-MM4mNn7t439CUBeLjYW%2FPTJ%7BF%7BJHW4K5I0P3%7DLY88TT.png?alt=media\&token=c20c06b5-b045-4e17-ae34-e0918d65fa5e)

case 2，也就是字符串为 ‘c’。调用 DeleteFile 删除文件，由于 Data 的内容即为 “C:\Temp\cc.exe”（见上图），因此该分支会删除 C:\Temp\cc.exe。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM44SMWb9xxThD3ED-N%2F-MM4nfMkiZPEVWNCmnPh%2F~QGTMGWF%608DKY_3IP%7DN3%24ZW.png?alt=media\&token=ea933d07-7721-4b58-a089-e79a747cab43)

case 3，也就是字符串为 ‘d’。看上去复杂，其实也就两个函数。首先调用 RegOpenKeyEx 打开注册表键 “Software\Microsoft\Windows\CurrentVersion\Run”，然后再在该键下创建一个新的键 “...\Malware”，其值为 “C:\Temp\cc.exe”。这样系统启动时，如果 C:\Temp\cc.exe 存在，则也会跟随系统启动，自动运行。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM44SMWb9xxThD3ED-N%2F-MM4oGG-ASXPSWMEaOQ7%2F4RX438%5BIB%25OQWBGIST%5DP8YT.png?alt=media\&token=865b45e2-b2d4-48ac-ae2c-6e4407d126fb)

case 4，也就是字符串为 ‘e’。调用 Sleep 休眠 186A0h=100000 毫秒，也即 100 秒。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM4pEbB_QTPhxOOGZ-y%2F-MM4wt7ufvBAI55UztXA%2FAXF%7D6MT%5D90M7L_H1VK1M07M.png?alt=media\&token=aca00053-4069-4a8a-9d4f-c09b67cf2a57)

default case，也就是字符串非 ‘a’\~‘d’。调用 sub\_401271，打印字符串 “Error 3.2: Not a valid command provided”。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM5-tY8-0neqTYXcLme%2F-MM53EMWF_SGrMQhmRBK%2FEHHH6%7D%25KR58K9YRIZ%7DILVP8.png?alt=media\&token=b3e79f50-69b4-449d-a73b-9ea2df55e8df)

### 5、在这个恶意代码中有什么本地特征吗？

答案：注册表键 Software\Microsoft\Windows\CurrentVersion\Run\Malware 和本地文件 C:\Temp\cc.exe。

### 6、这个恶意代码的目的是什么？

答案：该程序先检查是否存在有效的 Internet 连接。如果找不到，程序直接终止。否则，该程序会尝试下载一个网页，该网页包含了一段以 “\<!--” 开头的 HTML 注释。该注释的第一个字符被用于 switch 语句来决定程序在本地系统运行的下一步行为，包括是否删除一个文件、创建一个目录、设置一个注册表 run 键、复制一个文件或者休眠 100 秒。

## Lab 6-4

在这个实验中，我们会分析在文件 Lab06-04.exe 中发现的恶意代码。

静态分析一波。

VirusTotal 报告，报毒：

* &#x20;<https://www.virustotal.com/gui/file/cce96e5cb884c565c75960c41f53a7b56cef1a3ff5b9893cd81c390fd0c35ef3/behavior/VirusTotal%20Jujubox>

IDA 中查看 Strings，发现和 Lab06-03.exe 中有一句新增的字符串，“Internet Explorer 7.50/pm&#x61;**%d**”。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM5ArAGBSPe4KaX9rYi%2F-MM5DyZlRDPdM0XGzjjl%2F%7BQ3%24\(6U\(MC6PVHY~\(IMK~%7BP.png?alt=media\&token=43648bc7-0e41-4cf9-b7ee-f9f58843def1)

### 1、在实验 6-3 和 6-4 的 main 函数中的调用之间的区别是什么？

答案：用 IDA 打开，文本模式查看好像很多函数都和 Lab 6-3 很类似，不过用图模式打开，就可以看到 Lab 6-4 中有一个明显的循环结构（最左边蓝色向上的箭头）。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM60UjYT60d4vPx9iGT%2F-MM60YJFnO0ee0wuSUSn%2F50SX%5BV~0GVR%7DDS~J_%5B%406DK5.png?alt=media\&token=c96bd4e1-c20e-4a3a-9049-765dc7c31537)

该 for 循环语句的文本模式如下图。当 eax 超过 5A0h=1440 时，跳出循环：

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM61QBqWbaSTA1pTkCE%2F-MM645GDWG4EdnB_ooda%2FFD2_A0%5DQCPWP1J7DKQ3D%60PS.png?alt=media\&token=66ee9f06-3017-498b-95bb-1c45227a3a15)

### 2、什么新的代码结构已经被添加到 main 中？

答案：main 函数中添加了 for 循环语句。

### 3、这个实验的解析 HTML 的函数和前面实验中的那些有什么区别？

答案：注意绿色部分，在调用 fetch\_url 函数前 push  进栈的最后一个变量是 ecx，而 ecx 的值来自 \[ebp+var\_C]，再往上看，\[ebp+var\_C] 的值来自 eax，也即 ecx = \[ebp+var\_C] = eax。从第 1 问中我们也知道，eax 每次循环自增 1，所以其实 ecx 也就是计数器的数字。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM64Q4qgwVSwg_r0ks7%2F-MM68e4zuzT21Rj2FXDK%2FHQ9Y8%5DPHVB_%24VVJ0%40%25PUFWY.png?alt=media\&token=9c969106-6fa2-43d3-aa11-a29f08424baf)

双击进入 fetch\_url，注意其中的 \_sprintf 函数（粉色），以及第二个参数（格式化字符串）和第三个参数（字符）。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM6CCwvZgEw8OKbd4Ph%2F-MM6DD0kWUhWZlWvrO_K%2F\)GP%7B0WM9E03J1J2_GMUAMYL.png?alt=media\&token=f03862bf-d1ea-459f-a886-f748339bd523)

sprintf 函数的格式如下。可以看到第一个参数是指向存储 C-string 缓冲区的指针，第二个参数为格式化字符串，后面的参数是参与格式化的字符，在上图中，只有 “%d” 这一个格式，所以只有第三个参数，也即 eax。从上图橙色部分可以看出，eax = \[ebp+arg\_0]，而 arg\_0 的值即为上上图中 fetch\_url 函数上一行里最后一个压入栈中的 ecx，也即计数器的数字。所以这里的 “%d” 实际上就被替换成计数器的数字了。

```c
// int sprintf ( char * str, const char * format, ... );
char buffer [?];
int eax;
n = sprintf (buffer, "Internet Explorer 7.50/pma%d", eax);
// printf ("[%s] ... %d ...", buffer, eax)
```

* sprintf - C++ Reference&#x20;
  * <http://www.cplusplus.com/reference/cstdio/sprintf/>

### 4、这个程序会运行多久？（假设它已经连接到互联网。）

答案：由前面的分析可知，要循环 5A0h = 1440 次，每次循环除了调用正常的函数（比如 switch 的六个分支）外，最后还要休眠 0EA60h = 60000 毫秒，也即一分钟。所以这个程序会运行 1440 分钟 = 24 小时。

![](https://787279543-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MLT8iP0IvoyaLlQfCAi%2F-MM6F7iASWP2ktW4GKt9%2F-MM6F_MkB_qI5YA_dOhm%2F%40%7BRCLYZVZWN%60\)\)M85YA%25URL.png?alt=media\&token=d09dbd29-dc1d-4513-ade7-daeac1b2153a)

### 5、在这个恶意代码中有什么新的基于网络的迹象吗？

答案：对 User-Agent 进行了改造，内容是 “Internet Explorer 7.50/pma%d”，其中 %d 是 for 循环的计数器数字，其实也相当于程序已经运行的分钟数。

### 6、这个恶意代码的目的是什么？

答案：类似 Lab 6-3，只不过多了一个 for 循环了 1440 次的语句，并且每次 InternetOpen 的 User-Agent 都会和计数器的数字相关。
