Dekripsi DLL DUP2 Patcher

From Indonesian Research And Development Center
Jump to: navigation, search

Disclaimer

Tutorial ini hanya untuk tujuan pembelajaran. Penulis tidak bertanggungjawab atas penggunaan maupun penyalahgunaan dari tutorial ini. Use at your own risk!


Pendahuluan

Dup2 Universal Patcher adalah aplikasi yang dapat digunakan untuk membuat patch pada sistem operasi Microsoft Windows. Aplikasi tersebut bersifat freeware dan dibuat oleh diablo2oo2. Pada tutorial kali ini, akan dibahas sedikit mengenai cara untuk melakukan dekripsi secara manual dll yang terdapat pada rilis yang menggunakan dup2 universal patcher.


Cara Pertama

Cara pertama, cukup mudah, cukup jalankan patcher/crack yang dibuat menggunakan dup2 dan lihat direktori temporary (%temp%) menggunakan windows explorer. Pada direktori tersebut nantinya akan ada file "dup2patcher.dll".


Cara Kedua

Cara ke-dua ini adalah cara yang ditempuh jika Anda ingin mengetahui proses ekstraksi library "dup2patcher.dll" tersebut dari resource. Sebagai catatan, cara ke-2 ini dilakukan dengan static analysis pada sistem operasi GNU/Linux. Berikut ini adalah langkah-langkahnya:

  • Siapkan aplikasi target yang dibuat menggunakan dup2.
  • Dengan melakukan disassembly, bisa terlihat bahwa aplikasi tersebut akan mengekstrak resource berupa "dll" dengan memperhatikan pada alamat 0040107D terdapat pemanggilan API "LoadResource", dan berikut ini adalah listing disassemblynya:
.text:00401037 ; =============== S U B R O U T I N E =======================================
.text:00401037
.text:00401037 ; Attributes: bp-based frame
.text:00401037
.text:00401037 sub_401037      proc near                            ; CODE XREF: start^p
.text:00401037
.text:00401037 LibFileName     = byte ptr -40Ch
.text:00401037 nNumberOfBytesToWrite= dword ptr -0Ch
.text:00401037 lpBuffer        = dword ptr -8
.text:00401037 hResInfo        = dword ptr -4
.text:00401037
.text:00401037                 push    ebp
.text:00401038                 mov     ebp, esp
.text:0040103A                 add     esp, 0FFFFFBF4h
.text:00401040                 push    esi
.text:00401041                 push    edi
.text:00401042                 push    ebx
.text:00401043                 push    0                            ; lpModuleName
.text:00401045                 call    GetModuleHandleA
.text:0040104A                 mov     dword_403030, eax
.text:0040104F                 mov     [ebp+lpBuffer], 0
.text:00401056                 push    0Ah                          ; lpType
.text:00401058                 push    offset Name                  ; "DLL"
.text:0040105D                 push    0                            ; hModule
.text:0040105F                 call    FindResourceA
.text:00401064                 or      eax, eax
.text:00401066                 jz      short loc_401089
.text:00401068                 mov     [ebp+hResInfo], eax
.text:0040106B                 push    [ebp+hResInfo]               ; hResInfo
.text:0040106E                 push    0                            ; hModule
.text:00401070                 call    SizeofResource
.text:00401075                 mov     [ebp+nNumberOfBytesToWrite], eax
.text:00401078                 push    [ebp+hResInfo]               ; hResInfo
.text:0040107B                 push    0                            ; hModule
.text:0040107D                 call    LoadResource
.text:00401082                 or      eax, eax
.text:00401084                 jz      short loc_401089
.text:00401086                 mov     [ebp+lpBuffer], eax
.text:00401089
.text:00401089 loc_401089:                                          ; CODE XREF: sub_401037+2F^j
.text:00401089                                                      ; sub_401037+4D^j
.text:00401089                 cmp     [ebp+lpBuffer], 0
.text:0040108D                 jz      short loc_4010C1
.text:0040108F                 push    4                            ; flProtect
.text:00401091                 push    1000h                        ; flAllocationType
.text:00401096                 push    [ebp+nNumberOfBytesToWrite]  ; dwSize
.text:00401099                 push    0                            ; lpAddress
.text:0040109B                 call    VirtualAlloc
.text:004010A0                 mov     edi, eax
.text:004010A2                 push    [ebp+nNumberOfBytesToWrite]
.text:004010A5                 push    [ebp+lpBuffer]
.text:004010A8                 push    edi
.text:004010A9                 call    RtlMoveMemory
.text:004010AE                 mov     [ebp+lpBuffer], edi
.text:004010B1                 push    0DEADBEEFh                   ; 0xDEADBEEF
.text:004010B6                 push    [ebp+nNumberOfBytesToWrite]  ; DLL size
.text:004010B9                 push    [ebp+lpBuffer]               ; DLL resource
.text:004010BC                 call    sub_401000                   ; decrypt the DLL
.text:004010C1
.text:004010C1 loc_4010C1:                                          ; CODE XREF: sub_401037+56^j
.text:004010C1                 cmp     [ebp+lpBuffer], 0
.text:004010C5                 jz      short loc_4010FB
.text:004010C7                 lea     eax, [ebp+LibFileName]
.text:004010CD                 push    eax                          ; lpBuffer
.text:004010CE                 push    400h                         ; nBufferLength
.text:004010D3                 call    GetTempPathA
.text:004010D8                 push    offset String2               ; "\\dup2patcher.dll"
.text:004010DD                 lea     eax, [ebp+LibFileName]
.text:004010E3                 push    eax                          ; lpString1
.text:004010E4                 call    lstrcatA
.text:004010E9                 push    [ebp+nNumberOfBytesToWrite]  ; nNumberOfBytesToWrite
.text:004010EC                 push    [ebp+lpBuffer]               ; lpBuffer
.text:004010EF                 lea     eax, [ebp+LibFileName]
.text:004010F5                 push    eax                          ; lpFileName
.text:004010F6                 call    sub_401184
.text:004010FB
.text:004010FB loc_4010FB:                                          ; CODE XREF: sub_401037+8E^j
.text:004010FB                 lea     eax, [ebp+LibFileName]
.text:00401101                 push    eax                          ; lpLibFileName
.text:00401102                 call    LoadLibraryA
.text:00401107                 or      eax, eax
.text:00401109                 jz      short loc_401130
.text:0040110B                 mov     ebx, eax
.text:0040110D                 push    offset ProcName              ; "load_patcher"
.text:00401112                 push    ebx                          ; hModule
.text:00401113                 call    GetProcAddress
.text:00401118                 or      eax, eax
.text:0040111A                 jz      short loc_40111E
.text:0040111C                 call    eax
.text:0040111E
.text:0040111E loc_40111E:                                          ; CODE XREF: sub_401037+E3^j
.text:0040111E                 push    ebx                          ; hLibModule
.text:0040111F                 call    FreeLibrary
.text:00401124                 lea     eax, [ebp+LibFileName]
.text:0040112A                 push    eax                          ; lpFileName
.text:0040112B                 call    DeleteFileA
.text:00401130
.text:00401130 loc_401130:                                          ; CODE XREF: sub_401037+D2^j
.text:00401130                 pop     ebx
.text:00401131                 pop     edi
.text:00401132                 pop     esi
.text:00401133                 leave
.text:00401134                 retn
.text:00401134 sub_401037      endp
  • Setelah melakukan alokasi memori dan resource dll disalin ke memori tersebut, selanjutnya aplikasi akan melakukan dekripsi dengan memanggil fungsi yang memiliki 3 parameter yaitu: alamat memori yang berisi resource dll, ukuran memori dan key untuk dekripsi, seperti yang bisa dilihat pada snippet di atas, di bagian ini:
.text:004010B1                 push    0DEADBEEFh                   ; key: 0xDEADBEEF
.text:004010B6                 push    [ebp+nNumberOfBytesToWrite]  ; DLL resource size
.text:004010B9                 push    [ebp+lpBuffer]               ; DLL resource address
.text:004010BC                 call    sub_401000                   ; decrypt the DLL
  • Dari snippet di atas, bisa terlihat bahwa key yang digunakan adalah 0xDEADBEEF. Selanjutnya adalah melihat fungsi yang dipanggil, yang bertanggungjawab untuk proses dekripsi. Berikut ini adalah fungsi tersebut:
.text:00401000 ; =============== S U B R O U T I N E =======================================
.text:00401000
.text:00401000 ; Attributes: bp-based frame
.text:00401000
.text:00401000 sub_401000      proc near                    ; CODE XREF: sub_401037+85^p
.text:00401000
.text:00401000 arg_0           = dword ptr  8               ; encrypted DLL buffer
.text:00401000 arg_4           = dword ptr  0Ch             ; DLL size
.text:00401000 arg_8           = dword ptr  10h             ; 0xDEADBEEF
.text:00401000
.text:00401000                 push    ebp                  ;
.text:00401001                 mov     ebp, esp             ; prepare the stack
.text:00401003                 push    esi                  ;
.text:00401004                 push    edi                  ;
.text:00401005                 push    ebx                  ;
.text:00401006                 mov     esi, [ebp+arg_0]     ; ESI = encrypted DLL buffer
.text:00401009                 mov     edi, esi             ; EDI = ESI (source = dest)
.text:0040100B                 mov     ebx, [ebp+arg_8]     ; EBX = 0xDEADBEEF
.text:0040100E                 mov     ecx, [ebp+arg_4]     ; ECX = DLL size
.text:00401011                 jmp     short loc_401020     ; check if buffer not empty
.text:00401013 ; ---------------------------------------------------------------------------
.text:00401013
.text:00401013 loc_401013:                                  ; CODE XREF: sub_401000+22^j
.text:00401013                 lodsb                        ; get one byte from ESI and put it in AL
.text:00401014                 mov     dl, al               ; DL = AL
.text:00401016                 xor     al, bl               ; AL ^= BL
.text:00401018                 stosb                        ; store the result from AL to EDI
.text:00401019                 ror     ebx, 1               ; EBX >> 1
.text:0040101B                 xor     bl, dl               ; BL ^= DL
.text:0040101D                 add     ebx, ecx             ; EBX += ECX
.text:0040101F                 dec     ecx                  ; ECX-- (counter)
.text:00401020
.text:00401020 loc_401020:                                  ; CODE XREF: sub_401000+11^j
.text:00401020                 or      ecx, ecx             ; is it the last byte?
.text:00401022                 jnz     short loc_401013     ; if not, repeat
.text:00401024                 pop     ebx                  ;
.text:00401025                 pop     edi                  ;
.text:00401026                 pop     esi                  ;
.text:00401027                 leave                        ; restore stack
.text:00401028                 retn    0Ch                  ; return
.text:00401028 sub_401000      endp
  • Bisa terlihat bahwa fungsinya menggunakan algoritma yang cukup sederhana, yang jika dibuat dalam bahasa sederhana kurang lebih seperti ini:
1. Register EBX pada awalnya berisi key 0xDEADBEEF.
2. Register ECX berisi ukuran data yang terenkripsi (DLL).
3. Ambil 1 byte dari data yang terenkripsi.
4. Simpan/copy byte tersebut di register DL.
5. Lakukan operasi XOR pada byte tersebut dengan byte key yang ada di register EBX.
6. Simpan hasilnya pada lokasi memori data yang terenkripsi sesuai urutannya.
7. Lakukan operasi ROR pada key yang ada pada EBX sebanyak 1x.
8. Lakukan operasi XOR pada byte key dengan byte yang berada pada register DL (byte yang belum didekripsi).
9. Tambahkan key dengan counter yang berada pada register ECX.
10. Kurangi counter, dan jika data yang akan didekripsi masih ada, maka ulangi dari langkah ke-3.
  • Urutan algoritma di atas jika dibuat dalam bentuk kode, kurang lebih seperti ini:
key = 0xdeadbeef;

for (i=0; i<DLL_SIZE; i++)
{
    dl = buff[i];
    buff[i] ^= (key & 0xff);
    key >>= 1;
    key ^= dl;
    key += (DLL_SIZE - i);
}
  • Selanjutnya, untuk melakukan dekripsi tanpa menjalankan aplikasinya, kita terlebih dahulu harus mengekstrak resource yang ada pada aplikasi tersebut. Cara yang dapat ditempuh adalah, dengan menggunakan 7zip :D
% 7z x target.exe

7-Zip [64] 9.20  Copyright (c) 1999-2010 Igor Pavlov  2010-11-18
p7zip Version 9.20 (locale=en_US.utf8,Utf16=on,HugeFiles=on,4 CPUs)

Processing archive: target.exe

Extracting  .text     CRC Failed
Extracting  .rdata     CRC Failed
Extracting  .data     CRC Failed
Extracting  .rsrc/ICON/1.ico     CRC Failed
Extracting  .rsrc/RCDATA/DLL     CRC Failed
Extracting  .rsrc/GROUP_ICON/500     CRC Failed
Extracting  .rsrc/MANIFEST/1     CRC Failed
Extracting  .reloc     CRC Failed

Sub items Errors: 8
  • Akan terlihat bahwa terdapat peringatan mengenai CRC, namun hal tersebut dapat diabaikan. Selanjutnya adalah melihat file resource yang akan didekripsi. Perlu diingat bahwa direktori ".rsrc" bersifat "hidden" jika menggunakan sistem operasi GNU/Linux dan file tersebut tidak dikenali formatnya:
% file .rsrc/RCDATA/DLL
.rsrc/RCDATA/DLL: data

% hexdump -C -n128 .rsrc/RCDATA/DLL
00000000  a2 8f f4 44 e0 0d 86 3f  9d 49 e4 8c c0 2c b8 d6  |...D...?.I...,..|
00000010  96 71 b8 52 e8 08 f7 76  f6 15 86 ab e3 f6 70 2a  |.q.R...v......p*|
00000020  a0 50 d7 9a b4 4a ca 89  a6 cd 02 d9 0a 63 a5 c9  |.P...J.......c..|
00000030  7e 11 68 2a 8c 16 e8 e6  5e b9 2c 00 3d a3 35 71  |~.h*....^.,.=.5q|
00000040  04 de c7 b9 1f 78 d0 bb  98 44 70 32 8f c3 31 5d  |.....x...Dp2..1]|
00000050  11 2e 8f 76 d0 42 18 23  55 9a a8 71 fc b8 98 6a  |...v.B.#U..q...j|
00000060  fd 79 96 ef 67 92 88 7e  2f a9 0e 74 b7 ad bc fd  |.y..g..~/..t....|
00000070  c9 44 84 67 5d fd 9d 55  27 2e 40 e6 9a db 39 a7  |.D.g]..U'.@...9.|
  • Selanjutnya, karena kita telah mengetahui algoritma untuk dekripsinya, kita dapat membuat aplikasi sederhana untuk melakukan dekripsi. Berikut ini adalah contoh PoC untuk melakukan dekripsi terhadap resource yang telah diekstrak:
% gcc -Wall -s -o decryptor decryptor.c && ./decryptor .rsrc/RCDATA/DLL
All done...
  • Periksa apakah resource dll tersebut berhasil didekripsi:
% file .rsrc/RCDATA/DLL
.rsrc/RCDATA/DLL: MS-DOS executable, MZ for MS-DOS

% hexdump -C -n128 .rsrc/RCDATA/DLL
00000000  4d 5a 90 00 03 00 00 00  04 00 00 00 ff ff 00 00  |MZ..............|
00000010  b8 00 00 00 00 00 00 00  40 80 c0 20 30 98 d4 2e  |........@.. 0...|
00000020  a9 d4 26 97 4d ee b9 c4  ae 37 85 4e ed 2e 3d f2  |..&.M....7.N..=.|
00000030  5b ad f6 5f d1 f8 c4 ae  55 1a 03 81 b8 60 30 08  |[.._....U....`0.|
00000040  8a 5d 19 df d8 40 4f 62  08 4c 07 b3 28 d3 cf 5d  |.]...@Ob.L..(..]|
00000050  9f a8 13 99 7e 71 9e a6  df a2 05 d5 b4 44 f1 a4  |....~q.......D..|
00000060  53 33 ed 26 4f 1d 78 f4  7b b4 b0 93 2b 20 42 a8  |S3.&O.x.{...+ B.|
00000070  21 09 f5 ad d2 5b a4 de  be dd 9e 53 db 65 3e 9b  |!....[.....S.e>.|
  • Bisa terlihat bahwa proses dekripsi berhasil. Selanjutnya, kita dapat melakukan proses analisis terhadap file yang telah didekripsi.


Penutup

Sekian tutorial singkat kali ini, semoga bermanfaat. Terima kasih kepada Tuhan Yang Maha Esa, Maxindo, N3 dan Anda yang telah membaca tututorial ini.


Referensi