/\ || /\ [=========================================================================||===] [-------------------------[ 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? (__)