kohan v1.1.0.0 , sd 2.40.10, (c) r!sc fri - mon ;)

bad key #2? causes 

KOHAN caused an invalid page fault in
module ~DF394B.TMP at 0167:1002462b.

:loadlibrarya df349b
The value 10000000 is (a) ~DF394B
0167:00684E40  FF5178              CALL      [ECX+78]
0167:00684E43  8945F8              MOV       [EBP-08],EAX
0167:00684E46  837DF800            CMP       DWORD PTR [EBP-08],00
0167:00684E4A  750D                JNZ       00684E59

:loadlibrarya de1da0
The value 1200000 is (a) ~DE61BB
0167:100018F7  FF151C500410        CALL      [KERNEL32!LoadLibraryA]
0167:100018FD  A36C410610          MOV       [1006416C],EAX
0167:10001902  833D6C41061000      CMP       DWORD PTR [1006416C],00

; jmp oep
006840F1 jmp     loc_549AA5

df349b...

00CF32F0 - for fixing up SDapi jump table / etc .. dword for first api_struct in kohan is 1587f8h
    00D26D18 dword_D26D18    dd 1587F8h ; DATA XREF: sub_CE8F30+D1
    
    proc that does the crap is at CD4530 .. esp+10h ? -> first api_struct?

bpx getdrivetypea /pedump 10000000 1000 c:\df349b.dll,
run my maid matilda on it ... load into ida, goto Ox12121212 :-)

10004E5A loc_10004E5A:                           ; CODE XREF: Ox12121212+18Ej
10004E5A                 push    32h
10004E5C                 push    6Eh
10004E5E                 call    nullsub_2
10004E63                 add     esp, 8
10004E66                 push    1F4h
10004E6B                 push    64h
10004E6D                 call    nullsub_2
10004E72                 mov     eax, dword_100592C8    ; *
10004E77                 add     esp, 8
10004E7A                 lea     ecx, [ebp+var_8]
10004E7D                 lea     edx, [ebp+var_4]
10004E80                 push    ecx
10004E81                 push    edx
10004E82                 push    eax    ; **
10004E83                 push    3
10004E85                 push    esi
10004E86                 call    sub_10004770   ; 'dd esp l 10'

    [esp+0c] -> rva to ptr for first api_struct
    [esp+04] -> imagebase of module using api
    
016F:008BFABC 10004E8B  10000000  00000003  0005B400      .N..............
016F:008BF2D0 1000561C  01200000  00000002  0002F3F8      .V.... .........
016F:008BFA78 1001A013  00400000  00000001  0017E030      ......@.....0...

    100592C8 dword_100592C8  dd 5B400h  ; DATA XREF: Ox12121212+1C2
     is ptr to first api struct in df349b.dll

    10058D18 dword_10058D18 dd 17E030h  ; DATA XREF: .text:1001A003
     is ptr to first process api struct :p


:SDapi exit
0167:100256FD  9D                  POPFD
0167:100256FE  C3                  RET
:s 0 l -1 61 9d c3 5f 5e 5b 8b e5 5d c3
Pattern found at 016F:100256FC (100256FC)

10025706 -> 10 bytes padding

part of SDapi proc is encrypted / decrypted / encrypted, using crc type procedure ..

10024cf8, 10025209, 100252f5 are the culprit mov's .. two byte opcodes ... first execution,
he encrypts 70h bytes and sets a flag, so next time he skips the first encrypt procedure..

:cd check call
0167:01212859  68707A2301          PUSH      01237A70
0167:0121285E  E87D2CFFFF          CALL      012054E0
0167:01212863  83C404              ADD       ESP,04
0167:01212866  85C0                TEST      EAX,EAX
0167:01212868  7514                JNZ       0121287E


01205842                 push    0
01205844                 lea     edx, [ebp+var_120]
0120584A                 push    edx
0120584B                 call    sub_1206810    ; eventually call get key morphs?
01205850                 add     esp, 8
01205853                 mov     [ebp+var_8], eax

; key morph proc, one param, ptr to memory to store key
01208AD0 sub_1208AD0     proc near               ; CODE XREF: sub_1215DA0+76p

; key morph proc, no param, returns eax -> ptr to morphs
0120E230 sub_120E230     proc near               ; CODE XREF: sub_120D220+31p

:key morphs from 8ad0
F108DD78  71F3D545  261E4F2E  161317CE
5B1FD3BA  FA2E5F3B  1BD26E8A  5B1ED206
8D6F3013  E94F3DFF  (cf1088)
8D6F1813  C14F3DD7  (cf0c84)

;key morphs from e230
E0CB3316  0011C068
169561F2  311BFB09
16E5263A  F8606B90  18E8DB73  3171CFEF
8E67C25F  7FDE6AF8  7D4F08B2  70DD378A

; various other key morphs
9CFE94E0, D78A3FE9, A167D52E, AB3E1BFC, 3D42A236
9AB59E42, 7A5BD68B, F6914827, *08F2C0CD
F3D2E6E9

0121328A mov     [ebp+var_1C], 9CFE94E0h
012133D3 mov     [ebp+var_1C], 0D78A3FE9h
012135E8 mov     [ebp+var_1C], 0A167D52Eh
01213D38 mov     [ebp+var_1C], 3D42A236h

012149FE mov     [ebp+var_4], 0AB3E1BFCh

01215146 call    s_1205380_mov_eax_0C56B5472h   max - 0CCD1124Eh
0121514B push    eax
0121514C mov     ax, [ebp+arg_0]
01215150 push    eax
01215151 call    sub_1211550
-
012115AA mov     ecx, [ebp+dd_c56b5472]
012115AD push    ecx
012115AE call    s_1211000_xor_arg_5FDECA30h    max - xor 0DB0C2B95h
012115B3 add     esp, 4
012115B6 mov     [ebp+dd_9ab59e42], eax
-
0121186D mov     edx, [ebp+dd_c56b5472]
01211870 push    edx
01211871 call    s_1211110_xor_arg_0BF3082F9h   max - xor 659978E1h
01211876 add     esp, 4
01211879 mov     [ebp+dd_7a5bd68b], eax
0121187C mov     eax, [ebp+dd_c56b5472]
0121187F push    eax
01211880 call    s_1211440_xor_arg_0CD9994BFh
01211885 add     esp, 4
01211888 mov     [ebp+dd_08f2c0cd], eax
-
01211A0C mov     edx, [ebp+dd_c56b5472]
01211A0F push    edx
01211A10 call    s_1211220_xor_arg_33FA1C55h
01211A15 add     esp, 4
01211A18 mov     [ebp+dd_f6914827], eax

:-O

; var 24, if checks passed, is clone of dd_08f2c0cd ..

01211E7B lea     eax, [ebp+var_24]
01211E7E push    eax
01211E7F push    4
01211E81 push    9
01211E83 mov     ecx, dword_1237A84
01211E89 push    ecx
01211E8A call    sub_122B2F0    ; put key into 'morph buffer'

; var 50, if checks passed, is null ..
01211F9E mov     eax, [ebp+var_50]

; pirate cd patch 1203700 (or any other check proc) -> 33 c0 40 c3 !!

:anti bpm
:eb 10007ED0 33 c0 40 c3

:SDapi exit
0167:10024020  9D                  POPFD
0167:10024021  C3                  RET
:s 0 l -1 61 9d c3 5f 5e 5b 8b e5 5d c3
Pattern found at 016F:1002401F (1002401F)

; get wrapped dll count :-)
10029250 sub_10029250    proc near               ; CODE XREF: sub_10029030+118p
10029250 
10029250 arg_0           = dword ptr  4
10029250 arg_4           = dword ptr  8
10029250 arg_8           = dword ptr  0Ch
10029250 
10029250 mov     ecx, [esp+arg_0]
10029254 mov     eax, dword_1005AF34
10029259 cmp     ecx, eax
1002925B jb      short loc_10029261
1002925D xor     ax, ax
10029260 retn


10001f80 -> tea decrypt

10043c90 -> api unwrapper

10044C96 push    4493Eh ; api raxs ! :p

1002A200 -> thunk decrypt??

:10002bad - call tea decrypt

; get key 3 ?
1001A5E7 push    3
1001A5E9 call    sub_1002D400
; call decrypt
1001A606 call    sub_1000339D

[10065280] -> key struct .. (mov ecx, [10063200], mov ecx, [ecx+0c])

Break due to BPX #0137:1002D400  (ET=647.25 milliseconds)
:d ecx->c l 60
013F:00E00974 10045350  00CF047C  00000400  00000010      PS..|...........
013F:00E00984 10045350  00CF0880  00000400  00000010      PS..............
013F:00E00994 10045350  00CF0C84  00000400  00000010      PS..............
013F:00E009A4 10045350  00CF1088  00000400  00000010      PS..............
013F:00E009B4 10045350  00CF148C  00000400  00000010      PS..............
013F:00E009C4 10045350  00CF1890  00000400  00000010      PS..............

013F:00CF047C 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
013F:00CF0880 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
013F:00CF0C84 2E B7 B6 4F 04 78 D9 C6-90 38 5B 14 62 BE 42 FF  ...O.x...8[.b.B.
013F:00CF1088 2E B7 B6 4F 04 78 D9 C6-90 38 5B 14 62 BE 42 FF  ...O.x...8[.b.B.
013F:00CF148C 2E B7 B6 4F 04 78 D9 C6-90 38 5B 14 62 BE 42 FF  ...O.x...8[.b.B.


:


      
:raw key stuff
Break due to BPMB #0137:100058DD X DR3  (ET=5.23 seconds)
013F:012331E8 09 EE CA 3E D3 0C 27 02-75 79 D9 0F 0E 7C 7E 3B  ...>..'.uy...|~;
013F:012331F8 8C F3 25 48 3A DC C0 F8-1E 95 F9 31 29 68 AB 8B  ..%H:......1)h..
013F:01233208 F4 DF 85 04 B3 EF 50 F6-BA 58 A5 12 AD EF 63 E1  ......P..X....c.

012331E8 unk_12331E8     db    9 ;               ; DATA XREF: sub_122AF80+B8o

0122B034 mov     eax, [ebp+var_C]
0122B037 push    eax
0122B038 push    offset unk_12331E8
0122B03D push    2
0122B03F mov     ecx, dword_123868C
0122B045 push    ecx
0122B046 call    sub_1225840

-----------

; for reading and writing bytes into the 4kb key's ..

1002F060 mov     eax, [esp+arg_0]
1002F064 mov     edx, [ecx+4]
1002F067 cmp     eax, edx
1002F069 jnb     short loc_1002F073
1002F06B mov     ecx, [ecx]
1002F06D mov     al, [ecx+eax]
1002F070 retn    4

1002F030 mov     eax, [esp+arg_0]
1002F034 mov     edx, [ecx+4]
1002F037 cmp     eax, edx
1002F039 jnb     short loc_1002F04B
1002F03B mov     ecx, [ecx]
1002F03D mov     dl, [esp+arg_4]
1002F041 mov     [ecx+eax], dl
1002F044 mov     ax, 1
1002F048 retn    8

:bc*
:bpm cs:1002f0c0 x do "be1;bd0;x;"
:bpm cs:1002f1e0 x do "be0;bd1;dd ecx l10;d *(ecx)l10;d *(ecx+8)l10;x;"

1002F0C0 push    ebp
1002F0C1 mov     ebp, esp
..
1002F1DD lea     ecx, [ebp+arg_0]
1002F1E0 call    sub_1002F010
1002F1E5 cmp     [ebp+var_4], eax

; extra api wrapper stuff
1004411F mov     eax, [ebp+var_20]
10044122 shr     eax, 3
10044125 mov     ecx, [ebp+var_18]
10044128 mov     edx, dword_10065214
1004412E mov     ecx, [edx+ecx*4]
10044131 xor     edx, edx
10044133 mov     dl, [ecx+eax]
10044136 mov     ecx, [ebp+var_20]
10044139 and     ecx, 7
1004413C mov     eax, 1
10044141 shl     eax, cl
10044143 and     edx, eax
10044145 test    edx, edx
10044147 jz      short loc_100440E3

; lib id stuff
100445C0 mov     eax, [esp+arg_0]
100445C4 mov     ecx, dword_10065210
100445CA lea     eax, [eax+eax*2]
100445CD mov     al, [ecx+eax*2+2]
100445D1 and     eax, 1
100445D4 retn

; 100h byte key stuff..
1002562F mov     edx, [ecx+14h]
10025632 xor     edx, eax
10025634 and     edx, 40000000h
1002563A test    edx, edx          ; api struct contains a key?
1002563C jz      short loc_10025665
1002563E mov     eax, [ebp+arg_0]
10025641 mov     ecx, [eax+78h]    ; get key :-)
10025644 push    ecx
10025645 mov     edx, [ebp+arg_0]
10025648 mov     eax, [edx]
1002564A imul    eax, 14h
1002564D mov     ecx, [ebp+arg_0]
10025650 mov     edx, [ecx+50h]
10025653 xor     edx, eax          ; get offset to stamp it into (0..3fh)
10025655 push    edx
10025656 mov     eax, [ebp+var_30]  ; *
10025659 add     eax, 2Ch  ; 2ch to get virtual virtual pointer to special key buffer
1002565C push    eax
1002565D call    sub_10025CC0

10025D39 mov     ecx, [ebp+arg_0]
10025D3C mov     edx, [ecx+18h]
10025D3F mov     eax, [ebp+arg_4]
10025D42 cmp     dword ptr [edx+eax*4], 0A5A5A5A5h
10025D49 jnz     short loc_10025D5A
10025D4B mov     ecx, [ebp+arg_0]
10025D4E mov     edx, [ecx+18h]
10025D51 mov     eax, [ebp+arg_4]
10025D54 mov     ecx, [ebp+var_8]
10025D57 mov     [edx+eax*4], ecx

* remember ptr to key is in api_structs :-)
10024D0F mov     eax, [ebp+arg_0]   ; api struct
10024D12 mov     ecx, [eax]         ; decrypt key
10024D14 shl     ecx, 4
10024D17 mov     edx, [ebp+arg_0]
10024D1A mov     eax, [edx+40h]     ; struct + 40h -> encrypted ptr to special key buffer
10024D1D xor     eax, ecx
10024D1F mov     [ebp+var_30], eax  ; store ptr in var_30 !
10024D22 jmp     loc_10024D43

; jmp api lookup array .. 283000h is stxt774 RVA
1005A4C8 dword_1005A4C8  dd 283000h              ; DATA XREF: sub_10044400+83r
1005A4CC dword_1005A4CC  dd 146F95h              ; DATA XREF: sub_10044400+2Bo
