Ring-3 Debugger Blocking

Sunday, February 20 2005 @ 10:31 PM CET

Contributed by: KaGra

Level : intermediate

How you can block a Ring level 3 debugger.

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
$$$$$$$$$$$$$$$$ The ThinG => RinG-3 DebuggerZ BloCkEr FeaTuRe by KaGra $$$$$$$$$$$$$$$$$$
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$



See this tutor using notepad,Font Fixedsys Regular,size 10



Well,since my last Tutor many packerz got into my handz.And I should say that
the only one I saw having a Ring-3 Debugger Blocker is Armadillo.But why does not
the otherz use this wonderfull feature?The answer is I DON'T KNOW.

Well,creating such a feature is not difficult.The general idea is this:

Olly, (which is Ring-3) when we load an exe in her,locates dlls that the exe
will use (actually,will use the API's in those dll's) from their names in the
Import Address Table.Then,loads those dll's in memory that is also now being
allocated for this purpose.After that,fills the IAT with the API's addresses
that reside in the mentioned loaded dll's.The thing is that if we run this exe
now,and this exe creates a new proccess,Olly will not be able to breakpoint at
any API that is being used from this second process (although those API's are
part of the SAME dll code that has been allocated from the first loaded exe).And
this is because the allocated space that contains the API's (and dll's) is only
a copy of the original,and not the original dll memory space,because it is
a RinG-3 debugger.So,the new process created by the first exe will allocate
its own memory space from windows loader and will call from there the API's and
not from the allocated by Olly (Olly playz actually the windows loader for
the first exe).So,putting any kind of breakpoint in Olly (software or hardware)
will NOT trigger the API's that are called from the second proccess,thus making
Olly useless.

The procedure to follow is simple:

a) The original exe creates a process of itself.
b) Patches itself in memory,because if not then the new process will create another
one,and this another one etc. etc.
c) The process of the original exe (father) exits
d) Now the second proccess (child) continues running and Olly cannot
breakpoint on it.



These API's will be used in order to create the first original exe (the exe anyway):



1) CreateProcessA => To create the new proccess (child) ,which is actually a copy of the father

2) WriteProcessMemory => To patch the first process

3) ResumeThread => After patching child continues to execute and is Free!

4) MessageBoxA => This is actually the usefull code of the prog and cannot be
breakpointed from Olly.
5) ExitProcess => To exit the process



HeRe follows the source code of the exe:


00401000 >/$ 68 80204000 PUSH father.00402080 ; /pProcessInfo = father.00402080
00401005 |. 68 38204000 PUSH father.00402038 ; |pStartupInfo = father.00402038
0040100A |. 6A 00 PUSH 0 ; |CurrentDir = NULL
0040100C |. 6A 00 PUSH 0 ; |pEnvironment = NULL
0040100E |. 6A 04 PUSH 4 ; |CreationFlags = CREATE_SUSPENDED
00401010 |. 6A 00 PUSH 0 ; |InheritHandles = FALSE
00401012 |. 6A 00 PUSH 0 ; |pThreadSecurity = NULL
00401014 |. 6A 00 PUSH 0 ; |pProcessSecurity = NULL
00401016 |. 6A 00 PUSH 0 ; |CommandLine = NULL
00401018 |. 68 2D204000 PUSH father.0040202D ; |ModuleFileName = "father.exe"
0040101D |. E8 46000000 CALL <JMP.&KERNEL32.CreateProcessA> ; CreateProcessA
00401022 |. B8 00104000 MOV EAX,father.<ModuleEntryPoint>
00401027 |. 6A 00 PUSH 0 ; /pBytesWritten = NULL
00401029 |. 6A 05 PUSH 5 ; |BytesToWrite = 5
0040102B |. 68 90204000 PUSH father.00402090 ; |Buffer = father.00402090
00401030 |. 50 PUSH EAX ; |Address => 401000
00401031 |. FF35 80204000 PUSH DWORD PTR DS:[402080] ; |hProcess = NULL
00401037 |. E8 38000000 CALL <JMP.&KERNEL32.WriteProcessMemory> ; WriteProcessMemory
0040103C |. FF35 84204000 PUSH DWORD PTR DS:[402084] ; /hThread = NULL
00401042 |. E8 27000000 CALL <JMP.&KERNEL32.ResumeThread> ; ResumeThread
00401047 |. 6A 00 PUSH 0 ; /ExitCode = 0
00401049 . E8 2C000000 CALL <JMP.&KERNEL32.ExitProcess> ; ExitProcess
0040104E . 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
00401050 . 68 04204000 PUSH father.00402004 ; |Title = "hay :-)"
00401055 . 68 0C204000 PUSH father.0040200C ; |Text = "Did I secapEd frOm YoUr BPx s???"
0040105A . 6A 00 PUSH 0 ; |hOwner = NULL
0040105C . E8 1F000000 CALL <JMP.&USER32.MessageBoxA> ; MessageBoxA
00401061 . 6A 00 PUSH 0 ; /ExitCode = 0
00401063 . E8 12000000 CALL <JMP.&KERNEL32.ExitProcess> ; ExitProcess



At 0040101D it creates a new process which is a copy of the same exe,and pauses (SUSPENDS)
the execution of it.At 00401037 patches the second process at 00401000 with the opcode
JMP 0040104E.So,now the second process has the same code as the first (father) with the
only changed opcode the first at 00401000.At 00401042 the second (child) process continues
to execute (actually,now starts from 00401000).The father then terminates at 00401049,and
the child starting from 00401000,it jamps at 0040104E,and the messagebox pops up.If u place
a hardware of software or any other kind of breakpoint to MessageBoxA API (whenever u like
it doesn't matter) the API will not be triggered,and any other code may follow after 0040104E.


But what if we open a second Olly and attach to the child proccess?Well,do that and child is
not appearing in the tasks list to attach!So,we cannot attach!The child also cannot be
seen from LordPE.


How can this be defeated?Well,the first way is to make somehow the child to appear in the
attach list somehow (or any other attach list with more advanced dumping toolz) and the
second is to place a direct jamp at the "useful" code (here at 0040104E).


Well,u can also defeat those two.The first can be defeated by creating many many childs and
patching that way,that after the xxx child,will run the useful code.This will make attaching
in process (if anyone manages doing it) very irritating,since he has to do this many times.The
second can be defeated by using large garbadge and code of encryption of any kind.U can also
use code to check if the previouly childs have really run (because if someone patches with
jamps,the child(s) will not run).This is done by checking if there are actually modifications
of code,and will be if child(s) have run,due to the use of WriteProcessMemory.




BoNus: Another small trick to block debuggers and Dasm's

Load the bug.exe in Olly.What?Cannot be loaded.Try to see it's contents in WinDasm.What?
Cannot see the API calls.Now check the header using a hex editor,and see those two values:

LoaderFlags: EDABDDCA
NumberOfRvaAndSizes: BBDCBDFA

Well,because of those two values that are false,the tools are being confused.Change them
to LoaderFlags=0 and NumberOfRvaAndSizes=10h (common values for almost all exe's) and the exe
loads just fine in Olly and Dasm now shows the API calls.File was not packed or any other
kind protected as u may have assumed at first.This works by changing BOTH of them.


Well,this is the end of that.U can make the-ThinG routine much more sophisticated
using debugging API's.See MSDN library and U will get what I mean...


This is the end of it.Someone is hiTTing the DooR...

0 comments



http://www.reversing.be/article.php?story=20050220223131679