在主线程中将对A中函数进行hook,在32位正常,64位崩溃
如果加载B.dll,在b中hook A函数 32位、64位正常
整个程序只有1个线程
主进程
//头文件
extern int HXLocalHookProc(int x);
class CMainDlg
{
HMODULE m_hDll;// , strFuncName.GetBuffer());
//调用B.dll进行hook
LRESULT OnDllHookOn(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
CString strDll;
strDll = L"HXHookDll.dll";
CString szFuncName = "HXAddFunc";
m_hDll = ::LoadLibrary(strDll);// , strFuncName.GetBuffer());
return 0;
}
LRESULT OnDllHookOff(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
if (m_hDll)
{
::FreeLibrary(m_hDll);
}
return 0;
}
DWORD oldProtect;
BYTE JmpBtye[5];
BYTE OldByte[5];
//主线程进行hook
LRESULT OnLocalHookOn(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
CString strDll;
strDll = L"HXAdd.dll";
CString szFuncName = "HXAddFunc";
HMODULE hDll = ::LoadLibrary(strDll);// , strFuncName.GetBuffer());
if (!hDll)
{
return S_FALSE;
}
typedef int(*pHXAdd)(int);
pHXAdd addr = (pHXAdd)::GetProcAddress(hDll, "HXAddFunc");
if (!addr)
{
return S_FALSE;
}
VirtualProtect((void*)addr, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
JmpBtye[0] = 0xE9;
*(DWORD*)&JmpBtye[1] = (DWORD)((long long)HXLocalHookProc - (long long)addr - 5);
//保存原先字节
memcpy(OldByte, (void*)addr, 5);
//替换原先字节
memcpy((void*)addr, JmpBtye, 5);
return 0;
}
LRESULT OnLocalHookOff(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
CString strDll;
strDll = L"HXAdd.dll";
CString szFuncName = "HXAddFunc";
HMODULE hDll = ::LoadLibrary(strDll);// , strFuncName.GetBuffer());
if (!hDll)
{
return S_FALSE;
}
typedef int(*pHXAdd)(int);
pHXAdd addr = (pHXAdd)::GetProcAddress(hDll, "HXAddFunc");
if (!addr)
{
return S_FALSE;
}
//恢复原先字节
memcpy((void*)addr, OldByte, 5);
//恢复属性
DWORD p;
VirtualProtect((void*)addr, 5, oldProtect, &p);
return 0;
}
LRESULT OnOK(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
// TODO: Add validation code
int n = GetDlgItemInt(IDC_EDIT1);
CString strText, strCaption;
CString strDll;
strDll = L"HXAdd.dll";
CString szFuncName = "HXAddFunc";
HMODULE hDll = ::LoadLibrary(strDll);// , strFuncName.GetBuffer());
if (!hDll)
{
return S_FALSE;
}
typedef int(*pHXAdd)(int);
pHXAdd pFunc = (pHXAdd)::GetProcAddress(hDll, "HXAddFunc");
if (!pFunc)
{
return S_FALSE;
}
//32位先OnLocalHookOn再OnOK正常 64位崩溃
n = pFunc(n);
FreeLibrary(hDll);
strText.Format(L"结果:%d", n);
strCaption = L"结果";
MessageBox(strText.GetBuffer(), strCaption.GetBuffer());
return 0;
}
}
//cpp
int HXLocalHookProc(int x)
{
return x * x;
}
A.dll
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
int HXAddFunc(int x)
{
return x + x;
}
B.dll
DWORD oldProtect;
BYTE JmpBtye[5];
BYTE OldByte[5];
void* OpenProcessaddr;
bool H1_OpenProcess();
void UnHook();
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_THREAD_ATTACH:
case DLL_PROCESS_ATTACH:
H1_OpenProcess();
break;
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
UnHook();
break;
}
return TRUE;
}
int MyOpenProcess(int x)
{
return x * 10;
}
void* F1_OpenProcess()
{
//寻找到OpenProcess的地址
void* addr = 0;
//加载kernel32.dll
HMODULE hModule = LoadLibrary(TEXT("HXAdd.dll"));
if (!hModule)
{
return nullptr;
}
//获取OpenProcess的地址
addr = (void*)GetProcAddress(hModule, "HXAddFunc");
return addr;
}
void* F2_OpenProcess()
{
return (void*)OpenProcess;
}
bool H1_OpenProcess()
{
//1.开始寻找地址
void* addr = F1_OpenProcess();
OpenProcessaddr = addr;
//判断是否寻找成功
if (addr == 0)
{
MessageBox(NULL, TEXT("寻找地址失败"), NULL, 0);
return false;
}
//2.进行Hook
/*
一般代码段是不可写的,我们需要把其改为可读可写.
*/
VirtualProtect((void*)addr, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
//修改前面的5个字节为jmp 跳转到我们的代码.
//内联Hook 跳转偏移计算方式:跳转偏移=目标地址-指令地址-5
//jmp 的OpCode 为:0xE9
JmpBtye[0] = 0xE9;
*(DWORD*)&JmpBtye[1] = (DWORD)((long long)MyOpenProcess - (long long)addr - 5);
//保存原先字节
memcpy(OldByte, (void*)addr, 5);
//替换原先字节
memcpy((void*)addr, JmpBtye, 5);
return true;
}
void UnHook()
{
//恢复原先字节
memcpy((void*)OpenProcessaddr, OldByte, 5);
//恢复属性
DWORD p;
VirtualProtect((void*)OpenProcessaddr, 5, oldProtect, &p);
}
ps:代码来自:https://www.kanxue.com/chm.htm?id=13104&pid=node1000838
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法
最后于 2020-9-2 23:19
被乄羽落编辑
,原因: