在我调用Detoured函数后,应用程序崩溃我创建了@ Win7-x64

时间:2014-12-29 13:27:04

标签: c assembly 64-bit windbg x86-64

我是新来的,我的第一个问题就是问了。我希望能在这里相处得很好:) 对于我的问题!:

我为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.

1 个答案:

答案 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