现在的位置: 首页 > 综合 > 正文

《软件调试分析技术》学习笔记(十一)

2014年01月06日 ⁄ 综合 ⁄ 共 1210字 ⁄ 字号 评论关闭

(继上)这种间接调用的方式要比前面看到的直接调用方式麻烦很多。来看一个复杂一点的例子:

#include <stdio.h> 
void function0() 
{ 
  return; 
} 
void function1() 
{ 
  return; 
} 
int main() 
{ 
  int fn[2]; 
  fn[0] = (int)function0; 
  fn[1] = (int)function1; 
  void (*f)(); 
  for (int i = 0;i < 2;i++) 
  { 
    f = (void (*)())fn[i]; 
    f(); 
  } 
  return 0; 
}

这段函数定义了两个函数function1()和function2(),两个函数都是空的,只有一个返回语句。在主函数定义了一个int型的数组,大小为2,并分别给他们赋于函function1()function2()地址,再定义一个函数指针f,使用一个for循环,分别获取储存在fn数组里的函数function1()和function2()地址并调用。编译后使用IDA分析:

.text:00401010    push    ebp 
.text:00401011    mov     ebp, esp 
.text:00401013    sub     esp, 10h 

这里给整型数组fn、函数指针f、循环变量i开辟储存空间。

.text:00401016    mov     [ebp+fn], offset ?function1@@YAXXZ ; function1(void) 
.text:0040101D    mov     [ebp+fn+4], offset ?function1@@YAXXZ ; function1(void) 

 获取两个函数的地址放到数组fn中。

.text:00401024    mov     [ebp+i], 0 
.text:0040102B    jmp     short loc_401036 
.text:0040102D    mov     eax, [ebp+i] 
.text:00401030    add     eax, 1 
.text:00401033    mov     [ebp+i], eax 
.text:00401036    cmp     [ebp+i], 2 
.text:0040103A    jge     short loc_40104B 
.text:0040103C    mov     ecx, [ebp+i] 
.text:0040103F    mov     edx, [ebp+ecx*4+fn] 
.text:00401043    mov     [ebp+f], edx 
.text:00401046    call    [ebp+f] 
.text:00401049    jmp     short loc_40102D

这里是循环体的代码,首先给循环变量赋初值0,然后跳转到0x00401036把循环变量和2进行比较,如果大于等于2则跳出循环体;如果小于2则不执行跳转,取变量fn[i]中的数据,赋值给函数指针f,通过函数指针f调用函数,最后跳回循环头部

.text:0040104B    xor     eax, eax 
.text:0040104D    mov     esp, ebp 
.text:0040104F    pop     ebp 
.text:00401050    retn

抱歉!评论已关闭.