二进制入门及静态分析基础

HACKing三部曲

  • 理解系统
    • 系统性的基础课程学习,深入理解计算机系统的运作机制
  • 破坏系统
    • 学习与创作漏洞挖掘与利用技巧
  • 重构系统
    • 设计与构建系统防护

《汇编语言》

《c++反汇编与逆向分析技术揭秘》》
《加密与解密4》?

《恶意代码分析实战》

《0day安全:软件漏洞分析技术》
《漏洞战争》

fuzz test 模糊测试

PE文件格式

PE文件(Portable Executable)
常见的可执行文件如.exe和.dll文件都是典型的PE文件

PE文件格式把可执行文件分成若干个数据节,不同的资源被放在不同的节中。

  • .text 包含了CPU执行指令,所有其他节存储数据和支持性信息。一般来说这是唯一可以执行的节,也应该是唯一包含代码的节。
  • .rdata通常包含导入与导出函数信息,与Dependency Walker和PEview工具所获得的信息是相同的,这个节中还可以存储程序所使用的其他只读函数。有些文件还会包含.idata和edata节来存储导入导出信息。
  • .data 初始化的数据块,如宏定义,全局变量,静态变量
  • .idata 可执行文件所使用的动态链接库等外来函数与文件的信息
  • .rsrc 存放程序的资源,如图标菜单
  • .reloc
  • .edata
  • .tls
  • .rdata

内存

windows的内存被分为两个层面:物理内存和虚拟内存。其中,物理内存十分复杂,需要进入windows的内核级别ring0才可以看到。通常在用户模式下,我们用调试器看到的内存地址都是虚拟内存。

PE文件与虚拟内存之间的映射

  • 静态反汇编工具看到的PE文件中某条指令的位置是相对于磁盘文件而言的,即所谓的文件偏移,我们可能还需要知道这条指令在内存中所处的位置,即虚拟内存地址。

  • 反之,在调试时看到某条指令的地址是虚拟内存地址,我们也经常回到PE文件中找到这条指令对应的机器码。

  • 文件偏移地址(File Offset):数据在PE文件中的地址叫文件偏移地址,这是文件在磁盘上存放时相对于文件开头的偏移。(文件地址)

  • 装载地址(Image Base):PE装入内存时的基地址。默认情况下,EXE文件在内存中的基地址为0x00400000, DLL文件基地址为0x10000000,装载地址可以进行修改。

  • 虚拟内存地址(VA):PE文件中指令被装入内存后的地址。

  • 相对虚拟地址(RVA):相对虚拟地址是内存地址相对于映射基址的偏移量。RVA = VA - Image Base

几个注意事项

  1. 文件的偏移是相对于文件开始处0字节的偏移,RVA则是相对于转载地址0x00400000处的偏移。由于操作系统在进行装载时基本上保持PE中的各种数据结构,所以文件偏移地址和RVA有很大的一致性
  2. 之所以说基本一致,是因为还有一些细微的差异。
  3. PE文件中的数据以0x200字节为基本单位,因此PE数据节的大小永远是0x200的倍数。
  4. 当代码装入内存中,将按照内存数据标准存放,并以0x1000字节为基本单位。故内存中的节总是0x1000的整数倍。
  5. 我们把这种存储单位差异引起的节基址称作节偏移。
  6. 节偏移 = 相对虚拟偏移量RVA-文件偏移量
  7. 文件偏移地址 = RVA - 节偏移 = VA - Image Base -节偏移
  • DLL动态链接库文件
  • EXE可执行文件

静态分析基础

网络扫描

上传至virustotal等网站,调用多个反病毒引擎进行扫描

通过计算哈希值,确定恶意代码的指纹

windows中有md5deep、winmd5等工具

查找字符串

在字符串中进行搜索存在的字符

  • window函数名通常以大写字母开始的一个词开头,后面的每个词也以大写字母开始

加壳和混淆恶意代码

  • 混淆程序是恶意代码编写者尝试去隐藏其执行过程的代码
  • 加壳程序则是混淆程序中的一类,加壳后的恶意程序会被压缩,并且难以分析。
  • 至少包含LoadLibrary和GetProcAddress函数,用来加载和使用其他函数功能的。
  • 加壳程序运行时,会首先运行一小段脱壳代码,来解压加壳的文件,然后再运行脱壳后的文件
  • 当静态分析加壳程序时,只有脱壳代码可以被解析,如下图所示:
  • PEid工具:减策加壳器的类型,或者用来连接应用程序的编译器类型,

连接方式

  • 静态链接
  • 运行时链接
  • 动态链接
  • 静态链接再windows平台不常用,但在unix和linux是常用的,当一个库被静态链接到可执行程序时,所有这个库中的代码都会被复制到可执行程序中,这会让可执行程序增大很多,而在分析代码时,很难区分静态链接的代码与可执行程序自身代码,因为PE文件头中没有迹象表明这个文件包含有链接代码。
  • 使用运行时链接的可执行程序,只有当需要使用函数时,才链接到库,而不是像动态连接模式那样在程序启动时就会链接。
  • LoadLirary和GetProcAddress允许一个程序访问系统上任何库的任何函数,这意味着当这些函数被使用时,你无法静态分析出可以样本程序中会链接哪些函数
  • 动态链接是最常见的,在装载时搜索库函数

导出函数

  • 与导入函数类似,DLL和EXE的导出函数,是用来与其他程序和代码进行交互时所使用的,通常一个DLL会实现一个或多个功能函数,然后将他们导出,使得别的程序可以导入并使用这些函数。
  • DLL文件本身就是实现一些导出函数然后被EXE可执行文件所使用的,因此导出函数在DLL文件中是最常见的

当你不知道一个函数有什么功能的时候,需要对其查询,可以在MSDN库中进行搜索

一个很老的编译时间意味着古老的攻击,反病毒软件就可能包含这个恶意代码的检测特征,而一个很新的编译时间意味的情况则正好相反。(IMAGE_FILE_HEADER中的TIME DATE STAMP)

但所有的Delphi程序都使用统一的编译时间,1992.6.19,如果是这个则很可能是Delphi程序

  • IMAGE_OPTIONAL_HEADER部分包含几个重要信息:
  • 子系统Subsystem描述指出是一个控制台程序还是图形界面程序
  • 控制台的值为IMAGE_SUBSYSTEM_WINDOWS_CUI, 图形界面为GUI
  • 当text分节在内存占有空间比在磁盘更大一些时,极有可能为加壳代码的存在

发布了267 篇原创文章 · 获赞 51 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/AcSuccess/article/details/103440827