Lately many programs are using Virtual Machine code inside, it’s not so hard to deal with VM and it depends on the complexity of the VM. Fundamentally once you have understand the VM structure and some opcodes you are almost done because it’s a matter of time. This time the problems arise when you have to change one or more bytes because the entire VM instructions are surrounded by a nasty anti-patch check. I don’t describe the VM used in the crackme but I’ll focus my attention over the instruction I want to patch, the good/bad boy conditional jump:
The idea is to patch the conditional jump at 415638 letting it to accept any serial, the new instruction would be:
75 00 jnz 0040563A
If you try to patch the instruction the crackme won’t run anymore because an exception will occour. As I said before there are some anti-patch checks; the crackme uses the VM instructions in his anti-patch cheching routine and you can’t patch the VM’s instructions. So, what can I do? The first thing to do is to start looking at the code which lead me to the snippet above:
This is the last part of the VM instruction that preceed the check I showed you above. Obviously the snippet above is called many times (because an instruction is called many times…) and each time the loop (40D8E2/40D8ED) extracts the offset of the next instruction. The next instruction address is obtained adding the offset to the base address (which is 40CF60). Well, seems to be unpatchable or atleast very hard to patch but there’s a little flow in it.
Maybe you can’t patch a byte of a generic VM instruction but you can surely patch something else, I’m talking about the dwords from 41555F to 41557B. Firstly these bytes are not inside a VM instruction, they won’t be executed; secondly they are not used in the code, I mean they are not used in the various anti-patch routines. So, I can change them a little. I don’t need to change all the bytes, one dword is enough.
The idea is to create a new VM instruction, almost similar to the one I wanted to patch. The new instruction will have:
75 00 jnz 0041563A
75 01 jnz 41563B
In this way I always pass through the good boy. I’ll add the new instruction’s bytes starting from address 409704. Now, let’s see how can I do such a change. First of all, it’s better to look at the last iteraction of the loop:
xor edx, [ebx+28h] <– 24CA1F46 ^ [41555F] = 24CA1F46 ^ 24CA4311 = 5C57
add edx, [ebx+14h] <– 5C57 + 40CF60 = 412BB7
xor eax, [edx] <—— D8EEEC32 ^ [412BB7] = D8EEEC32 ^ D8EE6AB9 = 868B
add eax, [ebx+14h] <– 868b + 40CF60 = 4155EB
Ok, this is the normal situation. As I said before the new instruction is at 409704 so if I want to find the new value of [41555F] I have to go backward:
409704 – 40CF60 = FFFFC7A4
FFFFC7A4 ^ D8EEEC32 = 27112B96 <— I’ll put 0x27112B96 at . It’s the new [412BB7]
409700 – 40CF60 = FFFFC7A0
FFFFC7A0 ^ 24CA1F46 = DB35D8E6 <– I’ll put 0xDB35D8E6 at [41555F]
Click here to download the original and the patched version of the crackme.