函数拦截技术
我做了2个函数拦截并显示某个功能,有一个成功 ,有一个报错不知道哪出问题了,是不是返回类型错了还是?2个原型是
PK_linkage_m PK_ERROR_code_t PK_BODY_extrude
(
/* received */
PK_BODY_t /*profile*/, /* minimum, wire or sheet profile */
PK_VECTOR1_t /*path*/, /* direction of linear extrusion */
const PK_BODY_extrude_o_t * /*options*/, /* options structure */
/* returned */
PK_BODY_t *const/*body*/, /* resulting extruded body */
PK_TOPOL_track_r_t*const/*tracking*/, /* tracking information */
PK_TOPOL_local_r_t*const/*results*/ /* status information */
);
/*
This function creates a new body by performing a linear extrusion of a given
profile.
*/
PK_linkage_m PK_ERROR_code_t PK_CURVE_make_wire_body_2
(
/* received */
int /*n_curves*/, /* number of curves (ie, */
const PK_CURVE_t /*curves*/[], /* curves to create a wire */
const PK_INTERVAL_t /*bounds*/[], /* bounds of each curve */
const PK_CURVE_make_wire_body_o_t * /*options*/, /* options structure */
/* returned */
PK_BODY_t *const/*body*/, /* the created wire body */
int *const/*n_new_edges*/,/* number of new edges */
PK_EDGE_t **const/*new_edges*/, /* new edges */
int **const/*edge_index*/ /* pos in original array */
);
/*
This function creates a wire body from an array of curves and intervals. The
curves do not need to be ordered (unless specified otherwise) or directed.
*/
拦截代码如下,如果某个命令用到这2个函数就提示,使用了某函数
用于分析代码使用哪些函数完成的
HookApi_PK_BODY_extrude是成功的
BOOL HookApi_PK_BODY_extrude();
BOOL UnhookApi_PK_BODY_extrude();
typedef PK_ERROR_code_t(WINAPI* typedef_PK_BODY_extrude)(PK_BODY_t profile, PK_VECTOR1_t path, const PK_BODY_extrude_o_t* options, PK_BODY_t* const body, PK_TOPOL_track_r_t* const tracking, PK_TOPOL_local_r_t* const results);
PK_ERROR_code_t WINAPI New_PK_BODY_extrude(PK_BODY_t profile, PK_VECTOR1_t path, const PK_BODY_extrude_o_t* options, PK_BODY_t* const body, PK_TOPOL_track_r_t* const tracking, PK_TOPOL_local_r_t* const results);
BOOL UnhookApi_PK_BODY_extrude()
{
char* dll_name = "pskernel.dll";
char* addressname = "PK_BODY_extrude";
HMODULE hDll = ::GetModuleHandleA(dll_name);
if (NULL == hDll) { return FALSE; }
PVOID OldMessageBoxA = ::GetProcAddress(hDll, addressname);
if (NULL == OldMessageBoxA) { return FALSE; }
DWORD dwNewDataSize = 12;
DWORD dwOldProtect = 0;
::VirtualProtect(OldMessageBoxA, dwNewDataSize, PAGE_EXECUTE_READWRITE, &dwOldProtect);
::RtlCopyMemory(OldMessageBoxA, g_pOldData, dwNewDataSize);
::VirtualProtect(OldMessageBoxA, dwNewDataSize, dwOldProtect, &dwOldProtect);
return TRUE;
}
PK_ERROR_code_t WINAPI New_PK_BODY_extrude(PK_BODY_t profile, PK_VECTOR1_t path, const PK_BODY_extrude_o_t* options, PK_BODY_t* const body, PK_TOPOL_track_r_t* const tracking, PK_TOPOL_local_r_t* const results)
{
PK_ERROR_code_t fanhui = 0;
char* dll_name = "pskernel.dll";
char* addressname = "PK_BODY_extrude";
UnhookApi_PK_BODY_extrude();
HMODULE hDll = ::GetModuleHandleA(dll_name);
if (NULL == hDll) { return fanhui; }
typedef_PK_BODY_extrude OldFuncAddr = (typedef_PK_BODY_extrude)::GetProcAddress(hDll, addressname);
if (NULL == OldFuncAddr) { return fanhui; }
fanhui = OldFuncAddr(profile, path, options, body, tracking, results);
UF_UI_write_listing_window("你使用了PK_BODY_extrude函数\n");
HookApi_PK_BODY_extrude();
return fanhui;
}
BOOL HookApi_PK_BODY_extrude()
{
char* dll_name = "pskernel.dll";
char* addressname = "PK_BODY_extrude";
HMODULE hDll = ::GetModuleHandleA(dll_name);
if (NULL == hDll) { return FALSE; }
PVOID OldFuncAddr = ::GetProcAddress(hDll, addressname);
if (NULL == OldFuncAddr) { return FALSE; }
BYTE pNewData = { 0x48, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xe0 };
DWORD dwNewDataSize = 12;
ULONGLONG ullNewFuncAddr = (ULONGLONG)New_PK_BODY_extrude;
::RtlCopyMemory(&pNewData, &ullNewFuncAddr, sizeof(ullNewFuncAddr));
DWORD dwOldProtect = 0;
::VirtualProtect(OldFuncAddr, dwNewDataSize, PAGE_EXECUTE_READWRITE, &dwOldProtect);
::RtlCopyMemory(g_pOldData, OldFuncAddr, dwNewDataSize);
::RtlCopyMemory(OldFuncAddr, pNewData, dwNewDataSize);
::VirtualProtect(OldFuncAddr, dwNewDataSize, dwOldProtect, &dwOldProtect);
return TRUE;
}
//----
另一个不成功
HookApi_PK_CURVE_make_wire_body_2(); 不成功
BOOL HookApi_PK_CURVE_make_wire_body_2();
BOOL UnhookApi_PK_CURVE_make_wire_body_2();
typedef PK_ERROR_code_t(WINAPI* typedef_PK_CURVE_make_wire_body_2)(int n_curves, const PK_CURVE_t curves[], const PK_INTERVAL_t bounds[], const PK_CURVE_make_wire_body_o_t* options, PK_BODY_t* const body, int* const n_new_edges, PK_EDGE_t** const new_edges, int** const edge_index);
PK_ERROR_code_t WINAPI New_PK_CURVE_make_wire_body_2(int n_curves, const PK_CURVE_t curves[], const PK_INTERVAL_t bounds[], const PK_CURVE_make_wire_body_o_t* options, PK_BODY_t* const body, int* const n_new_edges, PK_EDGE_t** const new_edges, int** const edge_index);
BOOL UnhookApi_PK_CURVE_make_wire_body_2()
{
char* dll_name = "pskernel.dll";
char* addressname = "PK_CURVE_make_wire_body_2";
HMODULE hDll = ::GetModuleHandleA(dll_name);
if (NULL == hDll) { return FALSE; }
PVOID OldMessageBoxA = ::GetProcAddress(hDll, addressname);
if (NULL == OldMessageBoxA) { return FALSE; }
DWORD dwNewDataSize = 12;
DWORD dwOldProtect = 0;
::VirtualProtect(OldMessageBoxA, dwNewDataSize, PAGE_EXECUTE_READWRITE, &dwOldProtect);
::RtlCopyMemory(OldMessageBoxA, g_pOldData, dwNewDataSize);
::VirtualProtect(OldMessageBoxA, dwNewDataSize, dwOldProtect, &dwOldProtect);
return TRUE;
}
PK_ERROR_code_t New_PK_CURVE_make_wire_body_2(int n_curves, const PK_CURVE_t curves[], const PK_INTERVAL_t bounds[], const PK_CURVE_make_wire_body_o_t* options, PK_BODY_t* const body, int* const n_new_edges, PK_EDGE_t** const new_edges, int** const edge_index)
{
PK_ERROR_code_t fanhui = 0;
char* dll_name = "pskernel.dll";
char* addressname = "PK_CURVE_make_wire_body_2";
UnhookApi_PK_CURVE_make_wire_body_2();
HMODULE hDll = ::GetModuleHandleA(dll_name);
if (NULL == hDll) { return fanhui; }
typedef_PK_CURVE_make_wire_body_2 OldFuncAddr = (typedef_PK_CURVE_make_wire_body_2)::GetProcAddress(hDll, addressname);
if (NULL == OldFuncAddr) { return fanhui; }
fanhui = OldFuncAddr(n_curves, curves, bounds, options, body, n_new_edges, new_edges, edge_index);
UF_UI_write_listing_window("你使用了PK_CURVE_make_wire_body_2函数\n");
HookApi_PK_CURVE_make_wire_body_2();
return fanhui;
}
BOOL HookApi_PK_CURVE_make_wire_body_2()
{
char* dll_name = "pskernel.dll";
char* addressname = "PK_CURVE_make_wire_body_2";
HMODULE hDll = ::GetModuleHandleA(dll_name);
if (NULL == hDll) { return FALSE; }
PVOID OldFuncAddr = ::GetProcAddress(hDll, addressname);
if (NULL == OldFuncAddr) { return FALSE; }
BYTE pNewData = { 0x48, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xe0 };
DWORD dwNewDataSize = 12;
PK_ERROR_code_t ullNewFuncAddr = (PK_ERROR_code_t)New_PK_CURVE_make_wire_body_2;
::RtlCopyMemory(&pNewData, &ullNewFuncAddr, sizeof(ullNewFuncAddr));
DWORD dwOldProtect = 0;
::VirtualProtect(OldFuncAddr, dwNewDataSize, PAGE_EXECUTE_READWRITE, &dwOldProtect);
::RtlCopyMemory(g_pOldData, OldFuncAddr, dwNewDataSize);
::RtlCopyMemory(OldFuncAddr, pNewData, dwNewDataSize);
::VirtualProtect(OldFuncAddr, dwNewDataSize, dwOldProtect, &dwOldProtect);
return TRUE;
}
我的想法就是,做个DLL,注入某进程 ,某进程运行某个功能 ,看它调用什么哪个函数,然后我也做个命令山寨这样实现平替
不知道哪有问题了
C不熟,但觉得 HookApi_PK_CURVE_make_wire_body_2 里这句:
PK_ERROR_code_t ullNewFuncAddr = (PK_ERROR_code_t)New_PK_CURVE_make_wire_body_2
能返回正确地址吗? 这是写 获取程序在跑代码的时候都使用了什么函数吗 要是游戏的函数被拦截会不会数据弹出函数缺失无法运行{:1_904:} lies2014 发表于 2024-8-18 22:53
C不熟,但觉得 HookApi_PK_CURVE_make_wire_body_2 里这句:
PK_ERROR_code_t ullNewFuncAddr = (PK_ERROR ...
我也半懂不懂的,我怀姨是不是数组问题 tonyfeng 发表于 2024-8-19 08:44
我也半懂不懂的,我怀姨是不是数组问题
你就把 PK_ERROR_code_t 改为 ULONGLONG 看看效果呗 本帖最后由 yes2 于 2024-8-19 09:42 编辑
PK_ERROR_code_t ullNewFuncAddr = (PK_ERROR_code_t)New_PK_CURVE_make_wire_body_2;
::RtlCopyMemory(&pNewData, &ullNewFuncAddr, sizeof(ullNewFuncAddr));
你这句的逻辑是要把New_PK_CURVE_make_wire_body_2函数的地址写入到pNewData这个位置,长度上肯定是要指针长度的,PK_ERROR_code_t你没有给出定义,但是我猜应该是4字节。64位指针长度是8字节,少了一半所以出错了。
第一个函数之所以能成功,是因为用的是sizeof(ULONGLONG),够8个字节。两个hook函数基本都一样的东西为啥会有一个使用sizeof(ULONGLONG),另一个使用sizeof(ullNewFuncAddr)?要么是太粗心,要么就是本身对代码也不太理解,东拼西凑来的。
你对每一个需要hook的函数都有一套对应的hook、unhook函数,但是其实可以抽取出来只用一套hook、unhook函数,其中的变量可以通过参数传递,这样就不会出现你这种情况,明明是90%雷同的东西结果还能有一个出错。
另外sizeof(ullNewFuncAddr)是错的,sizeof(ULONGLONG)虽然能用但是其实也不算规范,应该使用sizeof(void*),这样如果迁移到32位,至少也能自适配,少改一点代码就少一点潜在的错误风险。
最后,这种实现方案在多线程下可能会出问题。 QQ我爱破解 发表于 2024-8-18 23:46
这是写 获取程序在跑代码的时候都使用了什么函数吗
是的,就是用这个原理就行了 yes2 发表于 2024-8-19 09:33
PK_ERROR_code_t ullNewFuncAddr = (PK_ERROR_code_t)New_PK_CURVE_make_wi ...
typedef int PK_ERROR_code_t;
它就是一个Int , yes2 发表于 2024-8-19 09:33
PK_ERROR_code_t ullNewFuncAddr = (PK_ERROR_code_t)New_PK_CURVE_make_wi ...
参考的代码是这里的,hook代码 不是很会,
#ifndef _HOOK_API_H_
#define _HOOK_API_H_
#include <Windows.h>
typedef int (WINAPI *typedef_MessageBoxA)(
HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption,// message box title
UINT uType // message box style
);
int WINAPI NewMessageBoxA(
HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption,// message box title
UINT uType // message box style
);
// Hook Api
BOOL HookApi_MessageBoxA();
// Unhook Api
BOOL UnhookApi_MessageBoxA();
#endif
//---------------------
//hookapi.cpp
#include "HookApi.h"
BYTE g_pOldData = {0};
void ShowError(char *pszText)
{
char szErr = {0};
::wsprintf(szErr, "%s Error[%d]\n", pszText, ::GetLastError());
::MessageBox(NULL, szErr, "ERROR", MB_OK);
}
// Hook Api
BOOL HookApi_MessageBoxA()
{
// 获取 user32.dll 模块加载基址
HMODULE hDll = ::GetModuleHandle("user32.dll");
if (NULL == hDll)
{
return FALSE;
}
// 获取 MessageBoxA 函数的导出地址
PVOID OldMessageBoxA = ::GetProcAddress(hDll, "MessageBoxA");
if (NULL == OldMessageBoxA)
{
return FALSE;
}
// 计算写入的前几字节数据, 32位下5字节, 64位下12字节
#ifndef _WIN64
// 32位
// 汇编代码:jmp _dwNewAddress
// 机器码位:e9 _dwOffset(跳转偏移)
// addr1 --> jmp _dwNewAddress指令的下一条指令的地址,即eip的值
// addr2 --> 跳转地址的值,即_dwNewAddress的值
// 跳转偏移 _dwOffset = addr2 - addr1
BYTE pNewData = {0xe9, 0, 0, 0, 0};
DWORD dwNewDataSize = 5;
DWORD dwOffset = 0;
// 计算跳转偏移
dwOffset = (DWORD)NewMessageBoxA - ((DWORD)OldMessageBoxA + 5);
::RtlCopyMemory(&pNewData, &dwOffset, sizeof(dwOffset));
#else
// 64位
// 汇编代码:mov rax, _dwNewAddress(0x1122334455667788)
// jmp rax
// 机器码是:
// 48 b8 _dwNewAddress(0x1122334455667788)
// ff e0
BYTE pNewData = { 0x48, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xe0};
DWORD dwNewDataSize = 12;
ULONGLONG ullNewFuncAddr = (ULONGLONG)NewMessageBoxA;
::RtlCopyMemory(&pNewData, &ullNewFuncAddr, sizeof(ullNewFuncAddr));
#endif
// 设置页面的保护属性为 可读、可写、可执行
DWORD dwOldProtect = 0;
::VirtualProtect(OldMessageBoxA, dwNewDataSize, PAGE_EXECUTE_READWRITE, &dwOldProtect);
// 保存原始数据
::RtlCopyMemory(g_pOldData, OldMessageBoxA, dwNewDataSize);
// 开始修改 MessageBoxA 函数的前几字节数据, 实现 Inline Hook API
::RtlCopyMemory(OldMessageBoxA, pNewData, dwNewDataSize);
// 还原页面保护属性
::VirtualProtect(OldMessageBoxA, dwNewDataSize, dwOldProtect, &dwOldProtect);
return TRUE;
}
// Unhook Api
BOOL UnhookApi_MessageBoxA()
{
// 获取 user32.dll 模块加载基址
HMODULE hDll = ::GetModuleHandle("user32.dll");
if (NULL == hDll)
{
return FALSE;
}
// 获取 MessageBoxA 函数的导出地址
PVOID OldMessageBoxA = ::GetProcAddress(hDll, "MessageBoxA");
if (NULL == OldMessageBoxA)
{
return FALSE;
}
// 计算写入的前几字节数据, 32位下5字节, 64位下12字节
#ifndef _WIN64
DWORD dwNewDataSize = 5;
#else
DWORD dwNewDataSize = 12;
#endif
// 设置页面的保护属性为 可读、可写、可执行
DWORD dwOldProtect = 0;
::VirtualProtect(OldMessageBoxA, dwNewDataSize, PAGE_EXECUTE_READWRITE, &dwOldProtect);
// 恢复数据
::RtlCopyMemory(OldMessageBoxA, g_pOldData, dwNewDataSize);
// 还原页面保护属性
::VirtualProtect(OldMessageBoxA, dwNewDataSize, dwOldProtect, &dwOldProtect);
return TRUE;
}
// 新的 API
int WINAPI NewMessageBoxA(
HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption,// message box title
UINT uType // message box style
)
{
// Unhook
UnhookApi_MessageBoxA();
// 获取 user32.dll 模块加载基址
HMODULE hDll = ::GetModuleHandle("user32.dll");
if (NULL == hDll)
{
return FALSE;
}
// 获取 MessageBoxA 函数的导出地址
typedef_MessageBoxA OldMessageBoxA = (typedef_MessageBoxA)::GetProcAddress(hDll, "MessageBoxA");
if (NULL == OldMessageBoxA)
{
return FALSE;
}
int iRet = OldMessageBoxA(hWnd, "I am Nobody!!!", "Who Am I", MB_YESNO);
// Hook
HookApi_MessageBoxA();
return iRet;
}
页:
[1]
2