Log in

View Full Version : Digging into RtlRemoteCall..by BanMe


BanMe
June 23rd, 2009, 20:49
ok so my current problem requires that I delve into RtlRemoteCall, as I am using it as the ThreadDispatcher for my recycling routine in my server..
and it is return a nasty error 0x80000002.. Another form of DATA_TYPE_MISALIGNMENT.. similiar to the error with Native_MapModule that some might remember..

the Problem occurs with the way im calling RtlRemoteCall. I'm sure that it has to do with the way im passing in the parameter for Native_AcceptConnectionRequest routine, I think I should just copy it to a PAGE_SIZE aligned heap and and then pass it..but im gonna try a harder approach and see if i can get the answer.

so rather then bore you with my assumptions and guess's, Im going to do a actual analysis of the function call with olly. but in order to due this I need to place a breakpoint on RtlRemoteCall before it is called.. Olly provides just such a mechanism for the user..ie Make First Pause at System Breakpoint or Break on new module(dll) in the debugging options both provide time before the actual exe is loaded in order to place breakpoints.

we simply right click when it break click goto->Expression and type RtlRemoteCall and then place a breakpoint.

and seeing how RtlRemoteCall is only executed after the first client has completed communication and a new client is making a connection request we must follow follow the execution of the first client and then restart the client when finished.. in order to successfully break on RtlRemoteCall..

*update*

ok so i taught myself how to use windbg.. and did a lil research in debugger.chm

windbg acts totally different then olly in that i can find no options to tell it where to breakpoint on load. it always seems to breakpoint at system breakpoint right before LdrInitializeProcess() but im guessing that is how its supposed to act..

so instead of the method described above for olly, I used this method to set a breakpoint with windbg click f9 then in "command" type "bp ntdll!RtlRemoteCall" and luckily windbg handles the connection of clients seamlessly

so after analyzing RtlRemoteCall and seeing that it actually succeeds in redirecting the local thread to Native_AcceptConnectionRequest,but sadly it mangles the ACCEPT_PARAMS that are passed to the function in the process...on this note Im still not sure how, or why at the moment..im to tired to continue now, but there will be definitly more on this tommorow.

regards BanMe

Kayaker
June 23rd, 2009, 22:13
Would a VMWare/Remote WinDbg session and simple bp not work? You might even be able to debug it at the native level rather than compiling as subsystem:windows.

kd> bp ntdll!RtlRemoteCall


*update*

Once again you updated your post as I was replying

BanMe
June 23rd, 2009, 22:16
Here is the output of the call to RtlRemoteCall to for any who are more expierenced then me to look at



Breakpoint 0 hit
7c964caa 8bff mov edi,edi
7c964cac 55 push ebp
7c964cad 8bec mov ebp,esp
7c964caf 81ecf4020000 sub esp,0x2f4
7c964cb5 837d1404 cmp dword ptr [ebp+0x14],0x4 ss:0023:0012fd04=00000001
7c964cb9 a1c8e0977c mov eax,[ntdll!__security_cookie (7c97e0c8)] ds:0023:7c97e0c8=0000df18
7c964cbe 8945fc mov [ebp-0x4],eax ss:0023:0012fcec=ffffffff
7c964cc1 8b4510 mov eax,[ebp+0x10]{CSRARSS!Native_AcceptConnectionRequest (00401dc0)} ss:0023:0012fd00=00401dc0
7c964cc4 56 push esi
7c964cc5 8b7508 mov esi,[ebp+0x8] ss:0023:0012fcf8=ffffffff
7c964cc8 57 push edi
7c964cc9 8b7d0c mov edi,[ebp+0xc] ss:0023:0012fcfc=fffffffe
7c964ccc 898520fdffff mov [ebp-0x2e0]{ntdll!RtlInitUnicodeString (7c901295)},eax ss:0023:0012fa10=7c901295
7c964cd2 8b4518 mov eax,[ebp+0x18] ss:0023:0012fd08=0012fd20
7c964cd5 89b524fdffff mov [ebp-0x2dc],esi ss:0023:0012fa14=001529c0
7c964cdb 89bd2cfdffff mov [ebp-0x2d4]{kernel32!_imp___wcsnicmp <PERF> (kernel32+0x0) (7c800000)},edi ss:0023:0012fa1c=7c800000
7c964ce1 898528fdffff mov [ebp-0x2d8],eax ss:0023:0012fa18=00403c2c
7c964ce7 760a jbe ntdll!RtlRemoteCall+0x49 (7c964cf3) [br=1]
7c964cf3 807d2000 cmp byte ptr [ebp+0x20],0x0 ss:0023:0012fd10=01
7c964cf7 7510 jnz ntdll!RtlRemoteCall+0x5f (7c964d09) [br=1]
7c964d09 53 push ebx
7c964d0a 8d8530fdffff lea eax,[ebp-0x2d0] ss:0023:0012fa20=00001000
7c964d10 50 push eax
7c964d11 57 push edi
7c964d12 c78530fdffff07000100 mov dword ptr [ebp-0x2d0],0x10007 ss:0023:0012fa20=00001000
7c964d1c e88d86faff call ntdll!ZwGetContextThread (7c90d3ae)
7c90d3ae b855000000 mov eax,0x55
7c90d3b3 ba0003fe7f mov edx,0x7ffe0300
7c90d3b8 ff12 call dword ptr [edx]{ntdll!KiFastSystemCall (7c90e510)} ds:0023:7ffe0300=7c90e510
7c90e510 8bd4 mov edx,esp
7c90e512 0f34 sysenter
7c90d3ba c20800 ret 0x8
7c964d21 8bd8 mov ebx,eax
7c964d23 85db test ebx,ebx
7c964d25 7d15 jge ntdll!RtlRemoteCall+0x92 (7c964d3c) [br=1]
7c964d3c 807d1c00 cmp byte ptr [ebp+0x1c],0x0 ss:0023:0012fd0c=00
7c964d40 8b9df4fdffff mov ebx,[ebp-0x20c] ss:0023:0012fae4=0012f9e0
7c964d46 7447 jz ntdll!RtlRemoteCall+0xe5 (7c964d8f) [br=1]
7c964d8f 8b4d14 mov ecx,[ebp+0x14] ss:0023:0012fd04=00000001
7c964d92 8dbd0cfdffff lea edi,[ebp-0x2f4] ss:0023:0012f9fc=00010007
7c964d98 8bb528fdffff mov esi,[ebp-0x2d8] ss:0023:0012fa18=0012fd20
7c964d9e 8b4514 mov eax,[ebp+0x14] ss:0023:0012fd04=00000001
7c964da1 f3a5 rep movsd ds:0012fd20=000007e8 es:0012f9fc=00010007
7c964da3 33ff xor edi,edi
7c964da5 3bc7 cmp eax,edi
7c964da7 7420 jz ntdll!RtlRemoteCall+0x11f (7c964dc9) [br=0]
7c964da9 57 push edi
7c964daa c1e002 shl eax,0x2
7c964dad 50 push eax
7c964dae 2bd8 sub ebx,eax
7c964db0 8d850cfdffff lea eax,[ebp-0x2f4] ss:0023:0012f9fc=000007e8
7c964db6 50 push eax
7c964db7 53 push ebx
7c964db8 ffb524fdffff push dword ptr [ebp-0x2dc] ss:0023:0012fa14=ffffffff
7c964dbe e8eb91faff call ntdll!ZwWriteVirtualMemory (7c90dfae)
7c90dfae b815010000 mov eax,0x115
7c90dfb3 ba0003fe7f mov edx,0x7ffe0300
7c90dfb8 ff12 call dword ptr [edx]{ntdll!KiFastSystemCall (7c90e510)} ds:0023:7ffe0300=7c90e510
7c90e510 8bd4 mov edx,esp
7c90e512 0f34 sysenter
7c90dfba c21400 ret 0x14
7c964dc3 8bf0 mov esi,eax
7c964dc5 3bf7 cmp esi,edi
7c964dc7 7c26 jl ntdll!RtlRemoteCall+0x145 (7c964def) [br=0]
7c964dc9 8b8520fdffff mov eax,[ebp-0x2e0]{CSRARSS!Native_AcceptConnectionRequest (00401dc0)} ss:7c964dcf 8985e8fdffff mov [ebp-0x218]{ntdll!KiFastSystemCallRet (7c90e514)},eax ss:0023:0012fad8=7c90e514
7c964dd5 8d8530fdffff lea eax,[ebp-0x2d0] ss:0023:0012fa20=00010007
7c964ddb 50 push eax
7c964ddc ffb52cfdffff push dword ptr [ebp-0x2d4] ss:0023:0012fa1c=fffffffe
7c964de2 899df4fdffff mov [ebp-0x20c],ebx ss:0023:0012fae4=0012f9e0
7c964de8 e8c18dfaff call ntdll!NtSetContextThread (7c90dbae)
7c90dbae b8d5000000 mov eax,0xd5
7c90dbb3 ba0003fe7f mov edx,0x7ffe0300
7c90dbb8 ff12 call dword ptr [edx]{ntdll!KiFastSystemCall (7c90e510)} ds:0023:7ffe0300=7c90e510
7c90e510 8bd4 mov edx,esp
7c90e512 0f34 sysenter
CSRARSS!Native_AcceptConnectionRequest+0x1:
00401dc1 8bec mov ebp,esp

BanMe
June 23rd, 2009, 22:31
Sorry kayaker, im a busy bee and update to often..I have alot of time on my hands, and enjoy keeping people updated on my progress..what you suggest does work, but I still expierence the downtime of the VM, doing it my way reduces the cost for me in time and in preciouse resources as I dont have the greatest computer in the world. I know I should be doing my debugging on the Native Application to make sure no bugs slip in there, but Im still working on getting my windbg setup in my VM, im not so expierenced with windbg as you can prolly tell from above.. :}

regards BanMe

Kayaker
June 23rd, 2009, 22:47
Understand, though it's probably quicker to reboot a VM than your system

You probably know this already, but just for reference all you need to set up VMWare/WinDbg for remote debugging is these:

http://silverstr.ufies.org/lotr0/windbg-vmware.html
http://www.catch22.net/tuts/vmware

Also, if you want to speed up remote kernel debugging you could try VirtualKD. (It's an update on Nynaeve's VMKD project). I haven't found the time to try it out yet myself, but would like to.

http://virtualkd.sysprogs.org/

Cheers,
Kayaker

JMI
June 23rd, 2009, 23:52
And the "other" thing you need to do is learn how to correctly make loooooong lists of "code" without running the page forever.

The proper way to do that is to use [] with the word "Code" inside (without the quotes) at the start of the code and the at the end put another [] with whe word "/Code" inside (again without the quotes.

What you did came close. You used [] with Quote and at the end [] with /Quote. That only makes the code indented and a different color and does not create the scroll bars for long and/or wide citations, such as yours.

Just a "head's-up" for next time. I've fixed it for you already.

Regards,

BanMe
June 24th, 2009, 20:55
sorry about that JMI, I cleaned it up a little bit ,and tried to shorten it by removing all of the stack trace information :}

also I know about the Code tags, I use them quite often actually. the only reason I used quote tags was so that I wouldnt have to scroll to go through the code and comment it up a little bit to provide a better overview to others(and myself :/).. but if this is how it is done, then I will do it that way from now on

Regards BanMe

JMI
June 25th, 2009, 08:49
Anyone who is "seriously" interested in studying the code can simply copy and paste such posts by "drag & copy" and then paste it into their own favorite text editor and play with it and/or comment it to their heart's content and then "copy & paste" it into their own Code Quote box in their Reply for anyone who cares to review.

Regards,

BanMe
June 27th, 2009, 21:07
just because it takes me a while to do things does not mean I am not "seriously" interested in analyzing the code it just takes me a while to actually do what I want, and put it all together in a presentable\understandable way.. this does not detract from my longterm interest in the subject. But I guess there is no excuse, so I will not post things I am in process of researching and analyzing without detailed information and analysis from now on..

regards BanMe

dELTA
June 28th, 2009, 07:54
No, no, that's not what JMI meant at all, he just meant that people who want to read the posted code can very well be expected to scroll the "CODE" box (i.e. if they won't bother to do that, they might not be considered as "seriously interested" in the code, that's what he was referring to), while all the other readers wont have to do it when the code is dumped right into the post in its entirety, without any "CODE" box.

Please, continue posting anything you want regarding your interesting project, no problem at all, it's just good if it could result in some extra interest and discussion.

BanMe
June 28th, 2009, 10:54
ahh, I see sorry about the misinterpretation JMI.

so on with the results..

so after digging into it's code and re-reading Alex's Ionescu's old posting about RtlRemoteCall:http://www.alex-ionescu.com/?p=28.. I grasped that RtlRemoteCall can only pass a maximum of 4 ULONG sized parameters..this is not good and is why the Call to Native_AcceptConnectionRequest first call to NtAcceptConnection results in a NTSTATUS of 80000002(DATA_TYPE_MISALIGNMENT).This can be seen in the code above as:

Code:

837d1404 cmp dword ptr [ebp+0x14],0x4 ss:0023:0012fd04=00000001
ebp+14 = 4th parameter(ULONG ParameterCount)


So how do I bypass this inline feature of RtlRemoteCall?

hooks..eww..

I could pass in a pointer to Heap and add error handling for DATA_TYPE_MISALIGNMENT, and overcome it by reading the pointer directly into there associated parameters and recalling the function..

this sounds alot cleaner then hooking :}

alternitivly I could recode RtlRemoteCall's remote oriented behavior into a local oriented function by simply replacing ZwRead\WriteProcessMemory with memcpy\memmove and directly modifying the threads stack location before resuming.

this method would be even cleaner then the previously mentioned alternitive and therefore is what I am going to do.

sorry I didnt really dig into this function, but I think it is self describing and I am going to release a locally similar function. so hopefully that makes up for my lack of total analysis of the funtions behavior.