恶意代码分析

Chapter1 静态分析基础技术

 

Ascii和unicode两种类型格式,在存储字符序列时都以null结束符表示字符串已经终结。一个null结束符表示该字符串是完整的。Ascii字符串每个字符使用1个字节、而unicode使用2个字节

 

由string程序检测到的字符串并非是真正的字符串。可能是一个内存地址,CPU指令序列,或是由某个程序所使用的一段数据

 

加壳和混淆代码通常会包含loadlibrary 和getpreaddress 函数,他们是用来加载和使用其他函数功能的

 

导入函数是一个程序所使用的但又存储在另一程序中的那些函数

 

常见的DLL程序:kernel32.dll  包含核心系统功能,如访问和操作内存、文件和硬件等

Advapi32.dll  提供了核心windows组件的访问,比如服务管理器和注册表

User32.dll          包含了所有用户界面组件,如按钮、滚动条以及控制和响应用户操作的组件

Gdi32.dll 包含了图形显示和操作的函数。

Nedll.dll 这个dll是windows内核的接口,可执行文件通常不直接导入这个函数,而是由kernel32.dll间接导入,若导入这个文件则意味着作者在企图非正常供windows程序使用的函数,一些如隐藏功能和操作进程等任务会使用这个接口

Wsock.dll,ws2_32.dll   联网dll,访问任一可连接网络,或是执行网络相关的任务

Wininet.dll 包含了更高层次的网络函数,实现了如ftp,http,ntp等协议

 

命名约定:当微软更新一个函数,而且新与旧不兼容,微软仍会支持旧,新与旧名字相同,并在后面加上ex后缀,被显著更新过两次的函数,则名字后面有两个ex后缀

 

以字符串作为参数的很多函数,名字后会包含一个A或一个W,如createdirectoryW,A/W在文档中并不体现,只意味着函数有两个不同的版本,A表示输入参数类型为ascii字符串,W表示输入参数为宽字符字符串

 

Dll文件本身就是实现一些导出函数然后被EXE可执行文件使用的,因此导出函数在dll文件中是最常见的

 

PE文件头与分节:.text节包含了CPU执行指令,所有其他节存储数据和支持性的信息,这是唯一可执行的节,也应该是唯一包含代码的节

 

                            .rdata节通常包含导入与导出函数信息。这个节中还可以存储程序所使用的其他只读数据

.data 字节包含了程序的全局数据。可以从程序的任何地方访问到,本地数据并不存储在这个节中。而是PE文件某个其他文件上。

.rsrc节包含由可执行文件所使用的资源。这些内容并不是可执行的

 

Windows平台可执行pe文件中的分节:

.text 包含可执行代码

.rdata 包含程序中全局可访问的只读数据

.data 存储程序中都可以访问的全局数据

.idata 有时会显示和存储导入函数信息,如果此节不存在,导入函数信息会存储在rdata中

.edata                 导出

.pdata 只在64位可执行文件中存在,存储异常处理信息

.rsrc 存储可执行文件所需的资源

.reloc 包含用来重定位库文件的信息

 

恶意代码经常会把一个嵌入的程序或驱动放在资源节中,在程序运行之前他们会将嵌入可执行文件或驱动提取出来

 

一些恶意代码在网络通信时必须改变字节序,因为网络数据使用大端字节序,而x86程序使用小端字节序

 

操作数说明指令要使用的数据有三种类型:

立即数(immediate)操作数是一个固定的值

寄存器(register)操作数指向寄存器

内存地址(memory address)操作数指向感兴趣的值所在的内存地址

 

 

寄存器是可以被CPU使用的少量数据存储器,x86处理器中有一组寄存器,可以用于临时存储或者作为工作区,最常用的x86寄存器分为三类:通用寄存器(cpu执行期间使用)、段寄存器(用于定位内存节)、状态标志(用于做出决定),指令指针(用于定位要执行的下一条指令)

 

反汇编时,经常看到xor指令,例如xoreax,eax就是一种将EAX寄存器置0的方法

 

移位经常用于对乘法运算的优化

 

在分析恶意代码时,如果遇到一个函数中有xor,or,shl,ror,shr,rol这样的指令,并且反复随机出现,可能就是遇到了一个加密或者压缩的函数

 

Nop指令是xchg eax,eax的伪名字。该指令的opcode为0x90,在缓冲区溢出攻击中,可以使用nop滑板,起到填充代码的作用,以降低shellcode可能在中间部分开始执行造成的风险

 

用于函数的内存、局部变量、流控制结构等被存储在栈中,x86架构有对栈的构建支持。用于这种支持的寄存器包括esp和ebp。Esp是栈指针,包含了指向栈顶的内存地址,ebp是栈基址寄存器,在一个函数中会保持不变,因此程序会把它当成定位器,用于确定局部变量和参数的位置。

 

与栈有关的指令包括push,pop,call,leave,enter和rct。在内存中,栈被分配成自顶向下的,最高的地址最先被使用。

 

栈只能用于短期存储,它经常用于保存局部变量、参数和返回地址。其主要用户是管理函数调用之间的数据交换

 

许多函数包括一段序言(prologue),它在函数开始处的少数几行代码,用于保存函数中要用到的栈和寄存器。相应地,在函数结尾的结语(epilogue)则将栈和这些寄存器恢复至被调用前的状态。

 

 

 

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值