Files
root 25f2286cb6 Trim both READMEs and add the tutorial primer
README 242 -> 180 lines: the 14-row tool table becomes three sentences pointing at capabilities.py, Read this first merges into Scope, and the six-script maintenance block becomes a table. Every path, command and anchor is unchanged.

README.zh-CN follows the same eight sections, and picks up two drifts: it named hwprobe.py as the cheapest first command (SKILL.md and the English README say doctor.py), and it translated triage as 'three categories', which sends a reader looking for categories that do not exist.

docs/primer is the Windows reverse-engineering tutorial series with an index, corrected in three places: x64dbg instead of OllyDbg, offsets fixed only within one build, and IAT hooking assuming the target imports the API it hooks.

docs/tool-acquisition keeps the part capabilities.py does not answer: licence classes, id resolution on the host, and what proves a tool runs.
2026-10-24 13:51:21 +08:00

135 lines
3.7 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
开发,是先写代码,再编译成软件。而逆向分析,到手的只有软件。从软件入手,推测对应的代码,需要了解一下编译之后的软件是怎么跑起来的。
 
软件运行过程
  1、软件加载到内存。
  2、CPU读取内存的指令。
  3、根据指令,再读取数据,进行运算。
  4、运算的过程,数据是存在CPU里面的寄存器。
  5、运算过程,用到另一个功能,需要保存当前环境,存到堆栈。
  (这里涉及操作系统和计算组成原理,大概了解,心里有底就好)
 
代码语言的变化
  1、C/C++语言:高级语言,给人看的
  2、汇编语言   :低级语言,给机器用的
  (逆向分析,接触多是汇编语言, 需要自行学习下)
 
软件加载过程
  磁盘 >>内存>>寄存器
  1、代码编译成软件,先放在磁盘(C盘,D盘这些)
  2、开始运行的时候,就会加载进内存(平时说的内存条)
  3、真正运行的是在CPU(也就是所谓的芯片),里面存数据的地方叫寄存器。
 
软件的构成
  软件的外部
    包含:一个主要程序(exe后缀),多个独立库(dll后缀)。
    内存一开始加载exe,有必要的时候,exe再把dll加载进内存来。
 
    exe或者dll在内存的开始位置,叫做基址。(每次加载,随机放置,基址不固定)
    exe或者dll里面和基址的距离,叫做偏移。(每次加载,内部不变,偏移固定)
 
    打个比喻:exe和dll相当小尺子,要放在内存这个大尺子上。
    大尺子上只要有空位,小尺子就可以随便放。
    小尺子不管怎么放,里面的刻度固定的。
     
 
  软件的内部
    软件 = 代码 + 数据
    数据 = 静态数据 (数据不会变)+ 动态数据 (数据会改变)
    动态数据 =  全局数据 (多个函数共用)+ 局部数据(单个函数私有)
 
    代码和静态数据在软件运行过程不会改变,位置固定,可以方便使用。
    全局数据,因为是共用的,位置固定,也可以方便使用。
    所以这三种的偏移是不变的。
 
    内存地址 =  基址 + 偏移。
    基址可以用GetModuleHandle得知。
    偏移又是不变的,内存地址也就可以算出来了 。
 
    而偏移会变化的局部数据,就不能直接算出来了。
    局部数据,是软件运行过程中,临时生成又销毁的。
    所以要获取局部数据,只能在软件的运行过程进行拦截。(也就是所谓的HOOK)
 
逆向分析目的
  逆向分析的两个目的
    1、调用功能
    2、获取数据
 
  通过上面的原理可以知道
    1、调用功能
      代码是固定的,找到偏移,就可以调用。
    2、获取数据
      对于全局数据,找到偏移,就可以得到。
      对于局部数据,需要拦截,才可以得到 。
      (拦截的是代码,所以要找代码的偏移)
 
  所以,逆向的核心点,是找固定的偏移。
  这里说的“固定”只在一个构建内成立:同一份exe,偏移每次加载都不变;但软件一升级、重新编译,偏移就变了。所以跨版本不能死记偏移,要用特征码这类能在新版本里重新定位的办法。
 
下一篇,找偏移的方法。