很多时候,我们分析一个程序的构架,必须了解其函数的相关信息,如何了解其函数信息呢,
我们必须监测函数的起始地址,结束地址,代码长度 等等信息。
如何做到这一点呢,我们编程实现之。
#include <windows.h> #include <iostream.h> DWORD code() { ////////////////////////////////////////////////////////////////////////// // *******变量说明******* // **dwCodeBegin :本函数的开始地址 // **dwCodeEnd :本函数的结束地址 // **dwMyCodeAddr :自己写的代码的开始地址 ////////////////////////////////////////////////////////////////////////// DWORD dwCodeBegin , dwCodeEnd , dwMyCodeAddr; // *******指针变量******* PBYTE pMove = NULL; // *******动态获取自己写的代码的开始地址******* _asm { call A A: pop eax mov dwMyCodeAddr , eax } // *******把地址赋给变量******* pMove = (PBYTE)dwMyCodeAddr; // *******向前搜索得到函数的真正入口地址******* while(!((*pMove == 0x55) && (*(pMove + 1) == 0x8B))) { pMove --; } // *******此时pMove指向函数的入口push ebp处******* dwCodeBegin = (DWORD)pMove; cout << "开始地址为:" << hex << dwCodeBegin << endl; // *******从自己写的代码处向后搜索******* pMove = (PBYTE)dwMyCodeAddr; while (!((*(pMove + 1) == 0xc3) && (*pMove == 0x5D) && (*(pMove - 1) == 0xE5))) { pMove ++; } // *******此时pMove指向ret的前一条指令pop ebp处******* dwCodeEnd = (DWORD)pMove; cout << "结束地址为:" << hex << dwCodeEnd << endl; return 0; } void main() { ////////////////////////////////////////////////////////////////////////// // *******变量说明******* // **dwFunBegAddr :函数的开始地址 // **dwFunEndAddr :函数的结束地址 // **dwFunCodeLen :代码长度 // **dwJmpOff :jmp到真正入口的偏移 ////////////////////////////////////////////////////////////////////////// DWORD dwFunBegAddr , dwJmpOff , dwFunEndAddr , dwFunCodeLen; ////////////////////////////////////////////////////////////////////////// // *******首先得到函数真正的入口地址******* ////////////////////////////////////////////////////////////////////////// // *******临时的指针变量******* PBYTE pMove = NULL; // *******首先指向函数的jmp指令******* pMove = (PBYTE)code; // *******定位到jmp后面的偏移处******* pMove ++; // *******把偏移赋值给变量******* dwJmpOff = *(PDWORD)pMove; // *******jmp下一条指令的地址(code + 5)+偏移得到函数真正的入口地址******* dwFunBegAddr = (DWORD)code + 5 + dwJmpOff; cout << "开始地址为:" << hex << dwFunBegAddr << endl; ////////////////////////////////////////////////////////////////////////// // *******搜索函数代码,找到函数结尾处******* ////////////////////////////////////////////////////////////////////////// // *******首先把函数的入口地址赋给变量******* pMove = (PBYTE)dwFunBegAddr; // *******向后搜索,直到结尾******* while (!((*(pMove + 1) == 0xc3) && (*pMove == 0x5D) && (*(pMove - 1) == 0xE5))) { pMove ++; } // *******此时pMove指向ret前一条指令******* dwFunEndAddr = (DWORD)pMove; cout << "代码结束地址为:" << hex << dwFunEndAddr << endl; // *******结束地址减去起始地址,得到代码长度******* dwFunCodeLen = dwFunEndAddr - dwFunBegAddr; cout << "总代码长度为:" << (int)dwFunCodeLen << endl; // *******调用函数******* code(); return; }