逆向工程

在不知道产品/软件源码的情况下,通过特定手段/工具反向获得源码,并了解其设计、功能、操作细节

  • 拿到软件后,理解内部工作机制以学习 (自我提升)
  • 需要分析某些恶意软件、病毒、游戏以得到破解方法 、制作MOD (恶意软件分析、游戏修改&破解)
  • 安全工程师需要发现软件漏洞以不断改善 (漏洞研究&利用)
  • 恢复丢失的软件数据/源码 (数字取证)

girl

基础知识

  1. 编程语言

    • C/C++:了解基础语法、指针,能进行简单的gcc编译
    • 汇编:熟悉至少一种体系结构的汇编 (x86、AMD、ARM),熟悉常见指令 (MOV、JMP、XOR、RET…)
    • python/go/java:最常见的exp用python编写,有时会出GO语言逆向,java逆向 (安卓逆向)
  2. 计算机体系结构、操作系统

    • CPU原理:寄存器 (EAX、EBX、ESP、EBP…)、指令集、堆栈 (POP、PUSH)

      re1

    • 函数调用约定

    • 内存管理:虚拟内存、内存布局

    • API调用机制:Win系统下的Windows API和Linux系统下的Linux System Calls

  3. 常见算法

    • 异或(XOR):特点是对称性,即flag XOR key = encrypt & encrypt XOR key = flag

    • TEA、XTEA、XXTEA:常见的块加密,有魔术number (0x9e3779b9) 也就是key

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      #include <stdint.h>

      void encrypt (uint32_t* v, uint32_t* k) {
      uint32_t v0=v[0], v1=v[1], sum=0, i;
      uint32_t delta=0x9e3779b9;
      uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];
      for (i=0; i < 32; i++) {
      sum += delta;
      v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
      v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
      }
      v[0]=v0; v[1]=v1;
      }

      void decrypt (uint32_t* v, uint32_t* k) {
      uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i;
      uint32_t delta=0x9e3779b9;
      uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];
      for (i=0; i<32; i++) {
      v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
      v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
      sum -= delta;
      }
      v[0]=v0; v[1]=v1;

      原文为8字节为一组,key则为16字节为一组32轮加密轮次

      更多参考TEA/XTEA/XXTEA系列算法

    • RC4:加解密使用相同key,特征为S盒、256轮次交换操作

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      void rc4_init(unsigned char *s, unsigned char *key, unsigned long Len) //初始化
      {
      int i =0, j = 0;
      unsigned char k[256] = {0};
      unsigned char tmp = 0;
      for (i=0;i<256;i++) {
      s[i] = i;
      k[i] = key[i%Len];
      }
      for (i=0; i<256; i++) {
      j=(j+s[i]+k[i]) % 256;
      tmp = s[i];
      s[i] = s[j];
      s[j] = tmp;
      }
      }

      void rc4_crypt(unsigned char *s, unsigned char *Data, unsigned long Len) //加or解密
      {
      int i = 0, j = 0, t = 0;
      unsigned long k = 0;
      unsigned char tmp;
      for(k=0;k<Len;k++) {
      i=(i+1) % 256;
      j=(j+s[i]) % 256;
      tmp = s[i];
      s[i] = s[j];
      s[j] = tmp;
      t=(s[i]+s[j]) % 256;
      Data[k] ^= s[t];
      }
      }

      看到256从0-255的循环(也就是00-0xFF的连续数据),就可以推断是RC4

  4. 常见文件格式

    • PE文件Windows系统的可执行文件
    • ELF文件Linux系统的可执行文件
    • APK文件:安卓逆向常见

工具使用

  1. 反汇编/反编译
    • IDA Pro:基本上是最常打开的反编译软件了,可以搭配 ida-pro-mcp 食用,相关配置
    • Ghidra:功能强大,支持很多文件格式、架构
    • JADX:常见的Andriod反编译工具
    • dnspy:专门针对C#的反编译工具
  2. 调试器
    • x64dbg/x32dbg:主流的动态调试器
    • OllyDbg:经典的调试器,更新较少,推荐吾爱破解版本
    • GDBLinux系统的调试器
  3. 进制编辑器/文件分析
    • 010:最常见的编辑器,会自动识别文件格式并安装插件
    • WinHex:很少用了,有试用期,可以找破解
  4. 虚拟机
    • VMware:最常见的虚拟机软件
    • VirtualBox:跟上面一样,在学x86汇编会用到

平台与网站

IDA-MCP配置

vscode里

1
2
3
4
5
6
7
8
9
10
11
12
{
"mcpServers": {
"ida-pro-mcp": {
"command": "E:\\IDA\\python311\\python.exe",
"args": [
"E:\\IDA\\python311\\Lib\\site-packages\\ida_pro_mcp\\server.py",
"--ida-rpc",
"http://127.0.0.1:13337"
]
}
}
}

opencode里

1
2
3
4
5
6
7
8
9
10
11
12
"mcp": {
"ida-pro-mcp": {
"enabled": false,
"type": "local",
"command": [
"E:\\IDA\\python311\\python.exe",
"E:\\IDA\\python311\\Lib\\site-packages\\ida_pro_mcp\\server.py",
"--ida-rpc",
"http://127.0.0.1:13337"
]
}
},