使用方法:
0.首先使用者请保证跑我的函数时已经注入到目标程序中
1.引用外部变量
extern DWORD *g_pApiAddr;
extern BYTE *g_pOldCode;
2.建立一个hook后工作函数
以下是hook后的测试函数
LPVOID _declspec(naked) WINAPI TestFun(LPVOID UnKnow1, LPVOID UnKnow2)
{
::MessageBox(NULL, TEXT("这是一个hook提示"), TEXT("提示"), NULL);
//以下汇编不可动
_asm
{
push g_pOldCode
ret;
}
}
3.调用
例子:
MODULEAPI tagModuleAPI = {
{TEXT("kernel32.dll"), "ExitProcess"},
};
MyApiHookFun(&tagModuleAPI,TestFun);
MyApiHookFun.h:
#pragma once
#include <windows.h>
//////////////////////////////////////////////////////////////////////////
//定义
typedef struct _MODULE_API
{
TCHAR *pModuleName;
char *pApiName;
}MODULEAPI,*PMODULEAPI;
//////////////////////////////////////////////////////////////////////////
//函数声明
BOOL WINAPI MyApiHookFun(PMODULEAPI pModuleAPI, LPVOID pfnHookFun);
MyApiHookFun.cpp:
#include "MyApiHookFun.h"
DWORD g_dwApiAddr = NULL;
BYTE *g_pOldCode = NULL;
/************************************************************************
函数名字:BOOL WINAPI MyApiHookFun(PMODULEAPI pModuleAPI, LPVOID pfnHookFun)
功 能:API HOOK主函数
参 数 1:pModuleAPI 模块和api名字的数组
参 数 2:pfnHookFun hook后执行的函数数组
返 回 值:TRUE - 成功/ FALSE - 失败
************************************************************************/
BOOL WINAPI MyApiHookFun(PMODULEAPI pModuleAPI, LPVOID pfnHookFun)
{
char chE9 = (char)0xe9;
TCHAR szTmp[MAX_PATH] = {0};
DWORD dwPID = 0;
BOOL bRet = FALSE;
LPVOID pAllocAddr = NULL;
DWORD dwOld = 0;
HMODULE hModule = NULL;
g_pOldCode = new BYTE[12];
if (g_pOldCode == NULL)
{
#ifdef _DEBUG
::OutputDebugString(TEXT("new g_pOldCode Error!"));
#endif
return FALSE;
}
memset(g_pOldCode, 0, 12);
//获得API地址
hModule = ::GetModuleHandle(pModuleAPI->pModuleName);
if (hModule == NULL)
{
#ifdef _DEBUG
::OutputDebugString(TEXT("GetModuleHandle Error!"));
#endif
return FALSE;
}
g_dwApiAddr = (DWORD)::GetProcAddress(hModule, pModuleAPI->pApiName);
if (g_dwApiAddr == NULL)
{
#ifdef _DEBUG
::OutputDebugString(TEXT("GetProcAddress Error!"));
#endif
return NULL;
}
//改变内存属性 HOOK
bRet = ::VirtualProtect((LPVOID)g_dwApiAddr,
5,
PAGE_EXECUTE_READWRITE,
&dwOld);
if (bRet == FALSE)
{
#ifdef _DEBUG
wsprintf(szTmp, TEXT("VirtualProtect %08X Error!"), pApiAddr[i]);
OutputDebugString(szTmp);
#endif
return FALSE;
}
//shell code
g_pOldCode[0] = (char)0xb8;
*(DWORD *)(&g_pOldCode[1]) = g_dwApiAddr + 5;
g_pOldCode[5] = *(BYTE *)g_dwApiAddr;
*(DWORD *)(&g_pOldCode[6]) = *(DWORD *)(g_dwApiAddr + 1);
g_pOldCode[10] = (char)0xff;
g_pOldCode[11] = (char)0xe0;
//写入
*(BYTE *)g_dwApiAddr = 0xE9;
*(DWORD *)(g_dwApiAddr + 1) = (DWORD)pfnHookFun - (g_dwApiAddr + 5);
bRet = ::VirtualProtect((LPVOID)g_dwApiAddr,
5,
dwOld,
&dwOld);
if (bRet == FALSE)
{
#ifdef _DEBUG
wsprintf(szTmp, TEXT("VirtualProtect2 %08X Error!"), pApiAddr[i]);
OutputDebugString(szTmp);
#endif
return FALSE;
}
return TRUE;
}
附件:
[课程]Android-CTF解题方法汇总!