红队专题-REVERSE二进制逆向反编译

红队专题

  • 招募六边形战士队员
  • 逆向基础
    • EIP
    • 1.1 汇编基础
      • x86寄存器
      • ARM寄存器
      • X86和ARM的汇编指令
  • 总论
    • 1.2 常用逆向思路
  • 1.3 工具
      • 1.3.1 二进制编辑器
      • 1.3.2 可执行文件查看工具
      • 1.3.3 格式转换工具
  • x64dbg 2020.06.04 反汇编修改神器
    • x64dbg调试器主要分为三部分载体:
    • x64dbg初步认知
      • 快捷键
  • IDA pro
    • 安装python2
    • 加入环境变量
    • py2安装pip
    • 安装IDA 7.0 pro
    • IDAPython: importing "site" failed.
  • IDA pro 内置调试器
    • 打开安装程序
  • APK反编译工具
    • 工具:
  • C#逆向 反编译工具
    • dotPeek
  • 实战小记
  • Android 反编译逆向调试与安全加固
  • 安卓逆向 初识
    • #了解下 安卓端的 逆向学习框架#
  • 001课 教学内容规划
    • 学习流程
    • 综合基础
  • C++游戏逆向 apk
  • 语言分析
    • 一 、基础知识
        • 1.1 cpu体系架构
            • 1.1-1 RISC和CISC
            • 1.1-2 CPU工作的基本原理
        • push ebp // 实现压入操作的指令
        • POP //实现弹出操作的指令
        • // ESP是堆栈指针 总是指向栈顶位置。一般堆栈的栈底不能动 无法暂借使用
        • MOV指令 //数据传送指令
        • push -0x1
        • F12暂停法 Alt+K
        • F8单步
        • fstsw 可以把状态寄存器读取到一个双字节内存位置或者AX寄存器中
        • fstcw 指令获取当前控制寄存器的值
        • fldcw 指令把 值加载到控制寄存器
        • fstcw 指令检查当前控制寄存器的值
        • ALT+M 内存镜像
        • ALT+E 调用了那些系统模块 该模块的存放地址和文件名
        • 程序领空 OD载入程序 程序本身的代码
        • 系统领空 USE32 程序调用的咱们系统的一个函数模块
        • AX、BX、CX、DX 用于存放数据 数据寄存器
        • EIP CPU下次要执行的指令的地址
        • EBP 栈的栈底指针 栈基址 (ESP传递给)
        • ESP 栈的栈顶。并且始终指向栈顶

红队专题-REVERSE二进制逆向反编译_第1张图片

招募六边形战士队员

一起学习 代码审计、安全开发、web攻防、逆向等。。。
私信联系
在这里插入图片描述

逆向基础

EIP

EIP是一个寄存器,用来存储CPU要读取指令的地址。
CPU通过EIP寄存器读取即将要执行的指令。
每次CPU执行完相应的汇编指令之后,EIP寄存器的值就会增加

windows 逆向 软件保护
IDA扩展

正向开发

.net C# 逆向

1.1 汇编基础

1.1.1目前计算机的常见指令集
● x86/x64
● ARM/ARM64(AArch64)
● 其他相对小众的架构(如MIPS)

汇编指令<-----C语言代码(简洁的运算符) 拆开写

CPU的运行方式:
取出下一条要执行的指令+执行当前的指令+输出结果
Intel AMD

常用汇编指令

运算指令:
加减乘除 与或非 异或

数据转移指令:
读取/写入不同长度的内存
写入寄存器

跳转指令:
无条件跳转/条件跳转

JMP 无条件跳转 
jmp 入口点

栈操作指令:
入栈、出栈

push 0
把立即数 0 和 -1 压入堆栈。
汇编指令: JO、JNO、JB、JNB、JE、JNE、JBE、JA、JS、JNS、JP、JNP、JL、JNL、JNG、JG、JCXZ、JECXZ、JMP、JMPE 
名称 功能 操作数 操作码 模数 寄存器1 寄存器2 或内存 位移量 立即数 符号方向 芯片型号 16位 32位

JO 溢出跳转 短 $70 无 无 无 无 10 无 无 8086 无 无 
JNO 不溢出跳转 短 $71 无 无 无 无 10 无 无 8086 无 无 
JB 低于跳转 短 $72 无 无 无 无 10 无 无 8086 无 无 
JNB 不低于跳转 短 $73 无 无 无 无 10 无 无 8086 无 无 
JE 相等跳转 短 $74 无 无 无 无 10 无 无 8086 无 无 
JNE 不等跳转 短 $75 无 无 无 无 10 无 无 8086 无 无 
JBE 不高于跳转 短 $76 无 无 无 无 10 无 无 8086 无 无 
JA 高于跳转 短 $77 无 无 无 无 10 无 无 8086 无 无 
JS 负号跳转 短 $78 无 无 无 无 10 无 无 8086 无 无 
JNS 非负跳转 短 $79 无 无 无 无 10 无 无 8086 无 无 
JP 奇偶跳转 短 $7A 无 无 无 无 10 无 无 8086 无 无 
JNP 非奇偶跳转 短 $7B 无 无 无 无 10 无 无 8086 无 无 
JL 小于跳转 短 $7C 无 无 无 无 10 无 无 8086 无 无 
JNL 不小于跳转 短 $7D 无 无 无 无 10 无 无 8086 无 无 
JNG 不大于跳转 短 $7E 无 无 无 无 10 无 无 8086 无 无 
JG 大于跳转 短 $7F 无 无 无 无 10 无 无 8086 无 无 
JO 溢出跳转 近 $0F80 无 无 无 无 10 无 无 386 无 $66 
JNO 不溢出跳转 近 $0F81 无 无 无 无 10 无 无 386 无 $66 
JB 低于跳转 近 $0F82 无 无 无 无 10 无 无 386 无 $66 
JNB 不低于跳转 近 $0F83 无 无 无 无 10 无 无 386 无 $66 
JE 相等跳转 近 $0F84 无 无 无 无 10 无 无 386 无 $66 
JNE 不等跳转 近 $0F85 无 无 无 无 10 无 无 386 无 $66 
JBE 不高于跳转 近 $0F86 无 无 无 无 10 无 无 386 无 $66 
JA 高于跳转 近 $0F87 无 无 无 无 10 无 无 386 无 $66 
JS 负号跳转 近 $0F88 无 无 无 无 10 无 无 386 无 $66 
JNS 非负跳转 近 $0F89 无 无 无 无 10 无 无 386 无 $66 
JP 奇偶跳转 近 $0F8A 无 无 无 无 10 无 无 386 无 $66 
JNP 非奇偶跳转 近 $0F8B 无 无 无 无 10 无 无 386 无 $66 
JL 小于跳转 近 $0F8C 无 无 无 无 10 无 无 386 无 $66 
JNL 不小于跳转 近 $0F8D 无 无 无 无 10 无 无 386 无 $66 
JNG 不大于跳转 近 $0F8E 无 无 无 无 10 无 无 386 无 $66 
JG 大于跳转 近 $0F8F 无 无 无 无 10 无 无 386 无 $66 
JO 溢出跳转 近 $0F80 无 无 无 无 10 无 无 386 $66 无 
JNO 不溢出跳转 近 $0F81 无 无 无 无 10 无 无 386 $66 无 
JB 低于跳转 近 $0F82 无 无 无 无 10 无 无 386 $66 无 
JNB 不低于跳转 近 $0F83 无 无 无 无 10 无 无 386 $66 无 
JE 相等跳转 近 $0F84 无 无 无 无 10 无 无 386 $66 无 
JNE 不等跳转 近 $0F85 无 无 无 无 10 无 无 386 $66 无 
JBE 不高于跳转 近 $0F86 无 无 无 无 10 无 无 386 $66 无 
JA 高于跳转 近 $0F87 无 无 无 无 10 无 无 386 $66 无 
JS 负号跳转 近 $0F88 无 无 无 无 10 无 无 386 $66 无 
JNS 非负跳转 近 $0F89 无 无 无 无 10 无 无 386 $66 无 
JP 奇偶跳转 近 $0F8A 无 无 无 无 10 无 无 386 $66 无 
JNP 非奇偶跳转 近 $0F8B 无 无 无 无 10 无 无 386 $66 无 
JL 小于跳转 近 $0F8C 无 无 无 无 10 无 无 386 $66 无 
JNL 不小于跳转 近 $0F8D 无 无 无 无 10 无 无 386 $66 无 
JNG 不大于跳转 近 $0F8E 无 无 无 无 10 无 无 386 $66 无 
JG 大于跳转 近 $0F8F 无 无 无 无 10 无 无 386 $66 无 
JCXZ 计数一六零跳转 位移8 $E3 无 无 无 无 10 无 无 8086 无 $67 
JECXZ 计数三二零跳转 位移8 $E3 无 无 无 无 10 无 无 386 $67 无 
JMP 跳转 寄16 $FF 11 100 3 无 无 无 无 8086 无 $66 
JMP 跳转 寄32 $FF 11 100 3 无 无 无 无 386 $66 无 
JMP 跳转 16[寄16] $FF 00 100 5 无 无 无 无 8086 无 $6766 
JMP 跳转 32[寄16] $FF 00 100 5 无 无 无 无 386 $66 $67 
JMP 跳转 16[寄32] $FF 00 100 5 无 无 无 无 386 $67 $66 
JMP 跳转 32[寄32] $FF 00 100 5 无 无 无 无 386 $6766 无 
JMP 跳转 16[寄16+位移8] $FF 01 100 5 9 无 无 无 8086 无 $6766 
JMP 跳转 32[寄16+位移8] $FF 01 100 5 9 无 无 无 386 $66 $67 
JMP 跳转 16[寄32+位移8] $FF 01 100 5 9 无 无 无 386 $67 $66 
JMP 跳转 32[寄32+位移8] $FF 01 100 5 9 无 无 无 386 $6766 无 
JMP 跳转 16[寄16+位移16] $FF 10 100 5 9 无 无 无 8086 无 $6766 
JMP 跳转 32[寄16+位移16] $FF 10 100 5 9 无 无 无 386 $66 $67 
JMP 跳转 16[寄32+位移32] $FF 10 100 5 9 无 无 无 386 $67 $66 
JMP 跳转 32[寄32+位移32] $FF 10 100 5 9 无 无 无 386 $6766 无 
JMP 跳转 近16[寄16] $FF 00 100 5 无 无 无 无 8086 无 $6766 
JMP 跳转 近32[寄16] $FF 00 100 5 无 无 无 无 386 $66 $67 
JMP 跳转 近16[寄32] $FF 00 100 5 无 无 无 无 386 $67 $66 
JMP 跳转 近32[寄32] $FF 00 100 5 无 无 无 无 386 $6766 无 
JMP 跳转 近16[寄16+位移8] $FF 01 100 5 9 无 无 无 8086 无 $6766 
JMP 跳转 近32[寄16+位移8] $FF 01 100 5 9 无 无 无 386 $66 $67 
JMP 跳转 近16[寄32+位移8] $FF 01 100 5 9 无 无 无 386 $67 $66 
JMP 跳转 近32[寄32+位移8] $FF 01 100 5 9 无 无 无 386 $6766 无 
JMP 跳转 近16[寄16+位移16] $FF 10 100 5 9 无 无 无 8086 无 $6766 
JMP 跳转 近32[寄16+位移16] $FF 10 100 5 9 无 无 无 386 $66 $67 
JMP 跳转 近16[寄32+位移32] $FF 10 100 5 9 无 无 无 386 $67 $66 
JMP 跳转 近32[寄32+位移32] $FF 10 100 5 9 无 无 无 386 $6766 无 
JMP 跳转 远16[寄16] $FF 00 101 5 无 无 无 无 8086 无 $6766 
JMP 跳转 远32[寄16] $FF 00 101 5 无 无 无 无 386 $66 $67 
JMP 跳转 远16[寄32] $FF 00 101 5 无 无 无 无 386 $67 $66 
JMP 跳转 远32[寄32] $FF 00 101 5 无 无 无 无 386 $6766 无 
JMP 跳转 远16[寄16+位移8] $FF 01 101 5 9 无 无 无 8086 无 $6766 
JMP 跳转 远32[寄16+位移8] $FF 01 101 5 9 无 无 无 386 $66 $67 
JMP 跳转 远16[寄32+位移8] $FF 01 101 5 9 无 无 无 386 $67 $66 
JMP 跳转 远32[寄32+位移8] $FF 01 101 5 9 无 无 无 386 $6766 无 
JMP 跳转 远16[寄16+位移16] $FF 10 101 5 9 无 无 无 8086 无 $6766 
JMP 跳转 远32[寄16+位移16] $FF 10 101 5 9 无 无 无 386 $66 $67 
JMP 跳转 远16[寄32+位移32] $FF 10 101 5 9 无 无 无 386 $67 $66 
JMP 跳转 远32[寄32+位移32] $FF 10 101 5 9 无 无 无 386 $6766 无 
JMP 跳转 短 $EB 无 无 无 无 10 无 无 8086 无 无 
JMP 跳转 位移16 $E9 无 无 无 无 10 无 无 8086 无 $66 
JMP 跳转 位移32 $E9 无 无 无 无 10 无 无 386 $66 无 
JMP 跳转 近 $E9 无 无 无 无 10 无 无 8086 无 $66 
JMP 跳转 近 $E9 无 无 无 无 10 无 无 386 $66 无 
JMP 跳转 远(数段址:)偏移16 $EA 无 无 无 无 10 无 无 8086 无 $66 
JMP 跳转 远(数段址:)偏移32 $EA 无 无 无 无 10 无 无 386 $66 无 
JMP 跳转 数段址:偏移16 $EA 无 无 无 无 12 无 无 8086 无 $66 
JMP 跳转 数段址:偏移32 $EA 无 无 无 无 12 无 无 386 $66 无 
JMPE 跳转扩展 寄16 $0F00 11 110 3 无 无 无 无 IA64 无 $66 
JMPE 跳转扩展 寄32 $0F00 11 110 3 无 无 无 无 IA64 $66 无 
JMPE 跳转扩展 16[寄16] $0F00 00 110 5 无 无 无 无 IA64 无 $66 
JMPE 跳转扩展 32[寄16] $0F00 00 110 5 无 无 无 无 IA64 $66 无 
JMPE 跳转扩展 16[寄32] $0F00 00 110 5 无 无 无 无 IA64 无 $66 
JMPE 跳转扩展 32[寄32] $0F00 00 110 5 无 无 无 无 IA64 $66 无 
JMPE 跳转扩展 16[寄16+位移8] $0F00 01 110 5 9 无 无 无 IA64 无 $66 
JMPE 跳转扩展 32[寄16+位移8] $0F00 01 110 5 9 无 无 无 IA64 $66 无 
JMPE 跳转扩展 16[寄32+位移8] $0F00 01 110 5 9 无 无 无 IA64 无 $66 
JMPE 跳转扩展 32[寄32+位移8] $0F00 01 110 5 9 无 无 无 IA64 $66 无 
JMPE 跳转扩展 16[寄16+位移16] $0F00 10 110 5 9 无 无 无 IA64 无 $66 
JMPE 跳转扩展 32[寄16+位移16] $0F00 10 110 5 9 无 无 无 IA64 $66 无 
JMPE 跳转扩展 16[寄32+位移32] $0F00 10 110 5 9 无 无 无 IA64 无 $66 
JMPE 跳转扩展 32[寄32+位移32] $0F00 10 110 5 9 无 无 无 IA64 $66 无 
JMPE 跳转扩展 位移16 $0FB8 无 无 无 无 10 无 无 IA64 无 $66 
JMPE 跳转扩展 位移32 $0FB8 无 无 无 无 10 无 无 IA64 $66 无 

x86寄存器

支持使用一个寄存器的不同长度的值

只包含通用寄存器
在这里插入图片描述

RIP-指向下一条执行的命令
RSP-指向栈顶
RBP-指向栈帧中心(稍后解释栈和栈帧)

ARM寄存器

在这里插入图片描述

SP与x86中esp相当
R11与x86中ebp相当
LR是link register的简称,用于保存调用者的地址方便返回
PC在ARM中指向两条指令之后(由于三级流水线的历史遗留问题)

X86和ARM的汇编指令

在这里插入图片描述

总论

在这里插入图片描述

一般指令执行时都会将返回的结果存储于寄存器中。
但寄存器数量很有限,于是我们需要经常的将它存入内存。

然后聪明的先人就创造了栈。

1.2 常用逆向思路

1.3 工具

1.3.1 二进制编辑器

● 010 Editor
在这里插入图片描述

模板功能, Templates→Template Repository即可看到各种已有模板
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Template的语法类似于C结构体,可自己直接编写并加载,且支持基本的C语法如循环、判断等
在这里插入图片描述
在这里插入图片描述

解析的结果会以列表的形式显示在Variables界面中

快速解析已知格式文件
二进制复制与粘贴支持
不同格式输入
编码支持较差

● EditPlus
在这里插入图片描述

编码支持相当好
二进制编辑能力较弱
UltraEdit、WinHex

1.3.2 可执行文件查看工具

● PE:CFF Explorer
在这里插入图片描述

● MachO:MachO View
● ELF:直接IDA

1.3.3 格式转换工具

● Shellcode Helper

1.3.4 反汇编器 非侵入式
● IDA:Interactive Disassembler
反汇编界面使用
不同界面说明
设置Data、Code(d、c)
查看Cross Reference(x)
查看String List(Shift-F12)

F5反编译器使用
设置Type (变量、函数)(Y)
设置Calling Convention (Y)

1.3.5 调试器
命令行调试器
● gdb
支持平台全面,有强大社区支持
支持配合gdbserver进行远程调试
社区维护大量插件
● WinDBG
仅支持Win平台
强于解析结构体,尤善于Windows内部结构的解析与显示
同样支持插件,但数量相对较少
支持Win内核调试
支持Win远程调试

图形界面调试器
● OllyDBG
Win下老牌调试器
有强大的社区,
支持脚本和插件扩展
仅支持32位
快捷键:F8步过 F7步进 F4运行至 F9运行 F2下断点

x64dbg 2020.06.04 反汇编修改神器

https://x64dbg.com/

在这里插入图片描述
pluginsdk 插件开发包
release x64dbg的主程序目录
在这里插入图片描述

支持32和64位
仍在活跃开发中
插件相对较少
快捷键与OD相同

在这里插入图片描述

逆向反汇编修改神器,免费开源x64/x32位动态调试器,适用Windows的专业程序调试器,软件原生支持中文界面和插件,其界面及操作方法与OllyDbg调试工具类似,
支持类似C的表达式解析器、
全功能的DLL和EXE文件调试、IDA般的侧边栏与跳跃箭头、动态识别模块和串、快反汇编、可调试的脚本语言自动化等多项实用分析功能。

x64dbg调试器主要分为三部分载体:

DBG 是调试器的调试部分,它处理调试技术(使用的 TitanEngine),并为GUI提供数据。
GUI 是调试器的图形部分,它建立在Qt上,并提供用户交互界面。
Bridge 是DBG和GUI部分的通信库,它可以用于在新建功能上工作,而无需更新代码的其它部分。

在这里插入图片描述在这里插入图片描述修订了啥
简体中文修订说明:王苏 2020.06.10

  1. 为帮助用户更好地了解 x64dbg 反汇编后的 CPU 汇编指令信息,对汇编指令的“助记符摘要”全部进行了汉化。
  2. 由于本次更新幅度较大,更改的内容较多,所以对“助记符帮助”进行了部分汉化。
  3. 汇编指令的汉化参考了“清华大学出版社”出版的《汇编语言程序设计教程》(第4版) 中术语,因此可能与其他软件的汉化术语略有不同。
  4. 对 Scylla 插件等进行了全面汉化。
  5. 对 x64dbg 帮助文档的主要内容进行了汉化,并按照最新版进行了修订、翻译。
  6. 对界面字体以及布局重新进行了设置。
  7. 将默认调用在线英文帮助更改为调用本地的中文帮助文件。
  8. 对 x64dbg 官方中文版的汉化错误及不一致处进行了修订,并与帮助文档的关键词进行了统一。
  9. 对中文版界面字体进行了重新设置,使其更为美观。

x64dbg初步认知

快捷键

附加进程 ALT + A
在这里插入图片描述在这里插入图片描述在这里插入图片描述
cpu 反汇编窗口
F2 断断点 同OD
F8 步过
空格键 编辑 汇编
在这里插入图片描述

IDA pro

安装python2

python-2.7.3.msi

加入环境变量

D:\python273
D:\python273\Scripts

py2安装pip


No module named setuptools
setuptools-2.1.2.zip

pip-1.2.1.tar.gz

python .\setup.py install

红队专题-REVERSE二进制逆向反编译_第2张图片红队专题-REVERSE二进制逆向反编译_第3张图片

安装IDA 7.0 pro

红队专题-REVERSE二进制逆向反编译_第4张图片红队专题-REVERSE二进制逆向反编译_第5张图片

IDAPython: importing “site” failed.

网上的解决方法

查看python27.dll的位置 
where python27.dll 
查看注册表中 HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.7\InstallPath 的值是python2.7的安装路径 

尽量用win7系统
我是重新安装了python环境和IDA pro
在这里插入图片描述

IDA pro 内置调试器

快捷键与OD相同
支持多种后端:
IDA内置调试器
gdb、windbg

支持远程调试
兼容gdbserver
官方支持ARM/ARM64、x86/x64指令集远程调试
支持Android iOS Win Linux
支持配合Hex-Rays调试

单步、查看运行过程中变量的值
步进
单步执行,遇到call调用时会跟进而不是跳过去
步过
单步执行,遇到call调用时会和别的指令一样跳过去
运行至指定位置
相当于临时下断点,碰到循环时可以方便的跳过去
运行
直接跑起来,而不是一条一条指令执行

红队专题-REVERSE二进制逆向反编译_第6张图片

F5 查看伪代码

在这里插入图片描述

打开安装程序

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

  • 安装错误 看看这里有没有 卸载
    在这里插入图片描述
  • 卸载 重新安装
    在这里插入图片描述在这里插入图片描述在这里插入图片描述

APK反编译工具

工具:

1、apktool.bat;apktool.jar
官网下载地址 https://ibotpeaches.github.io/Apktool/install/

作用:最大程度的还原apk中的manifest文件和资源文件 。
使用apktool工具反编译apk文件比直接解压同一个apk文件大;
还可以将反编译之后的apk重新打包成apk文件,
但需要重新签名,才能安装使用。

2、dex2jar
官方下载地址https://sourceforge.net/projects/dex2jar/

作用:
将APK直接解压后,目录下包含的一个classes.dex
文件反编译为classes-dex2jar.jar文件。

3、jd-gui.jar

作用:直接查看classes-dex2jar.jar文件。

网盘资源 完整工具压缩包下载
https://pan.baidu.com/s/1u9ZAIlnMMHJx9LWRO7OWcA


  1. apktool
    在这里插入图片描述
    在这里插入图片描述
    重新打包:

输入命令apktool b xxx

在这里插入图片描述在这里插入图片描述


  1. dex2jar
    在这里插入图片描述在这里插入图片描述在这里插入图片描述

3、jd-gui
在这里插入图片描述在这里插入图片描述

C#逆向 反编译工具

dotPeek

官网地址:https://www.jetbrains.com/decompiler/

是 JetBrains 开发的一款.Net反编译工具,是.Net工具套件中的一个

  • 将 .NET 程序集反编译为 C#

dotPeek 是一款基于 ReSharper 捆绑反编译器的免费独立工具。

它可以可靠地将任意 .NET 程序集反编译为对等的 C# 或 IL 代码。

支持包括库 (.dll)、可执行文件 (.exe) 和 Windows 元数据文件 (.winmd) 在内的多种格式。

  • 将反编译代码导出至 Visual Studio 项目
    在反编译完程序集后,您可以将其另存为 Visual Studio 项目 (.csproj)。
    如果您需要从旧程序集恢复丢失的源代码,此举可以为您节省大量的时间。

  • 下载源代码并调试第三方代码
    dotPeek 可以根据 PDB 文件识别本地源代码,或者从 Microsoft Reference Source Center 或 SymbolSource 等源服务器中获取源代码。

dotPeek 还可以作为符号服务器运行,
为 Visual Studio 调试器提供调试程序集代码所需的信息。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实战小记

Android 反编译逆向调试与安全加固

安卓逆向 初识

#了解下 安卓端的 逆向学习框架#

在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

  • ELF 程序逆向分析 ——可执行程序(功能)

001课 教学内容规划

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

学习流程

  • 汇编

在这里插入图片描述

  • 安卓逆向 软件分析(商业、工具、游戏)
  • 手游辅助 光是 游戏APP

综合基础

  • smail汇编 - java代码 逆向

  • ARM汇编 指令 (二进制文件 - 普通代码语言) IDA
    汇编 寄存器
    在这里插入图片描述

  • hook插件 开发

  • NDK工具
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 修改so dll 等 关键文件
    在这里插入图片描述

  • APK 防护 HOOK过掉
    改函数 返回值 该参数 打印参数

在这里插入图片描述

  • Dalvik虚拟机和ART虚拟机

在这里插入图片描述

C++游戏逆向 apk

在这里插入图片描述

语言分析

  • C# —— unity3d
  • Lua ——cocos2dx
  • c++ ——cocos2dx libgame.so

— /data/app-lib/包名/lib
找so 几百kb 就不是 c++(几个MB)(有cocos2d引擎在里面)

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

  • cocos2d
  • cpp ----->c++
    在这里插入图片描述在这里插入图片描述
  • arsc 资源文件
  • dex java代码
  • xml 配置文件
  • sdk manifest google

res 资源 配置 图片 动画 xml 音频
org linux
META-INF 签名文件夹
在这里插入图片描述
assets 资源
在这里插入图片描述在这里插入图片描述


在这里插入图片描述

  • this 上下文

在这里插入图片描述

  • 拿之前那个 恶搞程序 练手
  • 查看是否 代码混淆在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
  • 查看 类似有没有CN中文
    在这里插入图片描述在这里插入图片描述

看雪逆向-Security Documentation

  • 招募六边形战士队员
  • 逆向基础
    • EIP
    • 1.1 汇编基础
      • x86寄存器
      • ARM寄存器
      • X86和ARM的汇编指令
  • 总论
    • 1.2 常用逆向思路
  • 1.3 工具
      • 1.3.1 二进制编辑器
      • 1.3.2 可执行文件查看工具
      • 1.3.3 格式转换工具
  • x64dbg 2020.06.04 反汇编修改神器
    • x64dbg调试器主要分为三部分载体:
    • x64dbg初步认知
      • 快捷键
  • IDA pro
    • 安装python2
    • 加入环境变量
    • py2安装pip
    • 安装IDA 7.0 pro
    • IDAPython: importing "site" failed.
  • IDA pro 内置调试器
    • 打开安装程序
  • APK反编译工具
    • 工具:
  • C#逆向 反编译工具
    • dotPeek
  • 实战小记
  • Android 反编译逆向调试与安全加固
  • 安卓逆向 初识
    • #了解下 安卓端的 逆向学习框架#
  • 001课 教学内容规划
    • 学习流程
    • 综合基础
  • C++游戏逆向 apk
  • 语言分析
    • 一 、基础知识
        • 1.1 cpu体系架构
            • 1.1-1 RISC和CISC
            • 1.1-2 CPU工作的基本原理
        • push ebp // 实现压入操作的指令
        • POP //实现弹出操作的指令
        • // ESP是堆栈指针 总是指向栈顶位置。一般堆栈的栈底不能动 无法暂借使用
        • MOV指令 //数据传送指令
        • push -0x1
        • F12暂停法 Alt+K
        • F8单步
        • fstsw 可以把状态寄存器读取到一个双字节内存位置或者AX寄存器中
        • fstcw 指令获取当前控制寄存器的值
        • fldcw 指令把 值加载到控制寄存器
        • fstcw 指令检查当前控制寄存器的值
        • ALT+M 内存镜像
        • ALT+E 调用了那些系统模块 该模块的存放地址和文件名
        • 程序领空 OD载入程序 程序本身的代码
        • 系统领空 USE32 程序调用的咱们系统的一个函数模块
        • AX、BX、CX、DX 用于存放数据 数据寄存器
        • EIP CPU下次要执行的指令的地址
        • EBP 栈的栈底指针 栈基址 (ESP传递给)
        • ESP 栈的栈顶。并且始终指向栈顶

一 、基础知识

1.1 cpu体系架构


1.1-1 RISC和CISC

RISC(精简指令集计算机)Reduced Instruction Set Computer
CISC(复杂指令集计算机)Complex Instruction Set Computer
当前CPU的两种架构。

区别在于不同的CPU设计理念和方法。

早期的CPU全部是CISC架构,
它的设计目的是要用最少的机器语言指令来完成所需的计算任务。

比如对于乘法运算,
在CISC架构的CPU上,
您可能需要这样一条指令:MUL ADDRA, ADDRB
就可以将ADDRA和ADDRB中的数相乘并将结果储存在ADDRA中。

将ADDRA, ADDRB中的数据读入寄存器,相乘和将结果写回内存的操作
全部依赖于CPU中设计的逻辑来实现。

这种架构会增加CPU结构的复杂性和对CPU工艺的要求,但对于编译器的开发十分有利。
比如上面的例子,C程序中的a*=b就可以直接编译为一条乘法指令。
今天只有Intel及其兼容CPU还在使用CISC架构。

RISC架构要求软件来指定各个操作步骤。
上面的例子如果要在RISC架构上实现,

将ADDRA, ADDRB中的数据读入寄存器,相乘和将结果写回内存的操作
都必须由软件来实现,

比如:
MOV A, ADDRA; 
MOV B, ADDRB; 

MUL A, B; 

STR ADDRA, A。

这种架构可以降低CPU的复杂性
以及允许在同样的工艺水平下生产出功能更强大的CPU,
但对于编译器的设计有更高的要求。

1.1-2 CPU工作的基本原理
  • 如何设计一个简单的16位CPU模型
    中央处理器(central processing unit,简称CPU)

计算机的组成结构
数字电路基础
编程的基础

实现 一个RISC指令集的CPU
要自己为这个CPU设计指令并且编码

英特尔的 叫特德·霍夫(Ted Hoff)的工程师
设计和生产专用集成电路芯片
用于实现桌面计算器
各实现一种特定的功能
想法:
为什么不能用一块通用的芯片加上程序来实现几块芯片的功能呢?
当需要某种功能时,只需要把实现该功能的一段程序代码(称为子程序)加载到通用芯片上,其功能与专用芯片会完全一样。

计算器的新的体系结构图,
其中包含4块芯片:
一块通用处理器芯片,实现所有的计算和控制功能;
一块可读写内存(RAM)芯片,用来存放数据;
一块只读内存(ROM)芯片,用来存放程序;
一块输入输出芯片,实现键入数据和操作命令、打印结果等等功能

例1-1:

mov eax,0
repeat:inc eax
jmp repeat

例1-2:

 int main()
{
unsigned int i = 0;
while(1)
i++;
}

例1-3:
红队专题-REVERSE二进制逆向反编译_第7张图片

以上三个例子都产生了一个从0不断增加的序列
而且前两个例子会一直加到溢出又从0开始
(这个取决于计算机的字长也就是多少位的CPU,
eax是32位寄存器所以必然是加到4294967295然后回0,
而后面那个c程序则看不同编译器和不同平台不一样)

后面那个例子则看你用的是什么样的加法器和多少个D触发器

假设要一个递减的序列

例2-1:

 mov eax,0
repeat:dec eax
jmp repeat

例2-2:

 int main()
{
unsigned int i = 0;
while(1)
i--;
}

例2-3:
红队专题-REVERSE二进制逆向反编译_第8张图片
上面
(例1-3)中是个加法器,
减法器(例2-3)!

例3:
红队专题-REVERSE二进制逆向反编译_第9张图片
使用了一个加法器一个减法器,没比上面的电路省
(加上一个负数的补码确实就是减去一个数)

多了一组多路器,少了一组D触发器
而sel信号就是用来选择的(0是递增,1是递减)。

push ebp // 实现压入操作的指令
POP //实现弹出操作的指令

//缺省对堆栈操作的寄存器 ESP 和 EBP 扩展基址指针寄存器(extended base pointer)

// ESP是堆栈指针 总是指向栈顶位置。一般堆栈的栈底不能动 无法暂借使用

一般使用 EBP 来存取堆栈

调用中有两个参数

在 push 第一个参数前的堆栈指针 ESP 为 X,那么压入两个参数后的 ESP 为 X-8

计算机转移到调用的 子程序 call指令

//把返回地址压入堆栈 ESP 为 X-C 这时已经在子程序中了

可以开始使用 EBP 来存取参数

为了在返回时恢复 EBP 的值,我们还是再需要一句 push ebp

来先保存 EBP 的值,这时 ESP 为 X-10

再执行一句 mov ebp,esp

实际上这时候 [ebp + 8] 就是参数1,[ebp + c]就是参数2

MOV指令 //数据传送指令

//用于将一个数据从源地址传送到目标地址

(寄存器间的数据传送本质上也是一样的)。

其特点是不破坏源地址单元的内容

push -0x1

-1=FFFFFFFF

1=00000000

F12暂停法 Alt+K

显示调用 下断点

F8单步

FPU :(Float Point Unit,浮点运算单元)

状态寄存器

控制寄存器

fstsw 可以把状态寄存器读取到一个双字节内存位置或者AX寄存器中
fstcw 指令获取当前控制寄存器的值
fldcw 指令把 值加载到控制寄存器
fstcw 指令检查当前控制寄存器的值
ALT+M 内存镜像
ALT+E 调用了那些系统模块 该模块的存放地址和文件名
程序领空 OD载入程序 程序本身的代码
系统领空 USE32 程序调用的咱们系统的一个函数模块

放在WINDOWS目录下SYSTEM32文件夹里的一个DLL文件

esp定律 向 堆栈 中压入下一行程序的地址

逆向破解 暴力破解 绕过注册机制 追踪注册码

混淆器 壳 侦壳程序进行识别 伪装技术来混淆侦壳程序

压缩壳 程序进行体积缩小化处理

保护壳混淆或加密代码防止他人进行逆向程序、破解程序

EP段

AX 8086CPU微处理器中8个 通用寄存器之一

AX、BX、CX、DX 用于存放数据 数据寄存器

按16位使用时主要用于存放数据 临时用于存放地址

每一个都可以拆开成为两个独立的8位寄存器使用

分别用高字节和低字节表示

AH,AL等,按8位使用时只能用于存放数据

系统 地址 寄存器

EIP CPU下次要执行的指令的地址
EBP 栈的栈底指针 栈基址 (ESP传递给)

调用前 ESP存储的是栈顶地址,也是栈底地址

ESP 栈的栈顶。并且始终指向栈顶

三个指针 系统中栈 栈的数据结构 后进先处

1.栈是用来存储临时变量,函数传递的中间结果。
2.操作系统维护的,对于程序员是透明的。
函数调用 栈实现 原理

函数压栈 再出栈

你可能感兴趣的:(软件工程)