笔记
学习最新前沿软件逆向安全技术、游戏安全辅助脚本技术,B 站 小迪 xiaodi 老师
微信 i-xiaodi
今天的内容要求
大家能看懂,熟悉一下,并且知道什么意思就可以
不用死记硬背,忘了就查
1. mov
指令
作用:字符串赋值(将数据从一个位置复制到另一个位置)。
示例分析:
mov eax, offset str_hello ; 加载 "hello" 字符串的地址到 EAX
mov [edi], eax ; 把这个地址存入 EDI 指向的位置
00401007 | mov eax,测试程序课程01-1.481B50 | 481B50:"123456"
大家记住一点就可以了,S 代表 String(字符串)
2. rep movsb
指令
作用:批量复制字符串数据。
rep
是重复指令前缀,结合movsb
一次复制一个字节。- ECX 指定要复制的字节数,ESI 和 EDI 分别为源地址和目标地址。
mov ecx, length ; 设置要复制的字节数
mov esi, source ; 源字符串地址
mov edi, destination ; 目标字符串地址
rep movsb ; 批量复制字符串
在 x32dbg 中监视 rep,需要用到 F7,而不是 F8
用途:
- 常用于实现
memcpy
或strcpy
。
movs
指令简介
movs
是一组字符串操作指令的通称,表示“移动字符串数据”(Move String)。它可以根据操作的数据宽度分为以下几种具体形式:
movsb
:移动一个字节(b
表示 byte,1 字节)。movsw
:移动一个字(w
表示 word,2 字节)。movsd
:移动一个双字(d
表示 double word,4 字节)。movsq
(64 位模式下可用):移动一个四字(q
表示 quad word,8 字节)。
rep
系列的主要指令
rep
(Repeat【重复】)
-
- 作用:重复执行后续字符串操作指令(如
movsb
、stosb
、lodsb
等),直到ECX
(或CX
)寄存器的值减为 0。或者说 ECX 不断减少,且>0 时重复 - 用法:不关心条件,仅重复执行。
- 作用:重复执行后续字符串操作指令(如
repe
或repz
(Repeat While Equal / Repeat While Zero)
-
- 作用:当 ZF(Zero Flag)为 1 且
ECX
不为 0 时,重复执行字符串操作指令。 - 常用于字符串比较指令(如
cmpsb
或scasb
),表示”当相等时继续比较”。 repe
和repz
是等价的。
- 作用:当 ZF(Zero Flag)为 1 且
repne
或repnz
(Repeat While Not Equal / Repeat While Not Zero)
-
- 作用:当 ZF 为 0 且
ECX
不为 0 时,重复执行字符串操作指令。 - 常用于字符串操作指令,表示”当不相等时继续比较”。
repne
和repnz
是等价的。
- 作用:当 ZF 为 0 且
常见组合用法
1. repe cmpsb
- 比较两段内存的字节,直到遇到不相等的字节,或者
ECX
减为 0。 repe
会在以下条件时继续执行:
-
- 字节相等(
ZF = 1
)。 - 计数器
ECX
未减到 0。
- 字节相等(
2. repne scasb
- 在一个字符串中搜索某个字节,直到找到匹配的字节,或者
ECX
减为 0。 repne
会在以下条件时继续执行:
3. cmp
指令
用途:
- 检测字符串是否匹配。
- 用于实现
strcmp
、strncmp
等。
示例:
mov esi, offset str_userinput ; 用户输入字符串
mov edi, offset str_password ; 目标字符串
mov ecx, length ; 设置比较的字节数(length 是你希望比较的字节数)
cld ; 清除方向标志
repe cmpsb ; 比较两段内存的字符串
je match ; 如果相等,跳转到 match
cmp
系列指令
指令 |
作用 |
说明 |
|
比较两个操作数。 |
将两个操作数进行减法操作,但不保存结果,只更新标志位(ZF, SF, OF 等)。 |
|
比较 指向的字节与 指向的字节。 |
比较两段内存中的字节,通常用来逐字节比较两个字符串。 |
|
比较 指向的字与 指向的字。 |
比较两段内存中的字(2 字节),逐字比较。 |
|
比较 指向的双字与 指向的双字。 |
比较两段内存中的双字(4 字节),逐字比较。 |
|
比较 指向的四字与 指向的四字。 |
比较两段内存中的四字(8 字节),逐字比较。 |
4. scas
指令
作用:扫描字符串中的特定字符。
- 扫描方向由 DF (Direction Flag) 决定,
cld
清除 DF 从低地址扫描,std
设置 DF 从高地址扫描。 - 用于实现字符查找(如 strchr)。
mov edi, offset str_buffer ; EDI 指向要扫描的字符串
mov al, 'A' ; 查找字符 'A'
cld ; 设置扫描方向为递增
mov ecx, length_of_string ; ECX 设置为字符串的长度
repne scasb ; 扫描直到找到 'A' 或结束
jnz not_found ; 如果未找到 'A',跳转到 not_found
; 找到 'A' 后,继续处理
用途:
- 搜索特定字符或字节。
5. stos
指令
作用:向目标地址填充数据。
- 通常用于清空字符串或填充特定值。
mov edi, offset buffer ; 目标地址
mov al, 0 ; 填充值为 0
mov ecx, size ; 填充大小
cld ; 设置方向标志为递增
rep stosb ; 填充字符串
用途:
- 实现
memset
或清零操作。 - 全部填充为 1
6.loads
指令
lodsb
:加载一个字节到AL
,并将ESI
自增 1。lodsw
:加载一个字到AX
,并将ESI
自增 2。lodsd
:加载一个双字到EAX
,并将ESI
自增 4。
004606D1 | mov esi,测试程序课程01-1.481B50 | 481B50:"123456"
004606D6 | mov edi,0x2300000 | 2300000:"123456"
004606DB | mov ecx,0x6 |
004606E0 | cld |
004606E1 | lodsb |
004606E2 | stosb |
004606E3 | loop 测试程序课程01-1.4606E1 |
7. 堆栈中的字符串操作
- 通常字符串会通过栈传递给函数。
push
和pop
用于传递字符串地址。
push offset str_hello ; 将 "hello" 的地址压栈
call printf ; 调用 printf 函数
add esp, 4 ; 平衡堆栈
应用:寻找字符串引用
- 搜索静态字符串:
在 x32dbg 的字符串窗口中,搜索程序中引用的字符串,找到相关的函数。 - 查找动态操作:
设置内存断点监视字符串缓冲区(如WriteProcessMemory
或recv
函数)。 - 分析字符串比较:
当程序检测密码或关键字时,往往会调用strcmp
或类似函数,通过跟踪寄存器分析即可理解逻辑。
总结
专门用于操作内存中的字符串
操作符 |
功能 |
示例 |
|
移动字符串 |
|
|
存储字符串 |
|
|
加载字符串 |
|
|
扫描字符串 |
|
|
比较字符串 |
|