《逆向工程核心原理》第三~五章知识整理

查看上一章节内容《逆向工程核心原理》第一~二章知识整理

对应《逆向工程核心原理》第三章到第五章内容

小端序标记法

  • 字节序
    • 多字节数据在计算机内存中存放的字节顺序
    • 分为小端序和大端序两大类
  • 大端序与小端序
BYTE b = 0x12;
WORD w = 0x1234;
DWORD dw = 0x12345678;
char str[] = "abcde";

TYPE

Name

字节

大端序

小段序

BYTE

b

1

[12]

[12]

WORD

w

2

[12][34]

[12][34]

DWORD

dw

4

[12][34][56][78]

[78][56][34][12]

char[]

str

6

[61][62][63][64][65][00]

[61][62][63][64][65][00]

  • 1 字节,在二进制是 8 位,在十六进制是 2 位
  • 内存地址:从低到高增长(如 0x10000x10010x1002)。
  • 数据的高/低位:数值的权重高低。例如,0x12345678 中:
    • 高位字节是 0x12(权重最大,像数字的“千位”),
    • 低位字节是 0x78(权重最小,像数字的“个位”)
  • 大端序:内存的低地址存储数据的高位字节
    • 人类视角:从左到右(地址递增)阅读,数值顺序不变,符合直觉。
    • 网络传输(网络字节序)、某些文件格式(如JPEG)
    • 保存多字节数据很直观
  • 小端序:低位字节在低地址,高位字节在高地址
    • 硬件视角:低地址存低位字节,方便逐字节处理(如加法从低位开始)
    • x86/x64架构CPU,内存中直接处理低位数据更高效
  • 字符串:最后是以 NUll 结尾,a 的 ASCII 码十六进制是 0x61
    • 字符串被保存在一个字符数组中,字符数组在内存中是连续的,无论采用大端序还是小端序,存储顺序都相同

在 OllyDbg 中查看 LittleEndian.exe 文件

#include "windows.h"
BYTE b = 0x12;
WORD w = 0x1234;
DWORD dw = 0x12345678;
char str[] = "abcde";

int main(int argc, char *argv[])
{
    byte lb = b;
    WORD lw = w;
    DWORD ldw = dw;
    char *lstr = str;

    return 0;
}

直接给出 main() 函数的地址,按 Ctrl+G 跳转到 401000 地址处

可以看到我们的定义的变量 0x12 地址应该是 40AC40

可以发现,这些数据使用小端序存储

IA-32 寄存器

寄存器

  • 寄存器是 CPU 内部用来存储数据的一些小型存储区域,有非常高的读写速度
  • 与 RAM(随机存储器、内存)略有不同,CPU 访问 RAM 中的数据时要经过较长的物理路径,花费时间长

学习程序调试技术,需要学习调试器解析出的汇编指令

IA-32 提供了庞大的汇编指令,指令可以翻看 Intel 提供的用户手册了解,大部分汇编指令用于操作寄存器或检查其中的数据

IA-32 寄存器

IA-32 是英特尔推出的 32 位元架构,属于复杂的指令集架构,支持多种寄存器

基本程序运行寄存器是 IA-32 寄存器的一种

基本程序运行寄存器

E 表示扩展,表示该寄存器在 16 位 CPU(IA-16)时已存在,并且其大小在 IA-32 下由原 16 位扩展为 32 位

通用寄存器

  • 4 字节 32 位,保存常量与地址
  • 传送和暂存数据,参与算术逻辑运算,保存运算结果

  • 各寄存器
    • EAX:累加器(针对操作数和结果数据)
      • 用在函数返回值中,所有 Win32 API 函数都会先把返回值保存到 EAX 再返回
    • EBX:基址寄存器(DS 段中的数据指针)
    • ECX:计数器(字符串和循环操作)
      • 也可以用在循环命令(LOOP)中循环计数,每执行一次循环,ECX 减 1
    • EDX:数据寄存器(I/O 指针)

以上 4 个寄存器主要用在算法运算(ADD、SUB、XOR、OR)指令中,常用来保存常量与变量的值

某些汇编指令(MUL、DIV、LODS)直接操作特定寄存器,执行这些命令,仅改变特定寄存器的值

    • EBP:扩展基址指针寄存器(SS 段中栈内数据指针)
      • 表示栈区域的基地址,函数被调用时保存 ESP 的值,函数返回时再把值返回 ESP,保证栈不会崩溃(即栈帧技术)
    • ESI:源变址寄存器(字符串操作源指针)
    • EDI:目的变址寄存器(字符串操作目标指针)
    • ESP:栈指针寄存器(SS 段中栈指针)
      • 指示栈区域的栈顶地址,某些指令(PUSH、POP、CALL、PET)可以直接用来操作 ESP

后四个寄存器主要用作保存内存地址的指针

  • 对低 16 位兼容
    • EAX:(0~31)32 位
    • AX:(0~15)EAX 的低 16 位
    • AH:(8~15)AX 的高 8 位
    • AL:(0~7)AX 的低 8 位

段寄存器

  • 段是一种内存保护技术。它把内存划分为多个区段,并为每个区段赋予起始地址。范围、访问权限等,以保护内存,
  • 此外段还同分页技术一起用于将虚拟内存变更为实际物理内存。
  • 段内存记录在 SDT(段描述符表)中,而段寄存器就持有这些 SDT 的索引
  • 段寄存器由 6 中寄存器组成,每个寄存器大小为 2 字节 16 位,存放相应所在段的段基址
    • CS:代码段寄存器
    • SS:栈段寄存器
    • DS:数据段寄存器
    • ES:附加(数据)段寄存器
    • FS:数据段寄存器
      • 用于计算 SEH(结构化异常处理机制)、TEB(线程环境块)、PEB(进程环境块)等地址
    • GS:数据段寄存器
  • 每个段寄存器指向的段描述符与虚拟内存结合,形成一个线性地址,借助分页技术,线性地址最终被转换为实际的物理地址
    • 不使用分页技术的操作系统中,线性地址直接变为物理地址

程序状态与控制寄存器

  • EFLAGS:标志寄存器
    • 大小为 4 字节 32 位,由原来 16 为 FLAGS 寄存器扩展而来
    • 每位的值为 1 或 0
    • ZF:零标志,若运算结果为 0,则值为 1,否则为 0
    • OF:溢出标志,有符号整数溢出时,OF 值被设置为 1。MSB(最高有效位)改变时,其值也被设为 1
    • CF:进位标志,无符号整数溢出时,其值也被设置为 1

指令指针寄存器

  • EIP:指令指针寄存器
    • 指令指针寄存器保存着 CPU 要执行的指令地址,其大小为 4 字节 32 位,由原 16 位 IP 寄存器扩展而来。
    • 程序执行时,CPU 会读取 EIP 中一条指令的地址,传送指令到指令缓冲区后,EIP 寄存器的值自动增加,增加的大小即是读取指令的字节大小
    • 这样,CPU 每次执行完一条指令,就会通过 EIP 寄存器读取并执行下一条指令
    • 与通用寄存器不同,不能直接修改 EIP 的值,只能通过其他指令间接修改,比如 JMP,Jcc,CALL,RET,还可以通过中断或异常修改 EIP 的值

栈内存在进程中的作用如下:

  • 暂时保存函数内的局部变量
  • 调用函数时传递参数
  • 保存函数返回后的地址

栈是一种数据结构,按照 FILO(后进先出)的原则存储数据

栈的特征

一个进程中,栈顶指针(ESP)初始状态指向栈底端。

执行 PUSH 命令将数据压入栈时,栈顶指针就会上移到栈顶端。

执行 POP 命令从栈中弹出数据时,若栈为空,则栈顶指针重新移动到栈底端

栈是一种由高地址向低地址扩展的数据结构,栈是由下往上扩展的,逆向扩展

栈操作示例

打开 Stack.exe(调试过程中,寄存器的初始值与栈的初址会随运行环境的不同而不同)

可以看到栈顶指针的值为 19FF74,观察右下角的栈窗口,可以看到 ESP 指向的地址及其值

在代码窗口按 F7,执行 401000 地址处的 PUSH 100 命令

ESP 的值变为了 19FF70,比原来减少了 4 个字节,并且当前栈顶指针指向了 19FF20 地址,该地址保存的值就是 100

也就是说,执行 PUSH 命令时,数值 100 被压入栈,ESP 随之向上移动,值减少 4 个字节

再次按 F7,执行 401005 地址的 POP EAX 命令

可以发现,ESP 的值增加了 4 个字节,变为了 19FF74,变为了一开始的状态

也就是说,从栈中弹出数据后,ESP 随之向下移动

总结:栈顶指针在初始状态指向栈底。向栈压入数据时,栈顶指针减小,向低地址移动;从栈中弹出数据时,栈顶指针增加,向高地址移动。

  • 总结

第 3 到 5 章初看时可能感觉很多都是记忆类的知识,不太容易理解,尤其是寄存器相关,可以大概先留个印象,初步学习时,知道这个术语在这里出现过就可以了。

关键的点是栈的理解,可以结合实例去弄明白栈的特征

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/962745.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2025年数学建模美赛 A题分析(4)楼梯使用人数模型

2025年数学建模美赛 A题分析(1)Testing Time: The Constant Wear On Stairs 2025年数学建模美赛 A题分析(2)楼梯磨损分析模型 2025年数学建模美赛 A题分析(3)楼梯使用方向偏好模型 2025年数学建模美赛 A题分…

【cocos creator】【模拟经营】餐厅经营demo

下载:【cocos creator】模拟经营餐厅经营

29.Word:公司本财年的年度报告【13】

目录 NO1.2.3.4 NO5.6.7​ NO8.9.10​ NO1.2.3.4 另存为F12:考生文件夹:Word.docx选中绿色标记的标题文本→样式对话框→单击右键→点击样式对话框→单击右键→修改→所有脚本→颜色/字体/名称→边框:0.5磅、黑色、单线条:点…

高性能消息队列Disruptor

定义一个事件模型 之后创建一个java类来使用这个数据模型。 /* <h1>事件模型工程类&#xff0c;用于生产事件消息</h1> */ no usages public class EventMessageFactory implements EventFactory<EventMessage> { Overridepublic EventMessage newInstance(…

neo4j初识

文章目录 一 图论基础二 柯尼斯堡七桥问题2.1 问题背景2.2 欧拉的解决3.1 核心概念3.2 核心优势3.3 应用场景3.4 技术特性3.5 版本与部署3.6 示例&#xff1a;社交关系查询3.7 限制与考量 四 图论与 Neo4j 的关联4.1 数据建模4.2 高效遍历4.3 应用场景 五 示例&#xff1a;用 N…

吴恩达深度学习——超参数调试

内容来自https://www.bilibili.com/video/BV1FT4y1E74V&#xff0c;仅为本人学习所用。 文章目录 超参数调试调试选择范围 Batch归一化公式整合 Softmax 超参数调试 调试 目前学习的一些超参数有学习率 α \alpha α&#xff08;最重要&#xff09;、动量梯度下降法 β \bet…

行业规范要当作业务实体画出来吗

第五元素 总觉得这些没有逻辑的实体&#xff0c;在绘制的时候不应该绘出来&#xff0c;他们没有责任啊。 比如以下:查阅规范 感觉不太对 UMLChina潘加宇 你这个规范是一个电脑系统还是一本书 第五元素 是书 UMLChina潘加宇 书没有智能&#xff0c;唯一暴露的接口是“翻”…

冯·诺依曼体系结构

目录 冯诺依曼体系结构推导 内存提高冯诺依曼体系结构效率的方法 你使用QQ和朋友聊天时&#xff0c;整个数据流是怎么流动的&#xff08;不考虑网络情况&#xff09; 与冯诺依曼体系结构相关的一些知识 冯诺依曼体系结构推导 计算机的存在就是为了解决问题&#xff0c;而解…

Qt之数据库操作三

主要介绍qt框架中对数据库的增加&#xff0c;删除和修改功能。 软件界面如下 程序结构 tdialogdata.h中代码 #ifndef TDIALOGDATA_H #define TDIALOGDATA_H#include <QDialog> #include<QSqlRecord> namespace Ui { class TDialogData; }class TDialogData : pub…

8.攻防世界Web_php_wrong_nginx_config

进入题目页面如下 尝试弱口令密码登录 一直显示网站建设中&#xff0c;尝试无果&#xff0c;查看源码也没有什么特别漏洞存在 用Kali中的dirsearch扫描根目录试试 命令&#xff1a; dirsearch -u http://61.147.171.105:53736/ -e* 登录文件便是刚才登录的界面打开robots.txt…

算法基础学习——快排与归并(附带java模版)

快速排序和归并排序是两种速度较快的排序方式&#xff0c;是最应该掌握的两种排序算法&#xff0c; &#xff08;一&#xff09;快速排序&#xff08;不稳定的&#xff09; 基本思想&#xff1a;分治 平均时间复杂度&#xff1a;O(nlogn) / 最慢O(n^2) / 最快O(n) 步骤&…

51单片机开发——I2C通信接口

I2C是微电子通信控制领域广泛采用的一种总线标准。 起始和停止信号&#xff1a; void iic_start(void) {IIC_SDA1;//如果把该条语句放在SCL后面&#xff0c;第二次读写会出现问题delay_10us(1);IIC_SCL1;delay_10us(1);IIC_SDA0; //当SCL为高电平时&#xff0c;SDA由高变为低d…

力扣017_最小覆盖字串题解----C++

题目描述 我们可以用滑动窗口的思想解决这个问题。在滑动窗口类型的问题中都会有两个指针&#xff0c;一个用于「延伸」现有窗口的 r 指针&#xff0c;和一个用于「收缩」窗口的 l 指针。在任意时刻&#xff0c;只有一个指针运动&#xff0c;而另一个保持静止。我们在 s 上滑动…

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.16 内存黑科技:缓冲区协议的底层突破

1.16 内存黑科技&#xff1a;缓冲区协议的底层突破 目录 #mermaid-svg-RmGabswVIrCh5olE {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-RmGabswVIrCh5olE .error-icon{fill:#552222;}#mermaid-svg-RmGabswVIrCh5o…

MySQL数据库(二)- SQL

目录 ​编辑 一 DDL (一 数据库操作 1 查询-数据库&#xff08;所有/当前&#xff09; 2 创建-数据库 3 删除-数据库 4 使用-数据库 (二 表操作 1 创建-表结构 2 查询-所有表结构名称 3 查询-表结构内容 4 查询-建表语句 5 添加-字段名数据类型 6 修改-字段数据类…

jstat命令详解

jstat 用于监视虚拟机运行时状态信息的命令&#xff0c;它可以显示出虚拟机进程中的类装载、内存、垃圾收集、JIT 编译等运行数据。 命令的使用格式如下。 jstat [option] LVMID [interval] [count]各个参数详解&#xff1a; option&#xff1a;操作参数LVMID&#xff1a;本…

亚博microros小车-原生ubuntu支持系列:18 Cartographer建图

Cartographer简介 Cartographer是Google开源的一个ROS系统支持的2D和3D SLAM&#xff08;simultaneous localization and mapping&#xff09;库。基于图优化&#xff08;多线程后端优化、cere构建的problem优化&#xff09;的方法建图算法。可以结合来自多个传感器&#xff0…

SpringBoot或SpringAI对接DeekSeek大模型

今日除夕夜&#xff0c;deepseek可是出尽了风头&#xff0c;但是我看网上还没有这方面的内容对接&#xff0c;官网也并没有&#xff0c;故而本次对接是为了完成这个空缺 我看很多的博客内容是流式请求虽然返回时正常的&#xff0c;但是他并不是实时返回&#xff0c;而是全部响应…

嵌入式C语言:什么是共用体?

在嵌入式C语言编程中&#xff0c;共用体&#xff08;Union&#xff09;是一种特殊的数据结构&#xff0c;它允许在相同的内存位置存储不同类型的数据。意味着共用体中的所有成员共享同一块内存区域&#xff0c;因此&#xff0c;在任何给定时间&#xff0c;共用体只能有效地存储…

Unet 改进:在encoder和decoder间加入TransformerBlock

目录 1. TransformerBlock 2. Unet 改进 3. 完整代码 Tips:融入模块后的网络经过测试,可以直接使用,设置好输入和输出的图片维度即可 1. TransformerBlock TransformerBlock是Transformer模型架构的基本组件,广泛应用于机器翻译、文本摘要和情感分析等自然语言处理任务…