/\
|| /\
[=========================================================================||===]
[-------------------------[ pre-cracking for dummies ]--------------------||---]
[=========================================================================||===]
|| ||
|| _.d####b._ ||
|| .############. ||
||.################. ||
||##################.__ __ __ __ _ _ __ __ ||
|##############/´_`|#\ V V // _` | '_/ -_) ||
|##############\__,|# \_/\_/ \__,_|_| \___| ||
|###########>'<###### ||
|*#########( )####* ||
||##########>.<##### .aware eZine beta ||
|| ################ .text 2007-07-07 ||
|| *############* ||
|| "T######T" ||
|| ||
\/ ||
||
/\ ||
|| W W W . A W A R E N E T W O R K . O R G ||
|| ||
||_______________________________________________________________________||
||-----------------------------------------------------------------------||
||=======================================================================||
|| ||
|| PRE-CRACKING FOR DUMMIES ||
|| ----------------------------------------------- ||
|| a sexy text for those special moments ||
|| ...isn't that right, pac-man? ||
|| ||
|| ||
|| ,-'" "`-. ||
|| ,'_ `. ||
|| / / \ ,- \ PAC-MAN SAYS... ||
|| __ | \_0 --- | - EEEEEEYYYYYYYY!!! ||
|| / | | | ||
|| \ \ `--.______,-/ | ||
|| ___) \ ,--"" ,/ | ||
|| / _ \ \-_____,- / ||
|| \__-/ \ | `. ,' ||
|| \___/ < ´--------' ||
|| \__/\ | ||
|| \__// ||
|| ||
|| ||
|| ...and this my friends is what I call a big fat ||
|| stiff cock up the fucking arse with mint or celery ||
|| ||
|| - Mike Strutter ||
|| ||
|| ||
|| .text search strings ||
|| |-------------------------------------| ||
|| "0x00 Prologue" ||
|| "0x01 Common knowledge" ||
|| "0x02 Success story" ||
|| "0x03 The pattern" ||
|| "0x04 The source" ||
|| "0x05 U R L" ||
|| |---------------------------| ||
|| ||
||_______________________________________________________________________||
|| ||
|| 0x00 Prologue ||
||_______________________________________________________________________||
|| ||
|| Greetings mad undergr0und haxorz! ||
|| ||
|| This text will elucidate in a fairly straightforward way what a ||
|| pre-crack actually is as well as showing you how to produce one. ||
|| Since this article is written to be somewhat understandable even ||
|| for those without any prior knowledge of software cracking, ||
|| a listing of definitions would be helpful, yes? mmyyeesss... ||
|| ||
\/ Here is a "theory crash course" in software cracking! ||
Note! Hardcore black hats may skip the first chapter (0x01), ||
...maybe even the whole thing!? ||
/\ ||
|| ||
||_______________________________________________________________________||
|| ||
|| 0x01 Common knowledge ||
||_______________________________________________________________________||
|| ||
|| Reverse engineering (RE) is the process of discovering the ||
|| technological principles of a device or object or system through ||
|| analysis of its structure, function and operation. It often involves ||
|| taking something (e.g. a mechanical device, an electronic component, ||
|| a software program) apart and analysing its workings in detail, ||
|| usually to try to make a new device or program that does the same ||
|| thing without copying anything from the original. ||
|| ||
|| In computer science, an opcode is the portion of a machine language ||
|| instruction that specifies the operation to be performed. ||
|| The term is an abbreviation of Operation Code. ||
|| Their specification and format will be laid out in the instruction ||
|| set architecture (ISA) of the computer hardware component in ||
|| question normally a CPU, but possibly a more specialized unit. ||
|| A complete machine language instruction contains an opcode and, ||
|| optionally, the specification of one or more operands—what data ||
|| the operation should act upon. ||
|| ||
|| Machine language is tedious and difficult for humans to program ||
|| in directly, so if the abstraction given by a higher-level ||
|| programming language is not desired, an assembly language is used. ||
|| Here, mnemonic instructions are used that correspond to the opcode ||
|| and operand specifications of the machine language instructions ||
|| generated. In assembly language a mnemonic is a code, ||
|| usually from one to five letters, that represents an opcode. ||
|| This gives a greater level of readability and comprehensibility ||
|| than working with machine language operations directly, while still ||
|| giving accurate control of the machine language generated. ||
|| ||
|| Many of the mnemonics have rather self-explanatory names such as ||
|| ADD, MOV, CMP, INC, DEC. One of the most used mnemonics in software ||
|| cracking would have to be NOP (No operation). So why is that? ||
|| Well NOP doesn’t actually do anything (besides wasting cpu clock ||
|| cycles). So how is that useful? Well NOPs are most commonly used ||
|| for timing purposes, to force memory alignment, to prevent hazards, ||
|| to occupy a branch delay slot, or as a "place-holder" to be ||
|| replaced by active instructions later on in program development ||
|| (or to replace removed instructions when re-factoring would be ||
\/ problematic or time-consuming). In the eyes of a cracker it’s a ||
blessing. Let us watch some pseudocode, and a lame ass example! ||
||
/\ ||
|| This is the before code, which will actually check X to see if it ||
|| is elite enough to continue. ||
|| ||
|| check X ||
|| { \/
|| if X is not equal to 1337
|| return false
|| else /\
|| return true ||
|| } ||
|| ||
|| This is the modified code, which does not care about anything ||
|| really. It just returns true, which is exactly what we want ||
|| it to do! ||
|| ||
|| check X ||
|| { ||
|| nop // do nothing ||
|| nop // do nothing ||
|| nop // do nothing ||
|| return true ||
|| } ||
|| ||
|| This is of course simplified, but you get the idea, right? ||
|| ||
|| Below is a lame ... but working "real life" example. ||
|| We could of course modify this code in several different ways ||
|| to get the job done, but let's stick to the most common way. ||
|| ||
|| - code - ||
||#######################################################################||
|| ||
|| The original code: ||
|| ------------------ ||
|| org 100h ||
|| mov ax,01h ||
|| mov cx,02h ||
|| cmp ax,cx ||
|| jne notequal ; <-- here is your problem ||
|| mov dx,registered ||
|| mov ah,09h ||
|| int 21h ||
|| jmp exit ||
|| notequal ||
|| mov dx,trialmode ||
|| mov ah,09h ||
|| int 21h ||
|| exit ||
|| mov ah,4Ch ||
|| int 21h ||
|| registered db "program is registered.",0dh,0ah,24h ||
|| trialmode db "program is in trial mode.",0dh,0ah,24h ||
|| ||
|| ||
|| The modified code: ||
|| ------------------ ||
|| org 100h ||
|| mov ax,01h ||
|| mov cx,02h ||
|| cmp ax,cx ||
|| nop ; <-- nothing nop can't fix ||
|| nop ; <-- ...second that! ||
|| mov dx,registered ||
|| mov ah,09h ||
|| int 21h ||
|| jmp exit ||
|| notequal ||
|| mov dx,trialmode ||
|| mov ah,09h ||
|| int 21h ||
|| exit ||
|| mov ah,4Ch ||
|| int 21h ||
|| registered db "program is registered.",0dh,0ah,24h ||
|| trialmode db "program is in trial mode.",0dh,0ah,24h ||
|| ||
||#######################################################################||
|| - code - ||
|| ||
|| Since this is a text for dummies, let's explain what just ||
|| happened in a more "hands-off" ... theoretical way as well! ||
|| ||
|| Software cracking is the modification of software to remove ||
|| protection methods: copy prevention, trial/demo version, ||
|| serial number, hardware key, CD check or software annoyances like ||
|| nag screens and adware. The most common software crack is the ||
|| modification of an application's binary to cause or prevent a ||
|| specific key branch in the program's execution. This is ||
|| accomplished by reverse engineering the compiled program code ||
|| using a debugger until the software cracker reaches the subroutine ||
|| that contains the primary method of protecting the software ||
|| (or by disassembling it). The binary is then modified using the ||
|| debugger or a hex editor in a manner that replaces a prior ||
|| branching opcode with its complement or a NOP opcode so the key \/
|| branch will either always execute a specific subroutine or skip
|| over it. Almost all common software cracks are a variation of
|| this type. Hopefully that was clear enough for everyone? /\
|| ||
|| A pre-crack (or search'n'destroy crack) is essentially nothing ||
|| more then a "dynamic" software crack. The opcode modifying part ||
|| is not really "dynamic", but the end product is. One of the most ||
|| common software cracking techniques is the offset patching. Since ||
|| releasing a complete cracked binary is not considered very sexy, ||
|| the cracker compares the cracked binary with the original binary ||
|| and stores the altered parts. The cracker now knows where in the ||
|| binary to place his modifications (the offsets). All that remains ||
|| is to create a patch that replaces “whatever” to the given offsets ||
|| and voila: we have offset patching! The patch must of course make ||
|| sure that the binary to be modified has the right size (length) ||
|| and such vital details. ||
|| ||
|| The pre-crack is very similar to the offset patching technique, ||
|| though the cracker does not know any of the offsets or the size ||
|| (length) of the binary in advance. Instead a pattern must be ||
|| located, which hopefully won’t change in future software upgrades. ||
|| The cracker knows the interesting offsets of the present binary ||
|| and he or she knows what data to alter. The problem is that the ||
|| data must be found again in unknown territory... ||
|| (a possible software upgrade). ||
|| ||
|| A common way of finding the specific data (patch-data) again is to ||
|| search for "it", as well as surrounding patterns (data which is ||
|| most likely to be reused in a software upgrade). The easiest way is ||
|| to check the patterns pre/post the patch-data. If that is not ||
|| possible the cracker will have to check patterns further away and ||
|| then try to find the way back to the patch-data. This is the ||
|| obvious reason that pre-cracks also if referred to as... ||
|| search'n'destroy, seek'n'destroy or similar... ||
|| In Sweden we have a saying "A dear/beloved child has many names.". ||
|| ||
|| If everything goes as planed the pre-crack will be able to crack ||
|| the current binary as well as any future software upgrade, as long ||
|| as it contains the patch-data pattern(s). ||
|| ||
||_______________________________________________________________________||
|| ||
|| 0x02 Success story ||
||_______________________________________________________________________||
|| ||
|| An example of a pre-crack that indeed has fulfilled its purpose ||
|| is the .aware WinRAR (PC) *ALL* versions pre-crack. It was born ||
|| in the beginning of 2005 and has served the underground community ||
|| ever since. ||
|| ||
|| The following is from a file located in the .aware/usr directories: ||
|| ||
|| ||
|| - BOF - ||
||#######################################################################||
|| "This precrack is coded to hopefully crack the next release of Rarlab ||
|| WinRAR. The latest version (today) 09-Mars-2005 is WinRAR 3.42. ||
|| ||
|| So keep an eye on the rarlab website, and the same second they make ||
|| the next WinRAR release public, you download it and crack it with a ||
|| patch you've been holding for a long time." ||
||#######################################################################||
|| - EOF - ||
|| ||
|| During the last years Rarlab has released a shit load of version ||
|| upgrades, and they were all cracked by the .aware WinRAR ||
|| pre-cracker. Hopefully it will keep on keeping on for your ||
\/ pleasure and convenience! ||
||
/\ ||
||_______________________________________________________________________||
|| ||
|| 0x03 The pattern ||
||_______________________________________________________________________||
|| ||
|| Here is the pattern, which was used in the .aware WinRAR ||
|| pre-cracker: ||
|| ||
|| ||
|| []=================================================================[] ||
|| ||
|| -=<[HERE WE HAVE THE PRECRACK PATTERN]>=- ||
|| ||
|| --------------------------------------------------------------------- ||
|| ||
|| :0040DCA2 8D85D0EFFFFF lea eax, dword ptr [ebp+FFFFEFD0] ||
|| :0040DCA8 8B95D0F3FFFF mov edx, dword ptr [ebp+FFFFF3D0] ||
|| :0040DCAE E865DBFFFF call 0040B818 ||
|| --------------------------------------------------------------------- ||
|| ||
|| :0040DCB3 84C0 test al, al ||
|| :0040DCB5 0F85DFFEFFFF jne 0040DB9A ||
|| :0040DCBB 33C0 xor eax,eax <-- modify this part! ||
|| -------------------------------------------------------------------- ||
|| ||
|| --- 84C00F85DFFEFFFF33C0 --- ||
|| ||
|| :0040DCBD 8B95D4F3FFFF mov edx, dword ptr [ebp+FFFFF3D4] ||
|| :0040DCC3 64891500000000 mov dword ptr fs:[00000000], edx ||
|| --------------------------------------------------------------------- ||
|| ||
|| * Original code is - xor eax,eax [33C0] ||
|| * Replacement code will be - mov al,01 [B001] ||
|| ||
|| []=================================================================[] ||
|| ||
|| ||
|| What you see above is the disassembled code of some old WinRAR ||
|| release. The pre-crack searches for this pattern: ||
|| "84C00F85DFFEFFFF33C0". \/
||
|| ...Yaay, a shit load of numbers and letters, neat!
||
||
|| The first four characters is a comparison, the next twelve /\
|| characters are a jump related to the previous comparison and after ||
|| that comes the part of the code that we will modify. In this case ||
|| we replace the original code: "cleaning registry EAX" with: ||
|| "add a number to registry EAX->AX->AH,AL". It is all very sexy, ||
|| and if you feel you need to know more about cracking, disassembling, ||
|| debugging I recommend you to browse the .aware /usr directories ||
|| _or_ read some of the thousands of text published on the net and ||
|| in books. ||
|| ||
|| ||
|| Here we have the diff patterns: ||
|| ||
|| * 84C00F85DFFEFFFF33C0 - original code ||
|| * 84C00F85DFFEFFFFB001 - modified code ||
|| ||
||_______________________________________________________________________||
|| ||
|| 0x04 The source ||
||_______________________________________________________________________||
|| ||
|| When the patch pattern(s) is located the only thing left to do ||
|| is to write a patcher, which will read, locate and replace data. ||
|| If you add a sexy gui, some weird looking ogl and a mod/track ||
|| player you have yourself a decent release. ||
|| ||
|| ||
|| Note! The following code will not compile as it is now. ||
|| It is more of an example of how it could be done. ||
|| A working copy can be found in the .aware /usr directories. ||
|| Exact location(s) will be given in the end of this text. ||
|| ||
|| ||
|| - code - ||
||#######################################################################||
|| /* ||
|| W W W . A W A R E N E T W O R K . O R G ||
|| ||
|| []===========================================[] ||
|| WinRAR *ALL* Versions preCracker ||
|| []===========================================[] ||
|| iqlord | .aware crew -w1n4p1 style- ||
|| []===========================================[] ||
|| ||
|| */ ||
|| ||
|| void WinRAR_preCrack::OnOk() { ||
|| #define GC fgetc(fp); ||
|| CNoWinrarDlg nowrar; ||
|| CWinrarCrackedDlg finished; ||
|| CNotCrackableDlg notcrkable; \/
|| DWORD dwSize;
|| HKEY Regentry;
|| HKEY RegUserName; /\
|| static char WinRarInstallPath[0x0400], ||
|| WinRarKeyFile[0x0400], ||
|| UserName[0x0400]; ||
|| bool registry_trigger = true; ||
|| short cb01=0x00,cb02=0x00,cb03=0x00,cb04=0x00, ||
|| cb05=0x00,cb06=0x00,cb07=0x00,cb08=0x00, ||
|| cb09=0x00,cb10=0x00;unsigned int x=0x00; ||
|| FILE* fp; ||
|| FILE* pKeyFile; ||
|| ||
|| RegOpenKeyEx(HKEY_LOCAL_MACHINE, ||
|| "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" ||
|| "App Paths\\WinRAR.exe", ||
|| 0x00, KEY_QUERY_VALUE, &Regentry ); ||
|| ||
|| if (RegQueryValueEx(Regentry, TEXT(""), 0x00, 0x00, ||
|| (unsigned char *)WinRarInstallPath, &dwSize ) ||
\/ != ERROR_SUCCESS ) { registry_trigger = false; ||
} ||
if(registry_trigger) ||
strncpy(WinRarKeyFile,WinRarInstallPath, ||
strlen(WinRarInstallPath)-10); ||
else { ||
/\ strcpy(WinRarInstallPath, ".\\WinRAR.exe" ); ||
|| registry_trigger = true; ||
|| } ||
|| strcat(WinRarKeyFile,"rarreg.key"); ||
|| if((fp=fopen(WinRarInstallPath,"r+b"))==0x00) { ||
|| nowrar.DoModal(); RegCloseKey(Regentry); return; ||
|| } ||
|| while(cb10 != -1) { ||
|| cb01 = GC cb02 = GC cb03 = GC cb04 = GC cb05 = GC ||
|| cb06 = GC cb07 = GC cb08 = GC cb09 = GC cb10 = GC ||
|| if ( ||
|| cb01 == 0x84 && cb02 == 0xC0 && ||
|| cb03 == 0x0F && cb04 == 0x85 && ||
|| cb05 == 0xDF && cb06 == 0xFE && ||
|| cb07 == 0xFF && cb08 == 0xFF && ||
|| cb09 == 0x33 && cb10 == 0xC0 ){ ||
|| fseek(fp,ftell(fp)-0x02,0x00); fputs("\xB0\x01",fp); ||
|| if((pKeyFile=fopen(WinRarKeyFile,"w+b"))==0x00) { ||
|| registry_trigger = false; ||
|| } ||
|| if(registry_trigger) { ||
|| RegOpenKeyEx(HKEY_LOCAL_MACHINE, ||
|| "SOFTWARE\\Microsoft\\Windows NT\\" ||
|| "CurrentVersion\\Winlogon", ||
|| 0x00, KEY_QUERY_VALUE, &RegUserName ); ||
|| if ( RegQueryValueEx(RegUserName, ||
|| TEXT("DefaultUserName"),0x00, 0x00, ||
|| (unsigned char *)UserName, &dwSize ) ||
|| != ERROR_SUCCESS ) { ||
|| strcpy(UserName,"Full version"); ||
|| } ||
|| fprintf(pKeyFile,"pure pwnage by the .aware crew\n%s\n"||
|| "Single PC usage license.\n",UserName); ||
|| fclose(pKeyFile); ||
|| } ||
|| RegCloseKey(RegUserName); RegCloseKey(Regentry); ||
|| fclose(fp); ||
|| finished.DoModal(); // crack done. ||
|| return; ||
|| } fseek(fp,x,0x00); x++; \/
|| }
|| fclose(fp);
|| notcrkable.DoModal(); // error, abort.
|| return; /\
|| } ||
||#######################################################################||
|| - code - ||
|| ||
|| ||
|| Did you notice how the patcher copies the default winUserName and ||
|| uses it to register WinRAR? Well of course you did. ||
|| ||
|| So there you have it! Now start producing more pre-cracks people! ||
|| It will save time and effort later on... ||
|| ||
|| ||
|| Deepest respects to me fellow partners in crime; rattle'n'kspecial! ||
|| And of course to the rest of ya! (you know who you are). ||
|| ||
|| Take care ya'll ||
|| ||
||_______________________________________________________________________||
|| ||
|| 0x05 U R L ||
||_______________________________________________________________________||
|| [ www.awarenetwork.org ] ||
|| ||
|| WinRAR VSC++ workspace: ||
|| /home/iqlord/cracks%20&%20keygens/wrcrkr/winrarcrkr.src.rar ||
|| ||
|| WinRAR precompiled binary: ||
|| /home/iqlord/cracks%20&%20keygens/wrcrkr/winrarcrkr.rar ||
|| ||
|| WinRAR raw code: ||
|| /home/iqlord/cracks%20&%20keygens/wrcrkr/wrcrkr.cpp ||
|| ||
|| First WinRAR pre-crack attempt (works, but without the sexy stuff): ||
|| /home/iqlord/cracks%20&%20keygens/winrar-precrack/ ||
|| ||
|| - EOF - ||
|| ||
|| ___. ||
|| \_ |__ ____ _____ __ _ _______ _______ ____ ||
|| | __ \_/ __ \ \__ \\ \/ \/ /\__ \\_ __ \_/ __ \ ||
|| | \_\ \ ___/ / __ \\ / / __ \| | \/\ ___/ ||
|| |___ /\___ > /(____ /\/\_/ (____ /__| \___ > ||
|| \/ \/___\/ / /\/ \/ \/ ()()() ||
||_____________/ (^^, / /________________________________________________||
||-------------) _)` 7_/-------------------------------------------------||
||=============\(G\ , )==================================================||
|| /`_`-' \_ ,'`) ||
|| / / \ \/ \__,-. \/
|| __(_/ >. ` ) /\ /` )
|| \_ / ( `--'_/ \/\_/ - iqlord
|| U \_ _)
\/ ( `< ...and you thought that the texts exact
/___\ 512 lines was a fucking coincidence?
(__)
|