snoopy Posted July 23, 2012 Posted July 23, 2012 Hey guys,Small question, I've read the anti-debug reference from Peter Ferrie which goes into detail about tons of anti-debug tricks.Now what I am facing is the following.I am searching for a good way to hook NtQueryInformationProcess.Atm:;-------------------------------------------------------;Original instruction 6 bytes long:;ntdll!NtQueryInformationProcess:;774efa78 b816000000 mov eax,16h;774efa7d 33c9 xor ecx,ecx;-------------------------------------------------------NtQueryInformationProcessHook:mov eax,16hxor ecx,ecxpushfdcmp B[esp+0Ch],07h ;ProcesDebugPort 0x7jne >CheckProcesDebugFlagsmov B[esp+0Ch],00hCheckProcesDebugFlags:cmp B[esp+0Ch], 1Fh ;check ProcesDebugFlagsjne >CheckProcessDebugObjectHandlemov B[esp+0Ch],00hCheckProcessDebugObjectHandle:cmp B[esp+0Ch], 1Eh ;check ProcessDebugObjectHandlejne >EndOfNtQuerymov B[esp+0Ch],00hEndOfNtQuery:popfdnopnopBasicly what it does is wipe the the value on the stack before the actual call to NtQueryInformationProcess is done.The problem is when I code a small program which checks the process debug port it works fine.But I also discovered on a lot of protectors, VMProtect etc.. it doesn't work right.Most plugins are doing it different than I am doing, but since I don't have the source codes I am trying to discover why theyare doing it different, what part of hooking NtQueryInformationProcess am I missing.
Peter Ferrie Posted July 23, 2012 Posted July 23, 2012 there are two things wrong here. one is that you're missing the check for the process ID - that what's being queried is what's being debugged. the other is that if you arbitrarily change the class, you might have the wrong buffer size and corrupt memory.
snoopy Posted July 23, 2012 Author Posted July 23, 2012 Peter, thanks for your reply. What happened when arbitarily changing the class the return value is 0xc0000004 --> STATUS_INFO_LENGTH_MISMATCH.The that's what's being queried is what's being debugged makes sense. But the buffer and size isn't.Would this mean, you let the call go, than check the buffer for the return value and change the returned value. Because when the call is made the pointer to the buffer and size of the bufferare initialized before the call is made.
Peter Ferrie Posted July 28, 2012 Posted July 28, 2012 okay, so the message that you're seeing is because the buffer size is wrong for the class that you supplied.you should allow the original call to proceed, so that intentionally invalid parameters will get the expected failure (because it's a common detection method), but if the call succeeds, then you alter the results to hide your presence.
waliedassar Posted July 29, 2012 Posted July 29, 2012 I see that you are replacing the "ProcessInformationClass" parameter (if it is ProcessDebugPort, ProcessDebugObjectHandle, or ProcessDebugFlags) with zero (ProcessBasicInformation). The problem is that you don't modify the rest of parameters according to the new Process information class which results into an error in the return value.If you wanna keep the same code you have to use a well-chosen neutral "ProcessInformationClass" value. Below was taken from my "HookSysCalls" OllyDbg plugin (in Wow64).00280000 83F8 0A CMP EAX,0A00280003 75 1E JNZ CheckNtQueryInformationProcess00280005 837C24 0C 11 CMP DWORD PTR SS:[ESP+C],110028000A 75 17 JNZ CheckNtQueryInformationProcess0028000C C74424 0C 0F0000>MOV DWORD PTR SS:[ESP+C],0F00280014 B8 19000000 MOV EAX,1900280019 C74424 08 FFFFFF>MOV DWORD PTR SS:[ESP+8],-100280021 EB 5D JMP EmulationThunkCheckNtQueryInformationProcess:00280023 83F8 16 CMP EAX,1600280026 75 58 JNZ EmulationThunk00280028 837C24 0C 07 CMP DWORD PTR SS:[ESP+C],70028002D 74 49 JE ProcessDebugPort0028002F 837C24 0C 1E CMP DWORD PTR SS:[ESP+C],1E00280034 74 09 JE ProcessDebugObjectHandle00280036 837C24 0C 1F CMP DWORD PTR SS:[ESP+C],1F0028003B 74 1C JE ProcessDebugFlags0028003D EB 41 JMP EmulationThunkProcessDebugObjectHandle:0028003F 50 PUSH EAX00280040 8B4424 14 MOV EAX,DWORD PTR SS:[ESP+14]00280044 85C0 TEST EAX,EAX00280046 74 06 JE SHORT 0028004E00280048 C700 00000000 MOV DWORD PTR DS:[EAX],00028004E C74424 18 000000>MOV DWORD PTR SS:[ESP+18],000280056 58 POP EAX00280057 EB 1F JMP ProcessDebugPortProcessDebugFlags:00280059 50 PUSH EAX0028005A 8B4424 14 MOV EAX,DWORD PTR SS:[ESP+14]0028005E 85C0 TEST EAX,EAX00280060 74 06 JE SHORT 0028006800280062 C700 01000000 MOV DWORD PTR DS:[EAX],100280068 58 POP EAX00280069 B8 19000000 MOV EAX,190028006E C74424 0C 0F0000>MOV DWORD PTR SS:[ESP+C],0F00280076 EB 08 JMP EmulationThunkProcessDebugPort:00280078 C74424 0C 160000>MOV DWORD PTR SS:[ESP+C],16EmulationThunk:00280080 EA 1E27AD74 3300 JMP FAR 0033:74AD271E ; Far jumpYou can find the plugin here./>http://code.google.com/p/myollyplugins/downloads/detail?name=HookSysCalls.dllIts source code can also be found here./>http://code.google.com/p/myollyplugins/downloads/detail?name=HookSysCalls.rarN.B. The ZwQueryInformationProcess/ZwSetInformationThread tricks are typically used this way./>http://pastebin.com/sArnNGBN/>http://code.google.com/p/ollytlscatch/downloads/detail?name=HookMe.exe
Peter Ferrie Posted August 3, 2012 Posted August 3, 2012 but you still fail to deal with intentionally invalid parameters:00280048 C700 00000000 MOV DWORD PTR DS:[EAX],0has an issue with non-writable memory.You also lack the verification of the PID (or it's not visible in the code, anyway).Sometimes, a debugger is present for proper reasons, and so the query should succeed without interference.It's simply easier and safer to allow the OS to perform the original call and modify the returned information if it succeeds.
LCF-AT Posted August 11, 2012 Posted August 11, 2012 @ waliedassar Short question about your plugin HookSysCalls 0.1.So could you maybe add a enable / disable menu + plugin into Olly ini info? - Auto Patch - Patch Like this I mean.Auto Patch press = On for ever and another press = Off again for ever.Patch = One time session patch.Something like this you know.On this way it would patch it automaticly after loading a target in Olly without to choose it each time manually.Would be nice if you could add this little feature too maybe. [Plugin HookSysCalls]AutoPatch=0[Plugin HookSysCalls]AutoPatch=1 Thank you
snoopy Posted August 26, 2012 Author Posted August 26, 2012 Thanks for all the information guys. Sorry for my late reply, been out for a vacation period.I've succesfully changed my code according to what Peter suggested. It seems to work really well and the code is rather short.Changing the return value / values in the buffer works nicely.The plugin I am working on is designed for WinDBG. I will release my source when I get some gui in.There is one odd behaviour I came across when patching the BeingDebuggedFlag using: eb $peb+0x2 00.The problem that occurs is that WinDBG after the patching has problems breaking back into the code. Sometimes it takes up to 30 seconds beforeit breaks back into the process. I am on Windows 7 Proffesional 64 bit does it has anything to do with that?
Peter Ferrie Posted September 3, 2012 Posted September 3, 2012 some Windows APIs rely on the value in that location in order to recognise the debugger and then do debugger-specific things.however, you might have a better experience with a different debugger.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now