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

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

2012年10月22日 ⁄ 综合 ⁄ 共 2379字 ⁄ 字号 评论关闭

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

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

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

 

#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;
}

 

【上篇】
【下篇】

抱歉!评论已关闭.