RE4B Challenge 5
2017-10-20
Challenge
What does this code do?
Optimizing GCC 4.8.4 (x64):
f:
cmp rcx, rsi
ja .L10
sub rsi, rcx
add rsi, 1
mov r11, rsi
je .L10
test rcx, rcx
jne .L16
mov rax, rdi
ret
.L10:
xor eax, eax
ret
.L16:
push rbx
xor r10d, r10d
mov r9d, 1
.L4:
lea rax, [rdi+r10]
xor esi, esi
xor r8d, r8d
.L8:
movzx ebx, BYTE PTR [rdx+rsi]
cmp BYTE PTR [rax+rsi], bl
cmovne r8d, r9d
add rsi, 1
cmp rsi, rcx
jne .L8
test r8d, r8d
je .L12
add r10, 1
cmp r10, r11
jne .L4
xor eax, eax
.L12:
pop rbx
Reslove
- xor x, x -> x = 0
- movzx: move with zero extend.
- cmovne: move if Not Equal to Zero.
参数:
- arg1:
int
, len(a2) - arg2:
char *
- arg3:
char *
- arg4:
int
, len(a3)
等价于strstr,即寻找a2中的子串a3。
成功返回指向a2的指针,查找失败返回NULL(0);
char *f(int len_str1, char *str1, char *str2, int len_str2){
if(len_str2 >= len_str1){
return NULL;
}
int sub = len_str1 - len_str2 + 1;
for(int i = 0; i < sub; ++i){
int flag = 0;
for(int k = 0; k < len_str2; ++k){
if(str2[k] != str1[k + i]){
flag = 1;
}
}
if(flag == 0){
return (str2 + i);
}
}
return NULL;
}
分析思路
mov x, [y]
可以判断出y是指针类型。- 典型的循环操作:先设置i为0,并根据i的cmp值判断跳转。
- 有数组x就很可能有len(x)。再配合循环的计数就可以猜测出a1和a4的类型。
- 设置一个flag,并根据flag判断是否跳转很经典。
- 循环和逐次比较,每次只比较一个字节,很显然是字符串。