IDentify 1.3 |
SoftICE
3.24 |
oleh
CHuPaCaBRa
Pengenalan Program |
Dengan program IDentify ini, user dapat mengetahui identitas penelpon tanpa perlu mengangkat gagang telepon telrebih dahulu. Program ini juga mampu memutuskan hubungan telepon bagi penelepon - penelepon yang tidak diinginkan oleh user.
Seperti biasa, program menuntut user untuk memasukan Nama dan Kode Registrasi, agar program tersebut menjadi registered program, dengan membayar $ 14.95.
Essay |
Nama dan Kode Registrasi bisa kamu masukan melalui menu Help - Enter Code. Untuk tutorial ini aku mengisi :
Registration Name : CHuPaCaBRa
Registration Code : 123454321
Sebelum menekan tombol OK, pasang BreakPoint di SoftICE. Aku coba pasang 3 BreakPoint yang umum digunakan, yaitu GetWindowTextA ( BPX GetWindowTextA ), GetDlgItemTextA ( BPX GetDlgItemTextaA ) dan GetDlgItemInt ( BPX GetDlgItemInt ). Setelah itu, kembali ke Windows dengan menekan F5, lalu klik tombol OK. Kamu akan masuk ke dalam lingkungan SoftICE, tepat di dalam fungsi GetWindowTextA.
Tekan F12 untuk keluar dari fungsi itu dan kamu akan bertemu dengan perintah - perintah seperti ini :
:00433FF8 Call dword ptr [0043B370] ;GetWindowTextA :00433FFE mov ecx, dword ptr [ebp+10] :00434001 push FFFFFFFF :00434003 call 004307A0
Seperti yang kamu sudah ketahui, fungsi GetWindowTextA digunakan untuk mengambil inputan dari User dan memasukannya ke memory. Sekarang pertanyaannya, dimana inputan itu diletakan ??? Di bawah fungsi GetWindowTextA terdapat sebuah perintah MOV, setelah melewati perintah tersebut dengan menekan F10, periksa apa yang baru saja dimasukan ke dalam register ECX ???
Ketik D ECX
:d ecx 017F:0068FA1C C0 45 6A 00 28 A6 44 00-00 00 00 00 58 FB 68 00 .Ej.(.D.....X.h.
Koq ngak ada yang menarik ??? Jangan putus asa dulu, coba cara lain, ketikan perintah D *ECX untuk meliat isi dari alamat yang ditunjuk oleh register ECX ( ECX = 6A45C0 )
:d *ecx 017F:006A45C0 31 32 33 34 35 34 33 32-31 00 72 69 66 00 00 00 123454321.rif...
Nah sekarang baru keliatan dimana inputan kita diletakan di memory. Ternyata inputan yang pertama kali diambil adalah Kode Registrasi kita, pasang BreakPoint di memory tersebut dengan mengetik BPM 017F:006A45C0.
Untuk menyingkat waktu, tekan F5 dan kamu akan masuk kembali ke fungsi untuk menghitung panjang kode yang kamu masukan tadi. Ini ngak usah terlalu kamu pedulikan, tekan F5 lagi, kali ini kamu terlempar kembali ke dalam fungsi GetWindowTextA, tekan F12 satu kali untuk keluar dari fungsi tersebut dan kamu akan meliat baris - baris perintah yang sama dengan yang ada di atas. Ulangi langkah di atas untuk mencari dimana inputan kita akan diletakan di memory.
:d *ecx 017F:006A4750 43 48 75 50 61 43 61 42-52 61 00 00 00 00 00 00 CHuPaCaBRa......
Pasang lagi BreakPoint di lokasi tersebut....BPM 017F:006A4750. Kalo kamu menekan F5 lagi, kamu akan kembali masuk ke dalam fungsi untuk menghitung panjang nama. Khusus untuk program ini, kamu ngak usah terlalu pedulikan penghitungan panjang nama dan kode registrasi, tapi ada baiknya kamu waspada karena ada juga program yang menuntut panjang kode atau s/n yang dimasukan user harus memiliki panjang tertentu.
Kalo kamu menelusuri perintah - perintah seterusnya, kamu akan meliat bahwa panjang nama dan kode tidak akan berpengaruh. Buat kamu yang kepengen cepet, kamu bisa langsung menekan F5, kamu akan dibawa ke sini :
:0040652F mov al, byte ptr [ecx+edx] :00406532 mov esp, ebp ;Kamu di sini :00406534 pop ebp :00406535 ret 0004 ;Kembali ke procedure pemanggil
Setelah kembali ke procedure pemanggilnya, kamu akan barada di Offset 00416A7C. Telusuri perintah - perintah di bawahnya :
:00416A5C mov eax, dword ptr [ebp-18] :00416A5F add eax, 00000001 :00416A62 mov dword ptr [ebp-18], eax :00416A65 mov ecx, dword ptr [ebp-18] :00416A68 cmp ecx, dword ptr [ebp-1C] :00416A6B jge 00416AE1 :00416A6D mov edx, dword ptr [ebp-18] :00416A70 push edx :00416A71 mov ecx, dword ptr [ebp-2C] :00416A74 add ecx, 00000060 :00416A77 call 00406520 :00416A7C mov byte ptr [ebp-10], al :00416A7F movsx eax, byte ptr [ebp-10] ;EAX = Karakter dari Nama :00416A83 cmp eax, 00000021 ;Bandingkan dengan 21 hexa ( = "!" ) :00416A86 jl 00416A91 :00416A88 movsx ecx, byte ptr [ebp-10] ;ECX = Karakter dari Nama :00416A8C cmp ecx, 00000025 ;Bandingkan dengan 25 hexa ( = "%" ) :00416A8F jle 00416AC7 :00416A91 movsx edx, byte ptr [ebp-10] ;EDX = Karakter dari Nama :00416A95 cmp edx, 00000027 ;Bandingkan dengan 27 hexa ( = "'" ) :00416A98 jl 00416AA3 :00416A9A movsx eax, byte ptr [ebp-10] ;EAX = Karakter dari Nama :00416A9E cmp eax, 0000002B ;Bandingkan dengan 2B hexa ( = "+" ) :00416AA1 jle 00416AC7 :00416AA3 movsx ecx, byte ptr [ebp-10] ;ECX = Karakter dari Nama :00416AA7 cmp ecx, 0000002F ;Bandingkan dengan 2F hexa ( = "/" ) :00416AAA jl 00416AB5 :00416AAC movsx edx, byte ptr [ebp-10] ;EDX = Karakter dari Nama :00416AB0 cmp edx, 00000040 ;Bandingkan dengan 40 hexa ( = "@" ) :00416AB3 jle 00416AC7 :00416AB5 movsx eax, byte ptr [ebp-10] ;EAX = Karakter dari Nama :00416AB9 cmp eax, 0000005B ;Bandingkan dengan 5B hexa ( = "[" ) :00416ABC jl 00416ACC :00416ABE movsx ecx, byte ptr [ebp-10] ;ECX = Karakter dari Nama :00416AC2 cmp ecx, 0000005F ;Bandingkan dengan 5F hexa ( = "_" ) :00416AC5 jg 00416ACC :00416AC7 jmp 00416B91 :00416ACC movsx edx, byte ptr [ebp-10] ;EDX = Karakter dari Nama :00416AD0 cmp edx, 00000020 ;Bandingkan dengan 20 hexa ( = " " ) :00416AD3 jne 00416ADC :00416AD5 mov [ebp-14], 00000001 ;[EBP-14] = 01 hexa :00416ADC jmp 00416A5C ;Looping :00416AE1 cmp dword ptr [ebp-14], 00000000 ;Apakah [EBP - 14] = 00h ??? :00416AE5 je 00416AED ;Jika Ya, lompat ke 00416AED
Setelah selesai memproses semua karakter nama di atas, program akan melihat bahwa [EBP-14] sama dengan 00h sehingga program akan melompat ke Offset 00416AED. Pada saat pertama kali aku coba krak program ini aku tidak curiga sama sekali, dengan penuh semangat aku terus menelusuri perintah - perintah selanjutnya tapi ternyata sia -sia. Program ini menolak kode registrasi yang kita masukan, tapi kenapa ???
Aku kemudian mencoba pendekatan lain, yaitu dengan menggunakan W32Dasm. Setelah men-dissasembly file IDentify.Exe, aku mencari Offset - offset yang telah aku telusuri di atas dan menemukan sesuatu yang menarik :-)
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00416A6B(C) | :00416AE1 837DEC00 cmp dword ptr [ebp-14], 00000000 :00416AE5 7406 je 00416AED :00416AE7 837DE406 cmp dword ptr [ebp-1C], 00000006 :00416AEB 7D05 jge 00416AF2 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00416AE5(C) | :00416AED E99F000000 jmp 00416B91 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00416AEB(C) | * Possible StringData Ref from Data Obj ->"Phrozen Crew" | :00416AF2 6864A24400 push 0044A264 :00416AF7 8B45D4 mov eax, dword ptr [ebp-2C] :00416AFA 83C060 add eax, 00000060
Dengan W32Dasm ini, aku bisa mengamati perintah - perintah di bawah Offset 00416AE5 yang tadi tidak dijalankan oleh program. Perhatikan, jika tadi kita tidak melakukan lompatan ke Offset 00416AED, nilai [EBP-1C] yang merupakan panjang nama user, akan dibandingkan dengan 6. Jika penjang nama tersebut lebih besar dari 6, maka program akan menuju ke Offset 00416AF2.
Di sinilah yang menarik, di atas Offset 00416AF2 ada tulisan Possible StringData Ref from Data Obj ->"Phrozen Crew", ini berarti perintah di bawahnya PUSH 0044A264 akan memasukan tulisan "Phrozen Crew" ke dalam stack. Apa ato siapa Phrozen Crew ini ??? Phrozen Crew adalah salah satu kelompok kraker yang cukup terkenal, dari pengalamanku, aku sering menjumpai program - program yang mengecek apakah user memasukan nama - nama dari Kraker ato Kelompok Kraker terkenal sebagai Registration Name dan bila itu terjadi, maka program akan langsung menolak user tersebut. Aku rasa program ini juga tak jauh beda :-)
Tapi masalahnya, nama yang telah kita masukan ngak pernah dibandingkan dengan nama "Phrozen Crew", ini berarti sebelumnya nama yang aku masukan sudah ditolak mentah - mentah :-( Apa yang salah dengan nama yang aku masukan ???
Setelah mengamati lebih teliti, aku baru sadar bahwa nama yang kita masukan harus memiliki spasi. Darimana aku tahu hal ini ??? Perhatikan kembali perintah - perintah berikut :
:00416AD0 cmp edx, 00000020 ;Bandingkan dengan 20 hexa ( = " " ) :00416AD3 jne 00416ADC :00416AD5 mov [ebp-14], 00000001 ;[EBP-14] = 01 hexa :00416ADC jmp 00416A5C ;Looping :00416AE1 cmp dword ptr [ebp-14], 00000000 ;Apakah [EBP - 14] = 00h ??? :00416AE5 je 00416AED ;Jika Ya, lompat ke 00416AED
Pada Offset 00416AD0, karakter dari nama yang aku masukan akan dibandingkan dengan 20 hexa yang merupakan kode hexa untuk spasi. Jika ada hanya satu karakter saja dari nama kita yang berupa spasi, maka program akan merubah nilai [EBP-14] dari 0 menjadi 1 ( liat Offset 00416AD5 ). Dengan demikian, pada saat semua karakter telah selesai diproses, nilai yang tersimpan pada [EBP-14] akan dibandingkan dengan 0, jika ternyata [EBP-14] = 1 maka program akan melakukan perintah - perintah pada Offset selanjutnya ( menganggap nama yang dimasukan user adalah valid )
Karena itu aku merubah nama yang aku inputkan dengan "C H u P a C a B R a". Pada saat tracing kembali, nama tersebut akan dianggap valid dan melanjutkan pada perintah - perintah di bawahnya. Nama yang sudah aku masukan tadi kemudian dibandingkan dengan nama "Phrozen Crew" pada Rutin Call di Offset
:00416AFE call 00405960 ;Bandingkan Nama User dengan "Phrozen Crew" :00416B03 and eax, 000000FF ;EAX = EAX and 000000FF hexa :00416B08 test eax, eax ;Test apakah EAX = 0 ??? :00416B0A je 00416B11 ;Jika ya, maka lompat ke Offset 00416B11 :00416B0C jmp 00416B91
Lakukan tracing dengan menekan F10 terus, nantinya kamu akan menemukan baris - baris perintah untuk menghitung karakter - karakter nama dan mendapatkan s/n yang tepat......seperti ini :
:00416BFB mov ecx, dword ptr [ebp-1C] ;ECX = [EBP-1C] :00416BFE cmp ecx, dword ptr [ebp-20] ;Bandingkan ECX dengan [EBP-20] :00416C01 jge 00416C3B ;Jika ECX >= [EBP-20], lompat !!! :00416C03 mov edx, dword ptr [ebp-1C] ;EDX = [EBP-1C] :00416C06 push edx ;Masukan EDX ke Stack :00416C07 lea ecx, dword ptr [ebp+0C] ;ECX = [EBP+0C] :00416C0A call 00406520 :00416C0F movsx eax, al ;EAX = AL (EAX = Karakter dari nama) :00416C12 mov dword ptr [ebp-14], eax ;[EBP-14] = EAX :00416C15 mov ecx, dword ptr [ebp-1C] ;ECX = [EBP-1C] :00416C18 and ecx, 80000003 ;ECX = ECX and 80000003 hexa :00416C1E jns 00416C25 :00416C20 dec ecx :00416C21 or ecx, FFFFFFFC :00416C24 inc ecx :00416C25 shl ecx, 03 ;ECX = ECX << 03 hexa :00416C28 mov edx, dword ptr [ebp-14] ;EDX = [EBP-14] :00416C2B shl edx, cl ;EDX = EDX << CL :00416C2D mov dword ptr [ebp-14], edx ;[EBP-14] = EDX :00416C30 mov eax, dword ptr [ebp-10] ;EAX = [EBP-10] ([EBP-10] = 2C692E37) :00416C33 xor eax, dword ptr [ebp-14] ;EAX = EAX xor [EBP-14] :00416C36 mov dword ptr [ebp-10], eax ;[EBP-10] = EAX :00416C39 jmp 00416BF2 ;Looping
Seperti yang bisa kamu liat di atas, setaip karakter dari nama yang telah kamu inputkan akan diolah dan disimpan di dalam [EBP-10]. ( Pada awalnya [EBP-10] berisi 2C692E37 hexa )
Setelah semua karakter selesai diproses, nilai yang ada di [EBP-10] akan di-copy ke register ECX. Perhatikan perintah - perintah berikutnya :
:00416C3B mov ecx, dword ptr [ebp-10] ;ECX = [EBP-10] :00416C3E and ecx, 7FFFFFFF ;ECX = ECX and 7FFFFFFF hexa :00416C44 mov dword ptr [ebp-10], ecx ;[EBP-10] = ECX :00416C47 mov edx, dword ptr [ebp-10] ;EDX = [EBP-10] :00416C4A or edx, 40000000 ;EDX = EDX or 40000000 hexa
Ingat nilai yang ada di [EBP-10] adalah nilai hasil penghitungan karakter dari nama user. Setelah kamu melewati Offset 00416C4A, liat apa isi EDX sekarang :
:? edx 6C110E53 1813057107 "lS"
Perintah - perintah selanjutnya :
:00416C50 mov dword ptr [ebp-10], edx ;[EBP-10] = EDX :00416C53 push 0000000A :00416C55 lea eax, dword ptr [ebp-50] :00416C58 push eax :00416C59 mov ecx, dword ptr [ebp-10] :00416C5C push ecx :00416C5D call 0041CD9B :00416C62 add esp, 0000000C :00416C65 lea edx, dword ptr [ebp-50] :00416C68 push edx
Sekarang....periksa lagi apa isi EDX dengan mengetik :
:d edx 017F:0068F510 31 38 31 33 30 35 37 31-30 37 00 00 50 47 6A 00 1813057107..PGj.
Nah....itulah s/n yang tepat untuk nama yang aku masukan :-)
K R A K |
Listing KeyGen untuk IDentify 1.3
#include <string.h>
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
void main()
{
unsigned long EDX=0, EAX=0x2C692E37, ECX=0, Counter, Temp=0;
char Nama[30];
clrscr();
textcolor(10);
cputs(">>>>>>>>>>>>>>><<<<<<<<<<<<<<<\r\n");
cputs(">> <<\r\n");
cputs(">> IDentify 1.3 <<\r\n");
cputs(">> <<\r\n");
cputs(">> Kraked by CHuPaCaBRa <<\r\n");
cputs(">> http://chupa.cjb.net <<\r\n");
cputs(">> <<\r\n");
cputs(">>>>>>>>>>>>>>><<<<<<<<<<<<<<<\r\n");
puts("");
puts("");
textcolor(11);
cprintf("Masukan Nama Anda : ");
gets(Nama);
for ( Counter = 0; Counter <= strlen(Nama);Counter++)
{
Temp = Temp & 0x80000003;
ECX = Temp << 3;
EDX = Nama[Counter];
EDX = EDX << ECX;
EAX = EAX ^ EDX;
Temp++;
}
EAX = EAX & 0x7FFFFFFF;
EAX = EAX | 0x40000000;
cprintf ( "Registration Code : ");
cprintf("%ld",EAX);
puts("");
}
Catatan |
Ngak terlalu sulit khan ??? :-)
Ada beberapa catatan mengenai beberapa perintah SoftICE yang aku gunakan. Mungkin kamu agak bingung meliat perbedaan perintah '?' dan 'D' serta 'D *' yang aku gunakan untuk meliat isi atau nilai dari suatu Register.
Pertanyaan yang mungkin timbul adalah, kapan kamu tahu harus meliat nilai, isi ataupun isi dari alamat yang ditunjuk oleh suatu Register tertentu ???
Begini, pada saat program selesai melakukan suatu perintah Assembly seperti ini misalnya : XOR EAX, EBX, maka berarti kamu harus menggunakan perintah '?' untuk meliat nilai dari register EAX dan EBX karena nilai tersebutlah yang akan di-XOR. Jika perintah Assembly-nya menggunakan perintah LEA ato MOV, biasanya kamu harus meliat isi registernya dengan menggunakan perintah 'D' ato 'D *'
© Juni1999