前言
这篇文章带大家聊一聊逆向,以及怎么更好的去学习海东老师的这门课程,就相当于是公开课的内容了,首先大家去学习的时候,可以先去安一个 Windows XP,然后在上面去装一个 VC6,当然也可以直接在 64 位的电脑上去装 VS,我是尽量保持了与海东老师一样的操作,所以选择了前者,然后就是海东老师对 C 语言有独特的见解,建议大家好好听,可以不写笔记,但是课后作业一定要认真去做
课堂
这篇文章就相当于是滴水的那公开课,就是带大家看看要学什么,做个演示,里面涉及到的知识在后面笔记中都会具体说的
进制
-
计算机上都是以 0,1 来存储的
-
一位十六进制数用四位二进制数表示,八位二进制表示一个字节,字节是计算机管理的最小单元,所以两位十六进制数表示一个字节,我们平时用工具打开二进制文件,都是用十六进制显示,2 位就是一个字节
-
计算机存储一个数据可以有不同的数据宽度 数据宽度:一般常用有 Byte(字),Word(字),Dword(双字),DDword(四字),分别为 8 位,16 位,32 位,64 位 0 或 1
PE 文件结构
-
PE 文件结构只限于 windows 操作系统,windows 上运行的任何一个可执行的程序都应该遵循的结构。所以 PE 结构适用于 windows 上任何可执行程序
-
如果想分析知道别人写的程序,至少应该知道三件事:1.程序从哪里开始执行;2.数据藏在哪里;3.程序藏在哪里
-
如何分析一个 PE 文件:此处省略一万字,后面的文章会具体说
-
分析 PE 文件结构的工具:打开工具帮我们分析会大大减少我们的工作量,但是一定要知道 PE 中的一些关键信息:比如程序的入口点,代码入口点,数据入口点,输入表,输出表,资源表
-
所以如果 PE 学好,你给我一个 exe 文件,我差不多就可以大体的知道它的结构和功能等,接着就可以在特定位置给 PE 文件注入病毒等操作,或者修改其中的一些信息,所以外挂和注入病毒就是这么来的但是如果给 PE 文件加壳,可以打乱 PE 文件的结构和数字,让别人无法直接下手;或者反调试,别人用一些调试工具打开,程序立马退出等
-
注意一点内容:你用工具分析出来的文件的某结构的地址是多少,只是文件还没执行时的相对于文件初识地址的地址,但是如果一旦将程序运行,由于文件将要加载到内存中,所以所有工具显示的地址都会发生变化,实际上的地址应该是文件整体加载到内存中的基地址+文件某结构的基地址。比如工具显示 PE 文件的代码基址为 0x00001000,镜像基址为 0x00400000,所以此时代码基址在实际在内存的地址应该为代码基址+镜像基址
硬编码
比如用 PE 查看器–>找到了代码段起始地址–>找到了第一个函数,由很多的二进制,工具显示的是十六进制数构成,那么每一个数字代表什么含义,我们如果把数字转化为我们更容易理解的汇编语言:比如如果显示 55,根据硬编码可以知道 55 如果用汇编语言表示:则是 push ebp;再比如 8bec 用汇编表示为 mov ebp,esp。如果学过汇编语言则就知道这段函数是干什么用的
逆向的过程
-
二进制–>汇编–>C 语言
-
从一堆看不懂的二进制数,转换成可以看懂的汇编语言,再还原成高级代码
逻辑运算
-
逻辑运算:与(and)、或(or)、亦或(xor)、非(not)
-
计算机除了数据,还要做运算,二进制之间会进行逻辑运算,计算机不会加减乘除,这些运算计算机都是通过移位或者通过逻辑运算实现的。因为计算机只认识二进制数,所以所有的加减等运算都是通过 CPU 对二进制数据做逻辑运算实现的
-
比如我现在要让计算机计算 2+3,计算机 CPU 是如何运算出结果的呢
x:0010
y:0011
0010
xor 0011
------------
0001 R:0001
0010
and 0011
------------
0010 <<1 得 0100 #<<1表示左移一位
此时计算机会判断0100是否全为0,如果全为0表示运算结束,将R中此时的值作为结果输出,如果不为0则将R中的值赋给x。0100赋给y再做一次同样运算
0001
xor 0100
-------------
0101 R:0101
0001
and 0100
-------------
0000 <<1 得 0000
判断0000全为0,则运算结束,将R中的值0101作为运算的结果,化成十进制即为5
- 逻辑运算还和通信过程对数据加密解密有些关系,虽然现在有很多的加解密算法,但是目前有些人还在用亦或运算加密解密,异或加密,异或一次变密文,再异或一次变原文
寄存器和内存
这一块可以移步到我的王爽汇编那个笔记,反正我记得我写的还是挺全的
计算机的 32 位与 64 位是什么意思?
这里就拿 32 位来说,64 位和它一个道理,这个其实就是就是地址总线,王爽那里也说到过
我们要知道,内存划分为很多的内存单位来存储数据,每个内存单位的宽度是 8,即一个内存单位中可以存放 8 个 0 和 1,即一个字节大小。
此时每个内存单元都可以有一个编号称为地址,比如 0x00000000 或者 0xFFFFFFFF,当计算机想要从内存中读取或写入数据时,首先应该找到要读、写的位置,即地址。那么 32 位就表示,计算机在内存中的寻址宽度不能超过 32 位,可以找到 0,001,11111 等,但是不能超过 32 个 1。比如我现在找一个地址为 33 个 1 的,32 位计算机无法做到(但是不是说 32 位计算机最大的寄存器宽度为 32 位!!有很多寄存器都是大于 32 位的,之所以叫 32 位是 CPU 的最大寻址宽度不超过 32bit)。所以 32 位计算机表示计算机的最大的寻址宽度为 32 个 1,十六进制即为八个 F(0xFFFFFFFF)。那么也就是说 32 位计算机能识别的地址从 0x00000000 到 0xFFFFFFFF,一共有多少个地址呢?用十进制表示:4294967295+1=4294967285,我们前面说过内存单位大小为 1 字节,那么 32 位计算机的内存最多可以存放 4294967285*1 字节,除以 1024 换算成 K,再除以 1024 换算成 M,再除以 1024 换算成 G 为 4294967285/1024/1024=4,所以 32 位计算机能识别的最大内存为 4G。但是操作系统有一些固定的组件已经占用了一部分地址了,所以电脑上显示的内存肯定小于 4G
寻址方式
这个之后再说吧,啊啊啊我还是建议,要学逆向的话,可以先去学一下王爽的那本汇编语言,写的真的是非常不错
OD 及 vc6 快捷键
这个就很重要,以后基本上天天与它打交道
-
VC++的使用:
-
CTRL+F5 执行程序
-
F5 从断点处执行
-
F9 设置断点
-
F10 单步执行
-
F11 跟踪函数
-
SHIFT+F5 停止调试
-
ALT+8 进入反编译
-
-
OD 的使用:
-
CTRL+F2 重启程序
-
ALT+F2 关闭被调试程序
-
F2 设置断点
-
F4 从光标选中的地方开始执行,可用来跳过某些循环
-
F9CPU 从断点处开始执行
-
F8 单步调试
-
F7 进入函数
-
CTRL+G 跳转到某地址
-
作业
无