静态分析高级技术

静态分析高级技术

原文链接:https://hvnt3r.top/2019/03/静态分析高级技术/

知识点

本章内容为静态分析高级技术,知识点内容较多,很多知识点都是与x86体系结构下的指令等相关知识。

**微指令|机器码:**微指令层又称为固件,微指令只能在特定的电路上执行,其通常由更高的机器码层翻译而来,提供了访问硬件的接口;机器码层由操作码组成,操作吗是一些十六进制的数字,机器码一般由多条微指令实现,用于告诉底层硬件如何执行实际的代码。

**逆向工程:**逆向工程是将程序的二进制文件作为输入,由反汇编软件将其输出为汇编语言再进行分析的过程,汇编语言是一类语言的统称,例如x86、x64、SPARC、PowerPC、MIPS、ARM等。

内存:

一个程序的内存可以分为一下四个主要部分

		+------------------------+
低内存地址|          栈            |  用于函数的局部变量及参数,以及控制程序执行流
		+------------------------+
		|          堆            |  堆是为程序执行期间需要的动态内存准备的
		+------------------------+
		|                        |
		|          代码          |  包含在执行程序代码时CPU执行的指令
		|                        |
		+------------------------+
高内存地址|          数据          |  程序运行时的静态值,程序运行时不会发生变化
		+------------------------+

**指令:**指令时汇编程序的构成块,格式如下:

助记符目标操作数源操作数
movecx0x42

**操作码|字节序:**每条指令使用操作码opcode告诉CPU执行什么样的操作,反汇编器将操作码翻译为人类易读的指令,如下对比:

指令mov ecx0x42
操作码B942 00 00 00

大端序|小端序:x86架构使用小端字节序。数据的字节序指的是在一个数据项中,最高位(大端)还是最低位(小端)被排在第一位,一些恶意代码必须在网络通信时改变字节序,因为网络数据使用大端序,而x86程序使用小端序,再大端序下,网络地址127.0.0.1被表示为0x7f000001,而在小端序下表示为0x1000007f

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

  • 立即数:操作数是一个固定的值。
  • 寄存器:操作数指向寄存器。
  • 内存地址:操作数指向一个内存地址,一般由方括号内包含值、寄存器或方程式组成,如[eax]

**寄存器:**寄存器是可以被CPU使用的少量数据存储器,访问速度极快,寄存器分为以下四类:

  • 通用寄存器,在CPU执行期间使用
  • 段寄存器,用于定位内存节
  • 状态标志,用于做出决定
  • 指令指针,用于定位下一条要执行的指令

在x86环境下,这些寄存器的大小都为32位,有四个写寄存器可以以8位值的方式引用,应用示例如下:

                              EAX
32bits  ================================================
        |1010  1001  1101  1100  1000  0001  1111  0101|
        | A     9      D     C     8     1    F      5 |
        ================================================
        
                                           AX
                         16bits ========================
                                |1000  0001  1111  0101|
                                |  8     1    F      5 |
                                ========================
                                
                                     AH           AL
                          8bits ============ ============
                                |1000  0001| |1111  0101|
                                |  8     1 | | F      5 |
                                ============ ============
                                      

**通用寄存器:**通用寄存器一般用于存储数据或者地址,但是一些寄存器并不通用,如乘法和除法指令只使用EAXEDX,而EAX一般也会作为存储程序返回值的寄存器。

**标志寄存器:**EFLAGES是一个标志寄存器,在x86架构中,他是32位的,每一位是一个标志,在运行时每一位要不么置位,要么清零,常见的标志如下:

  • ZF:当一个运算结果等于0时,ZF为1,否则为0
  • CF:当一个运算的结果相对于目标操作数太大或太小时,CF为1,否则为0
  • SF:当一个运算的结果为负数,SF为1,否则为0,且当运算结果的最高位为1,SF也为1
  • TF:TF用于调试,当TF为1时,x86处理器每次只执行一条指令

**EIP:**EIP寄存器保存了程序将要执行的下一条指令的地址。、

NOP指令:nop指令即空指令,实际上此指令是xchg eax的一个伪名。

**栈:**用于函数的内存,局部变量,流程控制结构等存储在栈中,栈稚嫩那个用于短期存储,其主要用途是管理函数调用之间的数据交换。不同的编译器对这种管理方法实现的方式有所不同,但是大部分常见约定都使用相对EBP的地址来引用局部变量和参数。

**函数调用:**在函数调用时,最常见的调用方式是cdecl,调用函数的流程一般如下:

  1. 使用push将参数压入栈中
  2. 使用call memory_location来调用函数,当前指令地址被压入栈中
  3. 分配空间给局部变量,同时基地址EBP也被压入栈中
  4. 函数工作
  5. 恢复栈,调整ESP来释放局部变量占用的空间,从栈中弹出EBP
  6. 函数通过ret指令返回,从栈中弹出先前存储的EIP中的值给EIP,程序从原来调用的地方继续执行
  7. 调整栈,以移除之前压入的参数

**汇编指令:**常见的汇编指令数量较多,可从网上参阅。

**C语言主函数和主函数参数:**一个标准的C程序的主函数通常有两个参数:

int main(int argc, char ** argv)

参数argcargv在运行时决定。其中参数argc是一个整数,说明了命令行中参数的个数。参数argv是一个字符串数据指针,指向了所有命令行参数。

课后练习

本章无课后练习。


本章结束?

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值