rendari
March 24th, 2008, 03:02
(Part 2 of .NET native exe insights)Serial fishing and patching .NET exes with Ollydbg.
Last blog post I pointed out how native exes, when used improperly, do nothing to deter reverse engineer of completely decompiling your product, and doing with it as they please (cracking). Now, I would like to assume that the developer bothered reading my blog post, and actually bothered wiping the IL from his native exe. While I do admit that this is a "final" solution to decompilation, as I mentioned before it is faaaar from a "final" solution to crackers. Hackers have been going at native code for years, so with a bit of brainpower and Olly, a native .NET exe should pose no challenge to them.
In this post I will observe a simple keygenme, and I will show you how I was able to
a) patch it
b) fish a serial for it...
in less that 5 minutes with Olly.
Here is the link to the keygenme we will be dealing with(same as in last blog post):
http://www.filesend.net/download.php?f=644ee1dfd1b9246aee11d64b931bd0fb
Download it, extract it anywhere, and Ngen it
>ngen unpackme.exe.
Then, take unpackme.exe, and load it into Olly. Check all exceptions, and run the Unpackme. It will pop up with a little dialogue asking for a name and serial. Click the "Check" button, and observe the error message:
"Invalid serial. Pls don't hack me :'("
Hardy harr.
Well, now lets think for a second. This is a string that is needed for the unpackme to run. Therefore, it can probably be found the native image of the unpackme. We also know that all strings in a .NET exe are stored in the metadata. As I pointed out in the last tutorial, the metadata of a .NET exe is in the .IL section of the native exe. So, we know that somewhere in the .IL section of our native exe, we will find a string saying:
"Invalid serial. Pls don't hack me :'("
Furthermore, if you paid close attention to the .NET file format, you know that all strings in .NET are stored as unicode. So, somewhere in the .IL section of our native .NET exe there will be a UNICODE string that says:
"Invalid serial. Pls don't hack me :'(".
Now, suppose that we locate this string. What do we do with it? Quite simple: We put a hardware breakpoint upon it. Once it is accessed, we know that the routine it was accessed from is part of the serial checking routine.
Alright, now in Olly, with the unpackme running in the background, press ALT+M to open a list of all modules.
Scroll down a bit until you find the native image of unpackme.exe (Unpackme.ni.exe). You should see this:
Now, we are interested in the .IL section of this native exe, because that is where the string we are trying to breakpoint is. In the dump window of Ollydbg, press CTRL+G, type 30012000, and press enter. This will move the Ollydbg hex dump window to the beginning of the .IL section. Then, still in the dump window, press CTRL+B (binary search), and under unicode type in:
"Invalid serial.". Then press enter to let Olly search. It should end up here:
Cool! This is the badboy string we are interested in. Write down the address, restart the target in Olly, and press F9 to run Olly once again. Do not click on the check button yet. First, go to the address we wrote down (300142FD) select the first 4 bytes,
Right click -> breakpoint -> hardware, on access -> byte
Now, go back to the unpackme, and click on the "Check" button. Olly should break with a hardware DWORD on access at a place that looks like this:
Alright now, go to
Debug -> hardware breakpoints
in Olly, and delete your hardware breakpoint that you set upon this string.
Now, its time to trace a bit with F8 until we get to the .text section of Unpackme.exe. Just hold F8 until you end up here:
After you've debugged .NET exe's a bit in Olly you will recognize this as the beginning of a method, just like
PUSH EBP
MOV EBP, ESP
usually marks the beginning of a routine in VC++...
Anyways, since this routine has accessed the "Invalid serial" string, we can assume that this routine is the serial check routine. Start tracing at it with F8. A messagebox telling you you entered the wrong serial will pop up after you trace over this call:
Interesting... look around in Olly and try to get a feel for what is happening. Even a noob should be able to understand what is happening here:
Simple, eh? Just for kicks, nop the JE at 30004291 and press F9 to run the unpackme. Click on the "Check" button and watch as this string pops up:
"Good work! Now go and post a solution or suggestions so I can improve the protector =)"
And that's it. You more or less cracked this simple unpackme. If you want the solution to become permanent, just use a hex editor to change Unpackme.ni.exe accordingly. I'm sure you can figure out how to do that on your own
What it more interesting is actually fishing a valid serial with Olly. Look at this code right here:
It should be pretty obvious to an experienced reverser that a string compare is happening at 30004278. The only irregular thing is that the parameters are put in EDX and ECX, and people familiar with .NET will attest that this is actually regular.
The compiler simply prefers using registers to pass parameters instead of the stack. Not very neat, but w/e, .NET wasn't designed to be pretty (obviously).
Let's put a breakpoint upon 30004278 and examine the contents ot the EDX and ECX registers. Select 30004278, press F2 to place a breakpoint in Olly, and press F9 to run the target. Click on the "Check" button in the unpackme, and watch Olly break at 30004278. The contents of the EDX and ECX registers should be:
01323ED8
01323E74
(note: it's probably different on each machine. Don't worry about that).
Alright, these 2 values are both pointers. Lets see what they point to:
ECX:
EDX:
So, ECX is the contents of the textbox where we entered the serial. Since I didn't touch that text box, the text it is reading is: "Enter Serial Here".
In EDX is a jumbled unicode string. It doesn't take a genius to figure out that this is probably the correct serial, and it is being compared against the invalid serial. The jumbled unicode string is:
hy71q8ZmtINzzC5EEOuUYw==
Cool. So that is theoretically the valid serial. Let's put theory to the test. Restart the unpackme to undo all changes we have made to it so far, and then press F9 to run it again. In the dialog where is prompts us for name and serial, leave the name as is, while for the serial type in: hy71q8ZmtINzzC5EEOuUYw==. Press "Check" to let the crackme check if the serial is correct.
It is. You will get the goodboy message.
Now, incase you were wondering, the art of debugging .NET exes in Olly isn't just useful for native .NET exes. It also has practical applications.
Take for example the .NET unpackme I posted on crackmes awhile ago. Noone expect bigmouse was able to unpack it, so I assume a lot of people here don't have experience with JIT hooks, and are simply stumped when they see them in an unpackme.
So, screw the JIT hooks, lets fish a valid serial for the unpackme in Olly ^^.
Download the unpackme here:
http://www.filesend.net/download.php?f=67ccb0a87cc8f2f2f8d3776f9612f129
The procedure for cracking this is very similar to last time. First we find a string that we want to break upon, and then from there we trace to the serial check routine. From there on... well figure out what its doing and patch/fish accordingly
Start off by opening the file in Olly. If we analyze the file in ILDasm, we will see that it is invoking the assembly through Assembly.Load. Therefore, some buffer in memory must contain the semi-decrypted exe. Just look for that buffer in the Modules window. For me, it was 00C70000
I know that this is the memory area I was looking for because of the MZ header... Now, in this memory area, the string we are looking to break upon (Invalid serial. Pls don't hack me :'( ) Can be located. So, just do a binary search for the Unicode "Invalid serial." You will end up here:
...set a HW BP on access on the first 4 bytes of the string, just like I explained earlier in the post. Then proceed to run the file, click on the "Check" button, and you should break here:
Remove your hardware breakpoint, and proceed to trace with F8 until you come up to some code that looks like this:
(or you could just set a breakpoint at this place, as it is very important in .NET reversing. It is the exit point of the .NET jitter. When .NET exits from the JIT dll and goes into the native code, it will always pass through this point).
This is the JIT just checking if there were any errors during the jitting. Then it returns to a little memory area where it restores all registers modified by the jitter:
The above memory areas will always be returned to out of the jitter. Its just a little consistency that I noticed that helps my eyes adjust as I trace with F8 through native .NET code. Anyways, once you trace over the ret at 00341F5B, you will trace about 5 more lines and then be in the middle of the native code of the serial check routine:
Look familiar? Yep, its the exactly same stuff as I described previously in the post. Thus, if you were reading closely, you should understand how to be able to fish the serial and patch it to work however you might like.
Now, I was planning to show you how to write a loader to patch my .NET stuff right here, but that will have to wait on another post, where I show you how to write loaders to patch the native code and thus completely bypass relying on the IL
Right now, once again, I am too tired to continue =(.
In conclusion:
I showed you the basics of native .NET code, and I showed you how to break into it so that you may debug it in Olly. Thus, if the IL code of an exe is too well protected or simply not availible, you can fall back to reversing this stuff.
I would also like to note that I have not yet found a way to resolve the native function names/exports of VisualBasic.ni.dll. If I do find out a way, it will make reversing much similar because then we will be able to break upon functions with interesting names such as strcmp. Its something I need to look into.
but for now, sleeeeeeeep
peace
-Rendari
Last blog post I pointed out how native exes, when used improperly, do nothing to deter reverse engineer of completely decompiling your product, and doing with it as they please (cracking). Now, I would like to assume that the developer bothered reading my blog post, and actually bothered wiping the IL from his native exe. While I do admit that this is a "final" solution to decompilation, as I mentioned before it is faaaar from a "final" solution to crackers. Hackers have been going at native code for years, so with a bit of brainpower and Olly, a native .NET exe should pose no challenge to them.
In this post I will observe a simple keygenme, and I will show you how I was able to
a) patch it
b) fish a serial for it...
in less that 5 minutes with Olly.
Here is the link to the keygenme we will be dealing with(same as in last blog post):
http://www.filesend.net/download.php?f=644ee1dfd1b9246aee11d64b931bd0fb
Download it, extract it anywhere, and Ngen it
>ngen unpackme.exe.
Then, take unpackme.exe, and load it into Olly. Check all exceptions, and run the Unpackme. It will pop up with a little dialogue asking for a name and serial. Click the "Check" button, and observe the error message:
"Invalid serial. Pls don't hack me :'("
Hardy harr.
Well, now lets think for a second. This is a string that is needed for the unpackme to run. Therefore, it can probably be found the native image of the unpackme. We also know that all strings in a .NET exe are stored in the metadata. As I pointed out in the last tutorial, the metadata of a .NET exe is in the .IL section of the native exe. So, we know that somewhere in the .IL section of our native exe, we will find a string saying:
"Invalid serial. Pls don't hack me :'("
Furthermore, if you paid close attention to the .NET file format, you know that all strings in .NET are stored as unicode. So, somewhere in the .IL section of our native .NET exe there will be a UNICODE string that says:
"Invalid serial. Pls don't hack me :'(".
Now, suppose that we locate this string. What do we do with it? Quite simple: We put a hardware breakpoint upon it. Once it is accessed, we know that the routine it was accessed from is part of the serial checking routine.
Alright, now in Olly, with the unpackme running in the background, press ALT+M to open a list of all modules.
Scroll down a bit until you find the native image of unpackme.exe (Unpackme.ni.exe). You should see this:
Code:
30000000 00001000 ( Unpack_1 3 PE header Imag R RWE
30002000 00004000 ( Unpack_1 3 .text code Imag R E RWE
30006000 00001000 ( Unpack_1 3 .extrel code Imag R E RWE
30008000 00005000 ( Unpack_1 3 .data code,data Imag RW RWE
3000E000 00001000 ( Unpack_1 3 .xdata Imag RWE RWE
30010000 00001000 ( Unpack_1 3 .dbgmap Imag R RWE
30012000 00004000 ( Unpack_1 3 .il Imag R RWE
30016000 00001000 ( Unpack_1 3 .rsrc resources Imag R RWE
30018000 00001000 ( Unpack_1 3 .reloc relocations Imag R RWE
Now, we are interested in the .IL section of this native exe, because that is where the string we are trying to breakpoint is. In the dump window of Ollydbg, press CTRL+G, type 30012000, and press enter. This will move the Ollydbg hex dump window to the beginning of the .IL section. Then, still in the dump window, press CTRL+B (binary search), and under unicode type in:
"Invalid serial.". Then press enter to let Olly search. It should end up here:
Code:
300142FD 49 00 6E 00 76 00 61 00 I.n.v.a.
30014305 6C 00 69 00 64 00 20 00 l.i.d. .
3001430D 53 00 65 00 72 00 69 00 S.e.r.i.
30014315 61 00 6C 00 2E 00 20 00 a.l... .
3001431D 50 00 6C 00 73 00 20 00 P.l.s. .
30014325 64 00 6F 00 6E 00 27 00 d.o.n.'.
3001432D 74 00 20 00 68 00 61 00 t. .h.a.
30014335 63 00 6B 00 20 00 6D 00 c.k. .m.
3001433D 65 00 20 00 3A 00 27 00 e. .:.'.
30014345 28 00 01 81 7B 54 00 68 (.{T.h
3001434D 00 65 00 20 00 70 00 6F .e. .p.o
30014355 00 69 00 6E 00 74 00 20 .i.n.t.
3001435D 00 6F 00 66 00 20 00 74 .o.f. .t
30014365 00 68 00 69 00 73 00 20 .h.i.s.
3001436D 00 55 00 6E 00 70 00 61 .U.n.p.a
30014375 00 63 00 6B 00 6D 00 65 .c.k.m.e
3001437D 00 20 00 69 00 73 00 20 . .i.s.
30014385 00 66 00 6F 00 72 00 20 .f.o.r.
Cool! This is the badboy string we are interested in. Write down the address, restart the target in Olly, and press F9 to run Olly once again. Do not click on the check button yet. First, go to the address we wrote down (300142FD) select the first 4 bytes,
Right click -> breakpoint -> hardware, on access -> byte
Now, go back to the unpackme, and click on the "Check" button. Olly should break with a hardware DWORD on access at a place that looks like this:
Code:
7814507A F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
7814507C FF2495 94511478 JMP DWORD PTR DS:[EDX*4+78145194]
78145083 90 NOP
Alright now, go to
Debug -> hardware breakpoints
in Olly, and delete your hardware breakpoint that you set upon this string.
Now, its time to trace a bit with F8 until we get to the .text section of Unpackme.exe. Just hold F8 until you end up here:
Code:
300041D0 57 PUSH EDI
300041D1 56 PUSH ESI
300041D2 53 PUSH EBX
300041D3 55 PUSH EBP
300041D4 83EC 10 SUB ESP,10
300041D7 891424 MOV DWORD PTR SS:[ESP],EDX
300041DA 8BF1 MOV ESI,ECX
300041DC 8B05 0CE00030 MOV EAX,DWORD PTR DS:[3000E00C] ; Unpack_1.300081B4
300041E2 8338 00 CMP DWORD PTR DS:[EAX],0
300041E5 74 05 JE SHORT Unpack_1.300041EC
300041E7 E8 12E1084A CALL mscorwks.7A0922FE
After you've debugged .NET exe's a bit in Olly you will recognize this as the beginning of a method, just like
PUSH EBP
MOV EBP, ESP
usually marks the beginning of a routine in VC++...
Anyways, since this routine has accessed the "Invalid serial" string, we can assume that this routine is the serial check routine. Start tracing at it with F8. A messagebox telling you you entered the wrong serial will pop up after you trace over this call:
Code:
300042A6 8B05 18BF0030 MOV EAX,DWORD PTR DS:[3000BF18]
300042AC 8B08 MOV ECX,DWORD PTR DS:[EAX]
300042AE FF15 C0BF0030 CALL DWORD PTR DS:[3000BFC0] ; System_W.7B26EC88
300042B4 90 NOP
Interesting... look around in Olly and try to get a feel for what is happening. Even a noob should be able to understand what is happening here:
Code:
30004270 8BF8 MOV EDI,EAX
30004272 6A 00 PUSH 0
30004274 8BD3 MOV EDX,EBX
30004276 8BCF MOV ECX,EDI
30004278 FF15 BCBF0030 CALL DWORD PTR DS:[3000BFBC] ; Compare strings (Microsoft.VisualBasic.dll)
3000427E 8BF8 MOV EDI,EAX
30004280 85FF TEST EDI,EDI
30004282 0F94C0 SETE AL
30004285 0FB6C0 MOVZX EAX,AL
30004288 894424 04 MOV DWORD PTR SS:[ESP+4],EAX
3000428C 837C24 04 00 CMP DWORD PTR SS:[ESP+4],0 ; were they the same?
30004291 74 12 JE SHORT Unpack_1.300042A5 ; if not, JMP
30004293 8B05 14BF0030 MOV EAX,DWORD PTR DS:[3000BF14]
30004299 8B08 MOV ECX,DWORD PTR DS:[EAX]
3000429B FF15 C0BF0030 CALL DWORD PTR DS:[3000BFC0] ; good boy message.
300042A1 90 NOP
300042A2 90 NOP
300042A3 EB 10 JMP SHORT Unpack_1.300042B5
300042A5 90 NOP
300042A6 8B05 18BF0030 MOV EAX,DWORD PTR DS:[3000BF18]
300042AC 8B08 MOV ECX,DWORD PTR DS:[EAX]
300042AE FF15 C0BF0030 CALL DWORD PTR DS:[3000BFC0] ; bad boy message.
300042B4 90 NOP
300042B5 90 NOP
300042B6 90 NOP
300042B7 90 NOP
300042B8 83C4 10 ADD ESP,10
300042BB 5D POP EBP
300042BC 5B POP EBX
300042BD 5E POP ESI
300042BE 5F POP EDI
300042BF C2 0400 RETN 4
Simple, eh? Just for kicks, nop the JE at 30004291 and press F9 to run the unpackme. Click on the "Check" button and watch as this string pops up:
"Good work! Now go and post a solution or suggestions so I can improve the protector =)"
And that's it. You more or less cracked this simple unpackme. If you want the solution to become permanent, just use a hex editor to change Unpackme.ni.exe accordingly. I'm sure you can figure out how to do that on your own

What it more interesting is actually fishing a valid serial with Olly. Look at this code right here:
Code:
30004270 8BF8 MOV EDI,EAX
30004272 6A 00 PUSH 0
30004274 8BD3 MOV EDX,EBX
30004276 8BCF MOV ECX,EDI
30004278 FF15 BCBF0030 CALL DWORD PTR DS:[3000BFBC] ; Microsof.5E464AD0
It should be pretty obvious to an experienced reverser that a string compare is happening at 30004278. The only irregular thing is that the parameters are put in EDX and ECX, and people familiar with .NET will attest that this is actually regular.
The compiler simply prefers using registers to pass parameters instead of the stack. Not very neat, but w/e, .NET wasn't designed to be pretty (obviously).
Let's put a breakpoint upon 30004278 and examine the contents ot the EDX and ECX registers. Select 30004278, press F2 to place a breakpoint in Olly, and press F9 to run the target. Click on the "Check" button in the unpackme, and watch Olly break at 30004278. The contents of the EDX and ECX registers should be:
01323ED8
01323E74
(note: it's probably different on each machine. Don't worry about that).
Alright, these 2 values are both pointers. Lets see what they point to:
ECX:
Code:
01323ED8 E0 A3 0F 79 13 00 00 00 y...
01323EE0 11 00 00 00 45 00 6E 00 ...E.n.
01323EE8 74 00 65 00 72 00 20 00 t.e.r. .
01323EF0 53 00 65 00 72 00 69 00 S.e.r.i.
01323EF8 61 00 6C 00 20 00 48 00 a.l. .H.
01323F00 65 00 72 00 65 00 00 00 e.r.e...
EDX:
Code:
01323E74 E0 A3 0F 79 19 00 00 00 y...
01323E7C 18 00 00 00 68 00 79 00 ...h.y.
01323E84 37 00 31 00 71 00 38 00 7.1.q.8.
01323E8C 5A 00 6D 00 74 00 49 00 Z.m.t.I.
01323E94 4E 00 7A 00 7A 00 43 00 N.z.z.C.
01323E9C 35 00 45 00 45 00 4F 00 5.E.E.O.
01323EA4 75 00 55 00 59 00 77 00 u.U.Y.w.
01323EAC 3D 00 3D 00 00 00 00 00 =.=.....
So, ECX is the contents of the textbox where we entered the serial. Since I didn't touch that text box, the text it is reading is: "Enter Serial Here".
In EDX is a jumbled unicode string. It doesn't take a genius to figure out that this is probably the correct serial, and it is being compared against the invalid serial. The jumbled unicode string is:
hy71q8ZmtINzzC5EEOuUYw==
Cool. So that is theoretically the valid serial. Let's put theory to the test. Restart the unpackme to undo all changes we have made to it so far, and then press F9 to run it again. In the dialog where is prompts us for name and serial, leave the name as is, while for the serial type in: hy71q8ZmtINzzC5EEOuUYw==. Press "Check" to let the crackme check if the serial is correct.
It is. You will get the goodboy message.
Now, incase you were wondering, the art of debugging .NET exes in Olly isn't just useful for native .NET exes. It also has practical applications.
Take for example the .NET unpackme I posted on crackmes awhile ago. Noone expect bigmouse was able to unpack it, so I assume a lot of people here don't have experience with JIT hooks, and are simply stumped when they see them in an unpackme.
So, screw the JIT hooks, lets fish a valid serial for the unpackme in Olly ^^.
Download the unpackme here:
http://www.filesend.net/download.php?f=67ccb0a87cc8f2f2f8d3776f9612f129
The procedure for cracking this is very similar to last time. First we find a string that we want to break upon, and then from there we trace to the serial check routine. From there on... well figure out what its doing and patch/fish accordingly

Start off by opening the file in Olly. If we analyze the file in ILDasm, we will see that it is invoking the assembly through Assembly.Load. Therefore, some buffer in memory must contain the semi-decrypted exe. Just look for that buffer in the Modules window. For me, it was 00C70000
Code:
00C70000 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 MZ.........
I know that this is the memory area I was looking for because of the MZ header... Now, in this memory area, the string we are looking to break upon (Invalid serial. Pls don't hack me :'( ) Can be located. So, just do a binary search for the Unicode "Invalid serial." You will end up here:
Code:
00C7426D 49 00 6E 00 76 00 61 00 6C 00 69 00 64 00 20 00 I.n.v.a.l.i.d. .
00C7427D 53 00 65 00 72 00 69 00 61 00 6C 00 2E 00 20 00 S.e.r.i.a.l... .
00C7428D 50 00 6C 00 73 00 20 00 64 00 6F 00 6E 00 27 00 P.l.s. .d.o.n.'.
00C7429D 74 00 20 00 68 00 61 00 63 00 6B 00 20 00 6D 00 t. .h.a.c.k. .m.
00C742AD 65 00 20 00 3A 00 27 00 28 00 01 81 7B 54 00 68 e. .:.'.(.{T.h
00C742BD 00 65 00 20 00 70 00 6F 00 69 00 6E 00 74 00 20 .e. .p.o.i.n.t.
00C742CD 00 6F 00 66 00 20 00 74 00 68 00 69 00 73 00 20 .o.f. .t.h.i.s.
00C742DD 00 55 00 6E 00 70 00 61 00 63 00 6B 00 6D 00 65 .U.n.p.a.c.k.m.e
00C742ED 00 20 00 69 00 73 00 20 00 66 00 6F 00 72 00 20 . .i.s. .f.o.r.
00C742FD 00 79 00 6F 00 75 00 20 00 74 00 6F 00 20 00 67 .y.o.u. .t.o. .g
00C7430D 00 65 00 74 00 20 00 61 00 20 00 67 00 72 00 61 .e.t. .a. .g.r.a
00C7431D 00 73 00 70 00 20 00 6F 00 66 00 20 00 62 00 61 .s.p. .o.f. .b.a
00C7432D 00 73 00 69 00 63 00 20 00 4A 00 49 00 54 00 20 .s.i.c. .J.I.T.
00C7433D 00 68 00 6F 00 6F 00 6B 00 69 00 6E 00 67 00 2E .h.o.o.k.i.n.g..
...set a HW BP on access on the first 4 bytes of the string, just like I explained earlier in the post. Then proceed to run the file, click on the "Check" button, and you should break here:
Code:
79E7EFCB 6BC0 21 |IMUL EAX,EAX,21
79E7EFCE 33C6 |XOR EAX,ESI
79E7EFD0 41 |INC ECX
79E7EFD1 3BCA |CMP ECX,EDX
79E7EFD3 ^ 72 F3 \JB SHORT mscorwks.79E7EFC8
79E7EFD5 5E POP ESI
79E7EFD6 C2 0800 RETN 8
Remove your hardware breakpoint, and proceed to trace with F8 until you come up to some code that looks like this:
(or you could just set a breakpoint at this place, as it is very important in .NET reversing. It is the exit point of the .NET jitter. When .NET exits from the JIT dll and goes into the native code, it will always pass through this point).
Code:
79E7BBA3 . FF15 9411E779 CALL DWORD PTR DS:[<&KERNEL32.SetLastError>] ; \SetLastError
79E7BBA9 . 8B45 D8 MOV EAX,DWORD PTR SS:[EBP-28]
79E7BBAC . E8 365CFFFF CALL mscorwks.79E717E7
79E7BBB1 . C2 0400 RETN 4
This is the JIT just checking if there were any errors during the jitting. Then it returns to a little memory area where it restores all registers modified by the jitter:
Code:
00341F3E 897B 0C MOV DWORD PTR DS:[EBX+C],EDI
00341F41 8B4E 08 MOV ECX,DWORD PTR DS:[ESI+8]
00341F44 8946 08 MOV DWORD PTR DS:[ESI+8],EAX
00341F47 8BC1 MOV EAX,ECX
00341F49 83C4 04 ADD ESP,4
00341F4C 5A POP EDX
00341F4D 59 POP ECX
00341F4E 89EC MOV ESP,EBP
00341F50 5D POP EBP
00341F51 83C4 04 ADD ESP,4
00341F54 5F POP EDI
00341F55 5E POP ESI
00341F56 5B POP EBX
00341F57 5D POP EBP
00341F58 83C4 08 ADD ESP,8
00341F5B C3 RETN
The above memory areas will always be returned to out of the jitter. Its just a little consistency that I noticed that helps my eyes adjust as I trace with F8 through native .NET code. Anyways, once you trace over the ret at 00341F5B, you will trace about 5 more lines and then be in the middle of the native code of the serial check routine:
Code:
00C81F28 57 PUSH EDI
00C81F29 56 PUSH ESI
00C81F2A 53 PUSH EBX
00C81F2B 55 PUSH EBP
00C81F2C 83EC 10 SUB ESP,10
00C81F2F 891424 MOV DWORD PTR SS:[ESP],EDX
00C81F32 8BF1 MOV ESI,ECX
00C81F34 833D 90339300 00 CMP DWORD PTR DS:[933390],0
00C81F3B 74 05 JE SHORT 00C81F42
00C81F3D E8 BC034179 CALL mscorwks.7A0922FE
00C81F42 33D2 XOR EDX,EDX
00C81F44 895424 08 MOV DWORD PTR SS:[ESP+8],EDX
00C81F48 33ED XOR EBP,EBP
00C81F4A 33DB XOR EBX,EBX
00C81F4C 33D2 XOR EDX,EDX
00C81F4E 895424 0C MOV DWORD PTR SS:[ESP+C],EDX
00C81F52 C74424 04 00000000 MOV DWORD PTR SS:[ESP+4],0
00C81F5A 90 NOP
00C81F5B 8BCE MOV ECX,ESI
00C81F5D 8B01 MOV EAX,DWORD PTR DS:[ECX]
00C81F5F FF90 F8050000 CALL DWORD PTR DS:[EAX+5F8]
00C81F65 8BF8 MOV EDI,EAX
00C81F67 8BCF MOV ECX,EDI
00C81F69 8B01 MOV EAX,DWORD PTR DS:[ECX]
00C81F6B FF90 64010000 CALL DWORD PTR DS:[EAX+164]
00C81F71 8BF8 MOV EDI,EAX
00C81F73 8BEF MOV EBP,EDI
00C81F75 8BCE MOV ECX,ESI
00C81F77 8B01 MOV EAX,DWORD PTR DS:[ECX]
00C81F79 FF90 00060000 CALL DWORD PTR DS:[EAX+600]
00C81F7F 8BF8 MOV EDI,EAX
00C81F81 8BCF MOV ECX,EDI
00C81F83 8B01 MOV EAX,DWORD PTR DS:[ECX]
00C81F85 FF90 64010000 CALL DWORD PTR DS:[EAX+164]
00C81F8B 8BF8 MOV EDI,EAX
00C81F8D 897C24 0C MOV DWORD PTR SS:[ESP+C],EDI
00C81F91 8B05 78302902 MOV EAX,DWORD PTR DS:[2293078]
00C81F97 894424 08 MOV DWORD PTR SS:[ESP+8],EAX
00C81F9B FF7424 08 PUSH DWORD PTR SS:[ESP+8]
00C81F9F 8BD5 MOV EDX,EBP
00C81FA1 8BCE MOV ECX,ESI
00C81FA3 3909 CMP DWORD PTR DS:[ECX],ECX
00C81FA5 E8 4A67CBFF CALL 009386F4
00C81FAA 8BF8 MOV EDI,EAX
00C81FAC 8BDF MOV EBX,EDI
00C81FAE 8BCE MOV ECX,ESI
00C81FB0 8B01 MOV EAX,DWORD PTR DS:[ECX]
00C81FB2 FF90 00060000 CALL DWORD PTR DS:[EAX+600]
00C81FB8 8BF8 MOV EDI,EAX
00C81FBA 8BCF MOV ECX,EDI
00C81FBC 8B01 MOV EAX,DWORD PTR DS:[ECX]
00C81FBE FF90 64010000 CALL DWORD PTR DS:[EAX+164]
00C81FC4 8BF8 MOV EDI,EAX
00C81FC6 6A 00 PUSH 0
00C81FC8 8BD3 MOV EDX,EBX
00C81FCA 8BCF MOV ECX,EDI
00C81FCC E8 FF2A7E5D CALL Microsof.5E464AD0
00C81FD1 8BF8 MOV EDI,EAX
00C81FD3 85FF TEST EDI,EDI
00C81FD5 0F94C0 SETE AL
00C81FD8 0FB6C0 MOVZX EAX,AL
00C81FDB 894424 04 MOV DWORD PTR SS:[ESP+4],EAX
00C81FDF 837C24 04 00 CMP DWORD PTR SS:[ESP+4],0
00C81FE4 74 0F JE SHORT 00C81FF5
00C81FE6 8B0D 7C302902 MOV ECX,DWORD PTR DS:[229307C]
00C81FEC E8 97CC5E7A CALL System_W.7B26EC88
00C81FF1 90 NOP
00C81FF2 90 NOP
00C81FF3 EB 0D JMP SHORT 00C82002
00C81FF5 90 NOP
00C81FF6 8B0D 80302902 MOV ECX,DWORD PTR DS:[2293080]
00C81FFC E8 87CC5E7A CALL System_W.7B26EC88
00C82001 90 NOP
00C82002 90 NOP
00C82003 90 NOP
00C82004 90 NOP
00C82005 83C4 10 ADD ESP,10
00C82008 5D POP EBP
00C82009 5B POP EBX
00C8200A 5E POP ESI
00C8200B 5F POP EDI
00C8200C C2 0400 RETN 4
Look familiar? Yep, its the exactly same stuff as I described previously in the post. Thus, if you were reading closely, you should understand how to be able to fish the serial and patch it to work however you might like.
Now, I was planning to show you how to write a loader to patch my .NET stuff right here, but that will have to wait on another post, where I show you how to write loaders to patch the native code and thus completely bypass relying on the IL

In conclusion:
I showed you the basics of native .NET code, and I showed you how to break into it so that you may debug it in Olly. Thus, if the IL code of an exe is too well protected or simply not availible, you can fall back to reversing this stuff.
I would also like to note that I have not yet found a way to resolve the native function names/exports of VisualBasic.ni.dll. If I do find out a way, it will make reversing much similar because then we will be able to break upon functions with interesting names such as strcmp. Its something I need to look into.
but for now, sleeeeeeeep
peace
-Rendari