Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ---------------------------------------------------
- Antidebugging for (m)asses - protecting the env.
- ---------------------------------------------------
- written by Piotr Bania <bania.piotr@gmail.com>
- [___ http://pb.specialised.info ___]
- -----------------
- 0. DISCLAIMER
- -----------------
- Author takes no responsibility for any actions with provided information
- or codes. The copyright for any material created by the author is reserved.
- Any duplication of codes or texts provided here in electronic or printed
- publications (including compiled code) is not permitted without the author's
- agreement.
- -----------------
- I. INTRODUCTION
- -----------------
- The number of computer hackers/crackers has reached a very high level recently.
- Currently it is very hard to develop product which will be secure against
- those type of people, to be const-stricto it is surely impossible. However,
- why not make their dirty work harder and give them some more, so lets take a
- look of few new antidebugging methods/techniques.
- On the other hand it can help malware/virus researchers understand
- and analyse latest bad stuff. Enjoy!
- NOTE: Following examples were created/researched/tested on windows xp box
- it is possible that they will not work on other windows systems.
- -----------------
- II. EXAMPLES
- -----------------
- ----------------------
- [+] Example 01h
- ----------------------
- Affects (works on): All so-called SEH debuggers (tested on Ollydbg and Windbg).
- Note: Following example requires administrator privileges for well known
- reasons. In fact it doesn't affects scale of its severity much, because
- administrator privileges are required to use some debugger features, so
- if one wants to use all debug stuff it needs to run as admin.
- Generally after researching few things inside windows kernel, I found that it is
- possible to open CSRSS.EXE (client server runtime process - system process),
- while application is being debugged. Have a look at this code (I believe it will make it
- hell easier to understand):
- ----// SNIP SNIP //---------------------------------------------------------
- push <CSRSS_PID> ; pid
- push 0 ; Inheritable = FALSE
- push 0C3Ah ; access flags=CREATE_THREAD|VM_OPERATION|VM_READ|VM_WRITE
- ; \ |QUERY_INFORMATION|800
- @callx OpenProcess
- test eax,eax
- jz @we_are_not_debugged
- @evil_me: ; <- execution flows here when debugger is attached
- int 3
- @we_are_not_debugged: ; well no SEH debugger detected or not enough privileges
- ----// SNIP SNIP //---------------------------------------------------------
- Like I said before when application is debugged it is able to open CSRSS.EXE and it this
- case OpenProcess will not fail (of course I guess I don't have to remind you about
- privileges). What's more, look at the rights which we have used to open target process,
- *yuck* - debugged application has full control of CSRSS.EXE! The last thing I have figured
- out that a special native API exists exported by ntdll used to grab pid of CSRSS named as
- CsrGetProcessId.
- (microsoft windows xp sp1 output)
- E:\asm>find ntdll.dll CsrGetProcessId
- ------------------------------------------------------------
- Little GetProcAddress Utility
- coded by Piotr Bania <bania.piotr@gmail.com>
- ------------------------------------------------------------
- * ntdll.dll base addr at: 0x77F50000
- + CsrGetProcessId has address: 0x77F5EF76
- ------------------------------------------------------------
- If you don't want to execute CsrGetProcessId you can emulate it
- (address hard coded for microsoft windows xp sp1), like this example shows:
- ----// SNIP SNIP //---------------------------------------------------------
- mov eax,077FC46A4h ; ntdll variable where CSRSS pid is stored
- xchg eax,[eax] ; EAX=now CSRSS pid
- ----// SNIP SNIP //---------------------------------------------------------
- Following example (when debugged) causes BSOD because its creating a thread inside of
- client server runtime process at not existing location:
- ----// SNIP SNIP //---------------------------------------------------------
- mov eax,077F5EF76h
- call eax ; execute CsrGetProcessId, returns CSRSS pid
- push eax
- push 0
- push 0C3Ah
- @callx OpenProcess ; open CSRSS process
- test eax,eax
- jz exit ; opening failed
- call a
- dd 0
- a:
- push 0
- push 0
- push 0
- push 1234567h ; yep, it doesn't exist...
- push 0
- push 0
- push eax
- @callx CreateRemoteThread ; creates a thread inside of process, *BSOD*
- exit:
- push 0
- @callx ExitProcess
- ----// SNIP SNIP //---------------------------------------------------------
- Well I hope you enjoyed this one, so lets think about another example.
- ----------------------
- [+] Example 02h
- ----------------------
- The XP series provides magic API called CheckRemoteDebuggerPresent (well generally it
- provides a lot of new debug features), and like the name suggests it is used to check if
- debugger is present.
- E:\asm>find kernel32.dll CheckRemoteDebuggerPresent
- ------------------------------------------------------------
- Little GetProcAddress Utility
- coded by Piotr Bania <bania.piotr@gmail.com>
- ------------------------------------------------------------
- * kernel32.dll base addr at: 0x77E60000
- + CheckRemoteDebuggerPresent has address: 0x77EB582B
- ------------------------------------------------------------
- Few words from MSDN about this function:
- (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/
- \ debugactiveprocessstop.asp)
- ----
- CheckRemoteDebuggerPresent
- The CheckRemoteDebuggerPresent function determines whether the specified process
- is being debugged.
- BOOL CheckRemoteDebuggerPresent(
- HANDLE hProcess,
- PBOOL pbDebuggerPresent
- );
- Parameters
- hProcess - [in] Handle to the process.
- pbDebuggerPresent - [in, out] Pointer to a variable that the function sets to
- - TRUE if the specified process is being debugged, or FALSE otherwise.
- Return Values
- If the function succeeds, the return value is nonzero.
- If the function fails, the return value is zero. To get extended error information,
- call GetLastError.
- ----
- And here is a little code for this example:
- ----// SNIP SNIP //---------------------------------------------------------
- push offset is_present ; our variable
- push -1 ; process handle
- mov eax,077EB582Bh
- call eax ; execute CheckRemoteDebuggerPresent
- mov eax,dword ptr [is_present]
- test eax,eax
- jz @we_are_not_debugged ; no debugger found
- @we_are_debugged: ; execution flows here when debugger is attached
- int 3
- is_present dd 0
- ----// SNIP SNIP //---------------------------------------------------------
- Or if you prefer emulated way (by using NtQueryInformationProcess):
- E:\asm>find ntdll.dll NtQueryInformationProcess
- ------------------------------------------------------------
- Little GetProcAddress Utility
- coded by Piotr Bania <bania.piotr@gmail.com>
- ------------------------------------------------------------
- * ntdll.dll base addr at: 0x77F50000
- + NtQueryInformationProcess has address: 0x77F5BDD8
- ------------------------------------------------------------
- And here comes a little emulation example:
- ----// SNIP SNIP //---------------------------------------------------------
- lea eax,our_process_handle
- push eax
- mov ebx,esp
- push 0
- push 4
- push ebx
- push 7
- push dword ptr [eax]
- mov eax,077F5BDD8h
- call eax ; execute NtQueryInformationProcess
- pop ecx
- test eax,eax
- jl exit
- cmp ecx,0
- jge @we_are_not_debugged
- int 3 ; yes we are debugged!
- @we_are_not_debugged: ; no debugger detected
- exit:
- push 0
- @callx ExitProcess
- our_process_handle dd -1
- ----// SNIP SNIP //---------------------------------------------------------
- Now lets turn the page to another 3rd example.
- ----------------------
- [+] Example 03h
- ----------------------
- Many times Softice/D* users terminates debugged program by using "r eip ExitProcess"
- or by assembling direct jump/call to ExitProcess api in this example I will demonstrate
- how to detect debugger when such action/actions occurs.
- Well this thing can be done in many ways like patching ExitProcess with jmp to
- our procedure and so on, however it can be defeated easily and it is not so stealthy.
- I'm going to show you an example for this technique.
- Protecting region of ExitProcess by VirtualProtect (for known reasons dirty and not
- perfect), what is even more funny it causes Break-on-access exception in Olly in
- current version there is no option to bypass it :)) (of course I believe you
- know how to rewrite it for catching olly)
- Schema how this example works:
- I. STAGE - Setup SEH frame which will catch PAGE_GUARD exception
- II. STAGE - Change access protection of >ExitProcess to PAGE_GUARD
- III. STAGE - If debugger action will be found we will end in SEH frame
- with marker variable set to zero, otherwise it will be set
- to 1 (good flag).
- IV. STAGE - display message box
- NOTES: After STATUS_PAGE_GUARD exception the PAGE_GUARD access protection
- of ExitProcess is turned off. Better thing then variable marker?
- Yes you can try random keys stored in registers and so on
- then you can compare it in SEH frame (context structure)
- ----// SNIP SNIP //---------------------------------------------------------
- mov ebx,077E79863h ; ExitProcess addr
- push offset seh_handler ;setup SEH frame
- push dword ptr fs:[0]
- mov dword ptr fs:[0],esp
- push offset old_protect
- push PAGE_EXECUTE_READ OR PAGE_GUARD
- push 1
- push ebx
- @callx VirtualProtect ; give it PAGE_GUARD protection
- push 0
- push offset m1
- push offset m1
- push 0
- @callx MessageBoxA
- ; attach debugger and give "r eip ExitProcess"
- ; of course it must be done after protecting
- ; ExitProcess
- exit:
- mov dword ptr [marker],1 ; marker set to 1
- push 0
- @callx ExitProcess
- seh_handler:
- pop dword ptr fs:[0] ; remove SEH frame
- pop eax
- cmp byte ptr [marker],1 ; is this our call?
- je exit
- push 0
- push offset m2
- push offset m2
- push 0
- @callx MessageBoxA ; we are debugged...
- jmp exit
- m2 db "Ups im being debugged :)",0
- m1 db "Attach debugger now and change eip to ExitProcess!",0
- marker db 0
- old_protect dd 0
- ----// SNIP SNIP //---------------------------------------------------------
- ---------------------
- III. OUTRO(DUCTION)
- ---------------------
- This is seems to be the end of this short article, I have plenty more ideas but
- not enough time to write them all here. Anyway I hope you enjoyed the stuff
- I have provided here, if you have any questions drop me a mail.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement