Interlok VXD vagaries
defeating anti-debug trick inside tpkd.vxd

Not Assigned
by macilaci
Courtesy of Fravia's page of reverse engineering
slightly edited
by fravia+
I'll comment after having read it (you may of course comment my comments, I'll probably publish that as well :-)
There is a crack, a crack in everything That's how the light gets in
( )Beginner ( )Intermediate (X)Advanced (X)Expert

VxD protections seems harder to defeat, especially when need each time to restart. Do the Interlok guys make jokes from you? Be a good guy! Don't load the winice!
Interlok VXD vagaries
defeating anti-debug trick inside tpkd.vxd
Written by macilaci

          Joking apart. Guys from Interlok made device driver in order to 
defeat the winice. The tpkd.vxd is a part of Installshield protection.
In this document I will describe only the vxd part of this protection, 
the rest is on you. 

Tools required
Winice,IDA,filemon,exespy some VxD info: iczelion VxD tuts, Win98DDK /, some hw info about i/o ports

Target's URL/FTP /*get the pwd for instalation*/,,

Program History
Installshield - when you need to make instalation for your proggy. I haven't seen better program for making instalations.

I - sniff around

 I started the debug session with loading the program. I hit the CTRL+D, typed the
BMSG XXX ... then a restart. Wow. Trap for winice. Next I tried filemon and exespy.
Worked! I found vl.vxd and tpkd.vxd. Both are dynamically loaded. Tpkd.vxd is loaded
via CreateFileA. So I put the breakpoint on the control of the VXD. First of course 
I did bpx CreateFileA.

II - the main problem

 So we put bpx on control of the tpkd.vxd. Do it carefully! Otherwise you have 
to reboot. 

C000693A                 push    eax         ;place the bpx before the cli instruction
C000693B                 pusha
C000693C                 cld
C000693D                 pushf
C000693E                 cli
C000693F                 cmp     ds:dword_C0002400, 0

To do this propelry put bpx on CreateFileA or DeviceIoControl. After winice informs you
that tpkd module is loaded do the vxd command and find the control dispatcher.
After winice pops up step little inside the vxd. 
When I flew trough this piece of code I found something interesting:

C0000AAA                 push    ebp
C0000AAB                 mov     ebp, esp
C0000AAD                 sub     esp, 20h
C0000AB0                 push    ebx
C0000AB1                 push    esi
C0000AB2                 push    edi
C0000AB3                 mov     [ebp+var_C], 88h
C0000AB7                 push    ebx
C0000AB8                 push    dx
C0000ABA                 push    ax
C0000ABC                 lea     ebx, loc_C0000AD5        
C0000AC2                 xor     byte ptr [ebx], 0BEh       ;byte decryptor
C0000AC5                 jmp     short $+2
C0000AC7                 mov     dx, 38h
C0000ACB                 mov     ax, 80h
C0000ACF                 pushfw
C0000AD1                 cli
C0000AD2                 shl     dx, 1
C0000AD5 loc_C0000AD5:                           ; DATA XREF: sub_C0000AAA+12o
C0000AD5                 push    eax             ; out 70,80 - disable the NMI signal
C0000AD5                                         ;
C0000AD6                 xor     byte ptr [ebx], 0BEh
C0000AD9                 lea     ebx, loc_C0000AE8
C0000ADF                 xor     byte ptr [ebx], 8Ch       ;same as above
C0000AE2                 jmp     short $+2
C0000AE4                 jmp     short $+2
C0000AE6                 inc     dx              
C0000AE8 loc_C0000AE8:                           ; DATA XREF: sub_C0000AAA+2Fo
C0000AE8                 pusha                             ;in ax,71 ; ax=0
C0000AE9                 mov     ah, al
C0000AEB                 mov     al, 0
C0000AED                 dec     dx
C0000AEF                 xor     byte ptr [ebx], 8Ch
C0000AF2                 lea     ebx, loc_C0000AFF
C0000AF8                 xor     byte ptr [ebx], 8Fh
C0000AFB                 jmp     short $+2
C0000AFD                 jmp     short $+2
C0000AFF loc_C0000AFF:                           ; DATA XREF: sub_C0000AAA+48o
C0000AFF                 popa                               ; out 70,00
C0000B00                 popfw
C0000B02                 mov     byte ptr [ebp+var_8], ah

After this again interesting piece:

C0000B3D                 mov     dword ptr [eax], 4245C8Bh  ; what's this?
C0000B43                 mov     eax, [ebp+var_20]
C0000B46                 add     eax, 4
C0000B49                 mov     [ebp+var_20], eax
C0000B4C                 mov     eax, [ebp+var_20]
C0000B4F                 mov     dword ptr [eax], 66D23366h
C0000B55                 mov     eax, [ebp+var_20]
C0000B58                 add     eax, 4
C0000B5B                 mov     [ebp+var_20], eax
C0000B5E                 mov     eax, [ebp+var_20]
C0000B61                 mov     dword ptr [eax], 0E2C16642h
C0000B67                 mov     eax, [ebp+var_20]
C0000B6A                 add     eax, 4
C0000B6D                 mov     [ebp+var_20], eax
C0000B70                 mov     [ebp+var_A], 0C3h
C0000B74                 mov     eax, [ebp+var_20]
C0000B77                 mov     dword ptr [eax], 0EC426605h
C0000B7D                 mov     eax, [ebp+var_20]
C0000B80                 add     eax, 4
C0000B83                 mov     [ebp+var_20], eax
C0000B86                 jmp     short $+2
C0000B88                 push    offset byte_C0001D44
C0000B8D                 lea     eax, [ebp+var_1C]
C0000B90                 call    eax             ; call the above placed code
C0000B90                                         ;
C0000B92                 pop     ecx

C0000B9A                 call    sub_C000481F
C0000B9F                 mov     [ebp+var_4], eax
C0000BA2                 push    offset loc_C0000950
C0000BA7                 push    1
C0000BA9                 mov     ecx, offset byte_C0000130
C0000BAE                 call    sub_C00047A3
C0000BB3                 call    [ebp+var_4]     ; call what?
C0000BB6                 pop     edi
C0000BB7                 pop     esi
C0000BB8                 pop     ebx
C0000BB9                 leave
C0000BBA                 retn

I stepped inside the C0000BB3  call [ebp+var_4]. The tpkd was fiddling the winice code,
read my Interrupt descriptor and placed some strange values inside debug registers.
This was too much! At third or fourth time you reach the control comes the restart.
Then I put the whole problem on the message board. Spath gave me some hints. Thanks Spath!
The restart was done trough keyboard controller /*out 64,fe*/. Nice piece of code: 

C000451E                 push    ebp             ; come never back
C000451F                 mov     ebp, esp
C0004521                 push    ecx
C0004522                 push    ebx
C0004523                 push    esi
C0004524                 push    edi
C0004525                 mov     [ebp+var_4], ecx
C0004528 loc_C0004528:                           ; CODE XREF: sub_C000451E+1Aj
C0004528                 mov     dx, 32h          ;dx=32 - hide the value!
C000452C                 shl     dx, 1            ;dx*2=64 -the keyb. controller
C000452F                 in      al, dx          ; AT Keyboard controller 8042.
C0004530                 jmp     short $+2
C0004532                 jmp     short $+2
C0004534                 test    al, 2
C0004536                 jz      short loc_C000453A
C0004538                 jmp     short loc_C0004528
C000453A ; ---------------------------------------------------------------------
C000453A loc_C000453A:                           ; CODE XREF: sub_C000451E+18j
C000453A                 mov     al, 0FEh
C000453C                 out     dx, al          ; AT Keyboard controller 8042. 
C000453C                                         ; Resend the last transmission alias reset
C000453D loc_C000453D:                           ; CODE XREF: sub_C000451E+1Fj
C000453D                 jmp     short loc_C000453D 

I was missing some info so I downloaded the intel's keyboard controller manual. It doesn't
matter which one. It should be 8042 compatible. I found the 8XC51SL/LOW VOLTAGE 8XC51SL's
datasheet. It says:

Power Down mode can only be exited via a reset.
This reset may occur either from the RST pin, or an
internally generated reset. See the 51SL Hardware
Description (Order No. 272268) for a detailed de-
scription of this reset. 

Internal reset. I patched the vxd immediately - location at C000451E to ret. It worked with PAGE 
fault. Pretty complicated, huh? - Did you find this text? Pretty joke. No, it wasn't the stack 
problem. When I single stepped the first time routine the proggy worked! So it's the NMI problem. 
Try to jump over the in and outs in the C0000AAA subroutine. 
It fails when you reach this:

C0000BA9                 mov     ecx, offset byte_C0000130
C0000BAE                 call    sub_C00047A3
C0000BB3                 call    [ebp+var_4]              ; page fault inside
C0000BB6                 pop     edi
C0000BB7                 pop     esi
C0000BB8                 pop     ebx
C0000BB9                 leave
C0000BBA                 retn

At this point I tried a newbie trick - to change the C0000BB3 location to nops. Man! It works!
The tpkd is defeated.

Final Notes
 Programmers, don't make jokes. You just give hints to cracker where not to search.
The patch is pretty easy, huh?
  Special thanks to Spath who gave me some useful hints.
PS: I think there are still some traps left, so be careful.

Ob Duh
I wont even bother explaining you that you should BUY this target program if you intend to use it for a longer period than the allowed one. Should you want to STEAL this software instead, you don't need to crack its protection scheme at all: you'll find it on most Warez sites, complete and already regged, farewell, don't come back.

You are deep inside fravia's page of reverse engineering, choose your way out:

redhomepage redlinks redsearch_forms red+ORC redhow to protect redacademy database
redreality cracking redhow to search redjavascript wars
redtools redanonymity academy redcocktails redantismut CGI-scripts redmail_fravia+
redIs reverse engineering legal?