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

news2025/2/2 16:00:21

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

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

小端序标记法

  • 字节序
    • 多字节数据在计算机内存中存放的字节顺序
    • 分为小端序和大端序两大类
  • 大端序与小端序
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 章初看时可能感觉很多都是记忆类的知识,不太容易理解,尤其是寄存器相关,可以大概先留个印象,初步学习时,知道这个术语在这里出现过就可以了。

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2025 AI行业变革:从DeepSeek V3到o3-mini的技术演进

【核心要点】 DeepSeek V3引领算力革命,成本降至1/20o3-mini以精准优化回应市场挑战AI技术迈向真正意义的民主化行业生态正在深刻重构 一、市场格局演变 发展脉络 2025年初,AI行业迎来重要转折。DeepSeek率先发布V3模型,通过革命性的架构创…

SAP SD学习笔记28 - 请求计划(开票计划)之2 - Milestone请求(里程碑开票)

上一章讲了请求计划(开票计划)中的 定期请求。 SAP SD学习笔记27 - 请求计划(开票计划)之1 - 定期请求-CSDN博客 本章继续来讲请求计划(开票计划)的其他内容: Milestone请求(里程碑请求)。 目录 1,Miles…

SpringBoot+Vue的理解(含axios/ajax)-前后端交互前端篇

文章目录 引言SpringBootThymeleafVueSpringBootSpringBootVue(前端)axios/ajaxVue作用响应式动态绑定单页面应用SPA前端路由 前端路由URL和后端API URL的区别前端路由的数据从哪里来的 Vue和只用三件套axios区别 关于地址栏url和axios请求不一致VueJSPS…

大白话讲清楚embedding原理

Embedding(嵌入)是一种将高维数据(如单词、句子、图像等)映射到低维连续向量的技术,其核心目的是通过向量表示捕捉数据之间的语义或特征关系。以下从原理、方法和应用三个方面详细解释Embedding的工作原理。 一、Embe…

2025年1月22日(网络编程 udp)

系统信息: ubuntu 16.04LTS Raspberry Pi Zero 2W 系统版本: 2024-10-22-raspios-bullseye-armhf Python 版本:Python 3.9.2 已安装 pip3 支持拍摄 1080p 30 (1092*1080), 720p 60 (1280*720), 60/90 (640*480) 已安装 vim 已安装 git 学习…

ios swift画中画技术尝试

继上篇:iOS swift 后台运行应用尝试失败-CSDN博客 为什么想到画中画,起初是看到后台模式里有一个picture in picture,去了解了后发现这个就是小窗口视频播放,方便用户执行多任务。看小窗口视频的同时,可以作其他的事情…

ArkTS高性能编程实践

文章目录 概述声明与表达式函数数组异常 概述 本文主要提供应用性能敏感场景下的高性能编程的相关建议,助力开发者开发出高性能的应用。高性能编程实践,是在开发过程中逐步总结出来的一些高性能的写法和建议,在业务功能实现过程中&#xff0…

阿里新发的大模型Qwen2.5-max如何?

阿里新发布的大模型Qwen2.5-Max是一款性能卓越、技术先进的大型语言模型,其在多个方面展现了突出的表现。以下是基于我搜索到的资料对Qwen2.5-Max的详细评价: 技术特点 超大规模预训练数据:Qwen2.5-Max采用了超过20万亿tokens的超大规模预训…

走向基于大语言模型的新一代推荐系统:综述与展望

HightLight 论文题目:Towards Next-Generation LLM-based Recommender Systems: A Survey and Beyond作者机构:吉林大学、香港理工大学、悉尼科技大学、Meta AI论文地址: https://arxiv.org/abs/2410.1974 基于大语言模型的下一代推荐系统&…

第1章 量子暗网中的血色黎明

月球暗面的危机与阴谋 量子隧穿效应催生的幽蓝电弧,于环形山表面肆意跳跃,仿若无数奋力挣扎的机械蠕虫,将月球暗面的死寂打破,徒增几分诡异。艾丽伫立在被遗弃的“广寒宫”量子基站顶端,机械义眼之中,倒映着…

MCU内部ADC模块误差如何校准

本文章是笔者整理的备忘笔记。希望在帮助自己温习避免遗忘的同时,也能帮助其他需要参考的朋友。如有谬误,欢迎大家进行指正。 一、ADC误差校准引言 MCU 片内 ADC 模块的误差总包括了 5 个静态参数 (静态失调,增益误差,微分非线性…

【Rust自学】15.4. Drop trait:告别手动清理,释放即安全

喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 15.4.1. Drop trait的意义 类型如果实现了Drop trait,就可以让程序员自定义当值离开作用域时发生的操作。例如文件、网络资源…

【Block总结】CPCA,通道优先卷积注意力|即插即用

论文信息 标题: Channel Prior Convolutional Attention for Medical Image Segmentation 论文链接: arxiv.org 代码链接: GitHub 创新点 本文提出了一种新的通道优先卷积注意力(CPCA)机制,旨在解决医学图像分割中存在的低对比度和显著…

信息学奥赛一本通 1607:【 例 2】任务安排 2 | 洛谷 P10979 任务安排 2

【题目链接】 ybt 1607:【 例 2】任务安排 2 洛谷 P10979 任务安排 2 注:ybt1607中n最大达到 1 0 4 10^4 104,洛谷P10979中n最大达到 3 ∗ 1 0 5 3*10^5 3∗105,本题解统一认为n最大达到 3 ∗ 1 0 5 3*10^5 3∗105。 【题目考点…

OFDM系统仿真

1️⃣ OFDM的原理 1.1 介绍 OFDM是一种多载波调制技术,将输入数据分配到多个子载波上,每个子载波上可以独立使用 QAM、PSK 等传统调制技术进行调制。这些子载波之间互相正交,从而可以有效利用频谱并减少干扰。 1.2 OFDM的核心 多载波调制…

【Go语言圣经】第四节:复合数据类型

第四章:复合数据类型 本节主要讨论四种类型——数组、slice、map和结构体。 数组和结构体都是有固定内存大小的数据结构。相比之下,slice 和 map 则是动态的数据结构,它们可以根据需要动态增长。 4.1 数组 数组是一个定长的由特定类型元素…

完美还是完成?把握好度,辨证看待

完美还是完成? 如果说之前这个答案有争议,那么现在,答案毋庸置疑 ■为什么完美大于完成 ●时间成本: 做事不仅要考虑结果,还要考虑时间和精力,要说十年磨一剑的确质量更好,但是现实没有那么多…

Many Whelps! Handle It! (10 player) Many Whelps! Handle It! (25 player)

http://db.nfuwow.com/80/?achievement4403 http://db.nfuwow.com/80/?achievement4406 最少扣你50DKP! 第二阶段 当奥妮克希亚升空后,在10秒内引出50只奥妮克希亚雏龙,随后击败奥妮克希亚。 World of Warcraft [CLASSIC][80猎人][Grandel][最少扣你5…

【React】PureComponent 和 Component 的区别

前言 在 React 中,PureComponent 和 Component 都是用于创建组件的基类,但它们有一个主要的区别:PureComponent 会给类组件默认加一个shouldComponentUpdate周期函数。在此周期函数中,它对props 和 state (新老的属性/状态)会做一…

MongoDb user自定义 role 添加 action(collStats, EstimateDocumentCount)

使用 mongosh cd mongsh_bin_path mongosh “mongodb://user:passip:port/db”这样就直接进入了对应的db 直接输入: 这样 role “read_only_role" 就获得了3个 action, 分别是 查询,列举集合,集合元数据查询 P.S: 如果没有 …