rendari

  1. (Part 2 of .NET native exe insights)Serial fishing and patching .NET exes with Ollydb

    (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:

    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 ...

    Updated March 24th, 2008 at 02:00 by rendari

    Categories
    Uncategorized
  2. Rebuilding native .NET exes into managed .NET exes by Exploiting lefotver IL...

    In the last article I wrote about native exe's, I briefly touched upon the issue of IL code being
    left over in generated Native EXE's, and how this could be a possible security hole that hackers could
    exploit when trying to reverse your .NET app. How big of a hole is this, you might ask? Very big. I
    managed to fully rebuild my old managed .NET exe just from the native image provided by Ngen. I aim
    to explain the steps I took in this blog post.

    First things first, we will be using this .NET exe for out experimentations:
    http://www.filesend.net/download.php?f=644ee1dfd1b9246aee11d64b931bd0fb

    It's just a simple Unpackme I wrote and submitted to crackmes.de. If you suspect malicous code, feel
    free to decompile it in Reflector.

    Anyways, extract the exe anywhere, and execute Ngen upon it

    Code:
    H:\temp>ngen unpackme.exe
    Microsoft (R) CLR Native Image Generator - Version 2.0.50727.42
    Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.
    Installing assembly H:\temp\unpackme.exe
    Compiling 1 assembly:
        Compiling assembly H:\temp\unpackme.exe ...
    UnpackMe, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null <debug>
    
    H:\temp>
    Then browse to your Global Assembly Cache at H:\WINDOWS\assembly\NativeImages_v2.0.50727_32\UnpackMe,
    find UnpackMe.ni.exe, and copy it over to some temporary location, where we can "work" on it.

    Now, the interesting thing about Ngen is that it does not eliminate the IL or the metadata, because
    while the IL code is not needed for execution, the metadata is, because all the strings and other
    relevant data that the program needs are contained within the metadata. So, Ngen copies all the
    metadata to the .IL section of the native exe, and copies the IL code as an afterthought (I assume
    for debugging purposes). Anyways, the point is that native exe's generated with Ngen have the
    IL code and metadata still in them, so a wily hacker should be able to use them to rebuild a managed
    exe similar to the original exe before Ngen had its way with it. The hacker can then load this
    managed exe into Reflector to decompile it, and steal your code or crack it with ease.

    NOTE: managed code = bytecode (decompilable)
    unmanaged code = native code (I wish we could decompile that =( )

    This is a major issue because all protectors that boast converting IL code to native code to protect
    your programs all use Ngen, so if the protectors forget to remove the IL you (the reverser) can just
    reconstruct the original exe and then have fun with it =)

    Anyways, so you have a copy of UnpackMe.ni.exe. This is what you would get after a "native" protector
    converted your IL code into native code. So, UnpackMe.ni.exe is all a reverser trying to reverse this
    target would have availible to him.

    Now, let us proceed to convert UnpackMe.ni.exe into a decompilable exe =).

    Load UnpackMe.ni.exe into CFF explorer, and browse around a bit. You will see that the exe is not
    a valid win32 exe (no entrypoint) and that there appears to be next to no metadata (No Methods metadata
    table or any of that other good stuff...). Seems like we have our work cut out for us.

    In hindsight: no, not really.

    First things first: we want to have valid metadata. Thankfuly, with CFF explorer this is easy to
    achieve since Daniel Pistelli (the author) documented the native header of .NET exe's enough for us
    so that we don't have to use a hex editor to find the IL code/metadata anymore (btw, thanks Daniel
    for this neat lil tool =) )

    In CFF Explorer, go to a little tab on the left market "Native header". You will see that the "Native
    Header" is mostly populated with unknown RVA's and sizes. However, there are 4 DWORD's that are of interest
    to us. They are:
    Original metadata RVA - 0x00012000
    Original metadata size - 0x00002BC0
    Original MSIL code RVA - 0x00014D30
    Original MSIL Code Size - 0x00000DBF

    Ok, write down these values somewhere. Now, go to the tab in the left of CFF Explorer marked ".NET directory",
    and replace the values "Metadata RVA" and "Metadata Size" with the "Original metadata RVA" and
    "Original metadata size" values that we got from the native header. Also change the Flags dword from
    00000004 (IL Library) to 00000004 (IL only). Cool, now click on the "Tables" tab, so that we can browse the
    metadata tables that now became availible to us.

    The "Method" tables are of particular interest to us, because these are the ones that tell us where the IL code
    is. So, click on the "Method" tables to open the list. There are 56 Methods btw. Note that, since we will need
    that later on. Now, click on the first Method you see. In this case, it is cctor. CFF Explorer will then display
    all the interesting things about the "cctor" method. If you look at the method RVA, you will see that it is
    00000004. That's way too low. So, what is wrong here? Well, that RVA is actually the displacement from the
    "Original MSIL code RVA" value in the Native header. So, to get the "real" RVA is actually:

    cctor RVA + Original MSIL code RVA = Real RVA.

    Our next step, therefore is to replace all the RVA's in these tables with their "Real RVA's", so that reflector
    and ILDasm may load them. I wrote a primitive little CFF explorer script for this. Here it is:

    Code:
    -- this functions checks if a flag is set
    function IsFlag(value, flag)
        if (value & flag) == flag then
            return true
        end
        return false
    end
    
    -- --------------------------------------------------
    -- the main code starts here
    -- --------------------------------------------------
    
    filename = GetOpenFile("Open...",  "All\n*.*\nexe\n*.exe\ndll\n*.dll\n")
    
    
    if filename == null then
        return
    end
    
    pehandle = OpenFile(filename)
    
    if pehandle == null then
        return
    end
    
    -- get dotNet Directory offset if any
    
    dotnetoffset = GetOffset(pehandle, PE_DotNETDirectory)
    
    
    -----------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------
    
    MethodRVA = 0x0000D406
    MethodCounter = 0
    OrigMSILRVA = 0x00014D30
    NumberOfMethod = 56
    junkDWORD = 0
    
    
    
    while MethodCounter < NumberOfMethod do
    
        junkDWORD = ReadDword(pehandle, MethodRVA)
        junkDWORD = junkDWORD + OrigMSILRVA
        WriteDword(pehandle, MethodRVA, junkDWORD)
        MethodRVA = MethodRVA + 0x0E
        MethodCounter = MethodCounter + 1      
    
    
    end
    
    
    
    
    -----------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------
    
        filename = GetSaveFile("Save As...",  "All\n*.*\nexe\n*.exe\ndll\n*.dll\n")
    
        if filename == null then
            MsgBox("Couldn't save file", "fast dotnet fix", MB_ICONEXCLAMATION)
        else
            if SaveFileAs(pehandle, filename) == true then
                MsgBox("File successfully saved.", "fast dotnet fix", MB_ICONINFORMATION)
            else
                MsgBox("Couldn't save file", "fast dotnet fix", MB_ICONEXCLAMATION)
            end
        end
    
    return
    NOTE: If you are working on an executable other than the one I provided, fill in
    MethodRVA
    OrigMSILRVA
    NumberOfMethod
    with the appropriate values from the exe you are working on.

    NOTE: MethodRVA = the RVA of the first Method table entry in the metadata. In this case, the offset of
    where the Method table for the "cctor" method starts.

    Take the above script, and copy paste it into a new file called *anything*.cff. Then double click on the
    script to get CFF explorer to execute it, select "Unpackme.ni.exe" to be processed, and save the processed
    file as "fixing1.exe". Remember to save the changes we have done to Unpackme.ni.exe before executing this
    script on it.

    Now, close Unpackme.ni.exe and open fixing1.exe ...
    Categories
    Uncategorized
  3. Some Quick Insights Into Native .NET exe's (part 1 of?)

    So, what are natively compiled .NET exes? Well, to answer that question we have
    to go back to how the .NET runtime works.

    All your VB.NET and C# code is translated during compilation from the language
    in question to MSIL (Microsoft Intermediate Language). This is a sort of stack
    based assembler variant that, in combination with metadata present in the executable,
    can be translated back into high level code (VB.net and C#). This is why tools
    such as reflector and dotDecompile exist on the .NET platform; the same effect
    is much harder to achieve with native code.

    Basically, the new possibilities for decompilation introduced in the .NET
    architecture have caused a lot of companies to shit themselves. Intellectual
    property (IP) is the lifeblood of the company. If someone can rip the idea and
    or source out of your product, and implement it in theirs, there is very little
    you can do to prevent them. This is becoming a major issue in the .NET dev circles
    (along with the fact that decompilation = easier cracking for malicous reverse
    engineers bent upon pirating goods to disrupt the global economy and plunge the
    world into deep recession).

    So, .NET devs are a lot more willing to invest time and money in securing their
    products. Frankly, given how shitty 99% of the "security" products on the market
    are, they're wasting their time.

    One of the security products that in my opinion falls into the "not well thought
    out" category is anything that boasts security through native code. Look at it this
    way: hackers have been cracking native code for how long? 2 decades? 3 decades?
    What makes you think that all of a sudden, in the grand year of 2008, they will
    start having problems hacking native code? Maybe it will be even EASIER for them
    because they no longer have to adapt to the foreign .NET architecture, but now
    simply have to load the exe into Olly and go at it the "old fashioned way".

    So, back to the question at hand. What are natively compiled .NET exes? Basically,
    they are exe's containing platform specific code that has been produced by the JIT
    instead of the aforementioned MSIL code. This makes it impossible to decompile the
    .NET code the old fashioned way (with Reflector).

    Producing .NET exes isn't really that simple. To natively compile a .NET exe into a
    native exe, you must use ngen.exe (comes with the SDK). Ngen is a native code
    generator provided by M$, and it's purpose is to increase performance. An application
    that demands performance might use Ngen to compile itself during installation.

    The newly produced native executables are not runnable. In fact, they are not even
    valid Win32 applications. They may be located in the Global Assembly Cache (GAC) of
    the local machine where Ngen was executed. If you do not know what the GAC is, read
    up on it here:

    Demystifying the .NET Global Assembly Cache
    By Jeremiah Talkar
    http://www.codeproject.com/KB/dotnet/demystifygac.aspx

    Now, I guess you're anxious to see the native exes I was just talking about. Desafortunadamente,
    it is not possible for you to access the GAC with Windows explorer right away. Thankfuly,
    a quick registry fix from the article quoted above will lets us browse the GAC from
    Windows Explorer. I quote:

    "If you want to disable the Assembly Cache Viewer and see the GAC in all its naked glory
    within Windows Explorer, you can set HKLM\Software\Microsoft\Fusion\DisableCacheViewer [DWORD] to 1."

    Simple, eh? Now, take any exe .NET exe (for example helloworld.exe) and execute Ngen upon it:


    C:\Windows\system32>cd C:\temp

    C:\temp>ngen HelloWorld.exe
    Microsoft (R) CLR Native Image Generator - Version 2.0.50727.1433
    Copyright (c) Microsoft Corporation. All rights reserved.
    Installing assembly C:\temp\HelloWorld.exe
    Compiling assembly C:\temp\HelloWorld.exe ...
    HelloWorld, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null <debug>

    C:\temp>pause
    Press any key to continue . . .

    There, we Ngen'd HelloWorld.exe. Now, whenever we execute HelloWorld.exe, the JIT will load
    the native HelloWorld.exe from the GAC and execute it, instead of compiling the IL in the
    HelloWorld.exe we are double clicking on. Like I said, this is intended to improve performance.

    To find the native compiled HelloWorld.exe on our hard drive, browse to

    C:\Windows\assembly\NativeImages_v2.0.50727_32\HelloWorld\355240658e5a51e36767993bef4ed510\
    ^
    This is different on each computer.

    You should see one file, and that is: HelloWorld.ni.exe. As I mentioned before, it is this file
    that is loaded as a module when the JIT executes.

    As you can see by double clicking on HelloWorld.ni.exe, it is not a valid image. This means that
    you cannot distribute it. That is one of the downfalls of Ngen.exe. You must have a valid exe
    with MSIL in it to generate an Ngen image. You cannot simply distribute the Ngen'd image as it
    is invalid.

    Salamander .NET Protector changes all this. This is one of the protectors that takes a somewhat
    amusing approach towards solving the problem of invalid Ngen'd images. I took a quick look at it
    by downloading the Scribble Demo from their homepage:
    (no reversing involved, reversing is illegal you know :P )

    http://www.remotesoft.com/linker/intro.html

    Just look at the file paths in the link above:

    \scribble-native\mdeployed\C\WINDOWS\assembly\NativeImages_v2.0.50727_32\Scribble\eccb67b11447c9488a7a35bab51a a59b

    It will become quite obvious that all its doing is
    emulating the GAC. It has its own GAC in there, with all the components scribble (native compiled)
    needs. When you run scribble.exe, it initializes the .NET Jit and points it towards its own GAC. .NET
    then grabs everything it needs from there (including native compiled scribble(Scribble.ni.exe))), and executes it.

    Now that's just a hypothesis on how it works. Without real reversing I cannot verify my results.
    And since reversing it would be illegal, I guess I'll have to pass up the opportunity this time :P

    Now, how secure is salamander .net protector? Well, I guess compared to MSIL code native code is 10x more secure, but
    does that mean that its really SECURE? Not necessarily.

    First of all, there is a small bug in the protector where it makes it preserve the IL code from the original exe. Ntoskrnl
    described it in his article that he did on salamander .net protector. You can find it here:

    http://www.pmode.net/USERS/116/Files/salamander.htm

    But lets just ignore the IL code in memory for now, and focus on attacking the native code. Remember that HelloWorld.exe from
    earlier in the chapter? Let's try Ngenning that, and then having some fun with it :>

    First off, we need both need to be looking at the same HelloWorld.exe. Here is the code that I used, just paste it into an
    empty VB.net project and compile. For button1 you can put any button, so long as it executes the code below
    BTW, for the purposes of this project I used VB.net express 2008

    Code:
    Public Class Form1
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            MessageBox.Show("Greetings")
    
        End Sub
    End Class
    Simple piece of work, eh? Will just pop out a messagebox saying Greetings, and that's that. Compile it, run it, and then
    proceed to the next paragraph of this article.

    Ok now, first of all lets generate a valid native image for HelloWorld.exe. Just do:

    > ngen HelloWorld.exe

    Now go to the global assembly cache

    > cd C:\Windows\assembly\NativeImages_v2.0.50727_32\HelloWorld\355240658e5a51e36767993bef4ed510

    , find HelloWorld.ni.exe, and copy it to some temporary folder.

    Now do:

    > ngen uninstall HelloWorld

    I know this might not make sense to you, but just bear with me.

    Now, take Olly, and open the original HelloWorld.exe (the one which we execute ngen upon). Find the IL code in the hex view
    window (IL code is easy to recognize from a hex editor once you get used to looking at it; if you're having trouble finding
    it in the exe gets its RVA with CFF Explorer orjust search for 2A (2A is the bytecode for the IL_Ret instruction)). Here is
    how the beginning of the IL code looks for me from Olly:

    Code:
    00E221C0  13 30 02 00 3B 00 00 00  0.;...
    00E221C8  1B 00 00 11 00 7E 0D 00  ...~..
    00E221D0  00 04 14 28 58 00 00 0A  .(X...
    00E221D8  0C 08 2C 20 72 0B 01 00  ., r.
    00E221E0  70 D0 09 00 00 02 28 25  p...(%
    00E221E8  00 00 0A 6F 59 00 00 0A  ...oY...
    00E221F0  73 5A 00 00 0A 0B 07 80  sZ...
    00E221F8  0D 00 00 04 00 7E 0D 00  ....~..
    00E22200  00 04 0A 2B 00 06 2A 00  ..+.*.
    ...

    end of IL code:

    (scroll down)

    Code:
    00E22A10  00 00 04 02 7B 0C 00 00  ..{...
    00E22A18  04 14 FE 01 16 FE 01 0B  
    00E22A20  07 2C 0D 02
    ...
    Categories
    Uncategorized
  4. .NET unpackme

    Hey guys, check out my .NET unpackme over at
    http://crackmes.de/users/tfb/cryxenet_0.02_unpackme/

    I first want to give people time to have fun with it. Afterwards, I'll explain its inner workings so that you may all understand whats really going on in .NET.

    In the sad case that no one unpacks it, I'll post a solution anyways. I'll give it a couple of weeks... in the meantime, I got some new previously unseen JIT hooks in the works. You'll love em
    Categories
    Uncategorized
  5. Making an advanced api redirection more advanced?

    Anyways, I was playing around with a funny target today after school. Its got a bunch of features; I usually break one of them per week This week's "feature to break" was something I have dubbed advanced API redirection.

    Pretty much, what the protection does is take a huge routine of the target program, and stores it in a new section. There it replaces a bunch of the FF 15 calls with its own sort of 'macro', which calls into the protector code, where the protector then does whatever protectors do, and forwards it to the correct api. Here is a good example similar to what I am talking about:

    Original code:
    Code:
    ...
    PUSH 00401000  
    CALL DWORD PTR[11223344] ; VirtualAlloc
    ...
    After protection process:
    Code:
    ...
    PUSHFD
    PUSH EAX
    MOV DWORD PTR[ESP], 1EEDDF40
    XOR DWORD PTR[ESP], 1EADCF40
    POPFD
    PUSH 50010007
    MOV EAX, _protector_routine
    CALL EAX
    ...
    Note:
    the push 50010007 was just a pointer to an identifier used by the protector to see which API to forward to...

    Now this is pretty basic stuff, right? Just search for a byte pattern, execute it, let the code execute up to some hook you have in the code of the protector, where EAX will hold the correct API address, and then just NOP out the entire thing above and replace it with a FF 15 <correct addr>. If you want to be extra neat you could also resolve the XORing obfuscation above to the correct command before obfuscation, which was:
    push 00401000

    Well, the thing is, this protector added a bit o spice to the game. Instead of having just one type of routine that is used for API handling, they used five types. So the above routine could also be:

    Code:
    PUSH 00401000  
    PUSH 50010007
    PUSH EAX
    MOV DWORD PTR[ESP], EDX
    MOV DWORD PTR[ESP], xxxxxxxx
    XOR DWORD PTR[ESP], xxxxxxxx
    POP EAX
    CALL EAX
    and then you have 3 other types of routines that the protector can replace the original call with...

    Now, the trick in the protection is that you have to find and record the byte patterns for all 5 of these routines, and then subsequently fix them back to call dword <correct addr>.

    So, fixing this protection is a two step process:
    1) Identify all of the protector calls
    2) fixing them one by one.

    It is easily automated and fixed, once you have spent an hour hunting down the random crashes in your dump caused because your code has missed one of the protector calls.

    But this got me thinking. What if the protection devs were to add metamorphoses? It shouldn't be hard to write a metamorphic code generator to morph the above 5 routines into even more complex routines.

    Consider: only a couple of the same commands are being used in each of the protector routines:
    CALL EAX...
    MOV DWORD PTR[ESP], xxxxxxx
    XOR DWORD PTR[ESP], xxxxxxx
    ....

    and so on.

    Now, what if for each of those instructions your metamorphic code generator could morph into 4 different code chunks? For example, the CALL EAX could be morphed into:

    Code:
    PUSH EAX
    CALL _geteip
    _geteip:
    POP EAX
    ADD AL, 9
    XCHG DWORD PTR SS:[ESP],EAX
    JMP EAX
    db 0FF
    or

    Code:
    PUSH EAX
    call _geteip
    _geteip:
    POP EAX
    ADD EAX, 0F
    MOV WORD PTR[EAX], 0D0FFh
    MOV EAX, DWORD PTR[ESP]
    ADD ESP, 4
    NOP
    NOP

    and so on...

    Now lets assume that the devs took a couple of hours and coded this simple metamorphic code generator. Now all they have to do is:
    a) protect each call dword ptr with the old method (using one of the 5 possible protector routines)
    b) mark the offsets of each protected CALL in a list for later use
    c) after all the CALL DWORD's have been protected via the old method, take your metamorphic code generator and feed it the list of offsets of protected CALLS, and let it morph each protector routine to a new one.

    After it is done morphing, every single protector routine should be unique. This will throw a wrench in the prospective hacker's plans, because he can no longer easily identify all the protected CALLs that he needs to fix.

    Anyways, this was just an idea I had kicking around in my head for some time. Hope that someone could actually understand it.

    I'll re read this blog post and fix any errors in it later today.

    Updated October 1st, 2007 at 21:04 by rendari (bleh)

    Categories
    Uncategorized