Well,
I was going to write a tutorial on how to 'code-inject' but I thought better of it due to the fact I can't really explain why I am doing what I am doing. But I can show you two examples of working code that have worked on simple crackits for me. And ask a few questions of those more experienced than I for some pointers
The first was a simple crackit that I got from Woodmans site. Since actually b/forcing the full 20chr password is a bit much for a beginner (not to mention very time consuming), I truncated it to 4 characters. And because I am a wuss!
Patching the address of the conditional jump to the Bad Serial bit with the address of 401180 (which is a nice empty bit at the end of the code) I coded this brute forcer for the four characters.
Worth noting in the orginal the password is not 4 letters long
00401180 > BB 00254000 MOV EBX,abexcm5_.00402500 ;The address I chose in memory to manipulate the pass
;In this app the proper address is 402324
00401185 . C703 30303030 MOV DWORD PTR DS:[EBX],30303030 ;Fill that address with "0000"
0040118B . C743 04 000000>MOV DWORD PTR DS:[EBX+4],0 ;make sure its terminated
00401192 . 33C0 XOR EAX,EAX ;Zero EAX [redundant now I think]
00401194 > EB 42 JMP SHORT abexcm5_.004011D8 ;Jump to checking routine - I've replicated it here but
;normally you should call to Validation_Routine
00401196 > 8043 03 01 ADD BYTE PTR DS:[EBX+3],1 ;Increment password
0040119A . 8A43 03 MOV AL,BYTE PTR DS:[EBX+3] ;Move the byte incremented to AL
0040119D . 3C 7A CMP AL,7A ;Check it compared to "}" (the next chr after "z"

0040119F . 90 NOP
004011A0 . 90 NOP
004011A1 . 90 NOP
004011A2 .^7E F0 JLE SHORT abexcm5_.00401194 ;less than "z" then continue incrementing
004011A4 . C643 03 30 MOV BYTE PTR DS:[EBX+3],30 ;if greater reset to "0"
004011A8 . 8043 02 01 ADD BYTE PTR DS:[EBX+2],1 ;increment chr before
004011AC . 8A43 02 MOV AL,BYTE PTR DS:[EBX+2] ;move newly incremented chr to AL
004011AF . 3C 7A CMP AL,7A ;Check less than "}"
004011B1 .^7E E1 JLE SHORT abexcm5_.00401194 ;if less then continue checking
004011B3 . C643 02 30 MOV BYTE PTR DS:[EBX+2],30 ;as above
004011B7 . 8043 01 01 ADD BYTE PTR DS:[EBX+1],1
004011BB . 8A43 01 MOV AL,BYTE PTR DS:[EBX+1]
004011BE . 3C 7A CMP AL,7A
004011C0 .^7E D2 JLE SHORT abexcm5_.00401194
004011C2 . C643 01 30 MOV BYTE PTR DS:[EBX+1],30
004011C6 . 8003 01 ADD BYTE PTR DS:[EBX],1
004011C9 . 90 NOP
004011CA . 8A03 MOV AL,BYTE PTR DS:[EBX]
004011CC . 3C 7A CMP AL,7A
004011CE .^7E C4 JLE SHORT abexcm5_.00401194
004011D0 .^E9 2CFFFFFF JMP abexcm5_.00401101 ;if 1st chr of 4 byte pass is equal to '{' then the
;pass doesn't lie between 0 and z so jump to error message
004011D5 90 NOP
004011D6 90 NOP
004011D7 90 NOP
004011D8 > 68 00254000 PUSH abexcm5_.00402500 ; /String2 = "" <- Our pass
004011DD . 68 00204000 PUSH abexcm5_.00402000 ; |String1 = "" <- Correct pass
004011E2 . E8 66FFFFFF CALL <JMP.&KERNEL32.lstrcmpiA> ; \lstrcmpiA
004011E7 . 83F8 00 CMP EAX,0
004011EA .^75 AA JNZ SHORT abexcm5_.00401196 ;Doesn't work therefore continue
004011EC .^E9 26FFFFFF JMP abexcm5_.00401117 ;Works - this is in fact a jump to the good boy box
;and I have patched it so the text is our pass. Perhaps
;given space create a message box with the pass
;so it could be written down and then just pass it to
;the good boy routine to continue
Improvements I can see at this point
Eliminate double jumps going from 0401194 and then back to 04011D8
Tighten up the code to remove the now redundant nops. I used them to seperate my code into segments and also they are there as a result of some tidying up.
As mentioned above use a messagebox to give you the right pass. Then pass that to the good boy routine so it can continue i.e make registry entries etc so it knows its regged. Not in this instance with this program but for others.
At this point - I have the following questions:
It looks like its fairly easy to scale this up to say 8 or more letters (obviously there is a time penalty for doing so - duh!) There may be times when we are severley limited by space so is there an more efficient method of doing this?
I need to work out a good way to preserve the state of the password. As it stands, because I have replicated the validation routine, it becomes self contained and as a result the JMP from the 'goto bad boy section' will always reset the algorithm back to '0000'. If you used this method, and the correct memory addresses, then there is a good chance that the password would be 'freed' or overwritten at some point in the validation routine.
Anybody care to give me a hand? Please remember - when you've all finished laughing at my ASM coding - that this is my first attempt to do this
Anyways - buoyed by my brilliant foray into the world of code caving I tried another crackit. This one was a crackit from theblacksheep challenge site (I heartily recommend you check it out - there are some fun things to learn and do over there) for which I had written a brute forcer in VB to crack it some time ago. Infact it was my first b/fer of any kind.
This one is nice and easy to do because it tells you it is five characters long. Handy!
So with this one (I can attach if anyone wants to see it) I've overwritten a little of the bad boy message box, not the call to it because I cannot jmp far enough away to put my code and not overwrite the good boy message
So now instead of producing the Bad Key message box it will kick you into my routine which looks the same as above nearly.
0040122F > 8005 0C304000 >ADD BYTE PTR DS:[40300C],1 ;Real password location this time - Increment it
00401236 . A0 0C304000 MOV AL,BYTE PTR DS:[40300C] ; Usual Compare stuff
0040123B . 3C 7A CMP AL,7A
0040123D . 7E 6B JLE SHORT CrackIt-.004012AA ;Again redundant double jump - should just point at
;the call to Valid_routine
0040123F . C605 0C304000 >MOV BYTE PTR DS:[40300C],41 ;For the sake of speed I have just used A-z
;Since I know there are no numbers

00401246 . 8005 0B304000 >ADD BYTE PTR DS:[40300B],1
0040124D . A0 0B304000 MOV AL,BYTE PTR DS:[40300B]
00401252 . 3C 7A CMP AL,7A
00401254 . 7E 54 JLE SHORT CrackIt-.004012AA
00401256 . C605 0B304000 >MOV BYTE PTR DS:[40300B],41
0040125D . 8005 0A304000 >ADD BYTE PTR DS:[40300A],1
00401264 . A0 0A304000 MOV AL,BYTE PTR DS:[40300A]
00401269 . 3C 7A CMP AL,7A
0040126B . 7E 3D JLE SHORT CrackIt-.004012AA
0040126D . C605 0A304000 >MOV BYTE PTR DS:[40300A],41
00401274 . 8005 09304000 >ADD BYTE PTR DS:[403009],1
0040127B . A0 09304000 MOV AL,BYTE PTR DS:[403009]
00401280 . 3C 7A CMP AL,7A
00401282 . 7E 26 JLE SHORT CrackIt-.004012AA
00401284 . C605 09304000 >MOV BYTE PTR DS:[403009],41
0040128B . 8005 08304000 >ADD BYTE PTR DS:[403008],1 ;Five letters this time
00401292 . A0 08304000 MOV AL,BYTE PTR DS:[403008]
00401297 . 3C 7A CMP AL,7A
00401299 . 7E 0F JLE SHORT CrackIt-.004012AA
Since I didn't know how much code was involved this time, there is now a huge nop gap up until 4012AA which is the jump to the call (sigh) of the is_it_valid bit.
Amazingly, doing it this way (even when allowing for 0-z) it is in the order of DAYS faster than the VB bruteforcer I wrote for the same crackit. This addition to the code can do it in minutes but my last VB bruter for this took several days (presumably for two reasons :- my programming in VB is only slightly worse than in asm :shock: and two VB had to emulate the registers which is handled here quite nicely

)
Thinking more on this I also think that I should approach this in a slightly different fashion. I am concentrating in these examples (partially because I know they are of length x) changing the submitted password from 0000 to 0001 to 0002. With a little more simple coding I should be able to make the routine change the pass 0000 to 1000 to 2000 etc. I think this would give me the advantage of operating using passwords of length <x in that another check (CMP AL,00h) could be used to increment the length of the password so I start with password of length 1 and move up to length x.
Anyway, I think that is enough rambling from me for now. I would really appreciate some feedback on this and my techniques as I realise I am very new to this and am probably not doing it the best way.
Cheers all and happy RE'ing.
bb
What would Brian Boitano do?