C语言逆向(2)if语句与JCC

上一章节的学习后,通过本章节强化加深技能,顺便学习逆向if else结构代码的基础知识。

if语句的较为典型的标识为:

1
2
3
mov x1,...
cmp x1, x2
jcc 语句

如果是带有else代码块的语句,即if else,则类似:

1
2
3
4
5
6
mov x1,...
cmp x1, x2
jcc
...
...
jmp ret

由于if语句与JCC关系密切,可进行查表法:JCC速查

下面通过三道练习题来练习逆向ifif else结构代码。

练习题1

分析以下函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
00401030   push        ebp			
00401031 mov ebp,esp
00401033 sub esp,44h
00401036 push ebx
00401037 push esi
00401038 push edi
00401039 lea edi,[ebp-44h]
0040103C mov ecx,11h
00401041 mov eax,0CCCCCCCCh
00401046 rep stos dword ptr [edi]
00401048 mov eax,[004225c4]
0040104D mov dword ptr [ebp-4],eax
00401050 mov ecx,dword ptr [ebp+8]
00401053 cmp ecx,dword ptr [ebp+0Ch]
00401056 jg 00401064
00401058 mov edx,dword ptr [ebp+0Ch]
0040105B add edx,dword ptr [ebp-4]
0040105E mov dword ptr [004225c4],edx
00401064 pop edi
00401065 pop esi
00401066 pop ebx
00401067 mov esp,ebp
00401069 pop ebp
0040106A ret

分析参数

  1. 各寄存器没有从外部直接赋值
  2. 函数内使用了ebp+8ebp+0C ,易知栈上有两个参数

分析局部变量

函数内仅使用ebp-4一处局部变量

分析全局变量

根据:

1
mov         eax,[004225c4]	

可知[0x004225c4]为一处全局变量

功能分析

1
2
3
4
5
6
7
8
9
10
11
12
13
00401048   mov         eax,[004225c4]			
; a = global
0040104D mov dword ptr [ebp-4],eax
00401050 mov ecx,dword ptr [ebp+8]
; if(p1 <= p2) {
00401053 cmp ecx,dword ptr [ebp+0Ch]
00401056 jg 00401064
; global += p2
00401058 mov edx,dword ptr [ebp+0Ch]
0040105B add edx,dword ptr [ebp-4]
0040105E mov dword ptr [004225c4],edx
; }
00401064 pop edi

可知该函数功能为:如果参数1小于等于参数2,则将参数2累加到全局变量中。

返回值分析

函数直到尾声也没有清空eax内的值,也未对eax的值进行更新,可知返回值为全局变量累加之前存储的数值

还原成C函数

1
2
3
4
5
6
7
8
int global;
int func(int p1, int p2){
int a = global;
if(p1 <= p2){
globat+=p2;
}
return a;
}

练习题2

分析以下函数:

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
004010B0   push        ebp				
004010B1 mov ebp,esp
004010B3 sub esp,48h
004010B6 push ebx
004010B7 push esi
004010B8 push edi
004010B9 lea edi,[ebp-48h]
004010BC mov ecx,12h
004010C1 mov eax,0CCCCCCCCh
004010C6 rep stos dword ptr [edi]
004010C8 mov eax,[004225c4]
004010CD mov dword ptr [ebp-4],eax
004010D0 mov dword ptr [ebp-8],2
004010D7 mov ecx,dword ptr [ebp+8]
004010DA cmp ecx,dword ptr [ebp+0Ch]
004010DD jl 004010e8
004010DF mov edx,dword ptr [ebp-8]
004010E2 add edx,1
004010E5 mov dword ptr [ebp-8],edx
004010E8 mov eax,dword ptr [ebp+8]
004010EB cmp eax,dword ptr [ebp+0Ch]
004010EE jge 004010fb
004010F0 mov ecx,dword ptr [ebp-8]
004010F3 mov dword ptr [004225c4],ecx
004010F9 jmp 00401107
004010FB mov edx,dword ptr [ebp-4]
004010FE add edx,dword ptr [ebp-8]
00401101 mov dword ptr [004225c4],edx
00401107 pop edi
00401108 pop esi
00401109 pop ebx
0040110A mov esp,ebp
0040110C pop ebp
0040110D ret

分析参数

  1. 各寄存器没有从外部直接赋值
  2. 函数内使用了ebp+8ebp+0C ,易知栈上有两个参数

分析局部变量

函数内仅使用ebp-4ebp-8两个局部变量

分析全局变量

根据:

1
mov         eax,[004225c4]

可知[0x004225c4]为一处全局变量

分析功能

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
; int a = global
004010C8 mov eax,[004225c4]
004010CD mov dword ptr [ebp-4],eax
; int b = 2
004010D0 mov dword ptr [ebp-8],2
; if(p1 >= p2){
004010D7 mov ecx,dword ptr [ebp+8]
004010DA cmp ecx,dword ptr [ebp+0Ch]
004010DD jl 004010e8
; b+=1
004010DF mov edx,dword ptr [ebp-8]
004010E2 add edx,1
004010E5 mov dword ptr [ebp-8],edx
; }
; if(p1 < p2) {
004010E8 mov eax,dword ptr [ebp+8]
004010EB cmp eax,dword ptr [ebp+0Ch]
004010EE jge 004010fb
; global = b
004010F0 mov ecx,dword ptr [ebp-8]
004010F3 mov dword ptr [004225c4],ecx
004010F9 jmp 00401107
; }
; else {
; global = a + b
004010FB mov edx,dword ptr [ebp-4]
004010FE add edx,dword ptr [ebp-8]
00401101 mov dword ptr [004225c4],edx
; }
00401107 pop edi
00401108 pop esi

分析返回值

函数永远返回第一个参数

还原成C函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int global;
int func2(int p1, int p2){
int a = global;
int b = 2;
if(p1 >= p2){
b+=1;
}
if(p1 < p2){
global = b;
}else{
global = a + b;
}
return p1;
}

练习题3

分析以下函数:

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
004010B0   push        ebp			
004010B1 mov ebp,esp
004010B3 sub esp,4Ch
004010B6 push ebx
004010B7 push esi
004010B8 push edi
004010B9 lea edi,[ebp-4Ch]
004010BC mov ecx,13h
004010C1 mov eax,0CCCCCCCCh
004010C6 rep stos dword ptr [edi]
004010C8 mov dword ptr [ebp-4],0
004010CF mov dword ptr [ebp-8],1
004010D6 mov dword ptr [ebp-0Ch],2
004010DD mov eax,dword ptr [ebp+8]
004010E0 cmp eax,dword ptr [ebp+0Ch]
004010E3 jg 004010f0
004010E5 mov ecx,dword ptr [ebp-8]
004010E8 sub ecx,1
004010EB mov dword ptr [ebp-4],ecx
004010EE jmp 00401123
004010F0 mov edx,dword ptr [ebp+0Ch]
004010F3 cmp edx,dword ptr [ebp+10h]
004010F6 jl 00401103
004010F8 mov eax,dword ptr [ebp-0Ch]
004010FB add eax,1
004010FE mov dword ptr [ebp-4],eax
00401101 jmp 00401123
00401103 mov ecx,dword ptr [ebp+8]
00401106 cmp ecx,dword ptr [ebp+10h]
00401109 jle 00401116
0040110B mov edx,dword ptr [ebp-8]
0040110E add edx,dword ptr [ebp-0Ch]
00401111 mov dword ptr [ebp-4],edx
00401114 jmp 00401123
00401116 mov eax,dword ptr [ebp-0Ch]
00401119 mov ecx,dword ptr [ebp-8]
0040111C lea edx,[ecx+eax-1]
00401120 mov dword ptr [ebp-4],edx
00401123 mov eax,dword ptr [ebp-4]
00401126 add eax,1
00401129 pop edi
0040112A pop esi
0040112B pop ebx
0040112C mov esp,ebp
0040112E pop ebp
0040112F ret

分析参数

函数内各条件分支判断条件,均使用了ebp + 0x8epb + 0xcebp + 0x10,各寄存器均没有提前赋值,可知栈上有三个参数。

分析局部变量

函数内共有3个局部变量,分别是ebp - 4ebp - 8ebp - c,初始值分别为0、1、2

分析全局变量

函数内未使用全局变量

分析功能

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
; int a = 0
004010C8 mov dword ptr [ebp-4],0
; int b = 1
004010CF mov dword ptr [ebp-8],1
; int c = 2
004010D6 mov dword ptr [ebp-0Ch],2
; if(p1 <= p2) {
004010DD mov eax,dword ptr [ebp+8]
004010E0 cmp eax,dword ptr [ebp+0Ch]
004010E3 jg 004010f0
; a = b - 1
004010E5 mov ecx,dword ptr [ebp-8]
004010E8 sub ecx,1
004010EB mov dword ptr [ebp-4],ecx
004010EE jmp 00401123
; }
; else if(p2 >= p3){
004010F0 mov edx,dword ptr [ebp+0Ch]
004010F3 cmp edx,dword ptr [ebp+10h]
004010F6 jl 00401103
; a = c + 1
004010F8 mov eax,dword ptr [ebp-0Ch]
004010FB add eax,1
004010FE mov dword ptr [ebp-4],eax
00401101 jmp 00401123
; }
; else if (p1 > p3){
00401103 mov ecx,dword ptr [ebp+8]
00401106 cmp ecx,dword ptr [ebp+10h]
00401109 jle 00401116
; a = b + c
0040110B mov edx,dword ptr [ebp-8]
0040110E add edx,dword ptr [ebp-0Ch]
00401111 mov dword ptr [ebp-4],edx
00401114 jmp 00401123
; }
; else {
; a = c + b - 1
00401116 mov eax,dword ptr [ebp-0Ch]
00401119 mov ecx,dword ptr [ebp-8]
0040111C lea edx,[ecx+eax-1]
00401120 mov dword ptr [ebp-4],edx
; }
00401123 mov eax,dword ptr [ebp-4]
; return a + 1
00401126 add eax,1
00401129 pop edi
0040112A pop esi

分析返回值

函数最终返回局部变量a,即ebp-4的值。

返回时会在a的基础上再加1。

还原成C函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int func3(int p1, int p2, int p3){
int a = 0;
int b = 1;
int c = 2;

if(p1 <= p2){
a = b - 1;
}else if(p2 >= p3){
a = c + 1;
}else if (p1 > p3){
a = b + c;
}else{
a = c + b - 1;
}

return a + 1;
}

C语言逆向(2)if语句与JCC
http://dubhehub.github.io/blogs/2023121121101963755.html
Author
Sin
Posted on
December 11, 2023
Licensed under