64位的Win7下拦截malloc函数(二)

在上一篇的“64位的Win7下拦截malloc函数”基础上,测试crt(c运行时)库几个可能会调用malloc的API函数。


注意该程序必须在64位Release版本下运行,如果是DeBug版本的话,因为编译器没做优化和加了一些debug代码,所以会内存读写报错


// 说明:此test.cpp文件为win7下,对msvcr100.dll动态库中的maollc函数的hook测试文件,
//       即拦截win7平台下Release版本的malloc函数
// 
// 作者:过客
// 邮箱:386520874@qq.com
// 日期:2017.04.18


#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>
//#include <malloc.h>


typedef HANDLE (__stdcall * PFN_GETCURRENTPROCESS)(void);
typedef BOOL (__stdcall * PFN_WRITEPROCESSMEMORY)(HANDLE, LPVOID, LPCVOID, SIZE_T, SIZE_T *);
typedef DWORD (__stdcall * PFN_GETCURRENTTHREADID)(void);

typedef void * (__cdecl * PFN_MALLOC)(size_t _Size);
typedef int (__cdecl * PFN_PRINTF)(const char * _Format, ...);


//------------------------------------------------
#pragma pack(1) //#pragma pack(push, 4) 说明:可以1字节对齐也可以4字节对齐,此处非常重要
typedef struct HOOK_PARAM
{
	DWORD pGetCurrentProcess;
	DWORD pWriteProcessMemory;
	DWORD pGetCurrentThreadId;
	DWORD pMalloc;
	DWORD pPrintf;
	long long malloc_param_1; //用于保存malloc的输入参数值
	long long nextIpAddr; //64位地址
	void * pMallocReturn; //用于保存malloc的返回值
	DWORD currentThreadId; //用于保存GetCurrentThreadId的返回值
	char oldCode[20];
	char newCode[20];
	char str[100];
	char str_format[100]; //printf的参数
	DWORD dwFunAddr;
	DWORD dwParmaAddr;
}HOOK_PARAM;
#pragma pack() //#pragma pack(pop)


HOOK_PARAM hook_param = {0}; //全局变量


//------------------------------------------------
void * my_hook_malloc(void *lParam)
{
	HOOK_PARAM * p = (HOOK_PARAM *)lParam;

	PFN_GETCURRENTPROCESS pfnGetCurrentProcess = (PFN_GETCURRENTPROCESS)(p->pGetCurrentProcess);
	PFN_WRITEPROCESSMEMORY pfnWriteProcessMemory = (PFN_WRITEPROCESSMEMORY)(p->pWriteProcessMemory);
	PFN_GETCURRENTTHREADID pfnGetCurrentThreadId = (PFN_GETCURRENTTHREADID)(p->pGetCurrentThreadId);
	
	PFN_MALLOC pfnMalloc = (PFN_MALLOC)(p->pMalloc);
	PFN_PRINTF pfnPrintf = (PFN_PRINTF)(p->pPrintf);

	//恢复API原来的样子,即摘掉API钩子
	pfnWriteProcessMemory(pfnGetCurrentProcess(), (LPVOID)pfnMalloc, (LPCVOID)(p->oldCode), 20, NULL);
	
	//调用正常的malloc
	p->pMallocReturn = pfnMalloc(p->malloc_param_1);

	//调用win32 API GetCurrentThreadId()
	p->currentThreadId = pfnGetCurrentThreadId();

	//-------------------------------------------------
	pfnPrintf(p->str_format, p->currentThreadId, p->currentThreadId, p->malloc_param_1, p->malloc_param_1, p->pMallocReturn); //将hook到的信息打印出来

	return p->pMallocReturn; //将malloc申请的内存地址返回
}


//------------------挂上API钩子------------------------------
int hook_on(HANDLE hProcess)
{
	//--------------------------
	HMODULE hKernel32 = LoadLibraryA("kernel32.dll");
	HMODULE hMsvcr100 = LoadLibraryA("msvcr100.dll");

	hook_param.pGetCurrentProcess = (DWORD)GetProcAddress(hKernel32, "GetCurrentProcess");
	hook_param.pWriteProcessMemory = (DWORD)GetProcAddress(hKernel32, "WriteProcessMemory");
	hook_param.pGetCurrentThreadId = (DWORD)GetProcAddress(hKernel32, "GetCurrentThreadId");

	hook_param.pMalloc = (DWORD)GetProcAddress(hMsvcr100, "malloc");
	hook_param.pPrintf = (DWORD)GetProcAddress(hMsvcr100, "printf");

	hook_param.malloc_param_1 = 0x12345678;

	sprintf(hook_param.str_format, "GetCurrentThreadId() = %%ld = 0x%%X;   malloc(): size = %%ld = 0x%%X; ptr = 0x%%X;\n");

	//---------------------------------------------
	int size_Func = 1024 * 1;
	DWORD dwFunAddr = (DWORD)VirtualAllocEx(hProcess, NULL, size_Func, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); //在进程空间申请内存
	memset((void *)dwFunAddr, 0, size_Func);

	int size_Param = sizeof(HOOK_PARAM);
	DWORD dwParmaAddr = (DWORD)VirtualAllocEx(hProcess, NULL, size_Param, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); //在进程空间申请内存
	
	hook_param.dwFunAddr = dwFunAddr;
	hook_param.dwParmaAddr = dwParmaAddr;

	//---------------------------------------------
	hook_param.newCode[0] = 0x51; //push    rcx //将 char * p = (char *)malloc(0x0637); 的参数 0x0637 入栈
	hook_param.newCode[1] = 0x68; //0x68: push newcode[2..5],参数先压栈
	hook_param.newCode[2] = (dwParmaAddr << 24) >> 24;
	hook_param.newCode[3] = (dwParmaAddr << 16) >> 24;
	hook_param.newCode[4] = (dwParmaAddr << 8 ) >> 24;
	hook_param.newCode[5] = (dwParmaAddr << 0 ) >> 24;
	hook_param.newCode[6] = 0x59; //pop    ecx
	hook_param.newCode[7] = 0x67; //pop    qword ptr [ecx + 14h] // hook_param.malloc_param_1 = 0x0637; 将malloc(size);的size参数偷偷保存起来
	hook_param.newCode[8] = 0x8F;
	hook_param.newCode[9] = 0x41;
	hook_param.newCode[10] = 0x14;
	hook_param.newCode[11] = 0x48; //sub    rsp, 20h //目的是平衡栈
	hook_param.newCode[12] = 0x83;
	hook_param.newCode[13] = 0xEC;
	hook_param.newCode[14] = 0x18;

	int offsetaddr = dwFunAddr - (int)hook_param.pMalloc - 20;

	hook_param.newCode[15] = 0xE8; //0xE8: call newcode[16..19],然后调用函数 my_hook_malloc
	hook_param.newCode[16] = (offsetaddr << 24) >> 24;
	hook_param.newCode[17] = (offsetaddr << 16) >> 24;
	hook_param.newCode[18] = (offsetaddr << 8 ) >> 24;
	hook_param.newCode[19] = (offsetaddr << 0 ) >> 24;

	char add_rsp[5] = {0};
	add_rsp[0] = 0x48; //add    rsp, 20h //目的是平衡栈
	add_rsp[1] = 0x83;
	add_rsp[2] = 0xC4;
	add_rsp[3] = 0x20;
	add_rsp[4] = 0xC3; //ret

	//---------------------------------------------
	SIZE_T dwNumberOfBytesWrite = 0;

	BOOL ret4 = ::ReadProcessMemory(hProcess, (LPCVOID)hook_param.pMalloc, hook_param.oldCode, 20, &dwNumberOfBytesWrite); //将malloc函数体原始的前20个字节保存起来,以便hook后恢复

	BOOL ret5 = ::WriteProcessMemory(hProcess, (LPVOID)hook_param.pMalloc, &hook_param.newCode, 20, &dwNumberOfBytesWrite); //在新申请的进程地址空间,写函数my_hook_malloc的参数

	BOOL ret6 = ::WriteProcessMemory(hProcess, (LPVOID)dwFunAddr, &my_hook_malloc, size_Func, &dwNumberOfBytesWrite); //将编译后的函数体写到新申请的进程地址空间
	BOOL ret7 = ::WriteProcessMemory(hProcess, (LPVOID)(dwFunAddr + 0x93), &add_rsp, 5, &dwNumberOfBytesWrite); //此处目的是为了能正常返回main函数领空, 0x8A是原始函数体的大小
	
	BOOL ret8 = ::WriteProcessMemory(hProcess, (LPVOID)dwParmaAddr, &hook_param, size_Param, &dwNumberOfBytesWrite);

	return 0;
}


//------------------摘掉API钩子------------------------------
int hook_off(HANDLE hProcess)
{
	SIZE_T dwNumberOfBytesWrite = 0;

	BOOL ret1 = ::WriteProcessMemory(hProcess, (LPVOID)hook_param.pMalloc, &hook_param.oldCode, 20, &dwNumberOfBytesWrite);

	BOOL ret2 = VirtualFreeEx(hProcess, (LPVOID)hook_param.dwFunAddr, 0, MEM_RELEASE);
	BOOL ret3 = VirtualFreeEx(hProcess, (LPVOID)hook_param.dwParmaAddr, 0, MEM_RELEASE);

	return 0;
}


//---------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
	HANDLE hProcess = GetCurrentProcess();

	//----------------------------------
	printf("\n----------------------------------\n");

	hook_on(hProcess);
	
	char * p0 = (char *)malloc(0x0637);
	printf("malloc(): p=0x%X\n", p0);

	sprintf(p0, "dddddddd 6666666666: 我hook malloc成功啦! 嚯嚯嚯!");
	printf("%s\n", p0);

	free(p0);
	
	hook_off(hProcess);

	//----------------------------------
	printf("\n--------------new会调用malloc--------------------\n");

	hook_on(hProcess);
	
	int * p1 = new int; //new会调用malloc
	printf("new int(): p=0x%X\n", p1);
	delete p1;

	hook_off(hProcess);
	
	//----------------------------------
	printf("\n--------------new []会调用malloc--------------------\n");

	hook_on(hProcess);
	
	char * p2 = new char[17]; //new []会调用malloc
	printf("new char[](): p=0x%X\n", p2);
	delete [] p2;

	hook_off(hProcess);
	
	//----------------------------------
	printf("\n--------------calloc不会调用malloc--------------------\n");

	hook_on(hProcess);
	
	char * p3 = (char *)calloc(10, sizeof(char));
	printf("calloc(): p=0x%X\n", p3);
	free(p3);
	
	hook_off(hProcess);

	//----------------------------------
	printf("\n--------------realloc会调用malloc--------------------\n");

	hook_on(hProcess);
	
	char * p4 = (char *)realloc(NULL, 23); //realloc会调用malloc
	printf("realloc(): p=0x%X\n", p4);
	free(p4);
	
	hook_off(hProcess);
	
	//----------------------------------
	printf("\n--------------strdup会调用malloc--------------------\n");

	hook_on(hProcess);
	
	char str[] = "Hello World 1!";
	char * p5 = strdup(str); //strdup会调用malloc
	printf("strdup(): p=0x%X\n", p5);
	free(p5);
	
	hook_off(hProcess);

	//----------------------------------
	printf("\n--------------wcsdup不会调用malloc--------------------\n");

	hook_on(hProcess);
	
	wchar_t str2[] = L"Hello World 2!";
	wchar_t * p6 = wcsdup(str2); //wcsdup不会调用malloc
	printf("wcsdup(): p=0x%X\n", p6);
	free(p6);
	
	hook_off(hProcess);
	
	//----------------------------------
	printf("\n--------------_aligned_malloc会调用malloc--------------------\n");

	hook_on(hProcess);

	char * p7 = (char *)_aligned_malloc(17, 16); //_aligned_malloc会调用malloc
	printf("_aligned_malloc(): p=0x%X\n", p7);
	_aligned_free(p7);
	
	hook_off(hProcess);

	//----------------------------------
	printf("\n--------------_aligned_realloc会调用malloc--------------------\n");

	hook_on(hProcess);
	
	char * p8 = (char *)_aligned_realloc(NULL, 17, 16); //_aligned_realloc会调用malloc
	printf("_aligned_realloc(): p=0x%X\n", p8);
	_aligned_free(p8);
	
	hook_off(hProcess);

	//----------------------------------
	printf("\n--------------_aligned_offset_malloc会调用malloc--------------------\n");

	hook_on(hProcess);
	
	char * p9 = (char *)_aligned_offset_malloc(17, 16, 5); //_aligned_offset_malloc会调用malloc
	printf("_aligned_offset_malloc(): p=0x%X\n", p9);
	_aligned_free(p9);
	
	hook_off(hProcess);

	//----------------------------------
	printf("\n--------------_aligned_offset_realloc会调用malloc--------------------\n");

	hook_on(hProcess);
	
	char * p10 = (char *)_aligned_offset_realloc(NULL, 17, 16, 5); //_aligned_offset_realloc会调用malloc
	printf("_aligned_offset_realloc(): p=0x%X\n", p10);
	_aligned_free(p10);
	
	hook_off(hProcess);

	//----------------------------------
	CloseHandle(hProcess);

	return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值