我是新来的,我的第一个问题就是问了。我希望能在这里相处得很好:) 对于我的问题!:
我为x64处理器(普通的intel x64)编写了一个Detouring基础设施
主要有趣的功能如下:
typedef ULONG_PTR (WINAPI *MESSAGEBOX)(HWND, LPCSTR, LPCSTR, UINT);
DWORD WINAPI DETOUR_MyMessageboxA(MESSAGEBOX OriginalFunction, HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
OutputDebugPrintA("Success.");
return OriginalFunction(hWnd, lpText, lpCaption, uType);
}
当我绕道MessageBoxA时,我编写了以下ASM代码:
push rdi
push r9
sub rsp, 20
mov rdi, rsp
mov r9, r8
mov r8, rdx
mov rdx, ecx
mov ecx, [ORIGINAL_ADDRESS]
call DETOUR_MyMessageboxA
add rsp, 20
pop r9
pop rdi
ret
这个想法基本上是'#右移'"参数并向绕道添加另一个参数(我的原始函数地址)。 我希望我做对了,调用约定如下:
First Arg: RCX
Second Arg: RDX
第三个Arg: R8
第四个Arg: R9
rsp中的更多内容(在"影子空间"东西下)
只需确保与所有人在同一页面上..在调用函数之前,堆栈应该如下所示:
GARBAGE.....
RSP RetAddress
8BYTE-GARBAGE - [Shadow space]
8BYTE-GARBAGE - [Shadow space]
8BYTE-GARBAGE - [Shadow space]
8BYTE-GARBAGE - [Shadow space]
Arg5
Arg6
...
现在,在我开始绕道而且调用我的汇编代码而不是原始函数之后,我得到了一个例外:
0:000> g
(624.17b4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
ntdll!RtlCaptureContext+0x86:
00000000`76d508c5 0fae8100010000 fxsave [rcx+100h] ds:00000000`0026ead8=50
0:000> k
Child-SP RetAddr Call Site
00000000`0026e998 00000000`76d195c8 ntdll!RtlCaptureContext+0x86
00000000`0026e9a8 000007fe`fccc940d ntdll!RtlRaiseException+0x48
00000000`0026efe8 000007fe`fccdaa0d KERNELBASE!RaiseException+0x39
00000000`0026f0b8 000007fe`f6ec2c7a KERNELBASE!OutputDebugStringA+0x6d
00000000`0026f388 00000000`0014002f Detour_RekSai!DETOUR_MyMessageboxA+0x3a [c:\projects\test.c @ 14]
00000000`0026f3b8 00000000`00130000 0x14002f
00000000`0026f3c0 00000000`00000000 0x130000
0:000> !vprot 00000000`0026ead8
BaseAddress: 000000000026e000
AllocationBase: 00000000001f0000
AllocationProtect: 00000004 PAGE_READWRITE
RegionSize: 0000000000002000
State: 00001000 MEM_COMMIT
Protect: 00000004 PAGE_READWRITE
Type: 00020000 MEM_PRIVATE
0:000> db rcx+100 L20
00000000`0026ead8 50 f0 26 00 00 00 00 00-58 f9 26 00 00 00 00 00 P.&.....X.&.....
00000000`0026eae8 00 00 00 00 00 00 00 00-e9 c9 ec f6 fe 07 00 00 ................
0:000> !gle
LastErrorValue: (NTSTATUS) 0xc0000008 (3221225480) - An invalid HANDLE was specified.
LastStatusValue: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.
现在我不知道是什么导致这个.. 我想我得到了所有的变数并且卡住了..我不是吗? 我不知道这个记忆位置是什么或为什么会发生。
感谢您的帮助..
修改: 如果我删除" OutputDebugPrint"在我的功能:
DWORD WINAPI DETOUR_MyMessageboxA(MESSAGEBOX OriginalFunction, HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
return OriginalFunction(hWnd, lpText, lpCaption, uType);
}
我仍然得到一个例外(另一个例外,但Something告诉我他们都是因为同样的事情而引起的。)
0:000> g
(1e3c.298c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
LPK!LpkCharsetDraw+0x78:
000007fe`fe811775 440f29842450010000 movaps xmmword ptr [rsp+150h],xmm8 ss:00000000`0026ebf8=000007fefe91a8e40000000002051320
0:000> k
Child-SP RetAddr Call Site
00000000`0026eaa8 000007fe`fe8114cc LPK!LpkCharsetDraw+0x78
00000000`0026ec68 00000000`76af85c5 LPK!LpkDrawTextEx+0x68
00000000`0026ecd8 00000000`76af87fc USER32!DT_DrawStr+0xa6
00000000`0026ed78 00000000`76af8216 USER32!DT_GetLineBreak+0x241
00000000`0026ee28 00000000`76b51e07 USER32!DrawTextExWorker+0x3f8
00000000`0026ef38 00000000`76b523e9 USER32!MB_CalcDialogSize+0x187
00000000`0026efd8 00000000`76b51c15 USER32!SoftModalMessageBox+0x47d
00000000`0026f108 00000000`76b5146b USER32!MessageBoxWorker+0x31d
00000000`0026f2c8 00000000`76b51362 USER32!MessageBoxTimeoutW+0xb3
00000000`0026f398 000007fe`ecfe2c85 USER32!MessageBoxW+0x4e
00000000`0026f3d8 00000000`0015002f Detour_RekSai!DETOUR_MyMessageboxA+0x45 [c:\users\ariel\documents\visual studio 2012\projects\detour_reksai\detour_reksai\test.c @ 19]
00000000`0026f408 00000000`00140000 0x15002f
00000000`0026f410 00000000`00000000 0x140000
0:000> !vprot [rsp+150h]
BaseAddress: 000000000026e000
AllocationBase: 00000000001f0000
AllocationProtect: 00000004 PAGE_READWRITE
RegionSize: 0000000000002000
State: 00001000 MEM_COMMIT
Protect: 00000004 PAGE_READWRITE
Type: 00020000 MEM_PRIVATE
0:000> db [rsp+150h] L20
00000000`0026ebf8 20 13 05 02 00 00 00 00-e4 a8 91 fe fe 07 00 00 ...............
00000000`0026ec08 01 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0:000> !gle
LastErrorValue: (Win32) 0 (0) - The operation completed successfully.
LastStatusValue: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.
答案 0 :(得分:1)
您可能错过了这一行:This exception may be expected and handled.
报告的例外来自OutputDebugPrintA
,我怀疑这与你的绕行逻辑有很大关系。确保这是一个真正未处理的例外。
PS:不确定你想用mov edi, esp
做什么。
根据评论,您的问题似乎是rsp
错位。你应该保持16字节对齐。在这种情况下,您正在推送2个项目(值16个字节)然后调整32,最后您有一个call
,它在堆栈上放置8个字节的返回地址。总而言之,您有8个字节的错位。由于在此代码中您不需要rdi
,因此您可以简单地省略push
/ pop
,从而修复错位。此外,使用mov
可以使情况更加清晰:
sub rsp, 28h
mov [rsp+20h], r9
mov r9, r8
mov r8, rdx
mov rdx, rcx
mov ecx, [ORIGINAL_ADDRESS]
call DETOUR_MyMessageboxA
add rsp, 28h
ret
我应该如何实现一个让我们说5变量函数绕道?
mov rax, [rsp+28h] ; 5th arg
sub rsp, 38h ; space for 6 args + alignment
mov [rsp+28h], rax
mov [rsp+20h], r9
mov r9, r8
mov r8, rdx
mov rdx, rcx
mov ecx, [ORIGINAL_ADDRESS]
call DETOUR
add rsp, 38h
ret