Spelunking DOTNET : Microsoft .NET Framework is a new platform for building integrated, service oriented applications to meet the needs of today's Internet business, applications that gather information from & interact with a wide variety of sources regardless of the platforms or language in use. This is still Beta 1, we will have more targets in the future. Understanding the Framework of .NET (in short) : Microsoft Intermediate Language (MSIL), the Common Language Runtime (CLR) & JIT (Just in Time compilers). MSIL is a CPU - independent intermediate language created by MS. It means the PE file containing MSIL can run on any CPU platform as long as the OS running on that CPU platform hosts the .NET common language runtime engine. In simple when you compile a source under .NET the compiler produces an exe/dll file along with MSIL code. The MSIL code/instructions cannot be executed directly by CPU, so the common language runtime engine must first compile the MSIL instructions into native CPU instructions and than the CPU starts executing .NET programs. Tools Used : Target : No Target specifically. A small piece of code coded by me (source included along with this "pass.zip" file). It ask the user to give the password. If correct then show a Message Box "Correct Password ... have fun Cheers :-)" or "Wrong Password". There is an Exit Button to quit from the program. I was very much interested in the IL code hence did some work on it. Consider this tutorial as small findings only, it is just a begin. I assume you would have downloaded .NET SDK. Just run the compile.bat to produce the pass.exe. Now lets disassemble "pass.exe". So its time to use ildasm.exe, give the command below :- ildasm /bytes /out=pa.il pass.exe This will produce a file "pa.il" the parameter /bytes shows the bytes code /out instruction produces the output to the file "pa.il". Lets open this file in your favourite text editor. What you see is the below MSIL code. I will try to show the important part which I have understood. .method family hidebysig instance void button1_Click(class System.Object sender, class [mscorlib]System.EventArgs e) il managed { // Method begins at RVA 0x2290 // Code size 52 (0x34) .maxstack 2 .locals ([0] class System.String chkvalue) IL_0000: /* 02 | */ ldarg.0 IL_0001: /* 7B | (04)000004 */ ldfld class [System.WinForms]System.WinForms.TextBox Win32Form1Namespace.Win32Form1::textBox1 IL_0006: /* 6F | (0A)00001A */ callvirt instance class System.String [System.WinForms] System.WinForms.TextBoxBase::get_Text() IL_000b: /* 0A | */ stloc.0 IL_000c: /* 06 | */ ldloc.0 IL_000d: /* 72 | (70)00005F */ ldstr "jack" // Load the Correct String IL_0012: /* 28 | (0A)00001B */ call bool [mscorlib]System.String::Equals (class System.String, class System.String) IL_0017: /* 2D | 0D */ brtrue.s IL_0026 // If Correct Jmp to IL_0026 IL_0019: /* 72 | (70)000069 */ ldstr "Wrong Password" // Nag IL_001e: /* 28 | (0A)00001C */ call value class [System.WinForms]System.WinForms. DialogResult [System.WinForms]System.WinForms. MessageBox::Show(class System.String) IL_0023: /* 26 | */ pop IL_0024: /* 2B | 0D */ br.s IL_0033 IL_0026: /* 72 | (70)000089 */ ldstr "Correct Password ... have fun Cheers :-)" IL_002b: /* 28 | (0A)00001C */ call value class [System.WinForms]System.WinForms. DialogResult [System.WinForms]System.WinForms. MessageBox::Show(class System.String) IL_0030: /* 26 | */ pop IL_0031: /* 2B | 00 */ br.s IL_0033 IL_0033: /* 2A | */ ret } // end of method Win32Form1::button1_Click We can see from the Disassembly real pass is "jack" being loaded at IL_000d. So if we type jack at the input box we get a Good Message. We can change the "jack" to "xyz" & recompile it with ilasm.exe giving the command below :- ilasm pa.il This will compile the file & will create a file named "pa.exe" on your hard-disk. Execute it & then give the pass "xyz". We can change the code at IL_0017 from :- IL_0017: /* 2D | 0D */ brtrue.s IL_0026 // If Correct Jmp to IL_0026 to IL_0017: /* 2D | 0D */ brfalse.s IL_0026 // If Not Correct Jmp to IL_0026 Know if we compile it back with the above change now you type
anything & it will accept it. IL_0017: /* 2D | 0D */ brfalse.s IL_0033 // If Not Correct Jmp to IL_0033 Lets insert our small code of MessageBox to the Exit Button. So that when the user Clicks the Exit Button it will show our MessageBox & then Quit. Below is the original code for Exit Button :- .method family hidebysig instance void Exit_Click(class System.Object sender, class [mscorlib]System.EventArgs e) il managed // SIG: 11 F2 13 1C 21 A1 { // Method begins at RVA 0x2287 // Code size 7 (0x7) .maxstack 8 IL_0000: /* 02 | */ ldarg.0 IL_0001: /* 28 | (0A)000019 */ call instance void [System. WinForms]System. WinForms.Form::Close() IL_0006: /* 2A | */ ret } // end of method Win32Form1::Exit_Click Lets Insert Our NEW CODE For Exit_Click Button .method family hidebysig instance void Exit_Click(class System.Object sender, class [mscorlib]System.EventArgs e) il managed // SIG: 11 F2 13 1C 21 A1 { IL_0000: /* 72 | (70)000027 */ ldstr "Press OK to Exit Now ... Inserted MessageBox Code" IL_0005: /* 28 | (0A)000013 */ call value class [System.WinForms]System. WinForms.DialogResult [System. WinForms]System.WinForms.MessageBox ::Show(class System.String) IL_000a: /* 26 | */ pop IL_000b: /* 02 | */ ldarg.0 IL_000c: /* 28 | (0A)000019 */ call instance void [System.WinForms]System. WinForms.Form::Close() IL_0011: /* 2A | */ ret } // end of method Win32Form1::Exit_Click Using the ildasm /bytes option we know how many bytes are occupied by the instruction. We have to calculate the necessary bytes for our code & accordingly change the IL numbering instruction. Some More Findings There is an undocumented command /adv which can be used with ildasm.exe to show some new options in our disassembler View option. (a) Statistics How did I find about it. Well open ildasm.exe in your favourite hex editor & search for "adv", you will see majority of the options lined up together. Infact an anonymous person forced me to do this stuff when I read about .NET at _m forum. Click the link for more information. Prejit There is a tool called "prejit.exe" that can compile
an entire assembly listing to native code and save the
result on disk. Also note if you search for it on your hard-disk
you want find it why ? I guess it does not get extracted by default
& I don't remember from which file I extracted it. If anybody
requires it please drop me an e-mail. This will create 2 file "zap.man" & "pass.exe" in your global cache directory. If you try to look for this file through explorer you won't find it. We will have to go to the command prompt & search for it. I did try disassembling this prejited ver. of pass.exe inside IDA but its .... experts might help if useful or not. Also the prejited ver. of the file pass.exe does not execute. Why ? because it lacks the main entry point or something else, still digging :-). ILdasm While recompiling the disassembled file in our case "pa.il" we can use an option /OWNER switch which protects the resulting file against disassembling. Owner will be required to disassemble the file. e.g. ilasm /OWNER=some1 pa.il ... This will create pa.exe which cannot be decompiled with ildasm.exe if proper /OWNER is not given. Note: There is no guarantee that all your files when decompiled with ildasm.exe & recompiling it with ilasm.exe will execute perfectly. Tools to look Forward Reflector for .NET ... by Lutz Roeder's Programming.net Greetings Fly out to Christoph Gabler, Bardia, Unforgiven, CrackZ, MaV3RiCk, Cadlink,
ExeLord, Foxcy, Cbol, LBran, etc... & Dotnet.zip available here (1k). |