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

基于visual c++之windows核心编程代码分析(44)监测任意程序函数起始地址

2013年10月07日 ⁄ 综合 ⁄ 共 2898字 ⁄ 字号 评论关闭

很多时候,我们分析一个程序的构架,必须了解其函数的相关信息,如何了解其函数信息呢,

我们必须监测函数的起始地址,结束地址,代码长度 等等信息。

如何做到这一点呢,我们编程实现之。

[cpp]
view plain
copyprint?

  1. #include <windows.h> 
  2. #include <iostream.h> 
  3.  
  4. DWORD code() 
  5.     ////////////////////////////////////////////////////////////////////////// 
  6.     //  *******变量说明******* 
  7.     //  **dwCodeBegin   :本函数的开始地址 
  8.     //  **dwCodeEnd     :本函数的结束地址 
  9.     //  **dwMyCodeAddr  :自己写的代码的开始地址 
  10.     ////////////////////////////////////////////////////////////////////////// 
  11.     DWORD dwCodeBegin , dwCodeEnd , dwMyCodeAddr; 
  12.  
  13.     //  *******指针变量******* 
  14.     PBYTE pMove = NULL; 
  15.  
  16.     //  *******动态获取自己写的代码的开始地址******* 
  17.     _asm 
  18.     { 
  19.         call    A 
  20. A: 
  21.         pop     eax 
  22.  
  23.         mov     dwMyCodeAddr , eax 
  24.     } 
  25.  
  26.     //  *******把地址赋给变量******* 
  27.     pMove = (PBYTE)dwMyCodeAddr; 
  28.  
  29.     //  *******向前搜索得到函数的真正入口地址******* 
  30.     while(!((*pMove == 0x55) && (*(pMove + 1) == 0x8B))) 
  31.     { 
  32.         pMove --; 
  33.     } 
  34.      
  35.     //  *******此时pMove指向函数的入口push ebp处******* 
  36.     dwCodeBegin = (DWORD)pMove; 
  37.  
  38.     cout << "开始地址为:" << hex << dwCodeBegin << endl; 
  39.  
  40.     //  *******从自己写的代码处向后搜索******* 
  41.     pMove = (PBYTE)dwMyCodeAddr; 
  42.  
  43.     while (!((*(pMove + 1) == 0xc3) && (*pMove == 0x5D) && (*(pMove - 1) == 0xE5))) 
  44.     { 
  45.         pMove ++; 
  46.     } 
  47.  
  48.     //  *******此时pMove指向ret的前一条指令pop ebp处******* 
  49.     dwCodeEnd = (DWORD)pMove; 
  50.  
  51.     cout << "结束地址为:" << hex << dwCodeEnd << endl; 
  52.  
  53.     return 0; 
  54.  
  55. void main() 
  56.     ////////////////////////////////////////////////////////////////////////// 
  57.     //  *******变量说明******* 
  58.     //  **dwFunBegAddr  :函数的开始地址 
  59.     //  **dwFunEndAddr  :函数的结束地址 
  60.     //  **dwFunCodeLen  :代码长度 
  61.     //  **dwJmpOff      :jmp到真正入口的偏移 
  62.     ////////////////////////////////////////////////////////////////////////// 
  63.     DWORD dwFunBegAddr , dwJmpOff , dwFunEndAddr , dwFunCodeLen; 
  64.  
  65.     ////////////////////////////////////////////////////////////////////////// 
  66.     //  *******首先得到函数真正的入口地址******* 
  67.     ////////////////////////////////////////////////////////////////////////// 
  68.  
  69.     //  *******临时的指针变量******* 
  70.     PBYTE pMove = NULL; 
  71.      
  72.     //  *******首先指向函数的jmp指令******* 
  73.     pMove = (PBYTE)code; 
  74.      
  75.     //  *******定位到jmp后面的偏移处******* 
  76.     pMove ++; 
  77.  
  78.     //  *******把偏移赋值给变量******* 
  79.     dwJmpOff = *(PDWORD)pMove; 
  80.  
  81.     //  *******jmp下一条指令的地址(code + 5)+偏移得到函数真正的入口地址******* 
  82.     dwFunBegAddr = (DWORD)code + 5 + dwJmpOff; 
  83.  
  84.     cout << "开始地址为:" << hex << dwFunBegAddr << endl; 
  85.  
  86.     ////////////////////////////////////////////////////////////////////////// 
  87.     //  *******搜索函数代码,找到函数结尾处******* 
  88.     ////////////////////////////////////////////////////////////////////////// 
  89.  
  90.     //  *******首先把函数的入口地址赋给变量******* 
  91.     pMove = (PBYTE)dwFunBegAddr; 
  92.  
  93.     //  *******向后搜索,直到结尾******* 
  94.     while (!((*(pMove + 1) == 0xc3) && (*pMove == 0x5D) && (*(pMove - 1) == 0xE5))) 
  95.     { 
  96.         pMove ++; 
  97.     } 
  98.  
  99.     //  *******此时pMove指向ret前一条指令******* 
  100.     dwFunEndAddr = (DWORD)pMove; 
  101.  
  102.     cout << "代码结束地址为:" << hex << dwFunEndAddr << endl; 
  103.  
  104.     //  *******结束地址减去起始地址,得到代码长度******* 
  105.     dwFunCodeLen = dwFunEndAddr - dwFunBegAddr; 
  106.  
  107.     cout << "总代码长度为:" << (int)dwFunCodeLen << endl; 
  108.  
  109.     //  *******调用函数******* 
  110.     code(); 
  111.  
  112.     return

 

原文地址:http://blog.csdn.net/yincheng01/article/details/7214399

抱歉!评论已关闭.