#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