Log in

View Full Version : Interlok v5 exploration...


ptrace
August 8th, 2004, 19:58
Hi all, my first post here. After doing a search and reading through the few posts on interlok that are here (the only real usefull info on the whole net actaully) I thought I would post some of my findings reguarding the v5 interlok protection running on OS X.

First things first, as per usual, there is a piece of anti-debugging code playing around with gdb, a nice suprise though is its monumentally simple, which is why I got past this part so quickly. It is done with the ptrace() function, this can be used in linux too, but what is passed to the function differs. Here is a small piece of code illustrating it.


Code:

#include <sys/types.h>
#include <sys/ptrace.h>

int main()
{
ptrace(PT_DENY_ATTACH,-1,0,-1);
printf("Hello\n";
return 0;
}


when this is compiled and run from the shell, it works just fine

./ad
Hello

when you attempt to load it into gdb you get this (notice no Hello)

(gdb) r
Starting program: ad
Reading symbols for shared libraries . done

Program exited with code 055.

simple enough, so all that was needed to bypass the anti-debugging in the target was to patch the args passed to ptrace to something benign. For example;

0x00001d64 <main+28>: li r3,31
0x00001d68 <main+32>: li r4,-1
0x00001d6c <main+36>: li r5,0
0x00001d70 <main+40>: li r6,-1
0x00001d74 <main+44>: bl 0x1f3c <dyld_stub_ptrace>

A quick look at /usr/include/sys/ptrace.h shows the various other values that one can use. The bytes for the above args are this

3860001f
3880ffff
38a00000
38c0ffff

So all thats needed is to swap out 3860001f (li r3,31) with 38600001 (li r3,1).

on a side note, A poke into /darwinsource/Current/xnu-517.3.7/bsd/kern/mach_process.c will show you what the call to ptrace actually does.


Ok now that the debugger is functional there is something of use. I esentially am going into interlok completely blind, I have no past experience with it and have no idea how it does its thing (yet).

From what I can tell, the specific target im playing with still uses the older CFM/PEF executable format, ie. code fragments like in OS9/8 and after some exploration it seems that interlok builds dynamic stub tables at run time. Incidentally using ptrace() as a breakpoint to get into the interlok code is very usefull FYI. At this point im still clueless as to what the kernel extention PACESupport.kext does, allthough im guessing its decryption (for PC people, PACESupport.kext should be on par with Tpkd.sys). I fired up a little utility called PEFViewer and was able to see a fair amount of the unencrypted pace code inside the target (which will remain nameless for the time being).

I did some tracing for awhile and stumbled upon what I think is the spot where code is either called after its decrypted, or something along those lines, but still cant quite visualize the whole picture of how interlok is working (v5 on PPC) in my head, so if anyone has anything at all they can add or suggest it would be great! documentation, experience from the PC side, whatever. Naturally if I find out anythign else I'll post it.

ptrace

dELTA
August 9th, 2004, 12:52
Thanks for sharing your info, you are very welcome to submit more info when you get even further into the protection too if you like.

LiSa
August 10th, 2004, 07:02
Hello, I know noting about mac, but here is a way to decrypt the tpkd.sys. Maybe you can look for similar algo in your mac files. The antidebuuging tricks in PC seems to be definitely harder to bypass....

seed1 equ 0B9D000C6h
seed2 equ 0B9AD7FC9h
seed3 equ 0AB3D2B3h
seed4 equ 0DA32C597h

; decrypt bin file
mov eax, ptData
add eax, Doffset
push 0
push seed1
push seed2
push seed3
push Dlen
push eax
call sub_12260

; decrypt bin file
mov eax, ptData
add eax, Doffset2
push 0
push seed1
push seed2
push seed4
push Dlen2
push eax
call sub_12260

; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ

; Attributes: bp-based frame

sub_12260 proc near ; CODE XREF: .text:0001115Ap

var_1C= word ptr -1Ch
var_18= word ptr -18h
var_14= word ptr -14h
var_10= dword ptr -10h
var_C= dword ptr -0Ch
var_8= dword ptr -8
var_4= dword ptr -4
arg_0= dword ptr 8
arg_4= dword ptr 0Ch
arg_8= dword ptr 10h
arg_C= word ptr 14h
arg_10= word ptr 18h
arg_14= byte ptr 1Ch

push ebp
mov ebp, esp
sub esp, 1Ch
push ebx
push esi
push edi
cmp [ebp+arg_0], 0
jz short loc_12275
cmp [ebp+arg_4], 0
jnz short loc_1227C

loc_12275: ; CODE XREF: sub_12260+Dj
xor eax, eax
jmp loc_1241A
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

loc_1227C: ; CODE XREF: sub_12260+13j
mov eax, [ebp+arg_0]
mov [ebp+var_8], eax
mov eax, [ebp+arg_4]
shr eax, 1
mov [ebp+var_C], eax
movzx eax, [ebp+arg_14]
test eax, eax
jnz short loc_122D6
mov eax, [ebp+arg_8]
shr eax, 10h
mov ecx, [ebp+arg_8]
add ecx, eax
and ecx, 0FFFFh
mov [ebp+var_4], ecx
movzx eax, word ptr [ebp+var_4]
movzx ecx, [ebp+arg_C]
cmp eax, ecx
jle short loc_122C9
movzx eax, [ebp+arg_C]
mov ecx, [ebp+var_4]
sub ecx, eax
mov [ebp+var_4], ecx
mov eax, [ebp+var_4]
and eax, 0FFFFh
mov [ebp+var_4], eax

loc_122C9: ; CODE XREF: sub_12260+50j
mov eax, [ebp+arg_8]
and ax, 0
or eax, [ebp+var_4]
mov [ebp+arg_8], eax

loc_122D6: ; CODE XREF: sub_12260+30j
cmp [ebp+var_C], 0
jnz loc_12379
mov eax, [ebp+var_8]
mov [ebp+var_10], eax
movzx eax, word ptr [ebp+arg_8]
movzx ecx, [ebp+arg_10]
imul eax, ecx
mov [ebp+var_4], eax
mov ax, word ptr [ebp+var_4]
mov dx, word ptr [ebp+var_4+2]
div [ebp+arg_C]
shl edx, 10h
mov dx, ax
mov [ebp+var_4], edx
mov ax, word ptr [ebp+var_4]
xchg ax, word ptr [ebp+var_4+2]
mov word ptr [ebp+var_4], ax
mov ax, word ptr [ebp+var_4]
mov [ebp+var_14], ax
movzx eax, [ebp+var_14]
and eax, 8000h
test eax, eax
jz short loc_12336
mov ax, [ebp+var_14]
add ax, [ebp+arg_C]
mov [ebp+var_14], ax

loc_12336: ; CODE XREF: sub_12260+C8j
mov ax, [ebp+var_14]
mov [ebp+var_18], ax
mov ax, [ebp+var_18]
shr ax, 8
mov [ebp+var_18], ax
mov eax, [ebp+var_10]
mov al, [eax]
xor al, byte ptr [ebp+var_18]
mov ecx, [ebp+var_10]
mov [ecx], al
mov eax, [ebp+var_10]
inc eax
mov [ebp+var_10], eax
mov eax, [ebp+var_4]
and ax, 0
mov [ebp+arg_8], eax
movzx eax, [ebp+var_14]
mov ecx, [ebp+arg_8]
or ecx, eax
mov [ebp+arg_8], ecx
jmp loc_12417
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

loc_12379: ; CODE XREF: sub_12260+7Aj sub_12260+1B1j
movzx eax, word ptr [ebp+arg_8]
movzx ecx, [ebp+arg_10]
imul eax, ecx
mov [ebp+var_4], eax
mov ax, word ptr [ebp+var_4]
mov dx, word ptr [ebp+var_4+2]
div [ebp+arg_C]
shl edx, 10h
mov dx, ax
mov [ebp+var_4], edx
mov ax, word ptr [ebp+var_4]
xchg ax, word ptr [ebp+var_4+2]
mov word ptr [ebp+var_4], ax
mov ax, word ptr [ebp+var_4]
mov [ebp+var_1C], ax
movzx eax, [ebp+var_1C]
and eax, 8000h
test eax, eax
jz short loc_123C9
mov ax, [ebp+var_1C]
add ax, [ebp+arg_C]
mov [ebp+var_1C], ax

loc_123C9: ; CODE XREF: sub_12260+15Bj
movzx eax, [ebp+var_1C]
shl eax, 8
movzx ecx, [ebp+var_1C]
sar ecx, 8
or eax, ecx
mov ecx, [ebp+var_8]
mov cx, [ecx]
xor cx, ax
mov eax, [ebp+var_8]
mov [eax], cx
mov eax, [ebp+var_8]
inc eax
inc eax
mov [ebp+var_8], eax
mov eax, [ebp+var_4]
and ax, 0
mov [ebp+arg_8], eax
movzx eax, [ebp+var_1C]
mov ecx, [ebp+arg_8]
or ecx, eax
mov [ebp+arg_8], ecx
mov eax, [ebp+var_C]
dec eax
mov [ebp+var_C], eax
cmp [ebp+var_C], 0
ja loc_12379

loc_12417: ; CODE XREF: sub_12260+114j
mov eax, [ebp+arg_8]

loc_1241A: ; CODE XREF: sub_12260+17j
pop edi
pop esi
pop ebx
leave
retn 18h
sub_12260 endp


; link bin file using

Dlen equ 064Dh

Doffset equ 771Ch
Doffset2 equ 7D6Ch

Patch_table_off equ 0BAE8h


xor ecx,ecx
mov ebx, ptpactch
ici:
mov edi,[ebx]
;int 3
cmp edi,0
jz out_loc
mov eax, ptData
add eax, Doffset
add eax, edi
lea esi,[ebx+4]
mov edi,[esi]
mov [eax],edi
add ebx,8
jmp ici

good luck

ptrace
August 12th, 2004, 19:56
Thanks much for the info LiSa. Unfortunatly the kext on OSX isnt encrypted at all (or fortunatly if you wanna look at it that way :P). I have poked around a little more and have noticed that there are a few more anti-debug tricks, still easy to bypass. I seem to have located the code that does the loading of various code fragments, and then decrypts them, but have yet to find a way to intercept/dump anything. The way this target is working, its still compiled in the old PEF binary format, which means it has resource forks and various other things, and code only gets loaded as its needed (ie, in fragments). Has anyone been sucessfull in coding a util that completely removes pace? (out of curiosity, I dont want it).

It seems like it should be very simple if I can located the proper places in the code to either a) clone the decrypt code and make an unpacker, or b) figure out a way to dump the code from memory after decryption. The hard part about b is that code is only loaded in fragments as its needed, so that is probably not too practical. Thats why I wonder if it has been done on PC. A is just a matter of coding the tool. Also, for anyone who has experience doing this on OS9/8/7, since these binaries are PEF they are essentially the same, if there is anything you can add please do (or PM it to me)