最近逆向某聊天软件协议部分,需要打印出所有报文加解密的原文,密文以及密钥。想通过hook的方式,hook导出函数的地址,然后在函数进入前输出想要的入参,函数返回时输出想要的出参。用到了dll注入的方式。参考了逆向工程核心原理的内容。可通用性还可以,分享代码如下:
https://download.csdn.net/download/liutianheng654/10754049
如果想针对自己的dll进行hook,需要修改的文件部分如下:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include "gDC_ApiHook.h"
#include
#include
#include
#include
#pragma comment(lib,"ws2_32.lib") //主机转字节序
gDC_ApiHook g_objScaleHook;
gDC_ApiHook g_objCoreHook;
FILE *fp = NULL;
char buf[] = {0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05 };
char zero[] = {0x00, 0x00, 0x00,0x00, 0x00, 0x00,0x00, 0x00, 0x00,0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00}; //填充部分,我这里自己标识位,无意义。
typedef unsigned int (*AOUT_FILTERSPLAY) (int *in, __m128 *out, unsigned int flag, int param, const __m128i *param2); //待捕获函数的替代。这里注意参数需要和hook的函数个数一样,类型不是很重要。且函数调用方式要一样,这里函数调用方式指stdcall之类。
//这里就是函数的具体实现了,其中有函数的真实调用。在调用前后打印自己所需的参数即可。
unsigned int gDC_aout_FiltersPlay (int *in, __m128 *out, unsigned int flag, int param, const __m128i *param2)
{
AOUT_FILTERSPLAY oldFileterPlay = NULL;
oldFileterPlay = (AOUT_FILTERSPLAY)(g_objCoreHook.GetCallAddress());
CString str;
if(flag == 5)
{
int len = *in;
int length = ntohl(len);
fwrite(buf,1,16,fp);
str.Format("%d",length);
MessageBox(NULL, str,"len", MB_OK);
int temp = length%16+2;
str.Format("%d",temp);
MessageBox(NULL, str,"yu", MB_OK);
fwrite(in,1,length,fp);
fwrite(zero,1,temp,fp);
fwrite(param2,1,16,fp);
}
//上面是函数之前的调用
//下面接真实函数调用后,输出需要的返回参数
unsigned int p = oldFileterPlay(in, out, flag, param, param2);
if(flag == 5)
{
fwrite(buf,1,16,fp);
fwrite(out,1,64,fp);
fwrite(buf,1,16,fp);
fflush(fp);
}
return p;
}
void hook()
{
fp = fopen("C:\\Users\\liuti\\Downloads\\out\\test", "wb");
//打开文件,注释掉的是找那种有名字的导出函数的方式。我需要的是没有函数名,只有偏移地址的导出函数。
/*HMODULE hMod = GetModuleHandle("libvlccore.dll");
if (NULL == hMod)
{
MessageBox(NULL, "no Core module", "tip", MB_OK);
return ;
}
int addr = (int)GetProcAddress(hMod, "aout_FiltersPlay");
g_objCoreHook.HookApi((char*)addr, (char*)gDC_aout_FiltersPlay);*/
HMODULE hMod = GetModuleHandle("WeChatWin.dll");//dll名称
if (NULL == hMod)
{
MessageBox(NULL, "no Scale module", "tip", MB_OK);
return ;
}
int addr = ((int)hMod) + 0x215A0;//偏移地址
g_objCoreHook.HookApi((char*)addr, (char*)gDC_aout_FiltersPlay);
//g_objScaleHook.HookApi((char*)addr, (char*)gDC_DoWork);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
hook();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
fclose(fp);
break;
}
return TRUE;
}
共分两个exe,一个是hook的dll,就是上面那长段代码生成的。
一个是dll注入函数,用来将上面编写的hook用dll注入进exe,使用方式如下:
InjectDll.exe 276748 C:\Users\liuti\Downloads\ApiHook\ApiHook\Release\ApiHook.dll
其中 276748 是需要注入的exe的当前Pid。