0%

逆向学习笔记1(某爱技术吧的vip基础教程

逆向学习笔记1(某爱技术吧的vip基础教程

某爱技术吧的vip基础教程

常用汇编指令

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
6.常用汇编指令的认识
软件破解常用汇编指令

cmp a,b // 比较a与b
mov a,b // 把b值送给a值,使a=b
ret // 返回主程序
nop // 无作用
call // 调用子程序,子程序以ret结尾
je或jz // 相等则跳(机器码是74或84)
jne或jnz // 不相等则跳(机器码是75或85)
jmp // 无条件跳(机器码是EB)
jb // 若小于则跳
ja // 若大于则跳
jg // 若大于则跳
jge // 若大于等于则跳
jl // 若小于则跳
pop xxx // xxx出栈
push xxx // xxx压栈
★★破解经典句式★★
1.(最常用)
mov eax [ ]
mov edx [ ]
call 00?????? 关键call
test eax eax
jz(jnz)或 jne(je) 关键跳转
2 (最常用)
mov eax [ ]
mov edx [ ]
call 00?????? 关键call
jne(je) 关键跳转
3
mov eax [ ]
mov edx [ ]
cmp eax,edx
jnz(jz)
4
lea edi [ ]
lea esi [ ]
repz cmpsd
jz(jnz)
5
mov eax [ ]
mov edx [ ]
call 00??????
setz (setnz) al (bl,cl…)
6
mov eax [ ]
mov edx [ ]
call 00??????
test eax eax
setz (setnz) bl,cl…
7
call 00?????? ***
push eax (ebx,ecx…)
……
……
call 00??????
pop eax (ebx,ecx…)
test eax eax
jz(jnz)
一、数据传输指令
───────────────────────────────────────
它们在存贮器和寄存器、寄存器和输入输出端口之间传送数据.
1. 通用数据传送指令.
MOV 传送字或字节.
MOVSX 先符号扩展,再传送.
MOVZX 先零扩展,再传送.
PUSH 把字压入堆栈.
POP 把字弹出堆栈.
PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈.
POPA 把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈.
PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈.
POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈.
BSWAP 交换32位寄存器里字节的顺序
XCHG 交换字或字节.( 至少有一个操作数为寄存器,段寄存器不可作为操作数)
CMPXCHG 比较并交换操作数.( 第二个操作数必须为累加器AL/AX/EAX )
XADD 先交换再累加.( 结果在第一个操作数里 )
XLAT 字节查表转换.
── BX 指向一张 256 字节的表的起点, AL 为表的索引值 (0-255,即
0-FFH); 返回 AL 为查表结果. ( [BX+AL]->AL )
2. 输入输出端口传送指令.
IN I/O端口输入. ( 语法: IN 累加器, {端口号│DX} )
OUT I/O端口输出. ( 语法: OUT {端口号│DX},累加器 )
输入输出端口由立即方式指定时, 其范围是 0-255; 由寄存器 DX 指定时,
其范围是 0-65535.
3. 目的地址传送指令.
LEA 装入有效地址.
例: LEA DX,string ;把偏移地址存到DX.
LDS 传送目标指针,把指针内容装入DS.
例: LDS SI,string ;把段地址:偏移地址存到DS:SI.
LES 传送目标指针,把指针内容装入ES.
例: LES DI,string ;把段地址:偏移地址存到ES:DI.
LFS 传送目标指针,把指针内容装入FS.
例: LFS DI,string ;把段地址:偏移地址存到FS:DI.
LGS 传送目标指针,把指针内容装入GS.
例: LGS DI,string ;把段地址:偏移地址存到GS:DI.
LSS 传送目标指针,把指针内容装入SS.
例: LSS DI,string ;把段地址:偏移地址存到SS:DI.
4. 标志传送指令.
LAHF 标志寄存器传送,把标志装入AH.
SAHF 标志寄存器传送,把AH内容装入标志寄存器.
PUSHF 标志入栈.
POPF 标志出栈.
PUSHD 32位标志入栈.
POPD 32位标志出栈.

二、算术运算指令
───────────────────────────────────────
  ADD 加法.
ADC 带进位加法.
INC 加 1.
AAA 加法的ASCII码调整.
DAA 加法的十进制调整.
SUB 减法.
SBB 带借位减法.
DEC 减 1.
NEC 求反(以 0 减之).
CMP 比较.(两操作数作减法,仅修改标志位,不回送结果).
AAS 减法的ASCII码调整.
DAS 减法的十进制调整.
MUL 无符号乘法.
IMUL 整数乘法.
以上两条,结果回送AH和AL(字节运算),或DX和AX(字运算),
AAM 乘法的ASCII码调整.
DIV 无符号除法.
IDIV 整数除法.
以上两条,结果回送:
商回送AL,余数回送AH, (字节运算);
或 商回送AX,余数回送DX, (字运算).
AAD 除法的ASCII码调整.
CBW 字节转换为字. (把AL中字节的符号扩展到AH中去)
CWD 字转换为双字. (把AX中的字的符号扩展到DX中去)
CWDE 字转换为双字. (把AX中的字符号扩展到EAX中去)
CDQ 双字扩展. (把EAX中的字的符号扩展到EDX中去)

三、逻辑运算指令
───────────────────────────────────────
  AND 与运算.
OR 或运算.
XOR 异或运算.
NOT 取反.
TEST 测试.(两操作数作与运算,仅修改标志位,不回送结果).
SHL 逻辑左移.
SAL 算术左移.(=SHL)
SHR 逻辑右移.
SAR 算术右移.(=SHR)
ROL 循环左移.
ROR 循环右移.
RCL 通过进位的循环左移.
RCR 通过进位的循环右移.
以上八种移位指令,其移位次数可达255次.
移位一次时, 可直接用操作码. 如 SHL AX,1.
移位>1次时, 则由寄存器CL给出移位次数.
如 MOV CL,04
SHL AX,CL

四、串指令
───────────────────────────────────────
 DS:SI 源串段寄存器 :源串变址.
ES:DI 目标串段寄存器:目标串变址.
CX 重复次数计数器.
AL/AX 扫描值.
D标志 0表示重复操作中SI和DI应自动增量; 1表示应自动减量.
Z标志 用来控制扫描或比较操作的结束.
MOVS 串传送.
( MOVSB 传送字符. MOVSW 传送字. MOVSD 传送双字. )
CMPS 串比较.
( CMPSB 比较字符. CMPSW 比较字. )
SCAS 串扫描.
把AL或AX的内容与目标串作比较,比较结果反映在标志位.
LODS 装入串.
把源串中的元素(字或字节)逐一装入AL或AX中.
( LODSB 传送字符. LODSW 传送字. LODSD 传送双字. )
STOS 保存串.
是LODS的逆过程.
REP 当CX/ECX<>0时重复.
REPE/REPZ 当ZF=1或比较结果相等,且CX/ECX<>0时重复.
REPNE/REPNZ 当ZF=0或比较结果不相等,且CX/ECX<>0时重复.
REPC 当CF=1且CX/ECX<>0时重复.
REPNC 当CF=0且CX/ECX<>0时重复.

五、程序转移指令
───────────────────────────────────────
 1>无条件转移指令 (长转移)
JMP 无条件转移指令
CALL 过程调用
RET/RETF过程返回.
2>条件转移指令 (短转移,-128到+127的距离内)
( 当且仅当(SF XOR OF)=1时,OP1<OP2 )
JA/JNBE 不小于或不等于时转移.
JAE/JNB 大于或等于转移.
JB/JNAE 小于转移.
JBE/JNA 小于或等于转移.
以上四条,测试无符号整数运算的结果(标志C和Z).
JG/JNLE 大于转移.
JGE/JNL 大于或等于转移.
JL/JNGE 小于转移.
JLE/JNG 小于或等于转移.
以上四条,测试带符号整数运算的结果(标志S,O和Z).
JE/JZ 等于转移.
JNE/JNZ 不等于时转移.
JC 有进位时转移.
JNC 无进位时转移.
JNO 不溢出时转移.
JNP/JPO 奇偶性为奇数时转移.
JNS 符号位为 "0" 时转移.
JO 溢出转移.
JP/JPE 奇偶性为偶数时转移.
JS 符号位为 "1" 时转移.
3>循环控制指令(短转移)
LOOP CX不为零时循环.
LOOPE/LOOPZ CX不为零且标志Z=1时循环.
LOOPNE/LOOPNZ CX不为零且标志Z=0时循环.
JCXZ CX为零时转移.
JECXZ ECX为零时转移.
4>中断指令
INT 中断指令
INTO 溢出中断
IRET 中断返回
5>处理器控制指令
HLT 处理器暂停, 直到出现中断或复位信号才继续.
WAIT 当芯片引线TEST为高电平时使CPU进入等待状态.
ESC 转换到外处理器.
LOCK 封锁总线.
NOP 空操作.
STC 置进位标志位.
CLC 清进位标志位.
CMC 进位标志取反.
STD 置方向标志位.
CLD 清方向标志位.
STI 置中断允许位.
CLI 清中断允许位.

六、伪指令
───────────────────────────────────────
  DW 定义字(2字节).
PROC 定义过程.
ENDP 过程结束.
SEGMENT 定义段.
ASSUME 建立段寄存器寻址.
ENDS 段结束.
END 程序结束.

破解第一个简单的程序

就是一个简单的易语言工具

基本破解的四个步骤,但这个课程看着就很老了,笔者只是学一学看看,毕竟也是经典课程。

1
2
3
4
5
6
7
8
9
10
11
1.查壳

2.寻找关键字或断点(使用中文搜索引擎或者)

3.找到关键跳转或者关键call

4.修改达到破解的目的

ctrl+g 输入00401000来到程序的入口点(所有exe程序的入口点)

ctrl+f 输入要查找的信息

小知识

1
2
3
4
5
6
7
汇编jmp 就是无条件跳转
od下断点 可以右键 可以f2
je 大概是关键跳转的意思
od工具 f9是运行程序
od工具 f8是单步往下走
关键跳转步骤的时候可以试一下,je改成jne,jne改成je,jz就改成jnz,jnz就改成jz
右键

image-20220905110245394

这个大于号是有跳转跳转进来的意思,红色的线就是会跳转的,灰色的线就是不会跳转的

这个程序这里就是关键跳转步骤,输入正确就不会跳转,输入错误就会跳转

image-20220905140633949

我们把他改成jne

image-20220905141047226

成功

当然也可以使用nop填充,就是直接右键nop填充。

追出第一个注册码

1
2
3
4
5
6
7
8
小知识
在od中使用搜索功能的时候,右键find nxet可以看到搜索的下一个结果
od中提示断点损坏可以点击b然后右键激活断点

左上角 : 反汇编窗口 ;
右上角 : 寄存器窗口 ;
左下角 : 数据窗口 ;
右下角 : 堆栈窗口 ;

是一个软件

image-20220905142142695

需要注册码,这次的目标就是这个

首先查壳没查到

然后通过搜索弹出的注册失败字符串定位到关键的跳转地方

设置一个断点进行一个爆破

image-20220905152234987

随后给他改成jne

image-20220905152323728

这时候就注册成功了!

image-20220905152417992

但是我们需要的不是这个,我们这次的目的是将文件的注册码给拖出来

重新运行然后断点,发现堆栈中压入了我们输入的东西和一个看着很像注册码的东西。

那我们就用这个试一下

image-20220905153432443

成功拿下!

深入追踪注册码

感觉还是挺有意思的,学完学滴水逆向

又是拿到一个程序,我还是想先爆破一下再来拖注册码。

image-20220905154409712

image-20220905154711746

首先还是搜索到关键跳转位置然后断点,然后改成jz。

image-20220905154843848

注册成功喵

然后关键call就是关键跳转的上面的几个之中(加个断点,卡住了就是关键call),我们进入反汇编窗口,其中的内存地址也是可以进去的,按f7或者上面暂停右边的那个按钮进入。

可以看到栈里面压入了我们的用户名

image-20220905155500705

一步一步往下走就会发现,存在一个看上去就很象注册码的东西。

Pict-3323ureRe-138C,用它来注册

再次拿下

image-20220905155805136

但是这里提示一下,这是一个重启验证,光是爆破之后是没有效果的,我刚才只是练习一下,我们后面可以通过修改注册表之类的操作进行修改。

制作文件的补丁

用工具就好

这傻逼电脑给我吧工具删掉了

初识按钮事件

这里没有给我例子,我这里就简单的记录一下,事件过去那么就了我也不知道下面总结的对不对喵,可以更多参考后续的水滴逆向笔记

1
2
3
4
5
6
7
8
9
10
11
12
C++的按钮事件采用查找SUB EAX,0A

DELPHI查找按钮事件 右键查找--查找二进制字符串740E8BD38B83????????FF93????????采用crtl+l键进行下翻页查找,需每一个都下上断。

易语言按钮事件特征码:FF 55 fC 5F 5E

UV8的按钮事件采用查找SUB EAX ,0A

VB查找按钮事件是采用二进制字符串 816C2404??000000
注意:在识别VB P-code编译时,只需要查找不到按钮事件就是P-CODE编译

Ctrl+b 查找二进制字符串

这个也就是方便我们在没有字符串的时候破解程序。

暂停法的应用

1
2
3
4
5
6
7
1.出现提示

2.点击暂停

3.显示关键调用

4.修改破解

还是拿到一个程序,但是没有搜索到关键字,这时候我们就可以使用暂停法。

例如这个

image-20220905184429925

就是在弹窗的时候点击暂停

然后按上面k键,也就是调应用堆栈的意思。

image-20220905184613338

这时候就可以看到应用堆栈里面存在

找到其中的一个messageboxa,右键,显示调用

image-20220905184905616

就成功来到了弹窗的地方。

image-20220905185019983

在下面找到调用的地方,爆破即可。

易语言花指令的去除

首先拿到的是一个有易语言花指令的东西。

image-20220905205155751

我们选择插件,选择junk code插件,下面填一万

image-20220905205322659

这个时候就已经去除花指令了,直接用插件解决!

image-20220905205348441

最后就找到关键字符串爆破即可。

image-20220905211034083

易语言非独立编译查找字符串

首先判断加壳没有

如果查壳显示是c++6.0 但是查找字符串是这个样子的,特别是最后一个,那么基本就可以肯定是易语言加的伪装壳。

image-20220905212153326

1.方法:
搜索字符串
在error字符串那里,有一个机器码,FFD0这个就是易语言永远不变的机器码。
找到之后断点,f7进入他,随后f8到下面这地方的时候,继续f7进入,为什么呢,因为执行到这个call的时候就弹窗说密钥不对了。

image-20220905215418436

进入之后找到cld汇编指令,右键他查找字符串。

image-20220905215831449

可以看到已经查到了。这吾爱破解也不讲原理啊。麻了。

这tm对面的服务器挂了,软件也没了。额。。。

这里就是用第一个方法吧。

但是不建议大伙学这个课程,直接讲如何操作,一点原理都不讲,不利于日后发展,所以笔者在这节课就没看了,改为学习比较正规的某水逆向课程。