> 本文由 [简悦 SimpRead](http://ksria.com/simpread/) 转码, 原文地址 [mp.weixin.qq.com](https://mp.weixin.qq.com/s/7NXC-ZGVN4BwW-1Ta2w\_5w)
之前两篇文章,针对恶意代码为了确保自身只有一个实例在运行进行了正向开发和逆向分析。逆向入门分析实战(一)逆向分析入门实战(二)
这种现象在恶意代码中非常常见,现在对上次的内容进行一个简要的回顾和扩展:
使用 ida pro 对恶意代码进行反汇编时会发现如下特征:
1、可以找到使用了 windows 的 api 函数 CreateMutex,该函数其中一个参数为互斥变量名。
2、在调用 CreateMutex 函数之后,通常会调用 GetLastError 函数,返回值与 ERROR_ALREADY_EXISTS 相同,即会使用 cmp 指令对返回值 eax 和 ERROR_ALREADY_EXISTS 对应的常量(16 进制的 B7,10 进制的 183)进行对比。
当然,本篇文章不是为了继续讲这个,现在我们应该更加深入的分析其他恶意代码常见的手法,这次分析恶意代码常见的获取计算机基本信息的函数,同样是先通过正向开发,然后进行逆向分析。
通常,恶意代码比较关注的计算机基本信息包括计算机名,计算机用户名,计算机的版本。下面我们就以获取这三个基本信息为例,进行正向开发和逆向分析。
一 、正向开发,获取计算机基本信息
首先,我们需要掌握几个知识点:
1、GetComputerName 函数,该函数有两个参数,第一个参数是一个缓冲区,用来接收计算机名。第二个参数指定该缓冲区的大小。对于经常使用 Python 进行编程的人来说,可能觉得有点奇怪,因为以 Python 语言的风格可能会是这样的:
computerName=GetComputerName()
函数无需传递参数,返回值即为计算机名。但是对于 windows api 很多函数来说,都会是这种风格,用某一个参数用来接收返回值,习惯就好。
2、GetUserName 与 GetComputerName 函数用法十分类似。
3、GetVersionEx 是用来获取计算机版本的函数,该函数只有一个参数,我乍一看觉得这个函数还挺简单,肯定和上面两个函数一样直接把返回值即计算机的版本返回到这个参数里了,当我仔细去看 MSDN 文档时发现,呵,参数居然是 lpVersionInfo,这是什么破东西?经过仔细调研发现,这是一个指向 OSVERSIONINFO 结构体的指针,好吧,当初学 C 语言的时候就觉得指针这玩意贼烦,现在又来了。那就好好再学习一下指针吧!这个指针指向 OSVERSIONINFO 结构体,而这个结构体就是用来承载返回值系统版本的。也就是我们先创建一个 OSVERSIONINFO 结构体,之后把结构体的指针作为参数传入 GetVersionEx 函数即可,然后再从 OSVERSIONINFO 结构体中读取相应的系统版本。
接下来看代码:
这段代码中,在主函数中先声明子函数,然后调用子函数,之后使用 getchar 函数,用来获取一个键盘输入。为什么加这个 getchar 函数?主要是因为如果不加这个,有的时候,当你直接双击这个程序时,可能命令行一闪而过让你看不清输出的内容。
子函数中,首先是获取计算机名,创建了一个 szComputerName 字符数组用来接收计算机名,数组大小为 MAXBYTE,为一个常量,通常为 256,当然不同操作系统版本对应的大小可能不太一样,在后面逆向的时候我们可以查看。
之后,同理获取计算机用户名。最后获取系统版本,其中 if 语句里的条件可能看不太懂,这个主要是 OSVERSIONINFO 结构体的成员变量需要查阅 MSDN 即可。dwMajorVersion 就对应不同的系统版本。当对应的值为 6 并且 dwMinorVersion 为 1 则是 windows7 或者 windowsserver 2008 R2。如果想了解更多关于系统版本的内容可以查看 MSDN:
https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoa
之后编译,运行:
使用 windows7 时的效果:
该主机计算机名确实为 PC:
版本为 windows 7:
而使用 windows 10 时的效果:
二、逆向分析:
将程序拖入 ida pro:
首先调用 puts 将字符串输出,之后调用 getSystemInfo 函数,这就是我们前面编写的子函数。双击进入发现有很多行汇编代码,如果我们现阶段就要把每一行都弄得很明白,那要花很长时间,学习很多知识,所以和上次一样,我们要分清主次,把所调用的函数分析清楚即可,等后续自己 “功力深厚” 一些,再努力把每一行汇编代码都分析清楚。我们选中 call,会发现所有的 call 指令都变黄了,这样便于我们分析,为了便于描述,将每一行汇编的地址调出来,点击 options->General->Line prefixes,将其勾选:
1、逆向分析获取计算机名和用户名
此部分内容对应的汇编代码如下:
查看 0040175E 处的 call 命令,此处调用 GetComputerNameA 函数,之前提到过后面多出一个 A 指的是当前使用的为 ASCII 环境。
在这个函数前面有两个备注分别是 lpBuffer 和 nSize 这两个其实就是 GetComputerNameA 的参数,我们之前学习的时候,一般是使用 push 将参数入栈,此处怎么不是 push?其实是一样的,仔细查看汇编指令 push 即可知道,其实 push 指令将参数入栈后,栈顶指针 esp 便会指向该参数,而此处使用的是 mov 将参数的值赋值给 esp 所指的地址空间,本质上是一样的。至于为何将 nSize 赋值给 esp+4 所指的空间,这是因为栈的增长方向以及参数所占的内存大小有关,此处简要介绍一下,因为标准调用约定中需要从右往左入栈,需要先将 nSize 参数入栈,再将 lpBuffer 参数入栈。根据栈的特点,先入栈的参数地址高,后入栈的参数地址低。即栈是一种由高地址向低地址扩展的数据结构。有兴趣的可以进一步查阅 push 指令和函数调用约定相关的资料。
执行完 0040175E 处的 call 命令返回值便会存储在 lpBuffer 对应的缓冲区内,此处即 ebp+Buffer 所指的空间内。之后调用 printf 函数,进行格式化输出,其中同样涉及到 esp+4,原因也是因为需要将 GetComputerNameA 获取到的计算机名先入栈,再将 “computer name is %s \r\n” 入栈。如果你熟悉格式化字符串漏洞的话,你会有一种很熟悉的感觉,当然如果你已经掌握了这里的知识,可以深入去了解格式化字符串漏洞的相关内容。
获取用户名的逆向分析过程与获取计算机名的过程类似,此处不过多介绍了。
2、逆向分析获取操作系统版本
这段内容对应的汇编代码如下:
首先查看 00401812 处的代码,94h 对应 10 进制为 148,这个数值便是 sizeof(OSVERSIONINFO) 的返回值,即 OSVERSIONINFO 结构体的大小。之后使用 lea 指令,它是 LoadEffective Address 的缩写,即加载有效地址,将该结构体所在的地址赋值给 eax,之后将 eax 中保存的地址空间存入 esp 所指的空间中,整个过程即可完成结构体指针入栈工作。
然后调用 GetVersionEXA 函数,返回值将会放置在结构体中。之后将该结构体中的 dwMajorVersion 成员变量与 6 对比,dwMinorVersion 与 1 对比,之后使用 jnz 命令来决定是否跳转,之前的文章将提及过,该命令是 jump not zero 的缩写,当不等于 0 时跳转。如果此处不是很熟悉,建议查阅之前的文章,掌握 cmp 和 jnz 以及 zf 标志寄存器的相关知识。再之后便使用 puts 输出字符串。
总结:
获取这些基本的信息其实很简单,只需调用几个 windows API 即可,对恶意代码进行逆向分析也很容易定位到是否在获取这些基本信息。而如果我们通过对这些 windowsAPI 调用的过程进行深入分析,便可以进一步掌握 C 语言、汇编语言和数据结构等相关的原理,比如指针,lea 指令、栈的工作原理,或者进一步学习格式化字符串漏洞。
参考书籍:
《C++ 黑客编程揭秘与防范》冀云著,第 1 版,2012.6-- 北京,人民邮电出版社
《C++ 反汇编与逆向分析技术揭秘》钱松林,赵海旭著 -- 北京:机械工业出版社,2011 年 9 月。
《恶意代码分析实战》 (美)Michael Sikorski / Andrew Honig 著,诸葛建伟,姜辉,张光凯译 -- 北京:电子工业出版社,2014 年 4 月,原书名: Practical Malware Analysis: The Hands-On Guide to DissectingMalicious Software。
《汇编语言》王爽 著 --2 版,北京:清华大学出版社,2008 年 4 月。
《逆向工程核心原理》,李承远著 -- 北京,人民邮电出版社,2014 年第 1 版。
逆向游乐园第一关
https://www.hetianlab.com/expc.do?ec=ECID172.19.104.182016031811584100001
(通过该实验了解调试工具和反编译工具的使用方法,能够通过分析样本中的详细信息,进行程序的爆破或者算法的还原突破程序的限制。)
欢迎投稿至邮箱:[email protected]
有才能的你快来投稿吧!
投稿细则都在里面了,点击查看哦
精选推荐
《Web 安全零基础到精通》
-
如果你也是一名想进入 Web 安全行业,急需专业老师带路的人;
-
急需提升实战技能,想找一份心仪工作的 0-3 年 Web 安全新人;
-
在校大学生,想进入 Web 安全行业,急需参与实操项目的同学。
戳戳戳