0%

逆向工程核心原理第一—-十二章笔记

部分基础汇编指令的运用,以及寄存器类型;
如:8086汇编段寄存器:

CS:代码段寄存器(CPU执行命令仅从CS:IP指向的内容开始执行,到该内容截止。且CPU提供转义指令来修改CS、IP的内容)
SS:栈段寄存器
DS:数据段寄存器
ES:附加数据寄存器
FS:段寄存器
GS:段寄存器(FS,GS是80386起增加的两个辅助段寄存器,在这之前只有一个辅助段寄存器ES,增加这两个寄存器是为了减轻ES寄存器的负担,并能更好地配合适用于通用寄存器组的基址和变址寄存器.
这两个是通用的段寄存器,语法上同其它的段寄存器一样,不能直接用立即数给它赋值。)

更详细的段寄存器知识取自以下网址 段寄存器

image-20211207162249072

附上偏移地址的概念图

各种寄存器的简略介绍

image-20211207184336279

IP寄存器拓展:

EIP指针指令寄存器:保存着CPU要执行的指令地址,由IP寄存器拓展的EIP是不能直接修改的程序运行时CPU读EIP中的一条指令的地址,EIP寄存器的值自己增加,CPU每次执行完一条指令,就会通过EIP寄存器读取并执行下一条指令。

  • Ollydbg的部分使用方法
  • 大/小端序标记法。(字符串被保存在一个字符数组中时,无论采用哪种标记法,存储顺序都相同。)
    image-20211207170855768数据的低位存储在低地址位,数据的高位存储在高地址位,小端字节序称为LSB

数据的低位存储在高地址位,数据的高位存储在低地址位,大端字节序称为MSB

判断大小端序的方法

image-20211207183813150

 反之则为大端序。

EFLAGS(32位)是由FLAGS(16位)扩展来的。

每位值都有意义。

​ 初级阶段掌握 ZF(零标志)、OF(溢出标志)、CF(进位标志)即可。

​ ZF 运算结果0或1,True或False

​ OF 有符号整数溢出时,OF为1。MSB改变时,其值也为1。

​ CF 无符号整数溢出时,CF为1。

​ Tip

​ Jcc(条件跳转)指令要检查这3个标志的值(只要是条件跳转指令,都要检查这个值,来决定如何跳转。),并根据 其值决定是否执行某个动作。(以这点为核心的题目为攻防世界中RE的simple-check。)

汇编语言条件跳转指令汇总

栈–一种数据结构,其存储数据的规则为–先进(PUSH)后出(POP)

image-20211207185955041

image-20211207192440502

具体理解参考如下文章顺序栈基本操作(入栈和出栈)C语言详解

栈帧:

首先,在程序运行时,ESP寄存器的值是随时变化的;所以,调用某函数时,先把用作基准点(函数起始地址)的ESP值保存到EBP(栈帧指针),并维持在函数内部。这样,EBP的值能够安全访问到相关函数的局部变量、参数,返回地址,这就是EBP寄存器作为栈帧指针的作用。

栈帧—是利用EBP寄存器访问栈内局部变量、参数、函数返回地址等的手段。

image-20211207192332394

逆向工程核心原理第十三章PE文件格式

准备知识

  • 首先是类型

image-20211208184817595

(除OBJ之外都是可执行的,DLL、SYS是用其他方法间接执行的。OBJ不能以任何形式执行,所以逆向分析中一般不管它。)

  • 再贴一个易混淆的image-20211208184932670

    image-20211208190541199

    (RVA+imageBase=VA)

  • 节区:Flash芯片的最小数据存储单位称为节区。节区通常情况包含节区头、节区数据、节区尾等3个部分

    (节区头和节区尾用来存储该节区的一些管理字、ECC校验等管理信息,而节区数据则是存放实际有效的数据。这里可以将节区看成是带管理信息的扇区,一般情况下节区数据的长度为512个字节(一个扇区长度)。)

在生成进程时(加载到内存中),操作系统(OS)会为程序单独分配4G大小的虚拟内存,每个程序所分配的空间互不影响(即使运行同一程序)。)

image-20211211133948441

接下来正式开始

  • 在Windows下所谓PE文件即Portable Executable,意为可移植的可执行的文件。常见的.EXE、.DLL、.OCX、.SYS、.COM都是PE文件。PE文件有一个共同特点:前两个字节为4D 5A(MZ)。如果一个文件前两个字节不是4D 5A则其肯定不是可执行文件。比如用16进制文本编辑器打开一个“.xls”文件其前两个字节为:0XD0 0XCF;打开一个“.pdf”其前两个字节为:0X25 0X50。

    PE文件结构:DOS头+PE头+节表+.data/.rdata/.text。
    注意:一个exe文件本身是一个PE文件,但是由于包含dll库,所以一个exe文件也是许多PE文件组成的(包含多个dll)一个PE文件。

  • DOS头和DOS存根

    DOS头结构体中的v拉两个重要成员是e_magic(DOS签名)和e_lfanew(指示NT头的偏移(不同文件的值不同。))

    如第一条所说,所有PE文件的前两个字节都必须是4D5A(MZ),e_lfanew的值为000000E0

    (Intel的CPU采用小端序标识法存储数据–逆序。)

    DOS存根为可选内容(有无都不影响程序正常运行,且大小不固定。),其有代码和数据混合组成。

  • NT头:由签名结构体(值为50450000h–”PE“00),文件头和可选头组成。NT头的结构体大小为F8(十进制为248).

    文件头中,值得注意的是machine码,每个CPU都有唯一的machine码

    image-20211211115319553

image-20211211115418486

RVA to RAW

image-20211211122015407

(注:每个PE文件中的RVA和Pointer等值是不一样的,需根据具体情况来进行计算。上述VietualAddres是指的SizeofRawData)

  • IAT(导入地址表)—一种记录程序正在使用哪些库中的哪些函数的表格。(相对的为EAT—导出地址表。)

    image-20211211132147232

    image-20211211133010828

    INT是一个包含导入函数的信息的结构体指针数组。

    image-20211211140607158

    重要成员

    image-20211211140348489

    IAT的导入顺序如下

    image-20211211140800787

    • EAT(导出地址表)—它是不同的应用程序可以调用库文件中欧共提供的函数,只有通过EAT才能准确求得相应库中导出函数的起始地址。(在PE文件中仅有一个用来说明库EAT的结构体。)

    image-20211211132631404

    • IMAGE_EXPORT_DIRECTORY的重要成员如下图

    image-20211211132812251

  • DLL—一种动态链接库(附上DLL概念的描述和加载方式。)

    image-20211211130223999

DLL的存在使得内存和磁盘空间的浪费得以减小。

重定位:PE装载器先把一个DLL文件装载到内存为10000000(Imagebase处),然后尝试把另一个DLL文件也装载到该处,可该处已经装载了一个,故需要将其装载到其他内存地址(空白的)。

image-20211211130953633

image-20211211131019298

​ (注:ordinal为函数的固有编号。)

  • 值得一提的是,只要符合了PE文件规范就是PE文件,故可以在规范之外作出改动,从而制作出一些奇异的PE文件,这一类统称为Patched PE文件。(还没学到,以后会写。)