首页
学习
活动
专区
圈层
工具
发布
30 篇文章
1
《coredump问题原理探究》Linux x86版6.4节虚函数
2
《coredump问题原理探究》Linux x86版7.3节List对象
3
《coredump问题原理探究》Linux x86版4.4节函数的逆向之循环结构
4
《coredump问题原理探究》windows版8.5节堆布局空闲堆块遍历
5
《coredump问题原理探究》windows版9.1节栈溢出
6
《coredump问题原理探究》Linux x86版3.2节栈布局之函数桢
7
《coredump问题原理探究》Linux x86版3.4节栈布局之函数参数
8
《coredump问题原理探究》Linux x86版4.1节函数的逆向之序言
9
《coredump问题原理探究》Linux x86版4.2节函数的逆向之顺序结构
10
《coredump问题原理探究》Linux x86版4.3节函数的逆向之条件结构
11
《coredump问题原理探究》windows版3.4节coredump例子
12
《coredump问题原理探究》windows版第四章函数的逆向
13
《coredump问题原理探究》windows版5.1节基本数据类型
14
《coredump问题原理探究》windows版5.2节数组
15
《coredump问题原理探究》windows版5.3节结构体
16
《coredump问题原理探究》windows版5.4节联合体
17
《coredump问题原理探究》windows版6.1节无成员变量的类
18
《coredump问题原理探究》windows版6.2节有成员变量的类
19
《coredump问题原理探究》windows版6.3节虚函数
20
《coredump问题原理探究》windows版6.4节单继承
21
《coredump问题原理探究》windows版6.5节多继承
22
《coredump问题原理探究》windows版7.1节vector
23
《coredump问题原理探究》windows版7.2节list
24
《coredump问题原理探究》windows版7.3节map
25
《coredump问题原理探究》windows版7.4节set
26
《coredump问题原理探究》windows版7.5节iterator
27
《coredump问题原理探究》windows版7.6节string
28
《coredump问题原理探究》windows版8.1节堆布局背景
29
《coredump问题原理探究》windows版8.2节堆布局堆块结构
30
《coredump问题原理探究》windows版3.1节函数桢

《coredump问题原理探究》Linux x86版4.4节函数的逆向之循环结构

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1344516

在x86里,循环指令有:

代码语言:javascript
复制
LOOP:ECX不为零时循环
LOOPE/LOOPZ:ECX不为零且标志Z=1时循环
LOOPNE/LOOPNZ:ECX不为零且标志Z=0时循环

但实质上,由于上面指令适用范围太窄,只能用于循环体非常简单的。所以往往是用条件跳转指令来实际循环。用例子来体现一下:

代码语言:javascript
复制
 #include <stdio.h>

 int loop_for( int n )
 {
     int sum = 0;

     for ( int i = 0; i < n; i++ )
     {
         sum += i;
     }
 
     return sum;
 }
 
 int loop_while( int n )
 {
     int sum = 0;
     int i = 0;
 
     while ( i < n )
     {
         sum += i;
         i++;
     }
 
     return sum;
 }
 
 int loop_do( int n )
 {
     int sum = 0;
     int i = 0;
	 
     do
     {
         sum += i;
         i++;
     } while ( i < n );
 
     return sum;
 }
 
 int main()
 {
     int n = 0;

     scanf( "%d", &n );

     return loop_for( n ) + loop_while( n )
         + loop_do( n );
 }

看一下loop_do,loop_for, loop_while的汇编:

代码语言:javascript
复制
(gdb) disassemble loop_do
Dump of assembler code for function _Z7loop_doi:
   0x080485d4 <+0>:     push   %ebp
   0x080485d5 <+1>:     mov    %esp,%ebp
   0x080485d7 <+3>:     sub    $0x10,%esp
   0x080485da <+6>:     movl   $0x0,-0x4(%ebp)
   0x080485e1 <+13>:    movl   $0x0,-0x8(%ebp)
   0x080485e8 <+20>:    mov    -0x8(%ebp),%eax
   0x080485eb <+23>:    add    %eax,-0x4(%ebp)
   0x080485ee <+26>:    addl   $0x1,-0x8(%ebp)
   0x080485f2 <+30>:    mov    -0x8(%ebp),%eax
   0x080485f5 <+33>:    cmp    0x8(%ebp),%eax
   0x080485f8 <+36>:    setl   %al
   0x080485fb <+39>:    test   %al,%al

   0x080485fd <+41>:    jne    0x80485e8 <_Z7loop_doi+20>

   0x080485ff <+43>:    mov    -0x4(%ebp),%eax
   0x08048602 <+46>:    leave  
   0x08048603 <+47>:    ret    
End of assembler dump.
代码语言:javascript
复制
(gdb) disassemble loop_for
Dump of assembler code for function _Z8loop_fori:
   0x08048570 <+0>:     push   %ebp
   0x08048571 <+1>:     mov    %esp,%ebp
   0x08048573 <+3>:     sub    $0x10,%esp
   0x08048576 <+6>:     movl   $0x0,-0x4(%ebp)
   0x0804857d <+13>:    movl   $0x0,-0x8(%ebp)

   0x08048584 <+20>:    jmp    0x8048590 <_Z8loop_fori+32>

   0x08048586 <+22>:    mov    -0x8(%ebp),%eax
   0x08048589 <+25>:    add    %eax,-0x4(%ebp)
   0x0804858c <+28>:    addl   $0x1,-0x8(%ebp)
   0x08048590 <+32>:    mov    -0x8(%ebp),%eax
   0x08048593 <+35>:    cmp    0x8(%ebp),%eax
   0x08048596 <+38>:    setl   %al
   0x08048599 <+41>:    test   %al,%al

   0x0804859b <+43>:    jne    0x8048586 <_Z8loop_fori+22>

   0x0804859d <+45>:    mov    -0x4(%ebp),%eax
   0x080485a0 <+48>:    leave  
   0x080485a1 <+49>:    ret    
End of assembler dump.
代码语言:javascript
复制
(gdb) disassemble loop_while
Dump of assembler code for function _Z10loop_whilei:
   0x080485a2 <+0>:     push   %ebp
   0x080485a3 <+1>:     mov    %esp,%ebp
   0x080485a5 <+3>:     sub    $0x10,%esp
   0x080485a8 <+6>:     movl   $0x0,-0x4(%ebp)
   0x080485af <+13>:    movl   $0x0,-0x8(%ebp)

   0x080485b6 <+20>:    jmp    0x80485c2 <_Z10loop_whilei+32>

   0x080485b8 <+22>:    mov    -0x8(%ebp),%eax
   0x080485bb <+25>:    add    %eax,-0x4(%ebp)
   0x080485be <+28>:    addl   $0x1,-0x8(%ebp)
   0x080485c2 <+32>:    mov    -0x8(%ebp),%eax
   0x080485c5 <+35>:    cmp    0x8(%ebp),%eax
   0x080485c8 <+38>:    setl   %al
   0x080485cb <+41>:    test   %al,%al

   0x080485cd <+43>:    jne    0x80485b8 <_Z10loop_whilei+22>

   0x080485cf <+45>:    mov    -0x4(%ebp),%eax
   0x080485d2 <+48>:    leave  
   0x080485d3 <+49>:    ret    
End of assembler dump.

由于loop_for,loop_while的代码逻辑一样,连生成的汇编都是一样。loop_do和两者不大一样,所以,汇编不一样。现在只以loo_do进行分析:

代码语言:javascript
复制
(gdb) disassemble loop_do
Dump of assembler code for function _Z7loop_doi:
   0x080485d4 <+0>:     push   %ebp
   0x080485d5 <+1>:     mov    %esp,%ebp
   0x080485d7 <+3>:     sub    $0x10,%esp
   0x080485da <+6>:     movl   $0x0,-0x4(%ebp)
   0x080485e1 <+13>:    movl   $0x0,-0x8(%ebp)
   0x080485e8 <+20>:    mov    -0x8(%ebp),%eax
   0x080485eb <+23>:    add    %eax,-0x4(%ebp)
   0x080485ee <+26>:    addl   $0x1,-0x8(%ebp)
   0x080485f2 <+30>:    mov    -0x8(%ebp),%eax
   0x080485f5 <+33>:    cmp    0x8(%ebp),%eax
   0x080485f8 <+36>:    setl   %al
   0x080485fb <+39>:    test   %al,%al

   0x080485fd <+41>:    jne    0x80485e8 <_Z7loop_doi+20>

   0x080485ff <+43>:    mov    -0x4(%ebp),%eax
   0x08048602 <+46>:    leave  
   0x08048603 <+47>:    ret    
End of assembler dump.

由指令地址0x080485fd这一条指令可知,执行流程会回到0x080485e8,这个地址是比跳转指令地址更小,直到满足eax的值和ebp+8的内容相等才会停止。也就是说,从0x080485e8到0x080485fd就构成了一个循环。由于

代码语言:javascript
复制
   0x080485f5 <+33>:    cmp    0x8(%ebp),%eax

是用来设置标志位的,所以应该是对应于i < n子句

也就是说,

代码语言:javascript
复制
   0x080485e8 <+20>:    mov    -0x8(%ebp),%eax
   0x080485eb <+23>:    add    %eax,-0x4(%ebp)
   0x080485ee <+26>:    addl   $0x1,-0x8(%ebp)

对应于

代码语言:javascript
复制
36	         sum += i;
37	         i++;

如果同样分析loop_for,loop_while也会发现,跳转指令是跳到比当前指令地址更小的地址来执行。

从这里可以看出,如果在分析函数的汇编时,遇到跳转指令,如果它并不是跳到比当前指令地址更大的地址执行,那么它有可能是一个循环,否则就是一个普通的条件跳转结构

下一篇
举报
领券