逆向工程课程随记+总复习

本文最后更新于 2025年5月9日 下午

复习时间很充沛,打算从头到尾把ppt和相关的实验知识边摸鱼边捋一遍。

章节顺序按照老师的ppt顺序

涉及到栈的没整理,pwn玩了这么久栈,没必要整了(懒得整了)

上课让写交过的东西

  1. 静态桥与动态桥
  2. 栈附近,哪里是传入的函数参数,哪里是局部变量(32位)
  3. 病毒置入文件的操作

[TOC]

第一章 数据的存储及表示形式

  1. 这里的单位:字节(byte)、字(双字节word)、双字(四字节dword)、八字节(qword)
    • 注意,在计组中,机器字长也成为字,这里的字一般是32位或64位的。(所以还是喜欢叫它内存单元喵~)
  2. 注意,可执行文件一般采用小端序储存数据;TCP/IP中传递数据以网络字节序传输,通常是以大端序传输。
  3. d代表数据、db是一个字节的数据、dw是一个字的数据、dd是双字

第二章 x86汇编语言介绍

pwn狗只把这些常用传参rdi、rsi、rdx、rcx、r8、r9,以及系统调用要动rax记得死死的,其他它们的理论作用还真没记过,这里记一记

通用寄存器

  • 数据寄存器:eax、ebx、ecx、edx
  • 指针变址寄存器:ebp、esp、esi、edi
  1. 累加器eax

    在加法、乘法、除法指令中的默认寄存器、存储函数返回值。

  2. 基址寄存器ebx,ds段中的数据指针。

咦?ds,看到过,不知道啥用,问问gpt

现代操作系统和 64 位处理器架构已不再依赖传统的段式寻址,因此段寄存器(如 DS)的作用已经被削弱。在用户模式下,程序无法直接访问段寄存器的值,而是通过虚拟内存和分页机制来访问内存。

  • DS(数据段)外,常见的段寄存器还有:

  • **CS**(Code Segment):指向代码段,用于存储程序指令。

  • **SS**(Stack Segment):指向堆栈段,用于存储程序的栈数据。

  • **ES**(Extra Segment):通常用于额外的数据段。

  • FS 和 **GS**:这些是附加的段寄存器,用于存储额外的数据段或特定的操作系统用途。

也就是其实不怎么用了。

  1. 计数器ecx,用于循环中使用

补充一下loop指令

loop 地址:先将ecx-1,如果不为0,则跳转到该地址。

  1. edx:用于存放整数除法产生的余数

  2. ebp、esp,栈底栈顶指针,不赘述了(函数传参以及栈帧太熟了,略)

  3. eip,指令指针寄存器

  4. 标志寄存器(成为flags或PSW,也就是程序状态字寄存器),32位中扩展为32位寄存器,成为EFLAGS。

    image-20241228212752676

    • OF(overflow flag)、SF(sign flag)、ZF(zero flag)、PF、CF意如其名,略

    • AF:辅助进位标志,低字节向高字节进位或借位时置1(若是字节操作,低四位向高四位借位时置1)

    • DF、IF、TF没怎么细了解过,不怎么常用于目前我浅陋的知识需要的判断,直接截个课件了

      image-20241228213329899

汇编指令集

  • mov、lea(都是把右给左,intel_x86架构下)
  • pushad、popad 在栈上按顺序压入32位通用寄存器,顺序是eax、ecx、edx、ebx、esp、ebp、esi、edi。
  • jmp、call、leave
  • ret n 代表pop rip 后,再往下弹出n个字节的栈(也就是esp - n)

各种寻址:计组学了,略。

第三章od

就是介绍od的使用,没啥东西。

关于断点去搜了搜

  • shift + f12 可以设置条件断点

  • he 硬件断点

  • bp 软件断点。

第四章 关于PE文件(可移植的执行体)

由于一开始的导入图片的图床崩了,后续重新传了一遍图片,但有的图片本地没有了,可能有点乱序和少东西???我现在没有发现哪儿少啥了懒得再改了:dog:

已经弄了好几遍了,弄了好久,好累,有谁发现哪儿对不上或者少啥戳一下我,主要内容是顺着老师的ppt捋的

  • dll文件、exe文件都属于pe文件

  • 虚拟地址中,32位的一页为4kB(0x1000),64位的为8kb(0x2000)

  • 物理扇区以512字节(0x200)为一个单位对齐,因此PE文件在内存中的尺寸要比文件大。

  • pe文件有固定的开始特征,MZ头与PE头
    总体PE结构

    image-20241124184342102

    image-20241126160750732

DOS头剩余的作用

  • 在0x3c(地址固定)的位置处有一个B0,这个位置记录了PE头的偏移位置。

image-20241124183941912

PE头标识以及标准PE头

image-20241126161034551

image-20241124190256491

  • PE文件中自定义节的数量,在节表来描述节的信息,每个节的描述信息都固定40个字节。
  • 标志集合如果为0x2000就是dll(这是从网上搜到有人回复的,但是存疑)(网上是对的标志位)

image-20241124185228367

这是询问的gpt关于这个标志集合的解释(gpt有误,还好去问了问官方文档,下面这个是错的哦)

image-20241202154606214

官方文档给出的表格:

image-20241202155211599

这是一个dll文件对应的标志(?????)
image-20241202154647636

问了老师。。。小端序去读:0x210e

老师建议用pe editor去看

image-20241202162152492

pe文件可能的类型:

在 PE 文件格式中,根据用途和特性,主要可以分为以下几种类型:


  1. 可执行文件(Executable, EXE)
  • 特点:
    • 包含程序入口点(Entry Point)。
    • 可直接加载到内存中由操作系统运行。
    • 通过链接器将目标文件链接生成。
  • 典型扩展名.exe
  • 用途:
    • 普通的 Windows 应用程序。

  1. 动态链接库(Dynamic Link Library, DLL)
  • 特点:
    • 没有程序入口点,不能独立执行。
    • 提供函数和资源供其他程序调用。
    • 支持多进程共享代码和数据。
  • 典型扩展名.dll
  • 用途:
    • 系统和应用程序的共享库(如 kernel32.dll, user32.dll)。

  1. 系统文件(System File, SYS)
  • 特点:
    • 用于操作系统的内核模式。
    • 通常是设备驱动程序或系统服务的实现。
    • 加载时需要内核的帮助。
  • 典型扩展名.sys
  • 用途:
    • Windows 内核模块或驱动程序。

  1. 对象文件(Object File, OBJ)
  • 特点:
    • 是编译器生成的中间文件。
    • 由链接器处理后生成最终的可执行文件或库。
    • 包含代码和数据的片段以及重定位信息。
  • 典型扩展名.obj
  • 用途:
    • 静态库或最终程序的构建过程。

  1. 静态库(Static Library, LIB)
  • 特点:
    • 包含多个目标文件的集合。
    • 链接到最终的可执行文件中。
    • 不需要在运行时单独加载。
  • 典型扩展名.lib
  • 用途:
    • 提供代码重用功能的静态模块。

  1. 引导程序文件(Boot File)
  • 特点:
    • 用于操作系统引导阶段。
    • 一些特定情况下被解释为 PE 文件。
  • 典型扩展名:无固定扩展名(如 bootmgr)。
  • 用途:
    • 系统启动相关。

这些类型文件的基础格式是相同的,但具体的标志、段结构和用途有所不同。了解这些类型有助于分析不同的 PE 文件及其作用。

这个文件有5个节,如下:

image-20241124185419557

扩展PE头

总体结构:

image-20241124191408697

image-20241124191427964

数据示例:

image-20241124191023141

红框再往后,0x00001000,0x00000200,分别代表在内存和文件的对齐方式(对应32位)

PE扩展头的最后一个字段是16个元素的数组,里面定义了PE文件中各种数据的目录信息,如导出表、导入表、资源等16种。

节表(每一节40字节,0x28)

image-20241124192304406

如这里是text节表

image-20241124192944192

0x1092代表实际字节数,0x1000是RVA,0x1200是对齐后的尺寸,0x0400是原始数据在文件中的数据,也就是最下面的红框。

寻找kernel.32.dll的基地址

  1. 去除低两个字节的值,只保留高两个字节的高位地址,windows中32位程序的入口地址通常应该通常以7000 0000 H开始。如同linux中可执行文件,64位以7f开头,32位以ff开头。

  2. 不断寻找MZ与PE标志,如果找到MZ标志,就将它对应的地址+0x3c,把里面对应的地址加载到找到MZ时的基地址中,比对是否为PE,如果是,则代表这是真正的入口地址。

    image-20241124193742932

    总程序

    image-20241124202458642

    jb代表进位或借位信号

    大于的话,CF标志(借位)为0,不会进行跳转。

    流程图(这是老师留的作业,不理解的自己跟着画一遍,别直接截走):(第一步写成将低两位字节的地址置为0更清楚一点)

    image-20241124202241012

关于导入表

image-20241127115909912

PE位置+0x78是16个表项的序列信息。

image-20241127134544447

该字段定义了 PE 文件中出现的所有不同类型的数据的目录信息。如导出表、导入表、资源等。 16种

8个字节记录一个目录,0x00002010是虚拟偏移,0x0000003c(60)是长度

  • 该偏移位于.rdata段,物理对应的起始为0x600,文件中的导入表目录就是0x610位置

image-20241127135747068

  • 每个导入表的表项有0x14字节(20字节),这里涉及到了两个导入的库,2个表项,40字节,但是需要最后一个表项用全0表示终止,所以总共用了3个表项,60字节。(导入表表项的数量只与导入的库的数量有关)

image-20241127140106324

以下分别是桥1,指向链接库的指针,桥2

image-20241127140420154

桥一虚拟偏移2008,文件偏移608

桥1指向的内容静态与动态都是一个指向索引+字符串的地址

桥2静态与桥1指向一致,动态则指向是一个指向载入的函数的地址。

image-20241204213358524

由于实验让画静态与动态关于winresult.dll相关信息,不再重复上面的那个文件的课上内容,下面用实验的要求的文件进行分析。

导入表2084,对应于文件的684

image-20241204211727567

这4个框是导入的3个dll库和一个终止标志

image-20241204212340887

  • 桥1里hint的值是索引值

第三个框,dll库地址为227a(87a)->winresult.dll,是需要分析的库

image-20241204221437843

导出表

image-20241204111650355

image-20241204110407587

image-20241204111019820

节对应rva2000->foa800

nName 94c->2190—-990-> “winresult.dll”

nBase 950->01(这是起始序号,函数编号-起始序号就是索引号)

Address of functions 95c->2168—-968 ->数组(1183、1022逐个的RVA偏移)

Address of Names 960->2178—-978 ->数组(219E(99E->函数名字)、21AB)(对应相加)

Address of NameOrdinals 964->2188—988->数组(0000、0001、0002、0003)(这是索引号)

也可以得知函数编号分别为1、2、3、4.(第一张图的index就是函数编号)

image-20241229152626582

无导入表的情况下索引函数地址与导入库

image-20241211112402093

其中sub_4010A4是根据kernel32.dll的导出表,用字符串来索引函数地址。

以下是该函数

image-20241211113545115

这里解释一下:

  • v7是字符串长度包括\x00

  • v2=v6

  • v2[9]与v6[9]都是函数序列地址表

  • v2[8]是函数名称地址表

  • v2[7]是导出函数地址表

主要解释一下最后的返回值。

  1. kernel32_base+v6[7]找到导出函数地址表

  2. 4*序列号来索引

  3. 序列号用函数序列地址表来索引(kernel32_base+v6[9])

  4. 这个地址要乘对应的偏移来找到正确的指向函数

  5. v3是函数名称地址表中对应于正确函数的那一项的地址

  6. v3 - kernel_base - v6[8] (这个是函数名称地址表的起始地址)得到正确的函数距离起始地址的字节数,这里存的每一项都是两个字节,右移1位就是正确的序列号。

  7. 找到正确的序列号后,用导出函数地址表索引到对应的函数偏移,然后返回用kernel32的基地址与偏移相加得到的可以使用的函数地址。


逆向工程课程随记+总复习
https://xyyr-c.github.io/2024/11/22/逆向工程课程随记/
作者
xyyr
发布于
2024年11月22日
许可协议