#INCLUDE "NFO.h"
#INCLUDE "DISCLAIMER.h"
USING NAMESPACE REVERSE_ENGINEERING
char szTajuk[] = "Key Generator for Newbies"
char szPenulis[] = "Ancient One"
char szWeb[] = "http://www26.brinskter.com/paipx"
char szMod[] = "+n +s +c +sc"
VOID MAIN () {
Aku tulis tutorial ni disebabkan ramai members aku tanya how do I
create a key generator (keygen) for certain shareware applications.
Jadi dalam tutorial ni aku cuma nak bagitau bagaimana korang boleh
membina satu keygen. Walaupun aku akan kasi contoh shareware yang
akan kita bina key generator, korang tak boleh follow tutorial ni
untuk certain application je. Aku nak supaya korang boleh aplikasikan
tutorial ni untuk setiap shareware yang korang crack nanti.
Tidak semestinya setiap shareware yang membenarkan kita masukkan
nama, no. siri dan sebagainya membolehkan kita membuat keygen
untuknya. Terdapat banyak perkara yang perlu dipertimbangkan. Korang
cuma akan tahu samada keygen untuk shareware tersebut boleh dibuat
setelah menghabiskan masa cracking program tersebut di mana anda
boleh melihat sendiri how the program validate your serial number.
Terdapat pelbagai cara no. siri ini disahkan. Ada yang biasa memanipulasi
nama untuk menghasilkan valid key dan kemudian key ini akan dibandingkan
dengan key yang kita berikan. Ada juga yang cuma manipulate no. siri
itu sendiri dengan some arithmetic technique. Ada yang menggunakan
public key crypto dan sebagainya. Korang perlu pandai mencari bahagian
di mana no. siri tersebut disahkan. Skill ini cuma boleh diperolehi
dengan banyak melihat kod dalam debugger/disassembler. Pada kes2
tertentu anda perlu tahu banyak jenis arithmetic sebab ia lebih
popular digunakan dalam serial validation.
Pada sesetengah shareware pula korang tak perlu bersusah payah nak
reverse semula validation routine tersebut kerana ia dah sediakan
satu internal keygen untuk anda. Dalam perisian ini, no. siri yang
betul akan dikira dalam program tersebut dan dibandingkan dengan
no. siri yang kita berikan. Jika anda hendak buat keygen untuk
shareware seperti ini, korang cuma perlu rip kod tersebut dan
letak dalam source code keygen korang :). Tapi make sure anda
gunakannya dengan betul.
Bagi validation routine yang tidak boleh reverse pula, kita boleh
mmenggunakan teknik brute force dengan mencuba key pada range
tertentu atau menggunakan teknik yang lebih bijak lagi seperti
genetic algo. Biasanya, protection seperti ini cuma mempunyai
beberapa valid key yang unik dalam range tertentu.
Actually, aku takleh ajar korang camne nak cari internal keygen routine
(if any) atau serial validation routine. Ia bergantung kepada
pengetahuan anda membaca kod assembly sekaligus memahami apakah
yang berlaku dalam functions tertentu. Tapi generally, apa yang aku
selalu buat ialah :
Run program dan fikirkan bagaimana hendak break dalam validation
routine. Jika kita dibenarkan memasukkan nama dan no. siri dalam
edit box.. selalunya kita boleh setkan breakpoint pada Windows API
GetDlgItemText, GetWindowText dan juga SendDlgItemMessage, tapi
aku biasa menggunakan GetWindowText. Jika ada 2 kekotak, maka ia
sepatutnya break 2 kali untuk mengambil teks pada kedua2 edit box
tersebut (after breaking for the first time, press F5/exit SoftIce).
Jika ia cuma break sekali sahaja, maka kemungkinan besar ia cuma
mengambil no. siri dan mengesahkannya tanpa mengambil kira nama
yang dimasukkan. Jika korang berjaya break dalam protection routine,
mula2 sekali just step over (sambil cuba memahami kod tersebut)
secara sepintas lalu. Perhatikan call yang dibuat (but don't trace
into it) dan lihat arguments yg dipass ke function dan return value
yang dipulangkan. Ini amat penting kerana anda perlu bezakan call
yang tidak berkaitan dengan protection routine dengan yang betul.
Contoh mudah ialah katakan anda masukkan nama sebagai "Tukang Paip"
dan pointer ke string ini dipush sebagai argument untuk suatu
call. Jika kita step over call ini, lihat return value pada eax,
jika ianya bernilai 0000000B, maka sudah tentu function ini
cuma berfungsi untuk menentukan length string tersebut jadi kita tak
perlu bersusah payah untuk trace call ini.
Untuk mengetahui secara samar apakah tugas sesuatu fungsi/prosedur tersebut,
kita kena tengok arguments yg dipush dan oleh itu kita kena tau
beberapa jenis calling convention yang digunakan. Secara ringkasnya
terdapat beberapa calling convention yang digunakan seperti
stdcall, c, pascal, syscall, naked, fastcall. Windows API hampir
kesemuanya menggunakan stdcall di mana arguments akan dipush
dari kananke kiri dan function yang dicall akan cleankan stack.
c pula sama seperti stdcall cuma kod yang memanggil fungsi
tersebut yang akan cleankan stack. fastcall calling convention
pula adalah compiler specific kerana ia menggunakan registers
untuk beberapa paramater pertama dan stack untuk argument seterusnya.
Jika korang menggunakan Delphi/C++ Builder, default calling convention
adalah fastcall di mana 3 register iaitu EAX, EDX dan ECX akan
digunakan untuk 3 argument pertama (if possible), manakala
Micorsoft nyer fastcall implementation pula menggunakan ECX
dan EDX untuk dua argument pertama. Apa yang pasti ialah jika
function memulangkan nilai, maka ia akan diletakkan pada register
EAX :).
Tidak semestinya apabila fungsi tersebut tidak memulangkan apa2
nilai, maka ia tidak berkaitan dengan protection routine. Jika
kita lihat argument yang dipush mempunyai kaitan, seperti pointer
ke nama atau no. siri, maka kemungkinan besar ia berkaitan, cuma
ia tidak memulangkan apa2 nilai (mungkin kerana ia directly access
global memory). Anda juga patut sudah biasa dengan kod yang menukarkan
data kepada satu sama lain, ie hex ke ascii, ascii ke int dan sebagainya.
Ia akan menjimatkan masa anda daripada memahami kod2 yang tugasnya
cuma mengubah data.
Terdapat banyak cara yang kita boleh gunakan untuk break dalam
protection routine sesuatu perisian tersebut. Cuma daya fikiran
anda yang menghadkannya. Untuk contoh membina keygen ini, saya tidak
akan gunakan Windows API untuk break ke dalam perisian :). Sebaliknya
menggunakan teknik yang biasa digunakan dalam game training.
Latihan.
Target : Magellas Internet Tweak 2002 Standard Edition 1.00.
Tools : SoftIce + Memory Scanner.
Jika saya tak silap, program ini dipack dengan ASPack. Tapi ini
bukan unpacking tutorial :).. dan kita tak perlu unpack program
ini untuk membina keygennya nanti. Saya menggunakan memory scanner
kerana bpx tidak ditrigger apabila bpx pada common get text untuk
Windows API.. jadi saya assume maybe program ni ader bpx on API
protection (figure that out yourself). Tapi tak perlu bimbang
kerana memory scanner ada untuk membantu kita. Jika anda biasa
menipu dalam game, maka memory scanner bukanlah suatu yang asing
untuk anda. Mengapa gunakan memory scanner? Jika anda cuba registerkan
program ini, ia cuma memberikan anda 3 peluang untuk memasukkan
nama dan no. siri, jika tidak betul, maka program akan keluar.
Jadi di sini kita boleh gunakan memory scanner untuk mencari
counter yang menyimpan bilangan percubaan untuk memasukan nama
dan no. siri yang sah.
Sebelum tekan butang OK pada registration box, pastikan anda search
dahulu nilai 0 (byte) dalam memory scanner anda. Kemudian masukkan nama
dan tekan butang OK. Jika salah, edit box akan clear semula. Kali
ini serach pula untuk nilai 1 dan seterusnya sehinggalah anda mendapat
satu atau dua lokasi. Sebelum mencapai nilai 3 anda akan dapat satu
atau dua lokasi. Saya mendapat dua lokasi pada nilai 2 iaitu
4DB1D4 dan A40601. Address 4DB1D4 kemungkinan besar menyimpan
counter tersebut. Selepas sahaja kita masukkan input dan menekan
butang OK, input disahkan dan jika salah, isi kandunagn memory ini
akan ditingkatkan dan kemudian dibandingkan dengan 3, jika lebih,
program akan exit. Tu cara pemikiran saya.. saya tak pasti lagi
mengenainya until we break in SoftIce later..
Jadi dalam SoftIce.. pastikan anda berada dalam konteks program ini
(arahan addr itweaks) dan setkan breakpoint on memory access pada
kedua2 lokasi di atas (saya cuma setkan satu iaitu pada 4DB1D4 sebab
ianya logik sedikit :) (arahan bpmb 4DB1D4). Isikan semula input dan
tekan butang OK, SoftIce akan break pada lokasi berikut :
4A18E3 INC WORD PTR [4DB1D4] ;wrong serial, inc try
ED MOV EAX, [EBP-4] ;EIP point here
..
..
..
4A190A CMP WORD PTR [4DB1D4], 03 ;if try!=3
12 JNZ 4A1920 ;continue..
;else.. get out
Simple patch : change 3 to 0. Jadi kita dah dapat area di
mana serial dikira. Mungkin jauh, mungkin juga dekat, kita
tak tau lagi. APa yang saya buat ialah return kepada caller,
set bpx on that call dan trace into it. Anda perlu return beberapa
kali sehingga anda jumpa lokasi asal function ini dipanggil.
Ia adalah seperti di bawah :
4456FA MOV EAX, [EBX+124]
700 CALL [EBX+120] ;set bpx here for tracing later
06 POP ECX ;you'll eventually return here from above proc
07 RET
Jadi kita setkan bpx pada 445700 dan keluar. Clearkan bpm tadi kerana
kita dah temui lokasi untuk break dalam program ini. Sebaik sahaja
anda tekan OK kali ini anda akan break pada lokasi 445700 tadi
dan anda boleh trace call ni untuk memahami apa yang berlaku
di dalamnya. Anda akan berjumpa dengan kod seperti di bawah:
4A11F6 MOV EDX, [EBP-8] ;edx point to name
F9 MOV EAX, [EBP-4] ;tak pasti
201 CALL 4A0E70 ;some call
;return some weird value..
Kita boleh agak yang program ni adalah dibina dalam Borland
Delphi/C++ Builder since ia gunakan fastcall calling convention.
JIka anda lihat kod di atas, ia pass pointer ke nama dan some
pointer yang tak pasti apa gunanya untuk call 4A0E70 dan step
over call ini anda akan mendapat some weird return value in eax.
In fact ini adalah serial number yang kita cari2 :). Just
do ? eax dan decimal representationnya adalah serial number
untuk nama kita. call 4A0E70 adalah key generator program ini.
Anda boleh pastikan yang eax adalah serial number kita dengan
melihat kod2 seterusnya di bawah. Apa yang anda akan dapati pada
kod2 seterusnya ialah some comparisoan dengan some kod (format
lama) yang mungkin adalah pirated serial. saya tak tau. Kemudian,
serial yg betul akan ditukar ke ascii dan dibandingakn dengan
serial yang kita berikan. Jika betul, some registry entriy akan
ditulis. Kalau anda nak tahu, anda cuma perlu menambah entry
Gold (REG_SZ) dan berikan nilai True untuk mendaftarkan program
ini :). Tambah Owner (REG_SZ) dan berikan nama anda. Kita dah crack
program ini :).
Berbalik kepada serial calculation tadi, korang boleh trace into
CALL 4A0E70 untuk mengetahui bagaimana serial dibina untuk nama
anda. Saya cuma terangkan secara ringkas di sini. Anda cuma perlu
memahami kod assembly di dalam call tersebut kerana ianya sangat
mudah difahami.
-dapatkan len = length(nama)
-jika len>0x10, len=0x10
-satu = add all even ascii (including indeex 0) until <= len
-dua = add all odd ascii until <= len
-serial = satu + dua + constant 0xD72DD7
-serial = serial*2+serial.
itu sahaja.. dalam c++ ia akan nampak seperti berikut :
#include <iostream>
using namespace std;
int main()
{
char nama[100]= "\0"; int satu=0, dua=0, temp=0, serial=0;
cin.getline(nama, 0x10);
unsigned len = strlen(nama);
if (len>0x10) len=0x10;
for (unsigned i=0; i<=len; i +=2) {
satu += nama[i];
};
for (unsigned i=1; i<=len; i +=2) {
dua += nama[i];
};
satu = satu*0x22713;
dua = dua*dua;
temp = satu + dua + 0xD72DD7;
serial= temp*2+temp;
printf("%d", serial);
return 0;
}
}
Kembali ke Isi Kandungan