首页
社区
课程
招聘
[求助]晷於THEMIDA 可以翻诅一下? THX
2006-10-12 05:44 7844

[求助]晷於THEMIDA 可以翻诅一下? THX

2006-10-12 05:44
7844
TheMida: defeating ring0

deroko/ARTeam
Version 1.0? May2006

1. Abstract..................................................2
2. Know your enemyand dump it................................3
3. Imports, IAT and I........................................14
4. Foo Bar Baz code..........................................19
5. Conclusion................................................30
6. References/Tools..........................................31
7. Greetings.................................................32

Keywords
Themida, unpacking

1.Abstract

TheMida 1.0.0.5 with offensive ring0 driver is not very used nowadays. But still it doesn't mean that we shouldn't pay

attention to it. Even more, when something is not researched and written about it is more fun to play with such protection. I

have nothing more to say about it, I will show you myresearchand allI have done to repair dump.

Mytarget is Advanced Submitter 4.1.4[3]

Ofcourse,to playwiththemida 1.0.0.5 weare going to use some tools:

- IDA
- LiveKd
- wARK
- hiew
- tasm32

Forget about debugger it is not usefulwhile playing withthemida 1.0.0.5and ring0 hooks.

2. Know your enemyand dump it

Protection implemented byoreans.sys is weird it hooks some SSDT entries, IDT and some exports ofntoskrnl.exe:

SSDT entry 0035 hooked by : 0xF3B7ACBE - NtCreateThread
SSDT entry 003A hooked by : 0xF3B7B1A0 - NtDebugContinue
SSDT entry 00B2 hooked by : 0xF3B7AACA - NtQueryVirtualMemory
SSDT entry 00BA hooked by : 0xF3B7A014 - NtReadVirtualMemory
SSDT entry 0101 hooked by : 0xF3B7A9D0 - NtTerminateProcess
SSDT entry 0115 hooked by : 0xF3B7A000 - NtWriteVirtualMemory

Now wewillcheck hooks inexportsofntoskrnl.exe:

C:\>scanhook.exe
scanhook - (c) 2006 deroko/ARTeam
Hooked : KeAttachProcess
Hooked : vsprintf
C:\>

Well KeAttachProcess is hooked because themida want to deny any pte changing from ring0 and process dumping from ring0. Well

it doesn't hook KeStackAttachProcess so we can still attach to process fromring0 and dump it, but we are also able to emulate

KeAttachProcess verysimple.

Now let's see what we have inIDT:

01h 0008:FFFFFFFF Interrupt 32 bit 03 0
03h 0008:FFFFFFFF Interrupt 32 bit 03 0
0Bh 0008:EBF0E3E8 Interrupt 32 bit 00 1
0Eh 0008:EBF0E000 Interrupt 32 bit 00 1

Oki, int1 and int3 are “hooked” with 0xFFFFFFFF, the reason why themida hooks int 0eh is to catch 0xFFFFFFFF memory access

and according to instruction that caused access to 0xFFFFFFFF totransfer executionto KiTrap01 orKiTrap03, inother words,

default handlers. Ofcourse ifit finds int3h in themida protected process, my best guess is BSOD because I didn't want to

experiment and to cause another BSOD just to learn in hard wayto do not mess withthemida hooks

Ifyou tryto remove anyofthese hooks you willget BSOD.

So to understand themida hooks I used one small home made ring0 memory dumper to dump hooks. But before we move to hook dumps

I willshow you hooks for KeAttachProcess and vsprintf in ntoskrnl.exe dumped withLiveKd:

kd> u KeAttachProcess
nt!KeAttachProcess:

804e3173   E9884E5D78   jmp F8AB8000
804e3178   56           push esi
804e3179   57           push edi

kd> u ntoskrnl!vsprintf
nt!vsprintf:

8050716b   33C0        xor eax,eax
8050716d   C3          ret

Oki, ifwe dump memorycontent ofhook storedin KeAttachProcess we willsee this code:

           push ebp
           mov ebp, esp
           pusha
           call $+5
           pop edx
           sub edx, 940FB78h
           push fs                        ; save FS
           mov eax, 30h                   ; make it point to kpcr
           mov fs, ax                     ;
           mov eax, large fs:124h         ; grab CurrentThread from kpcr
           mov eax, [eax+44h]             ; grab EPROCESS from ETHREAD
           mov [edx+940FC00h], eax        ; save EPROCESS struct
           pop fs                         ; restore fs
           mov eax, [ebp+4]               ; now it takes saved EIP from stack
           cmp eax, [edx+940FBF0h]        ; this part is not interesting for us
           jbe short loc_F8AB8040         ; because it is junk
           cmp eax, [edx+940FBF4h]        ;
           jnb short loc_F8AB8040
           jmp short loc_F8AB807D

; AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

loc_F8AB8040:
           cmp eax, [edx+940FBF8h]        ;still junk
           jbe short loc_F8AB8052
           cmp eax, [edx+940FBFCh]
           jnb short loc_F8AB8052
           jmp short loc_F8AB807D

; AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

loc_F8AB8052:
           mov eax, [ebp+8]               ;oki now we get to good stuff
           cmp eax, [edx+940FC00h]        ;cmp passed EPROCESS to KeAttachProcess
           jz short loc_F8AB8076          ;with EPROCESS of protected process
           mov esi, 0F8AAC000h            ;themida internal struct
           add esi, 4                     ;esi points to EPROCESS field in
                                          ;internal struct
loc_F8AB8065:
           cmp dword ptr [esi], 47616420h ;is it signature?
           jz short loc_F8AB807D          ;if so end of loop
           cmp [esi], eax                 ;EPROCESS of protected process
           jz short loc_F8AB8076          ;compared to saved one
           add esi, 4                     ;go to next entry in struct
           jmp short loc_F8AB8065         ;loop

; AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
; dumped structure comes here so it is easier to follow code

           dd 47616420h                   ;signature (' daG'
           dd 81B58DA0h                   ;EPROCESS of protected process
           dd 47616420h                   ;signature again
           dd 0

; AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
loc_F8AB8076:                             ;return w/o attaching to target process
           popa
           pop ebp
           xor eax, eax
           retn 4

loc_F8AB807D:                             ;call some code in oreans.sys
           popa
           pop ebp
           jmp short loc_F8AB8095

loc_F8AB8095:
           mov edi, edi
           push ebp
           mov ebp, esp
           jmp near ptr 804E3178h         ;KeAttachProcess+5

To write driver that will be able to use KeAttachProcess we have to write small procedure that will be wrapper for

KeAttachProcess, but this is completely unnecessary work because we may attach using KeStackAttachProcess but what the hell,

we are doing this for fun and to learn something, at least that's the onlyreasonwhyI'mplaying withthemida.

KeAttachProcessWraper:
           mov edi, edi
           push ebp
           mov ebp, esp
           iMOV eax, KeAttachProcess
           add eax, 5
           jmp eax                        ;execute KeAttachProcess+5

Simple isn't it
This is very important instruction inabove code:

           mov esi, 0F8AAC000h            ;themida internal struct

If we take a look in disassembly of hook in IDA we might see that this instruction is located at hook_base + 5Dh:

seg000:0000005B      jz short loc_76
seg000:0000005D      mov esi, 0F8AAC000h
seg000:00000062      add esi, 4

This structure is very important because it describes state of protected process, it has simple structure:

           dd 47616420h                   ;signature (' daG'
           dd 81B58DA0h                   ;EPROCESS of protected process
           dd 47616420h                   ;signature again
           dd 0
           dd 0

Ifwe examine address 81B58DA0h in livekd we may notice that it is actuallyEPROCESSof protectedapplication:

kd> dt nt!_EPROCESS 81b58da0
  ...
  +0x168 PageDirectoryPte   : _HARDWARE_PTE
  +0x168 Filler             : 0
  +0x170 Session            : 0xf8a55000
  +0x174 ImageFileName      : [16] "AdvanceSubmitte" <--- application name
  +0x184 JobLinks           : _LIST_ENTRY [ 0x0 - 0x0 ]
...
kd>

Voila we have researched internalthemida struct.

Next important thing is that themida willremove hooksonce protectedapplication is done with its executing. To accomplishthis

themida uses hookofNtTerminateProcess so we are going to dump that memoryregionand analyze NtTerminateProcess hook:

           push ebp
           mov ebp, esp
           pusha
           call $+5
           pop edx
           sub edx, 94552AFh
           push edx
           push 0
           lea eax, [edx+945531Fh]
           push eax
           push 0
           mov eax, 80559CD8h              ;PsProcessType
           xor eax, eax                    ;eax set to 0
           push eax
           push 10h
           push dword ptr [ebp+8]
           mov eax, 8055D468h
           call eax                        ;ObReferenceObjectByHandle
           pop edx
           cmp dword ptr [edx+945531Fh], 0
           jz short loc_F364BA3A
           mov eax, [edx+945531Fh]         ;EPROCESS of cur process
           mov ebx, eax
           and ebx, 7FFFFFFFh
           mov esi, 0F8AAC000h             ; internal struct

loc_F364BA1D:
          add esi, 4
          cmp dword ptr [esi], 47616420h
          jz short loc_F364BA3A
          cmp [esi], eax
          jz short loc_F364BA32
          cmp [esi], ebx
          jz short loc_F364BA32
          jmp short loc_F364BA1D

loc_F364BA32:
          mov dword ptr [esi], 0FFFFFFFFh  ;signal to unhook probably
          jmp short loc_F364BA42           ;what else could it be

; AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

loc_F364BA3A:
          popa
          pop ebp
          push 80583E1Eh                   ;NtTerminateProcess
          retn

; AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

loc_F364BA42:                              ;only return from
          popa                             ;NtTerminateProcess
          pop ebp
          xor eax, eax
          retn 8

; AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

As you may see NtTerminateProcess will only set EPROCESS in internal themida struct to 0FFFFFFFFh which is signal probably

for ring0 thread to signal some ring3 thread to call ExitProcess.

Oki, once themida process was loaded I was ready to play with themida internal struct and to set it to 0FFFFFFFFhas is done

bythemida itselfwhenNtTerminateProcess is called.

I wrote driver for this particular target and used hook in KeAttachProcess to reach internal themida struct [keattachgame

driver] notethatthis driver also hooks some entries inIDT:

         iMOV esi, KeAttachProcess
         cmp byte ptr[esi], 0e9h
         jne __sh_fail
         mov ecx, [esi+1]
         add esi, 5
         add esi, ecx
         push esi
         pushs <"Jmp KeAttach 0x%.08X", 13, 10>
         iWin32 DbgPrint
         add esp, 8
         add esi, 5dh
         cmp byte ptr[esi], 0beh
         jne __sh_fail
         mov esi, [esi+1]
         push esi
         pushs <"Internal struct 0x%.08X", 13, 10>
         iWin32 DbgPrint
         add esp, 8

;
;terminate themdia protected process
;
         mov [esi+4], 0ffffffffh

Loading and running this part of code in ring0 resulted in themida process termination. Next step for me was to prevent

themida process termination by hooking NtTerminateProcess before themida process is loaded, because any modificationofSSDT

while themida is running willresult inBSOD.

So I recoded my driver to load and wait ioctl codes sent to it by my programs to update PID of traced process:

myntterminateprocess label dword
                     push ebp
                     mov ebp, esp
                     sub esp, 4
                     pusha
                     push 0
                     lea eax, [ebp-4]
                     push eax
                     push 1
                     iMOV ebx, PsProcessType
                     push dword ptr[ebx]
                     push 0
                     push dword ptr[ebp+8]
                     iWin32 ObReferenceObjectByHandle
                     test eax, eax
                     jnz __failobjget
                     mov eax, [ebp-4]
                     push eax
                     iWin32 ObDereferenceObject
                     mov eax, [ebp-4]
                     mov eax, [eax.ep_UniqueProcessId]
                     cmp eax, traced_pid
                     jne __failobjget
                     push eax
                     pushs <"themdia process is terminating : 0x%.08X">
                     iWin32 DbgPrint
                     add esp, 8
                     pushs <"faking NtTerminateProcess for themida driver">
                     iWin32 DbgPrint
                     add esp, 4
                     popa
                     mov esp, ebp
                     pop ebp
                     retn 8

__failobjget:        popa
                     mov esp, ebp
                     pop ebp
                     jmp cs:[ntterminateprocess]

Basically I return from NtTerminateProcess if themida process is being terminated. Good, we run driver and wait. After we

execute pid_giver.asm which will notify NtTerminateProcess hook about PID and will tell driver to “play” with internal

struct. Sooner or later we get exception at 1xxxxx trying to execute int 3h. Well, process is deprotected so we candump it

atmand load it in IDA. But still I was wondering what was located at 1xxxxx when int 3h occurred so I dumped that region with

LordPE and was more than shocked, it was virtually mapped kernel32.dll and suddenly occurrence ofint3hbecame morethanclear.

DisassemblyofExitProcess:

.text:7C81CAA2       mov edi, edi
.text:7C81CAA4       push ebp
.text:7C81CAA5       mov ebp, esp
.text:7C81CAA7       push 0FFFFFFFFh
.text:7C81CAA9       push 77E8F3B0h
.text:7C81CAAE       push dword ptr [ebp+8]
.text:7C81CAB1       call loc_7C81C9FC
.text:7C81CAB6       jmp near ptr unk_7C8399E4

First we have call to NtTerminateProcess and other stuff needed for nice and clean shutdown of a process. In normal case, our

process will be terminated in call at 7C81C9FC and jmp will be never reached, but in this case, when I hook

NtTerminateProcess to return without killing process, jmp at 7C81CAB6h is executed and we arrive here:

dword_7C8399E4       dd 0CCCCCCCCh, 8428E9CCh, 9090FFFCh

Bingo, there is our int 3h, so next step was to modify virtual kernel32.dll to call ExitThread once thread inring3 tries to

execute it. But to do this we have to hook CreateFileA. Before themida starts executing virtualkernel32.dllthese

files/devices are accessed:

\\.\SICE
\\.\SIWVID
\\.\NTICE
\\.\Global\XPROTECTOR
\\.\Global\XPROTECTOR
C:\WINDOWS\system32\KERNEL32.dll
C:\WINDOWS\system32\USER32.dll
C:\WINDOWS\system32\ADVAPI32.dll
\\.\Global\XPROTECTOR
C:\WINDOWS\system32\ntdll.dll
\\.\Global\XPROTECTOR

My next approach was to hook CreateFileA so it will load my modified kernel32.dll with this little modification:

.7C81CAA2|   E90202FFFF       jmp ExitThread ---? (1)
.7C81CAA7:   6AFF             push -1
.7C81CAA9:   68B0F3E877       push 077E8F3B0 ;'wF=|'

Good, now I was ready to test my theory and to see if process will remain in memory when hooks are removed. Luckily my plan

worked like a charm and I had deprotected process running in memory ready to be dumped without a problem. Of course, ring3

memory manager [5] is present and running allthis time so I'mable to dump allallocated buffers inone file.

Then, of course I loaded file in Ida and after 30mins of analyzing and applying signatures I figured that I'mdealing

withDelphiapp.

Whenwe are dealing withDelphi App we search forInitExe signature and I found it here:

___:00407408 ; __fastcall Sysinit::__linkproc__ InitExe(void *)
___:00407408 @Sysinit@@InitExe$qqrpv proc near
___:00407408                 push ebx
___:00407409                 mov ebx, eax
___:0040740B                 xor eax, eax
___:0040740D                 mov ds:TlsIndex, eax
___:00407412                 push 0
___:00407414                 call sub_407344          ;call to GetModuleHandleA
___:00407419                 mov ds:dword_866718, eax
___:0040741E                 mov eax, ds:dword_866718
___:00407423                 mov ds:dword_85C094, eax
___:00407428                 xor eax, eax
___:0040742A                 mov ds:dword_85C098, eax
___:0040742F                 xor eax, eax
___:00407431                 mov ds:dword_85C09C, eax
___:00407436                 call @SysInit@_16395     ; SysInit::_16395
___:0040743B                 mov edx, (offset a123456789abcde+0Fh)
___:00407440                 mov eax, ebx
___:00407442                 call sub_4046C4
___:00407447                 pop ebx
___:00407448                 retn
___:00407448 @Sysinit@@InitExe$qqrpv endp ; sp = -4

Now I knew what to hook to reach oep and to put bestard in infinite loops so I could inform driver to change themida internal

struct, unload hooks, unload driver and attach to process with olly to get magic Delphivalue and to find oep:

First I had to hook GetModuleHandleA to jmp $ only if and only if it is called from certain locations:

.text:7C80B529               mov edi, edi
.text:7C80B52B               push ebp
.text:7C80B52C               mov ebp, esp
.text:7C80B52E               cmp [ebp+arg_4], 0
.text:7C80B532               jz short loc_7C80B54C
.text:7C80B534               push [ebp+arg_4]
.text:7C80B537               call sub_7C80E2A4
.text:7C80B53C               test eax, eax
.text:7C80B53E               jz short loc_7C80B548
.text:7C80B540               push dword ptr [eax+4]
.text:7C80B543               call GetModuleHandleW
.text:7C80B548 loc_7C80B548:
.text:7C80B548               pop ebp
.text:7C80B549               retn 4
.text:7C80B54C loc_7C80B54C:
.text:7C80B54C               mov eax, large fs:18h
.text:7C80B552               mov eax, [eax+30h]
.text:7C80B555               mov eax, [eax+8]
.text:7C80B558               jmp short loc_7C80B548
.text:7C80B558               GetModuleHandleA endp

I decided to hook after retn4 because GetModuleHandleA is called fromDelphiapp withargument equalto 0.OkiI installed myhook:

                             cmp [ebp+4], 407419h
                             jne __orig
                             jmp $_orig: mov eax, 400000h
                             pop ebp
                             retn 4

Now when my hook is reached I signal driver to fake process termination, faked kernel32.dll is loaded and voila our process

is running deprotected in memory, of course, use wARK to unload driver and attach to process with olly. You should check

value of EBX because that will be your magic value and after a few stepover inollyyou reach youroep:

___:0085BB01                 call @Sysinit@@InitExe$qqrpv
___:0085BB06                 mov ebx, ds:off_86454C
___:0085BB0C                 mov esi, ds:dword_864920
___:0085BB12                 mov eax, [esi]

Bingo, now go a little bit up and assemble your little patch:

___:0085BAFC                 mov eax, offset dword_85AF14
___:0085BB01                 call @Sysinit@@InitExe$qqrpv
___:0085BB06                 mov ebx, ds:dword_86454C
___:0085BB0C                 mov esi, ds:dword_864920
___:0085BB12                 mov eax, [esi]

Congratulation, you have dumped themida protected applicationat oep, now we have to fix imports and replaced code.

To be able to inject memory manager in virtualkernel32.dll I used int 80h hook to store jmp to my code in virtual_k32.dll!

VirtualAlloc, to load mykernel32.dllI hooked CreateFileA so it will give to themida .\myk32.dll instead of

C:\windows\system32\kernel32.dll, all modifications are performed in mycopyofkernel32.dllnamed myk32.dll:

.7C809A81|   CD80            int 080
.7C809A83:   55              push ebp
.7C809A84:   8BEC            mov ebp,esp
.7C809A86:   FF7514          push d,[ebp][14]
.7C809A89:   FF7510          push d,[ebp][10]
.7C809A8C:   FF750C          push d,[ebp][0C]
.7C809A8F:   FF7508          push d,[ebp][08]
.7C809A92:   6AFF            push -1
.7C809A94:   E809000000      call VirtualAllocEx ---? (1)
.7C809A99:   5D              pop ebp
.7C809A9A:   C21000          retn 00010   ;' ?'

Now I hooked int 80h in IDT and changed its DPL to 3 so instruction can be executed from ring3 without a problem:

                             initint
                             pushs <"int 80h called", 13, 10>
                             iWin32 DbgPrint
                             add esp, 4
                             mov edi, [esp.int_eip]
                             sub edi, 2
                             mov al, 68h
                             stosb
                             mov eax, memorymanager
                             stosd
                             mov al, 0c3h
                             stosb
                             sub [esp.int_eip], 2
                             restoreint
                             iretd

Now we know that call to VirtualAlloc in our virtual_k32.dll will be redirected to memory manager. I also wrote one procedure

to hook interrupts because I needed it during themida unpacking. Except int 80h I needed 2 more interrupts so writing same

code 3 times would result in huge and unreadable source:

HookInteruptAdjustDpl proc
                      arg intterupt_number:dword
                      arg new_handler:dword
                      arg old_handler:dword
                             pusha
                             push edi
                             sidt fword ptr[esp-2]
                             pop edi
                             mov eax, interupt_number
                             shl eax, 3
                             lea edi, [edi+eax]
                             mov ebx, old_handler
                             movzx ecx, word ptr[edi+6]
                             rol ecx, 16
                             mov cx, word ptr[edi]
                             mov [ebx], ecx
                             mov ecx, new_handler
                             cli
                             mov word ptr[edi], cx
                             rol ecx, 16
                             mov word ptr[edi+6], cx
                             movzx ecx, word ptr[edi+4]
                             or ch, 060h                 ; dpl == 3
                             mov word ptr[edi+4], cx
                             sti
                             popa
                             leave
                             retn 0ch
                             endp

And unhookprocedure:

UnHookInteruptAdjustDpl proc
                        arg interupt_number:dword
                        arg old_handler:dword
                             pusha
                             push edi
                             sidt fword ptr[esp-2]
                             pop edi
                             mov eax, interupt_number
                             shl eax, 3
                             lea edi, [edi+eax]
                             mov ecx, old_handler
                             cli
                             mov word ptr[edi], cx
                             rol ecx, 16
                             mov word ptr[edi+6], cx
                             movzx ecx, word ptr[edi+4]
                             and ch, 9fh
                             mov word ptr[edi+4], cx ;dpl == 0
                             sti
                             popa
                             leave
                             retn 8
                             endp

Usage:
                             push offset oldint80handle
                             push offset __newint80handle
                             push 80h
                             call HookInteruptAdjustDpl
                             and:
                             push oldint80handle
                             push 80h
                             call UnHookInteruptAdjustDpl

That's all for this chapter, you might wanna check loader22.asmwhich has all stuff I used to dump themida and fix imports.

Code is not very well optimized because I added code to it as I was advancng further inthemida unpacking.

3. Imports, IAT and I

Import protection is verynice inthemida, whenI saynice, that means that it tookme a lot oftime to fixIAT. Iwillsum how import

protection is performed:

First it will disassemble API and take 1 instruction and store it in separate buffer, then it will store garbage code and

take next instruction and store it, and again garbage code, original byte, garbage code etc. if jmp/jcc is found it will be

redirected to original jmp spot in destination API and if we have some API w/o jcc/jmp nor call to some procedure whole API

with garbage code between originalinstructions will be copied to buffer allocated byprotector,ofcourse, jcc/jmp are

redirected and garbage is stored afterthemso next instructionthat follows themis obfuscated tillret/retn.

Ofcourse, jmp dword ptr[api] are changed with jmp _buffer:

___:00407408                 push ebx
___:00407409                 mov ebx, eax
___:0040740B                 xor eax, eax
___:0040740D                 mov ds:TlsIndex, eax
___:00407412                 push 0
___:00407414                 call sub_407344 <---- call GetModuleHandleA
...
___:00407344                 sub_407344 proc near
___:00407344                 jmp near ptr 2FC0E78h
___:00407344                 sub_407344 endp

As you may see there is relative jmp (e9) instead of jmp dword ptr [] (ff25h). Of course, fixing relative jmps is not

problem, and to automate process of their fixing I wrote iatfix.asm which is supplied withthis document.

Bigger problem is how to prevent themida from obfuscating APIs, after a 5-6 bsods I finally got goodsolution.

Let me tell you something, with memory manager injected I got all buffers in memory including obfuscated APIs, to get

partially working dump I injected dll loader in last section which will load used dlls by target and in such way make all

jmp/jcc in obfuscated apis valid. Now we may run application and it should work. For this code please refer to [addsec.asm]

supplied with this document.

Now afterI run[iatfix.asm] I got everything as I wanted it to be:

.dumped:00407344             sub_407344 proc near
.dumped:00407344             jmp ds:off_1BD50E4
.dumped:00407344             sub_407344 endp
.dumped:00407344
.dumped:0040734A             mov eax, eax
.dumped:0040734C
.dumped:0040734C             sub_40734C proc near
.dumped:0040734C             jmp ds:off_1BD50E8
.dumped:0040734C             sub_40734C endp

For all olly lovers, jmp ds:off_ is actually jmp dword ptr[] aka ff25, now I had everything I needed. Working code that will

fix jmps but still no valid API pointers. Now I can run importrec and find modified IAT but still no valid APIs.

Since themida obfuscates API by stealing instruction and inserting garbage in its own buffer I planned to hook all exports of

loaded dlls with code that will help me later on with importrec plug- into find APIs. MyAPI hookis verysimple. [Check

hook4.asmsample code]

Fromthis:
.text:7C80B529               mov edi, edi <-----+
.text:7C80B52B               push ebp |
.text:7C80B52C               mov ebp, esp <-----+
.text:7C80B52E               cmp [ebp+arg_4], 0
.text:7C80B532               jz short loc_7C80B54C
.text:7C80B534               push [ebp+arg_4]
.text:7C80B537               call sub_7C80E2A4

Apibecomes:
.text:7C80B529               jmp my_hook
.text:7C80B52E               cmp [ebp+arg_4], 0
.text:7C80B532               jz short loc_7C80B54C
.text:7C80B534               push [ebp+arg_4]
.text:7C80B537               call sub_7C80E2A4

And my hookis :
00F297E2    50               PUSH EAX
00F297E3    B8 29B5807C      MOV EAX,kernel32.GetModuleHandleA
00F297E8    58               POP EAX
00F297E9    8BFF             MOV EDI,EDI
00F297EB    55               PUSH EBP
00F297EC    8BEC             MOV EBP,ESP
00F297EE  - E9 3B1D8E7B      JMP kernel32.7C80B52E

So later onmyimportrec plug-in should onlytrace till moveax, API and returnvalid API pointer Luckily TheMida didn't try to

obfuscate API when jmp at its entry is found so after running my hookengine I got valid pointers:

00407412    6A 00            PUSH 0
00407414    E8 2BFFFFFF      CALL AdvanceS.00407344

We tracethis call:
00407344  - E9 E041407C      JMP kernel32.GetModuleHandleA

Ohhh, clap, clap
7C80B529 >- E9 B4E27184      JMP AdvanceS.00F297E2
7C80B52E    837D 08 00       CMP DWORD PTR SS:[EBP+8],0

And jmp goes to hook and back to code.

To avoid hooking all dlls, the ones loaded by target and those loaded by other dlls we have to hook LoadLibraryA and

GetModuleHandleA but we are also aware that there is virtual kernel32.dll. So to hookthosetwo I installed two more interrupts

withDPL3 [keattachgame driver]:

GetModuleHandleA:
.7C80B529|  CD79             int 079
.7C80B52B:  55               push ebp
.7C80B52C:  8BEC             mov ebp,esp
.7C80B52E:  837D0800         cmp d,[ebp][08],0

and LoadLibraryA:
.7C801D77|  CD81             int 081
.7C801D79:  55               push ebp
.7C801D7A:  8BEC             mov ebp,esp
.7C801D7C:  837D0800         cmp d,[ebp][08],0

My hooks in ring0 are similar to above one used for memory manager so now we are sure that everydllthat is being loaded will

be hooked

Also I avoid hooking of ntdll.dll because if I store jmp at entry of Native APIs themida will BSOD my system. BSOD comes from

simple fact that themida expects to find valid service number in a few exported APIs from ntdll.dll (the ones hooked in SDT)

if we store “jmp hook” reading service number will result in wrong number, and writing to wrong address in ring0 is equal

to bye, bye my dear system.

Now driver is loaded, and we are readyto watchoutputofDebugView[2]:

00000000 0.00000000 Oreans driver loaded in memory (v1.40)
00000001 0.00000112
00000002 0.14517654 int 80h called
00000003 0.42267776 int 79h called
00000004 0.44069371 [2080]
00000005 0.44069371 [2080]
00000006 0.44069371 [2080]
00000007 0.44069371 [2080] ----------------------------------------------
00000008 0.44069371 [2080] --- Themida Professional ---
00000009 0.44069371 [2080] --- (c)2005 Oreans Technologies ---
00000010 0.44069371 [2080] ---------------------------------------------
00000011 0.44069371 [2080]
00000012 0.44069371 [2080]
00000013 0.46072280 int 81h called
00000014 0.46082562 [2080] loadlibrarya hooked?
00000015 0.46086192 [2080] dll loaded 0x7C900000
00000016 0.48601010 [2080] loadlibrarya hooked?
00000017 0.51330322 [2080] dll loaded 0x7C900000
00000018 0.52680326 [2080] loadlibrarya hooked?
00000019 0.52794141 [2080] dll loaded 0x7C900000
00000020 0.53012294 [2080] hooking damn dll
00000021 0.53035456 [2080] dll hooked : 0x7C800000
00000022 0.54317516 [2080] hooking damn dll
00000023 0.54372722 [2080] dll hooked : 0x77D40000
00000024 0.55571115 [2080] hooking damn dll
00000025 0.55580807 [2080] dll hooked : 0x77DD0000
00000026 0.57459623 [2080] loadlibrarya hooked?
00000027 0.57480603 [2080] dll loaded 0x77120000
00000028 0.57484204 [2080] hooking damn dll
00000029 0.57495522 [2080] dll hooked : 0x77120000
00000030 0.59113181 [2080] loadlibrarya hooked?
00000031 0.59117877 [2080] dll loaded 0x71B20000
00000032 0.59121144 [2080] hooking damn dll
00000033 0.59145534 [2080] dll hooked : 0x71B20000
00000034 0.59156036 [2080] loadlibrarya hooked?
00000035 0.59159249 [2080] dll loaded 0x77C00000
00000036 0.59162354 [2080] hooking damn dll
00000037 0.59174669 [2080] dll hooked : 0x77C00000
00000038 0.59180927 [2080] hooking damn dll
00000039 0.59224790 [2080] dll hooked : 0x77F10000
00000040 0.60678184 [2080] hooking damn dll
00000041 0.60691762 [2080] dll hooked : 0x774E0000
00000042 0.62314314 [2080] hooking damn dll
00000043 0.62323815 [2080] dll hooked : 0x5D090000
00000044 0.63646275 [2080] loadlibrarya hooked?
00000045 0.63650769 [2080] dll loaded 0x76390000
00000046 0.63654011 [2080] hooking damn dll
00000047 0.63662922 [2080] dll hooked : 0x76390000
00000048 0.64198887 [2080] loadlibrarya hooked?
00000049 0.64205229 [2080] dll loaded 0x73000000
00000050 0.65171999 [2080] hooking damn dll
00000051 0.65182054 [2080] dll hooked : 0x73000000
00000052 0.66523176 [2080] loadlibrarya hooked?
00000053 0.66548234 [2080] dll loaded 0x7C9C0000
00000054 0.66551697 [2080] hooking damn dll
00000055 0.66563183 [2080] dll hooked : 0x7C9C0000
00000056 0.69346023 [2080] loadlibrarya hooked?
00000057 0.69481510 [2080] dll loaded 0x771B0000
00000058 0.69487798 [2080] hooking damn dll
00000059 0.69498020 [2080] dll hooked : 0x771B0000
00000060 0.72827160 [2080] loadlibrarya hooked?
00000061 0.72832191 [2080] dll loaded 0x77260000
00000062 0.72835487 [2080] hooking damn dll
00000063 0.72844315 [2080] dll hooked : 0x77260000
00000064 0.73640925 [2080] loadlibrarya hooked?
00000065 0.73645365 [2080] dll loaded 0x763B0000
00000066 0.73648578 [2080] hooking damn dll
00000067 0.73663414 [2080] dll hooked : 0x763B0000
00000068 1.11949956 [2080] loadlibrarya hooked?
00000069 1.11961353 [2080] dll loaded 0x7C900000
00000070 1.12467396 [2080] loadlibrarya hooked?
00000071 1.13394499 [2080] dll loaded 0x7C900000
00000072 1.19805110 [2080] loadlibrarya hooked?
00000073 1.19807744 [2080] dll loaded 0x7C800000

Now when last hook is reached we may check in Process Explorer from www.sysinternals.com or in Task Manager that our process

is killing our CPU due to hook in GetMoudleHandleA (jmp $) and now we will inform driver to simulate process exit and we

watch output in DebugView [pid_giver.asm]:

00000072 42.45299149 Jmp KeAttach 0xF8AC8000
00000073 42.45300674 Internal struct 0xF8AC2000
00000074 45.15629578 themdia process is terminating : 0x000009B4
00000075 45.15634918 faking NtTerminateProcess for themida driver

Wait a few seconds and use wARK to unload driver (usually I check IDT using wARK to know if hooks areremoved,

veryusefultool):

00000076 227.15957642 Oreans driver unloaded

Now dump process and run addsec and iatfix and voila, there is only couple of wrong APIs which are not hooked:

- forwarded ones to ntdll.dll
- ntdll.dllAPIs
- the ones that have call/jmp/jcc in 1st5 bytes ofAPI (some exports fromuser32.dll)

Ofcourse, I willrecode myloader to hook everything except ntdll.dlland to handle forwarded APIs fromkernel32.dllin

anappropriate way:

IMAGE-01

Now all I have to do is to save import tree.txt, modify it a little bit and inject same apiloader as one presented

inunpacking armadilloed dll[1] and after we runinjected loader we get these pointers:

IMAGE-02

That's allabout import fixing. Check [apiloader.asm] for complete codeand dumped iat.

4. Foo Bar Baz code

Run application and you will see beauty of Delphi application, it will inform you about address where exception is caused, in

mycase it was this message:

IMAGE-03

It seems that themida is trying to read memory from F8700DE1 which is obviously ring0 memory and ring3 application w/o

gateway to ring0 can't access it. If you keep following this address you will see that process is somehow accessing to r0

memory because you may also see how handlers for int1 and int3 are installed in your ring3 code, once handler is installed

you will see int1 and int3 in code which should transfer execution to handlers in memory < 80000000h. Weird, but if we check

this address inIDAwe maysee a few interesting stuff:

.dumped:00BB07CD               pusha
.dumped:00BB07CE               call $+5
.dumped:00BB07D3               pop ebp
.dumped:00BB07D4               sub ebp, 945B90Eh
.dumped:00BB07DA               mov esi, [ebp+9350759h]
.dumped:00BB07E0               mov eax, 2
.dumped:00BB07E5
.dumped:00BB07E5 loc_BB07E5:
.dumped:00BB07E5               xchg al, [esi]

There you go, xchg al, [esi] is causing exception. Now if we follow xrefs to this code in IDA we willendup here:

.dumped:00826C6D               call @Db@TWideStringField@GetAsString$qqrv
.dumped:00826C72               call near ptr sub_BB07CD
.dumped:00826C77               or eax, [eax]
.dumped:00826C77 ; -------------------------------------------------------------
.dumped:00826C79               dd 0
.dumped:00826C7D               dd 230000h
.dumped:00826C81               dd 15200000h
.dumped:00826C85               dd 1E153B40h
.dumped:00826C89               dd 988AC38Fh
.dumped:00826C8D               dd 5B58CDD3h
.dumped:00826C91               dd 68DF40EAh
.dumped:00826C95               dd 1F890FA3h
.dumped:00826C99               dd 453723EBh
.dumped:00826C9D               dd 2C7234A8h
.dumped:00826CA1               dd 0B8AFCB1h
.dumped:00826CA5               dd 1000000h
.dumped:00826CA9               dd 23000000h
.dumped:00826CAD               dd 20000000h
.dumped:00826CB1 ; -------------------------------------------------------------
.dumped:00826CB1               mov edx, ds:dword_87FFC4
.dumped:00826CB7               mov eax, 826DB4h
.dumped:00826CBC               call unknown_libname_68

If we step into procedure at BB07CDh we might see how it reads from ring0 memory and how int1 and int3 entries in IDT are

changed from ring3 code to point to some code in ring3. At first I thought that I'm crazy and I don't see well but honestly

there is code that sets IDT entries from ring3. I was wondering how this is performed. I dumped cs/ds registers just to make

sure that those are ring3. Then I wrote small driver to walk trough memory addresses from 80000000h ? FFFFFFFFh and check

PDE/PTE for User/Supervisor flag set in them. If 3rd bit of PDE or PTE, depending onpage size, is set that page can be

accessed fromanyring that is lover thanring0 (lover DPL) so afterrunning mydriver I gotthis fromDebugView:

00000000 0.00000000 Page at 0x8003F000 user visible

Huh, 0x8003F000 is base of IDT and is visible/writable/present in PTE so this address can be accessed by any ring3 program

without problem. Themida will deny access to this memory to any ring3 process except protectedone,ofcourse.

Then to test my theory I recoded int0e handler used by themida to allow access to any ring3 application to play with IDT

(write/read) and set int1/int3 handlers. Here is disassembly ofthemida int0e handler [check intfoobar driver]:

                     mov eax, [esp+28h]               ;eip in eax
                     cmp eax, 0FFFFFFFFh              ;is it caused by eip = ffffffff in other words
                     jz short loc_39                  ;caused by execution of int1 and int3
                     mov eax, [esp+24h]               ;takes ErrorCode
                     cmp eax, 0FFFFFFFFh              ;errorcode cann't be -1 so this jmp is taken
                     jnz loc_1DD
...
                     mov eax, [ebx]                   ;this takes EIP passed to int1/int3
                     cmp byte ptr [eax-1], 0CCh       ;and check if -1 is caused by int3h
                     jz short loc_1E5                 ;pass exception to _KiTrap03
                     cmp word ptr [eax-2], 3CDh       ;caused by INT 3h
                     jz short loc_1E5                 ;pass exception to _KiTrap03
                     cmp word ptr [eax-2], 1CDh       ;caused by INT 1h
                     jz short loc_1B1                 ;pass Exception to _KiTrap0D
                     popa
                     popf
                     add esp, 10h
                     jmp short loc_1F0                ;pass Exception to _KiTrap01

This code is very simple, since int1 and int3 handles are set to 0FFFFFFFFh each occurrence of int3h (cc, cd03) from ring3

will try to call 0FFFFFFFF which will result in calling page fault handler (int 0eh), also if Trap Flag is set in eflags or

drX registers are used it will result in 0FFFFFFFF access. Calling int 1 (cd01) will also result in 0FFFFFFFF because themida

sets int1 handler to DPL 3, and in normal case its DPL is 0 which means each occurrence of int1 in ring3 will result in

calling Global Protection fault aka _KiTrap0D or int 0d handler(remember SoftIce detection via int1trick?). Oki, here is how

it works:

Int1/int3 ? stacklayout

+------------+
| Eflags     |
+------------+
| CS         |
+------------+
| EIP        |
+------------+

Now it tries to access address at 0FFFFFFFFhand page fault is generated so stack looks like this:

+------------+
| Eflags     | saved from int1/int3
+------------+
| CS         | saved from int1/int3
+------------+
| EIP        | saved from int1/int3
+------------+
| Eflags     | saved for int 0e
+------------+
| CS         | saved for int 0e
+------------+
| EIP        | EIP == 0FFFFFFFFh
+------------+
| ErrorCode  | ErrorCode
+------------+

Now if int 0e handler detects that access to 0FFFFFFFFh is caused by certain conditions as shown in above disassembly it will

align stack, eg. remove data passed to int 0e handler and call KiTrap01/KiTrap03/KiTrap0D depending on instruction that

caused access violation. For fun I wrote small driver to do the same thing as themida and you may find it in [intfoobar]

folder witch will grant any ring3 application to read/write IDT and also will set int1/int3 handlers to 0FFFFFFFFh. Run your

debugger and debug any application w/o problem. Difference between my driver and oreans.sys is that oreans.sys will BSOD your

system if int1/int3 exception occurs in protected process. You may change protection in themida protected application and

inject nonintrusive tracers in it to see what is happening withcodeonce we reachcode caves.

We MAY use PAGE_GUARD in protected process to trace its execution. PAGE_GUARD, PAGE_NOACCESS and other page attributes are

implemented in Windows memory manger troughPage File. Ifwe trace VirtualProtect withany "weird" attributes set that are not

CPU specific we may see how page is erased from PTE and P bit is set to 0, also ntoskrnl.exe generates some "internal

protection mask" , stores PFN in PTE and uses invlpg to flush TLB, making sure that any access to PAGE goes trough int0e

handler. Once _KiTrap0E gains control it will check "internal protection mask" and decide what exception to throw back to

ring3. If no exception is needed PAGE is brought back to memoryand PTE is set to point to right Physical frame and P flag is

set to 1. Playing with PFN saved in PTE is kinda dangerous, we don't know if Microsoft is going to change PFN format so we

can't write any generic toolto check for presence ofPAGE_GUARD, in such way themida int 0e handler doesn't know if exception

occurred due to PAGE_NOACCESS or PAGE_GUARD. For moreonthis subject please refer to [6].

Role of int 0e handler hook is to prevent system from crashing if some other application access int1/int3, and to grant

access to the themida protected process to ring0 memory allocated by oreans.sys and to IDT as well.

Now when we know theory we should try that in practice, and see if everything worked as we planned. For this I have used

again hook in GetModuleHandleA to reach OEP, but now, I redirect executionto mycode whichwillprepare nonintrusive tracer.

Before we move to nonintrusive tracer forthemida protected application, you must be aware that we are not allowed to use

int1/int3 in it or we will get BSOD. So how to step over instruction which generated exception? Simple, use some other

instruction, privileged instruction. I used CLI, its usage in ring3 will generate privileged instruction exception and its

size is one byte (0fah), same size as int3h(0cch).

Okiletstake a lookat our crypted codeagain:

.dumped:0082E03E               call @System@@LStrAsg$qqrv
.dumped:0082E043               call near ptr sub_BB07CD
.dumped:0082E048               or eax, [eax]
.dumped:0082E048 ; ----------------------------------------------------
.dumped:0082E04A               db 0
.dumped:0082E04B               db 0
.dumped:0082E04C               db 0
.dumped:0082E04D               db 0
.dumped:0082E04E               db 0
.dumped:0082E04F               db 0
.dumped:0082E050               db 3Ah
.dumped:0082E051               db 1
.dumped:0082E052               db 0
.dumped:0082E053               db 0
.dumped:0082E054               db 20h
.dumped:0082E055               dd 8F20EF73h
.dumped:0082E059               dd 0AF22EC81h
.dumped:0082E05D               dd 8ACBEB98h
.dumped:0082E061               dd 8ACBEB98h


.dumped:0082E18D               db 0
.dumped:0082E18E               db 0
.dumped:0082E18F               db 0
.dumped:0082E190               db 1
.dumped:0082E191               db 0
.dumped:0082E192               db 0
.dumped:0082E193               db 0
.dumped:0082E194               db 3Ah
.dumped:0082E195               db 1
.dumped:0082E198               db 20h
.dumped:0082E199 ; --------------------------------------------------------
.dumped:0082E199               mov cl, 1
.dumped:0082E19B               mov edx, esi
.dumped:0082E19D               mov eax, [ebp-4]

Call at 0082E043h will actually leave on stack address of crypted code and jmp to decrypt proc. Also you might see how there

is same code marker at 0082E048 and 0082E18D, don't be confused with or eax, [eax] it is also signature but disassembled

byIDA

My next approach was to change call near ptr sub_BB07CD with jmp to my hook which will initialize nonintrusive tracer, store

good ret address on stack and wait for access in code section. Actually I didn't know at first that this code is crypted, my

original intension was to log which part of code are accessed, what register values re used at that point, and then, later

on, to emulate those calls. After running tracer for 1st time I was more then happy, I had decrypted code. After I saw that

my approach is working I created two loaders: loader_bingo and loader_type3. Loader bingo is supposed to tell me from where

starts decrypted code, and loader_type3 is used later on to dump that memory region. There is totally 5 code crypt blocks, 3

during initialization and 2 during gallerycreation. [Allofdumped blocks are supplied withthis document]

82E055h
82E6C3h
855361h
826C84h
82740Ch

Let's take a lookat important partsofnonintrusive tracer forthis application:

                             cmp [ebp+4], 407419h
                             je __makefun
                             mov eax, 400000h
                             pop ebp
                             retn 4
__makefun:                   pusha
                             call newcodedelta
newcodedelta:                pop ebp
                             sub ebp, offset newcodedelta
                             mov edi, 082e043h
                             lea ebx, [ebp+test2]
                             mov ecx, edi
                             add ecx, [edi+1]
                             add ecx, 5
                             mov dword ptr[ebp+ring0ring3address+1], ecx
                             mov ecx, edi
                             mov byte ptr[edi], 0e9h
                             add ecx, 5
                             sub ebx, ecx
                             mov dword ptr[edi+1], ebx
                             popa
                             mov eax, 400000h
                             pop ebp
                             retn 4

This part of code is called from GetModuleHandleA hook, and is used to check when we are close to our OEP. When we reach OEP

we will hook 1st call to themida decrypt code and redirect executiontoourcodewhichwillinitialize nonintrusive tracer:

test2                        label dword
                             pusha
                             call test2delta
test2delta:                  pop ebp
                             sub ebp, offset test2delta
                             mov [esp+8*4], 0082E048h
                             pushs <"ntdll.dll">
                             call [ebp+GetModuleHandleA]
                             mov [ebp+ntdll], eax
                             mov ebx, [eax+3ch]
                             add ebx, eax
                             pushv <dd ?>
                             push PAGE_EXECUTE_READWRITE
                             push [ebx.pe_sizeofimage]
                             push eax
                             call [ebp+VirtualProtect]
                             gethash <NtContinue>
                             push hash
                             push [ebp+ntdll]
                             call getprocaddress
                             mov [ebp+NtContinue], eax
                             gethash <KiUserExceptionDispatcher>
                             push hash
                             push [ebp+ntdll]
                             call getprocaddress
                             mov [ebp+KiUserExceptionDispatcher], eax
                             mov edi, eax
                             lea ebx, [ebp+nonintrusive_logger]
                             mov ecx, edi
                             mov byte ptr[edi], 0e9h
                             add ecx, 5
                             sub ebx, ecx
                             mov dword ptr[edi+1], ebx
                             add edi, 7
                             mov dword ptr[ebp+retkiuser+1], edi
                             pushv <dd ?>
                             push PAGE_EXECUTE_READWRITE or PAGE_GUARD
                             push 45bb01h
                             push 400000h
                             call [ebp+VirtualProtect]
                             popa
ring0ring3address:           push 0deadc0deh
                             retn

test2 code is here used to initialize nonintrusive tracer, 1st we change ret address onstack to point to crypted code, then

we retrieve base of ntdll.dll and change protection on it to PAGE_EXECUTE_READWRITE, then we get address of

KiUserExceptionDispatcher and NtContinue because we need both for nonintrusive tracer. Now we insert hook in KiUser as I did

in ExeCryptor and Anit-anti-dump and nonintrusive tracers articles [4, 5] and we wait for a little bit of magic.

Nonintrusive tracer:

nonintrusive_logger          label dword
                             mov ecx, [esp+4]
                             mov ebx, [esp]
                             cmp dword ptr[ebx], EXCEPTION_PRIV_INSTRUCT
                             je __check_CLI
                             cmp dword ptr[ebx], EXCEPTION_GUARD_PAGE
                             jne retkiuser
                             call nidelta
                             nidelta: pop ebp
                             sub ebp, offset nidelta
                             mov esi, ecx
                             cmp [esi.context_eip], end_address
                             je remove_pguard
                             pushv <dd ?>
                             push PAGE_EXECUTE_READWRITE
                             push 45bb01h
                             push 400000h
                             call [ebp+VirtualProtect]
                             mov ebx, [esi.context_eip]
                             cmp ebx, bingo_address
                             jne __donotdumpregion
                             push bingo_size
                             push bingo_address
                             call dumpregiontofile
                             pushs <"dumping address and removing PG", 13, 10>
                             call [ebp+OutputDebugStringA]
                             push 0
                             push esi
                             call [ebp+NtContinue]
                             nop
                             nop

This is part whichactuallydumps regiononce certainconditions are met (eip == bingo_address). If there are no our conditions

yet, I dump via OutputDebugStringA instructions that caused access to my code and EIP. Then as in any other debugger, I get

len of instruction and store CLI after it making sure not to lose controlover nonintrusive tracer.

There are a few values used by me in loader_type3:

bingo_address            equ         82e6c3h
bingo_size               equ         0082E74Fh-bingo_address
call_address             equ         0082E6B1h
ret_address              equ         call_address+5
end_address              equ         0082E750h

bingo_address    - address where decrypted code is (find it with loader_bingo)
bingo_size       - len of crypted code
call_address     - address where call to Decrypt is
ret_address      - adress left on stack by call (call_address+5)
end_address      - address of 1st valid instruction after crypted code

One example would be muchbetter:

.dumped:0082E6B1        call near ptr sub_BB07CD   <-- call_address
.dumped:0082E6B6        or eax, [eax]              <-- ret_address
...
.dumped:0082E750        mov edx, offset aSoftwareAdva_4
.dumped:0082E755        lea ecx, [ebp-0CCh]
end_address = 82E750h

loader_bingo only needs these 3 values to work and by launching loader_bingo with those values and watching its output

inDebugView we get this:

00000009 1.56604767 [1524] Accessing to page from : 0x00BB0B93
00000010 1.56610692 [1524] CLI reached
00000011 1.56645024 [1524] Accessing to page from : 0x00BB156B
00000012 1.56649160 [1524] CLI reached

00000277 3.75921321 [1524] Accessing to page from : 0x00B0A7ED
00000278 3.75996923 [1524] CLI reached
00000279 3.76135755 [1524] Accessing to page from : 0x0082E6C3
00000280 3.76140451 [1524] CLI reached
00000281 3.76171827 [1524] Accessing to page from : 0x0082E6C8
00000282 3.76175857 [1524] CLI reached

Well there is start of decrypted code (bingo_address): 0x0082E6C3 if we apply these values to loader_type3 then you willget

dump ofthat smallregion:

seg000:00000000               mov edx, 830084h
seg000:00000005               lea ecx, [ebp-0C0h]
seg000:0000000B               mov eax, 830658h
seg000:00000010               call near ptr 0FFFF49B5h
seg000:00000015               mov edx, [ebp-0C0h]
seg000:0000001B               mov eax, [ebp-4]
seg000:0000001E               mov eax, [eax+600h]
seg000:00000024               call near ptr 0FFC35415h
seg000:00000029               mov edx, 830084h
seg000:0000002E               lea ecx, [ebp-0C4h]
seg000:00000034               mov eax, 83066Ch
seg000:00000039               call near ptr 0FFFF49B5h
seg000:0000003E               mov edx, [ebp-0C4h]
seg000:00000044               mov eax, [ebp-4]
seg000:00000047               mov eax, [eax+604h]
seg000:0000004D               call near ptr 0FFC35415h
seg000:00000052               mov edx, 830084h
seg000:00000057               lea ecx, [ebp-0C8h]
seg000:0000005D               mov eax, 830680h
seg000:00000062               call near ptr 0FFFF49B5h
seg000:00000067               mov edx, [ebp-0C8h]
seg000:0000006D               mov eax, [ebp-4]
seg000:00000070               mov eax, [eax+608h]
seg000:00000076               call near ptr 0FFC35415h
seg000:0000007B               call near ptr 374C95h
seg000:00000080               or eax, [eax]

Voila, now you have to repeat all steps for all 5 crypted code sequences. I gave you addresses so it will not be problem for

you to find them. To fix dump fast I wroteone smalltoolcalled offset fixer, actually I used it to fix SVKP code_crypt macros

5-6 months ago, but it will work like a charm here. [ofixer folder]

We take all five dumps and store them in same folder with our dump, all regions have filenames as virtual_address.bin so

offset fixer will search in current directory for *.bin and from name of file will extract virtual_address and apply fix to

dump. All we have to do now is to patch all calls to decrypt codeproceduretoourdecrypted code:

IMAGE-04

Now werunofixer.exe and select test3.exe (myfinaldump):

IMAGE-05

Now all we have to do is to apply patches, each call _decrypt should be patched as shown on this picture:

IMAGE-06

And it willjmp to decrypted code:

IMAGE-07

Indecrypted code wefix call_EncryptCodeto jmp __next_valid_code:

IMAGE-08

You have to repeat these steps for all 5 code blocks, you have all addresses, you have all dumped regions allyou have to do

is to applythemusing [ofixer.exe].

And we are done, we run unpacked application and try to produce some “gallery” and we see that we have unpacked it

perfectly:

IMAGE-09

That's it… if you want to crack it go ahead; I was interested in themida ring0 protection, not in application itself.

5. Conclusion

Verygood protection, verygood, ifI was software developer I would use themida 1.0.0.5 to protect my application. That would

for sure nook 90% ofreversing communityand your application would remain uncracked for a long time It was fun to play with

themida, just to show myself that I can do it. Now Iwillfocus onsome other protector

                                                    S verom uBoga, deroko/ARTeam

Allthe code provided withthistutorialis free forpublic use, just make a greetzto the authors and the ARTeamifyou

finditusefulto use. Don'tuse these concepts formaking illegaloperation, allthe info here reported are only meant forstudying

andtohelp having a betterknowledge ofapplication code security techniques.

6. References/Tools

[1] Unpacking Armadilloed DLL, deroko, http://tutorials.accessroot.com
[2] DebugView, Mark Russinovich, www.sysinternals.com
[3] AdvancedSubmitter 4.1.4,Target,
http://root.accessroot.com/tools/AdvSubmitter-v4.1.4-Unregistered.exe
[4] Unpacking and Dumping ExeCryptorand coding loader, deroko,http://tutorials.accessroot.com
[5] Anti-Anti-Dump and nonintrusive tracers, deroko, http://tutorials.accessroot.com
[6] Microsoft c Windows R Internals, Mark Russinovich, David Solomon, Microsoft Press

7. Greetings

I wish to tank all the ARTeam members for sharing their knowledge, to 29a virus writing group for one of the best e-zines, to

my friends from phearless e-zine, and to all great coders out there… and ofcourse you for reading this article.

IMAGE-10
http://cracking.accessroot.com

[培训]内核驱动高级班,冲击BAT一流互联网大厂工 作,每周日13:00-18:00直播授课

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (5)
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
Isaiah 10 2006-10-17 02:08
2
0
这个是1.0.0.5版本的。对你没有帮助
现在的themida主要是VM  BT
雪    币: 154
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jazhi 2006-10-18 10:56
3
0
研究的就是1.0.0.5 驱动版啊
雪    币: 320
活跃值: (104)
能力值: (RANK:180 )
在线值:
发帖
回帖
粉丝
djpvd 4 2006-10-21 10:36
4
0
最初由 jazhi 发布
研究的就是1.0.0.5 驱动版啊


我办?一件事 不管是1.5.0.0或是1.0.0.5 或是其他版本加? 用PEiD 蒌入都是锢示themida 1.0.0.5

我已?更新咿 userdb.txt 了

我感迂有些不是所洲1.0.0.5加的?

?上真的是 VM 的催?人很钷大
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
kongruojun 2006-10-27 01:50
5
0
要是51PYWG的达达愿意在这里传授点经验就好了,好象他们的破解里脱了1.0.0.5的壳。我对壳没共鸣,加密壳捍不动,见到ASPR都腿软。
雪    币: 2108
活跃值: (208)
能力值: (RANK:1260 )
在线值:
发帖
回帖
粉丝
arhat 31 2006-10-27 17:49
6
0
lwglucky已经翻译了这篇文章,正在修改中。。。
感谢lwglucky
游客
登录 | 注册 方可回帖
返回