nonintrusive tracer on x64

Rating: 2 votes, 1.50 average.
Well time has come to dig a little bit into x64 systems, and to move our lovely tools and ideas to that system.

Lets have a look at KiUserExceptionDispatcher from ntdll.dll:

.text:0000000077EF31B0                 public KiUserExceptionDispatcher
.text:0000000077EF31B0 KiUserExceptionDispatcher:              
.text:0000000077EF31B0                 mov     rax, cs:Wow64PrepareForException
.text:0000000077EF31B7                 test    rax, rax
.text:0000000077EF31BA                 jz      short loc_77EF31CB
.text:0000000077EF31BC                 mov     rcx, rsp
.text:0000000077EF31BF                 add     rcx, 4D0h
.text:0000000077EF31C6                 mov     rdx, rsp
.text:0000000077EF31C9                 call    rax ; Wow64PrepareForException
.text:0000000077EF31CB loc_77EF31CB:                         
.text:0000000077EF31CB                 mov     rcx, rsp
.text:0000000077EF31CE                 add     rcx, 4D0h
.text:0000000077EF31D5                 mov     rdx, rsp
.text:0000000077EF31D8                 call    RtlDispatchException
.text:0000000077EF31DD                 test    al, al
.text:0000000077EF31DF                 jz      short loc_77EF31ED
.text:0000000077EF31E1                 mov     rcx, rsp
.text:0000000077EF31E4                 xor     edx, edx
.text:0000000077EF31E6                 call    RtlRestoreContext

Wow64PrepareForException is used only when loading wow64 process, so in "native x64" environment this variable is set to 0, and we can use that variable to write our own SEH handler in asm or nonintrusive tracer. Well let's cut to the point and see some real code:

                        mov     rax, KiUserExceptionDispatcher
                        xor     rbx, rbx
                        mov     ebx, dword ptr[rax+3]
                        add     rbx, rax
                        add     rbx, 7

                        mov     rax, offset __mykiuser
                        mov     [rbx], rax
                        xor     rax, rax
                        mov     [rax], rax
                        xor     r9, r9
                        mov     r8, offset szntdll
                        mov     rdx, offset szkiuser
                        mov     rcx, 0
                        callW   MessageBoxA
                        xor     rcx, rcx
                        callW   ExitProcess
__mykiuser:             add     qword ptr[rdx+0F8h], 3
                        mov     rcx, rdx
                        xor     rdx, rdx
                        callW   RtlRestoreContext
If everything worked as planned, MessageBoxA will be shown... simple isn't it

Submit "nonintrusive tracer on x64" to Digg Submit "nonintrusive tracer on x64" to Submit "nonintrusive tracer on x64" to StumbleUpon Submit "nonintrusive tracer on x64" to Google