Cracking for newbies #5 - by woody^drn I want to show you how to make some tricks for your programs, so it will be more difficult to crack - some anti cracking routines. In vaczine #3 I talked about how to xor strings so they don't seem that interesting when the cracker looks at the .exe file. This time I'll talk about a packing method and some checks you can make in your program. First we can start with the checks. Lets say the program is like this: You've made two nag screens, one that isn't xored and one that's packed and xored. We'll call them n1 and n2. 1) When your program starts, we let it check if any of the bytes (where the program calls the nag) of n2 is changed or modified. If it has been changed goto 2., else goto 4. 2) Display the n1. 3) Check if n1 has been changed, if so goto 4. 4) Display the n2. 5) Check if check 1) has been changed, if so goto 8. if not goto 6. 6) Check if check 3) has been changed, if so goto 9. if not goto 7. 7) Run the program. 8) fix check 1) and goto 5) 9) fix check 3) and goto 5) Can you follow this ... the code checks it self, if something has been changed aka patched/cracked it will fix the bytes that has been patched. The crme#2.exe is a good example. You can make several nags that has been hidden (I'll explain how to hide them later) just in case if the other once is patched or destroyed, and just make the code display those who are not patched. There are several ways to hide strings, you can pack or xor the strings. Make a depacking routine in the start of the program or just depack it only when needed. If they are only depacked when needed it will make it hard to dump it, well not hard, but the string refs wouldn't be there. In w32dasm you can only see the strings if they are referenced to some of the code. And we can use that weakness ... with illegal opcode placement .. or whatever we choose to call it. etc.: :0040103C 0000 add byte ptr [eax], al :0040103E 6A00 push 00000000 * Possible StringData Ref from Data Obj ->"Crackme v1.6 for Vaczine #4" | :00401040 6800304000 push 00403000 * Possible StringData Ref from Data Obj ->"NAG :)" | :00401045 681C304000 push 0040301C :0040104A 6A00 push 00000000 * Reference To: USER32.MessageBoxA, Ord:01BBh | :0040104C E8E5FFFFFF Call 00401036 You can see that this will make it say "Crackme v1.6 .." ... the opcodes fit, but what if the opcodes at 40103C has more than 2 bytes, like a call. We could change 40103C 0000, to 40103C E83D, then it would need more bytes and will overlab the push 00403000. Lets change it: :0040103C E83D6A0068 call 68407A7E :00401041 0030 add byte ptr [eax], dh :00401043 40 inc eax :00401044 00681C add byte ptr [eax+1C], ch :00401047 304000 xor byte ptr [eax+00], al :0040104A 6A00 push 00000000 * Reference To: USER32.MessageBoxA, Ord:01BBh | :0040104C E8E5FFFFFF Call 00401036" See ?? now it doesn't show the string refs to the "NAG :)" or "Crackme v1.6" ... really easy and quick. This is called delta offsets The only thing is .. we have to make sure that the code doesn't jump to 40103C but only jumps to 40103E. That was one way of doing it .. ofcause this wont confuse softice! We can't code this, this has to be done manually either by hiew or any good hexeditor. I've allready explained how to xor strings in vaczine #3, so lets move on ... how to pack the opcodes. Packing is fairly easy, I'll explain a very easy method that I've used in crme#2.exe. The program starts normally, after initializing all the stuff it needs to do, it jumps to the depacking routine: (I'll explain as we go on..) .0040103B: B85F304000 mov eax,00040305F ;" @0_" Moves the char at 40305F into eax, that char is 78h. .00401040: 33D2 xor edx,edx Xors edx with edx .. aka edx = 0 .00401042: 8A10 mov dl,[eax] Moves the char in eax into dl, dl is now 78h. .00401044: 80F212 xor dl,012 ;" Now it xors dl with 12 ... 78h xor 12h = 6A. .00401047: 8810 mov [eax],dl Moves dl into eax's place (the place where it got the 78h from). .00401049: 40 inc eax .0040104A: 3D76304000 cmp eax,000403076 ;" @0v" .0040104F: 76F1 jbe .000401042 Increases eax and compares eax with 403076. If eax is below or equal then it will goto the the depacking start again .. just with the next char at eax's place (inc eax). Eax was 40305F and it will xor every char until eax is 403076. 40305F - 403076 looks like this: .0040305F: 7812 js .000403073 .00403061: 7A12 jp .000403075 .00403063: 225212 and dl,[edx][00012] .00403066: 7A0E jp .000403076 .00403068: 225212 and dl,[edx][00012] .0040306B: 7812 js .00040307F .0040306D: FA cli .0040306E: D0CD ror ch,1 .00403070: ED in eax,dx .00403071: ED in eax,dx .00403072: FB sti .00403073: 89CD mov ebp,ecx .00403075: ED in eax,dx .00403076: ED in eax,dx Alot of opcodes which makes no sense at all. But when the depacking routine is done with xoring all these opcodes with 12, it will look like this: .0040305F: 6A00 push 000 .00403061: 6800304000 push 000403000 ;" @0" .00403066: 681C304000 push 00040301C ;" @0" .0040306B: 6A00 push 000 .0040306D: E8C2DFFFFF call .000401034 .00403072: E99BDFFFFF jmp .000401012 Very easy to understand ... pushes the top text of the window and the text in the window. then it calls messageboxa to display the window. and jumps back into the normal code again. The packed/depacked code is actually at the strings offsets. So this wont appear in w32dasm. The string can now be used as executing code instead of strings. nice ... ;) This is basicly how all packers are done .. this is just a very *very* basic way of doing it. If the packed opcodes was supposed to be a nag screen, then you can implant the checking routine to see if it has been depacked .. if not .. the program is patched/cracked. That's all for now .. cya ! -wOODY^dRN