5.逆向的你基本思路
-
正向工程(Forward Engineering)
抽象的逻辑设计 => 具体的物理实现设计概念和算法 => 编写源代码 => 编译成二进制机器码
将想法和设计理念变成具体实现的过程
-
逆向工程(Reverse Engineering)
具体的物理实现 => 抽象的逻辑设计
反编译机器码 => 汇编代码(类似的高级语言代码) => 理解其算法和设计概念
从二进制码中提取设计概念和算法
-
程序的编译和反编译
高级语言(C/C++/Oc/Java/Python/C#) -> 中间语言(如:汇编等) -> 目标代码(exe/lib/dll/sys/dylib等二进制文件)编译链接 高级语言 -------> 机器码 <------ 机器码 反汇编/反编译
编译链接 高级语言 ===> 机器码 <=== 反汇编/反编译
-
逆向的思路
-
逆向必须是有目的的、有针对性的(明确你要做的事情)
-
先熟悉你要逆向的目标程序,从正向的思路去猜测他可能的实现方法(使用的框架、调用的系统API等)
-
定位关键代码
-
通过监控UI事件的响应定位关键代码
-
通过监控底层API的调用定位关键代码(如网络访问接口、文件读写接口等)
-
通过观察数据的变化来定位关键代码和地址
-
逆向是一个试错的过程,需要不停的猜测、查找和进行验证,既考验耐心也考验动手能力
6.程序、进程、线程、内存结构的概念
-
程序(静态的,磁盘上)
程序是完成某个功能的指令集。程序一般是指可执行的二进制文件。 -
进程(动态的,内存中)
- 进程的概念
进程是程序的运行实例,是系统进行资源分配和调度运行的基本单位。
换句话说进程是一个容器,包含程序执行需要的代码、数据还有资源等信息。多任务的操作系统,可以同时执行多个进程。
- 进程虚拟地址空间
多任务操作系统中的每一个进程都运行在一个属于它自己的内存沙盘中,这个沙盘就是虚拟地址空间
(virtual addressspace), 在32位经典模式下,它总是一个4GB的内存地址块。这些虚拟地址通过页表(pagetable)
映射到物理内存,页表由操作系统维护并被处理器引用。每个进程都拥有一套属于它自己的页表,但是还有一个隐情,
只要虚拟地址被使能,那么它将会作用于这台机器上运行的所有软件,包括内核本身,因此,有一部分虚拟地址必须保
留给内核使用。
- 进程的概念
-
线程
轻量级进程,是进程内一个相对独立的、可调度的执行单元,是CPU调度的基本单元。 -
函数
包含某个特定功能的代码块,可以叫做子程序。 -
典型的内存空间布局
-
从低地址到高地址依次为:代码区、只读常量区、全局区/数据区、BSS段、堆区、栈区。
代码区:存放可执行指令。 只读常量区:存放字面值常量、具有常属性且被初始化的全局和静态局部变量(如:字符串字面值、被const关键字修饰的全局变量和被const关键字修饰的静态局部变量)。 全局区/数据区:存放已初始化的全局变量和静态局部变量。 BBS段:存放未初始化的全局变量和静态局部变量,并把它们的值初始化为0。 堆区:存放动态分配的内存。 栈区:自动变量和函数调用时需要保存的信息(逆向分析的重点) 补充: 代码区和只读常量区一般统称为代码段 栈区和堆区之间相对生长的,堆区的分配一般按照地址从小到大进行,而栈区的分配一般按照地址从大到小进行分配。
网友评论