使用 Microsoft Detours 时出现访问冲突
Access violation when using Microsoft Detours
我在使用 Microsoft Detours 时遇到访问冲突问题。我制作了一个加载到第三方应用程序中的 dll。我正在使用 Detours 制作一个蹦床函数到一个未记录的函数,Ida Pro 显示为:
void __thiscall sub_6142E0(int a2, int a3)
我的代码如下所示:
#include "stdafx.h"
#包括
#include
typedef void(__stdcall* pFunc)(int d1, int d2);
pFunc FuncToDetour = (pFunc)(0x6142EC);
void MyFunc(int d1, int d2)//Function does not mach call convension __thiscall. Possible problem?
{
printf("a2 %i, a1 %i);\n", d1, d2);
FuncToDetour(d1, d2);
}
void Init()
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)FuncToDetour, MyFunc);
DetourTransactionCommit();
}
我要拦截的函数原程序集是这样的:
sub_6142E0 proc near
arg_0= dword ptr 8
arg_4= dword ptr 0Ch
push ebp
mov ebp, esp
mov eax, [ecx+8]
mov ecx, [ebp+arg_4]
mov edx, [ebp+arg_0]
Detours 所做的更改导致:
.text:006142EC jmp near ptr unk_F9C6802
...
d3d9.dll:0F9C6802 jmp near ptr unk_F9D5FE0 //jump to function in my dll
...
void MyFunc(int d1, int d2)//my function
{
printf("updateHealth(%i, %i);\n", d1, d2);
}
...
Stack[00004A8C]:0019FB4C sub ah, bh
Stack[00004A8C]:0019FB4E sbb [eax], eax //eax=0x491B -> access violation
Stack[00004A8C]:0019FB50 cmc
Stack[00004A8C]:0019FB51 inc si
Stack[00004A8C]:0019FB53 add [eax], dl
Stack[00004A8C]:0019FB55 add [eax], eax
Stack[00004A8C]:0019FB57 add [eax+80019FDh], cl
Stack[00004A8C]:0019FB5D add byte_19FC6415[eax], dh
Stack[00004A8C]:0019FB5D ; -------------------------------------------------
我收到的错误信息是:
The instruction 0x19FB4E referenced memory at 0x491B. The memory could not be written -> 0000491B (exc.code c0000005, tid 19084)
我将尝试回答我自己的问题。
这归结为两个函数之间的调用约定不匹配。我要挂接的函数使用 __thiscall and my function is using __cdecl(默认调用约定)。 __thiscall 用作 class 中成员函数的调用约定,其中 "this pointer" 在调用成员函数时在 ecx 寄存器中传递。
ecx 在我的例子中是在调用 MyFunc 时写入的,以便设置堆栈框架(我认为)。当我从我的 trampoline 函数中调用它时,我挂接的函数将得到一个无效的 this 指针。
查看此 link 以获得有关如何正确完成此操作的一些解释和示例。
我在使用 Microsoft Detours 时遇到访问冲突问题。我制作了一个加载到第三方应用程序中的 dll。我正在使用 Detours 制作一个蹦床函数到一个未记录的函数,Ida Pro 显示为:
void __thiscall sub_6142E0(int a2, int a3)
我的代码如下所示: #include "stdafx.h" #包括 #include
typedef void(__stdcall* pFunc)(int d1, int d2);
pFunc FuncToDetour = (pFunc)(0x6142EC);
void MyFunc(int d1, int d2)//Function does not mach call convension __thiscall. Possible problem?
{
printf("a2 %i, a1 %i);\n", d1, d2);
FuncToDetour(d1, d2);
}
void Init()
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)FuncToDetour, MyFunc);
DetourTransactionCommit();
}
我要拦截的函数原程序集是这样的:
sub_6142E0 proc near
arg_0= dword ptr 8
arg_4= dword ptr 0Ch
push ebp
mov ebp, esp
mov eax, [ecx+8]
mov ecx, [ebp+arg_4]
mov edx, [ebp+arg_0]
Detours 所做的更改导致:
.text:006142EC jmp near ptr unk_F9C6802
...
d3d9.dll:0F9C6802 jmp near ptr unk_F9D5FE0 //jump to function in my dll
...
void MyFunc(int d1, int d2)//my function
{
printf("updateHealth(%i, %i);\n", d1, d2);
}
...
Stack[00004A8C]:0019FB4C sub ah, bh
Stack[00004A8C]:0019FB4E sbb [eax], eax //eax=0x491B -> access violation
Stack[00004A8C]:0019FB50 cmc
Stack[00004A8C]:0019FB51 inc si
Stack[00004A8C]:0019FB53 add [eax], dl
Stack[00004A8C]:0019FB55 add [eax], eax
Stack[00004A8C]:0019FB57 add [eax+80019FDh], cl
Stack[00004A8C]:0019FB5D add byte_19FC6415[eax], dh
Stack[00004A8C]:0019FB5D ; -------------------------------------------------
我收到的错误信息是:
The instruction 0x19FB4E referenced memory at 0x491B. The memory could not be written -> 0000491B (exc.code c0000005, tid 19084)
我将尝试回答我自己的问题。
这归结为两个函数之间的调用约定不匹配。我要挂接的函数使用 __thiscall and my function is using __cdecl(默认调用约定)。 __thiscall 用作 class 中成员函数的调用约定,其中 "this pointer" 在调用成员函数时在 ecx 寄存器中传递。
ecx 在我的例子中是在调用 MyFunc 时写入的,以便设置堆栈框架(我认为)。当我从我的 trampoline 函数中调用它时,我挂接的函数将得到一个无效的 this 指针。
查看此 link 以获得有关如何正确完成此操作的一些解释和示例。