Practical Reverse Engineering Exercise P11
1
2
3
4
5
6
7
8
9
10
11
|
01
:
8B
7D
08
mov edi, [ebp
+
8
]
02
:
8B
D7 mov edx, edi
03
:
33
C0 xor eax, eax
04
:
83
C9 FF
or
ecx,
0FFFFFFFFh
05
: F2 AE repne scasb
06
:
83
C1
02
add ecx,
2
07
: F7 D9 neg ecx
08
:
8A
45
0C
mov al, [ebp
+
0Ch
]
09
:
8B
FA mov edi, edx
10
: F3 AA rep stosb
11
:
8B
C2 mov eax, edx
|
先贴出这个练习的代码。主要考察的是 scas
和stos
指令的用法。首先根据[ebp+8]和[ebp+0ch]可以判断出这应该是一个被调用函数的实现代码,但这对于我们分析这段代码没关系。下面对每行代码进行分析。
Line 1 mov edi, [ebp+8]
取地址为 ebp+8 的 double word 存入 edi 中。若此代码段为被调用函数,则此条语句为取第一个参数到 edi。现在看不出来这个 double word 到底是什么。
Line 2 mov edx, edi
把 edi 的值复制到 edx 中。
Line 3 xor eax, eax
将 eax 置零。
Line 4 or ecx, 0FFFFFFFFh
设置 ecx = -1,做什么用处现在还看不出来。
Line 5 repne scasb
这是最关键的一步。首先看 scas
指令,它进行如下操作:
- 将 edi 指向的地址与 al/ax/eax 比较,具体长度由后缀决定,如
scasb
, scasw
, scasd
分别对应 1-,2-,4- 字节。同时,edi 自增相应长度(这里有个需要注意的是 esi 未必一定是自增的,其自增和自减与否有 DF 寄存器的值决定)。
- ecx = ecx - 1
由于以上特性,所以此指令经常与 REP
指令一起出现,例如此条指令就是将 edi 指向的 double word 与 eax 比较,如果不等,则 edi = edi + 4, 直到相等。
Line 6 add ecx, 2
Line 7 neg ecx
之所以把这俩放到一起,是因为单看第六行指令很难理解,所以就继续往下看,发现对 ecx 取相反数了。首先由第五行的 scasd
指令可知 ecx 的值从 -1 又减小了从开始字符到遇到第一个 \0 时的长度。所以可以猜测这段代码用来计算字符串长度。
所以,如果 edi 指向的字符串为 \0
,则 ecx 完成第五行指令后的值为 -2。则完成第六行和第七行指令后的值分别为 0, 0。同理,如果 edi 指向的字符串为 hello\0
,则上述值分别为 -7, -5, 5。
故,此时 ecx 内存放的是此字符串的长度。
Line 8 mov al, [ebp+0Ch]
将地址为 ebp+0Ch 的 byte 存入 al 中。若此代码段为被调用函数,则此条语句为取第二个参数到 al。
Line 9 mov edi, edx
这里将第二行存入 edx 的值取出来,即将 edi 恢复成字符串头地址。
Line 10 rep stosb
继续先看 stos
指令,它进行如下操作:
- 根据具体指令,如
stosb
, stosw
, stosd
分别将 al, ax, eax 的值写入到 edi 所指向的位置, edi 同样根据 DF 寄存器的值自增/自减相应长度。
- ecx = ecx - 1
所以这条指令就是把从字符串头开始位置,长度为 ecx(从第七行可知 ecx 为字符串长度)的内存块写入寄存器 al 的值。相当于 memset()。
Line 11 mov eax, edx
将字符串首地址作为返回值返回。
这段代码的 C 语言表示为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
char
* replace_with_x(
char
*des,
char
x) {
int
count = -1;
char
*ret = des;
while
(*des !=
'\0'
) {
count -= 1;
des += 1;
}
count += 2;
count = -count;
des = ret;
while
(count != 0) {
*des = x;
des += 1;
count -= 1;
}
return
ret;
}
|
更多【Practical Reverse Engineering Exercise P11 Write-up】相关视频教程:www.yxfzedu.com