All Blog Entries

  1. Phoenix Protector

    This application is now freeware for various reasons. I first wrote the core of the Phoenix Protector for a company when I was 19. That project didn't work out for internal reasons not related to the quality of the product itself. I then wrote the Phoenix Protector, which was basically a new GUI for the now improved core. However, during the years (one has to consider that I was quite young when I developed the .NET obfuscator) I became ever more conscious that I didn't want to spend my life writing protections and also that I was not convinced by protections for the .NET technology in the first place. That's partly why I wrote Rebel.NET. By combining Rebel.NET with the DisasMSIL engine it is very easy to write a code obfuscator for .NET assemblies. The only thing which would be missing is name obfuscation and string encryption, which are even easier as protections. That's why I'm releasing the Phoenix Protector for free: nowadays, writing a commercial obfuscator doesn't make much sense to me. The code obfuscation provided by the Phoenix Protector is quite good when compared to other commercial obfuscators. I noticed that most obfuscator provide a very easy to reverse code obfuscation scheme. I'm not saying that the Phoenix Protector's code obfuscation can't be reversed. Every .NET code obfuscation scheme can be reversed somehow and the rebuilding task becomes very easy through Rebel.NET.
  2. .NET Internals and Native Compiling

    Strictly speaking it means converting the MSIL code of a .NET assembly to native machine code and then removing the MSIL code from that assembly, making it impossible to decompile it in a straightforward way. The only existing tool to native compile .NET assemblies is the Salamander.NET linker which relies on native images to do its job. The "native images" (which in this article I called "Native Framework Deployment") technique is quite distant from .NET internals: one doesn't need a good knowledge of .NET internals to implement it. But, as the topic is, I might say, quite popular, I'm going to show to the reader how to write his Native Framework Deployment tool if he wishes to. However, the article will go further than that by introducing Native Injection, which means nothing else than taking the JIT's place. Even though this is not useful for commercial protections (or whatever), it's a good way to play with JIT internals. I'm also going to introduce Native Decompiling, which is the result of an understanding of .NET internals. I'm also trying to address another topic: .NET Virtual Machine Protections.

    I hope you'll enjoy this.

    P.S. As always, if you notice typos, please report them.

    Updated May 25th, 2008 at 10:53 by Daniel Pistelli

  3. IDA and vmread/vmwrite x64

    These 2 instructions are defined as:

    VMREAD  Ed/q, Gd/q
    VMWRITE Gd/q, Ed/q
    where d is for 32 bit environment, and q for 64 bit environment, which means that in 32 bit environment operands are always 32bit, and in 64bit environment those are 64bit, and operand size prefix can't affect size.

    But IDA displays wrong info:

    .text:0000000000011010                 mov     [rsp+arg_8], rdx
    .text:0000000000011015                 mov     [rsp+arg_0], rcx
    .text:000000000001101A                 sub     rsp, 38h
    .text:000000000001101E                 mov     edx, 1
    .text:0000000000011023                 mov     rcx, 1234567812345678h
    .text:000000000001102D                 call    VmWrite_proc
    .text:0000000000011032                 mov     rcx, 1234567812345678h
    .text:000000000001103C                 call    VmRead_proc
    .text:0000000000011041                 mov     [rsp+38h+var_18], rax
    .text:0000000000011046                 xor     eax, eax
    .text:0000000000011048                 add     rsp, 38h
    .text:000000000001104C                 retn
    .text:000000000001104C DriverEntry     endp
    .text:0000000000011060 VmWrite_proc    proc near               
    .text:0000000000011060                 vmwrite ecx, edx    <----- 32bit operands, which is not possible
    .text:0000000000011063                 retn
    .text:0000000000011063 VmWrite_proc    endp
    .text:0000000000011064 VmRead_proc     proc near              
    .text:0000000000011064                 vmread  eax, ecx    <----- again 32 bit operands
    .text:0000000000011067                 retn
    .text:0000000000011067 VmRead_proc     endp

    Instead this should be displayed as vmwrite rcx, rdx and vmread rax, rcx. This is also verified by looking at intel documentation (CHAPTER 5 VMX INSTRUCTION REFERENCE - Volume 2B):

    VMREAD—Read Field from Virtual-Machine Control Structure
    Opcode Instruction Description
    0F 78 VMREAD r/m64, r64 Reads a specified VMCS field (in 64-bit mode).
    0F 78 VMREAD r/m32, r32 Reads a specified VMCS field (outside 64-bit mode).

    VMWRITE—Write Field to Virtual-Machine Control Structure
    Opcode Instruction Description
    0F 79 VMWRITE r64, r/m64 Writes a specified VMCS field (in 64-bit mode)
    0F 79 VMWRITE r32, r/m32 Writes a specified VMCS field (outside 64-bit mode)
    Nothing spectacular, but still, wrong disassembly

    Updated May 20th, 2008 at 18:49 by deroko

  4. Intel VT and cpuid break

    Do you want to use cpuid as int 3 or any other event? Well Intel VT allows us that, as cpuid always generates VM-Exit. In this case what we do is:

    1. Read Guest Cr3 to check correct process
    2. inject int 3 event into Guest
    3. SoftICE will popup if i3here on is set
    4. Enjoy

    bin/src ->
  5. Downloader.Win32.Small or Win32/PolyCrypt Reversing


    Here the analysis of Trojan-Downloader.Win32.Small.ihj and its msstub.dll actually reported as malware but not fully documented.


    MD5 Hash Signature:5f9e38abd1c20ba44ff07903489bac10
    Identification: AVG Antivirus -> Win32/PolyCrypt
    Kaspersky -> Trojan-Downloader.Win32.Small.ihj

    Format: EXE and Embedded DLLs

    The Essay

    PolyCrypt is spreaded through infected Websites by using Exploits or every other form of abusive Download mechanism.
    PolyCrypt is weakly Packer Protected, so with VMUnpack we can suddenly obtain the full working unpacked copy.

    Let's trace from the EP:

    00401000 mov eax, 104h
    00401005 mov edx, offset dword_403033
    0040100A push eax
    0040100B inc ecx
    0040100C push edx
    0040100D push offset loc_4013BE ;points to jmp GetSystemDirectoryA
    00401012 call sub_4012BD ;Call GetSystemDirectoryA

    PolyCrypt uses an basilar method for API call, just to deceit basical fast analysis, the call sub_4012BD access directly the jump table at the entry passed as parameter.

    0040101B push offset aMsstub_dll ; "\\msstub.dll"
    00401020 push offset dword_403033 ;System Directory
    00401025 push offset loc_4013E2
    0040102A call sub_4012BD ;lstrcat
    0040102F pop dword_402027
    00401035 pop ebx
    00401036 push ebx
    00401037 push 80h
    0040103C push 2
    0040103E push ebx
    0040103F push 1
    00401041 push 40000000h
    00401046 push offset dword_403033 ;Full Path
    0040104B push offset CreateFileA
    00401050 call sub_4012BD
    00401060 mov edx, esp
    00401062 push ebx
    00401063 push edx
    00401064 push 1000h
    00401069 push offset dword_402027
    0040106E push dword_403027
    00401074 push offset WriteFile
    00401079 call sub_4012BD
    0040107E pop ecx
    0040107F push dword_403027

    00401085 push offset CloseHandle
    0040108A call sub_4012BD

    This piece of code builds the a string path c:\windows\system32\msstub.dll and next creates this DLL (msstub.dll) and fills if it with embedded data.

    0040108F push offset aDb5825eaB434C6 ; "{DB5825EA-B434-C69E-8E2D-81387140521A}"
    00401094 push offset aClsid ; "CLSID\\"
    00401099 push offset byte_403137
    0040109E push offset wsprintfA
    004010A3 call sub_4012BD
    004010A8 add esp, 0Ch
    004010AB push eax
    004010AC push esp
    004010AD push offset dword_40302F
    004010B2 push ebx
    004010B3 push 3
    004010B5 push 0
    004010B7 push ebx
    004010B8 push ebx
    004010B9 push offset byte_403137 ; “CLSID\\{DB5825EA..”
    004010BE push 80000000h
    004010C3 push offset RegCreateKeyExA

    To overcome basical detecting attemps it's used the CLSID Splitting, the complete string is CLSID\\{DB5825EA-B434-C69E-8E2D-
    , obviously next operation
    is to create this Registry Key Entry.

    004010D6 push eax
    004010D7 push esp
    004010D8 push offset dword_40302B
    004010DD push ebx
    004010DE push 2
    004010E0 push 0
    004010E2 push ebx
    004010E3 push ebx
    004010E4 push offset aInprocserver32 ; "InprocServer32"
    004010E9 push dword_40302F
    004010EF push offset RegCreateKeyExA
    00401111 inc eax
    00401112 push eax
    00401113 push offset aApartment ; "Apartment"
    00401118 push 1
    0040111A push ebx
    0040111B push offset aThreadingmodel ; "ThreadingModel"
    00401120 push dword_40302B
    00401126 push offset RegSetValueExA
    0040112B call sub_4012BD
    0040113A inc eax
    0040113B push eax
    0040113C push offset dword_403033
    00401141 push 1
    00401143 push ebx
    00401144 push ebx
    00401145 push dword_40302B
    0040114B call RegSetValueExA
    00401150 push dword_40302B
    00401156 call RegCloseKey

    This piece of code creates into the previously builded CLSID the following entry:

    {CLSID}\InprocServer32 = iexplorer.exe
    \ThreadingModel = Apartment (which is single threaded)

    In other words Registers a 32-bit in-process server and specifies the threading model of the apartment the server can run in, in our case the InprocServer32 is Internet Explorer.

    So the malicious dll (msstub.dll) could be called by IE, indeed the next operation accomplished by PolyCrypt is to Open IE with ShellExecuteA(), finally builds a .bat script file, called dmfg.bat to delete the Executable..

    PolyCrypt is completly Reversed, let's see now what happens into msstub.dll

    msstub.dll Reversing

    The first fast way to analyze this dll is with LoadDll.exe of OllyDbg, but during the analysis
    is important to change some conditional jump that checks if the dll was called by IE.

    003567C1 MOV AL,BYTE PTR DS:[EDI] ;EDI is the raw address table
    003567C3 INC EDI
    003567C4 OR AL,AL
    003567C6 JE SHORT msstub.003567A4
    003567C8 MOV ECX,EDI
    003567CA PUSH EDI ;HeapAlloc
    003567CB DEC EAX
    003567CE PUSH EBP
    003567CF CALL DWORD PTR DS:[ESI+6068] ;GetProcAddress("HeapAlloc")
    003567D5 OR EAX,EAX
    003567D7 JE SHORT msstub.003567E0 ;Address == NULL Jump Out
    003567D9 MOV DWORD PTR DS:[EBX],EAX ;EBX is the address function table
    003567DB ADD EBX,4 ;next address
    003567DE JMP SHORT msstub.003567C1

    This piece of code builds an Address Function Table, this is a method of indirect API Importing, just to make a bit harder Disasm Analysis, here a list of Imported APIs:

    HeapAlloc, GetCurrentProcessId, HeapFree, DeleteFileA,
    HeapCreate, GetLastError, CreateEvent, HeapRealloc, GetTempPathA,
    GetVersion, GlobalAlloc, ExitProcess, CreateFile, HeapDestroy,
    CreateThread, CloseHandle, HeapSize, GetModuleFilename, LoadLibrary,
    Sleep, VirtualFree, WriteFile, lstrcat, lstrcmp, lstrcpy, GlobalFree,
    wsprintf, InternetCloseHandle, HttpSendRequest, HttpQueryInfoA.
    HttpOpenRequest, InternetSetOption, TnternetReadFile,
    InternetQueryDataAvailable InternetOpenA, InternetBadConnectionState, InternetCrackUrlA, InternetConnectA

    It's important to say that this little dll works entirely with the Heap Memory,
    everithing is runtime decrypted and pushed into heap.

    After a decryption routine we obtain some intersting strings:


    CLSID\{DB500391040 825EA-B434-C69E-8E2D-81387140521A}

    SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects\


    Cause is a Downloader, it's easy to understand that the URL contains malicious code that will be used to build csesw.dll and finally acts in the same way that was used to load msstub.dll, by creating a CLSID Registry Key entry (CLSID\{DB500391040 825EA-B434-C69E-8E2D-81387140521A}) with an InprocServer32 procedure..

    As should be clear by analysing deadly this dll no traces of these operations could be founded, so let's move to a debug approach.

    The core algorithm of the Downloader is obtained by the decryption of a portion of data that is pushed into Heap, so execution flows in the Heap..cause the code is long I've reported only the significants pieces of code..

    00390030 MOV ECX,390581 ; JMP to kernel32.GetModuleFileNameA
    0039003 CALL 00390115 ; GetModuleFileNameA
    00390045 PUSH EAX
    00390046 PUSH 390108 ; ASCII "iexplore.exe"
    0039004B MOV ECX,3905A5 ; JMP to kernel32.lstrcmpiA
    00390050 CALL 00390115
    00390055 TEST EAX,EAX
    00390057 JNZ SHORT 003900C1 ;Jump out
    00390059 PUSH 104
    0039005E PUSH 3912E3
    00390063 PUSH DWORD PTR SS:[EBP+8]
    00390066 CALL 00390581 ; JMP to kernel32.GetModuleFileNameA
    0039006B MOV ECX,390521 ; JMP to kernel32.GetCurrentProcessId
    00390070 CALL 00390115
    00390075 PUSH EAX
    00390076 PUSH 3910CD ; ASCII "ntdfgz_%u" ;ntdfgz_PID
    003900A8 JE SHORT 003900C8
    003900AA PUSH EBX
    003900AB PUSH ESP
    003900AC PUSH EBX
    003900AD PUSH EBX
    003900AE PUSH 39011C ;Thread Procedure
    003900B3 PUSH EBX
    003900B4 PUSH EBX
    003900B5 CALL 0039056F ; JMP to kernel32.CreateThread

    If the dll is not loaded through IE, execution is aborted, else is opened a new thread procedure at address 0039011C, which is the Downloader releated part..

    00390144 PUSH DWORD PTR SS:[EBP-4]
    00390147 PUSH 391000 ; "" ...
    Reverse Engineering
  6. .NET Internals and Code Injection

    The first article of the two is out. The next will be about .NET native compiling.

    If you notice typos in the text, please do tell me. I'm a bit wasted, as you can see it's a long article.

    The content should be quite a new thing. I hope you enjoy the journey into the .NET internals from the perspective of a reverser.

    Also the applications of this can be many.
  7. DisasMSIL and CFF Explorer

    Today I wrote a free/open disasm engine for Microsoft's Intermediate Language (MSIL).

    You can use it any context you wish. There are no license restrictions. The only thing I ask you to do is to send me your bug fixes (if any).

    I also added the MSIL disasm engine to the CFF Explorer which is now able to disassemble the methods' code directly from the MetaData tables.

    I hope you aren't already fed up with me and my updates =)
  8. My next 2 articles

    Not that I want to make a big announcement, just wanted to tell you what those articles will be about.

    The first as I already told you is about code injection.

    The second one is about .NET native linking (no MSIL left). And even WITHOUT .NET native images, something I came up just today and already discovered that it can absolutely be done.

    I expect these articles to be released in the next 10 days. I decided to split the two of them up because they treat different things and the native linking is just "too hot".

    Just wanted to let you know...

    Updated April 28th, 2008 at 03:13 by Daniel Pistelli

  9. Rebel.NET

    As promised, I'm hereby releasing the Rebe.NET software.

    Rebel.NET is a rebuilding tool for .NET assemblies which is capable of adding and replacing methods and streams. It's possible to replace only a limited number of methods or every method contained in a .NET assembly. The simplicity of Rebel.NET consists in the replacing process: one can choose what to replace. Rebel.NET is, mainly, a very solid base to overcome every .NET protection and to re-create a fully decompilable .NET assembly. As such, Rebel.NET has to be considered a research project, not an encouragement to violate licensing terms.

    As I have written the software and the article in this week when during my sickness (fever), I'm expecting bugs and typos. Please report them.

    Of course, I've tested the Rebel.NET with more advanced .NET assemblies than those presented in the guide.

    Updated April 25th, 2008 at 14:59 by Daniel Pistelli

  10. Control Flow Deobfuscation Part 2

    In part one I explained how to get a CFG from bytecode, and today I'll tell you about the inverse operation.
    Well, actually there are two parts to it:
    1. Decide in which order you place the vertices
    2. Put them in that order and insert the correct branches

    I'll discuss point 1 in part three, and point 2 now.

    It may sound trivial to do this: just get the data for the first vertex, then the branch for the first vertex etc. However this doesn't work because to create the branch we need to know the position of its targets. But for the position of the targets we need to know how big the branch is!

    To create an optimal solution where all branches are as small as possible we use a simplification of Robertson's algorithm. The original paper is hard to find but there is good documentation of it in the source of YASM ( ). Basically what we do is assume all branches are 0 bytes1, then increase the size for each branch that doesn't fit and repeat until we find a fixed point where all branches fit.

    We can skip some sizes that are impossible, for instance there exists no 1 byte branch in .NET. However a 4 byte branch is possible with two 2 byte branches ("jnz xxx; jmp xxx"). Also we don't have to recalculate every branch if one doesn't fit, only the ones that are affected by the increased branch size; but since I saw little performance increase (surprisingly), I chose to use the simpler version.

    Now that I have explained everything, here is the pseudocode:
    rebuild_from_order(cfg, order):
        for vertex in order
            size_of_branch[vertex] = 0
            length = 0
            for vertex in order
                start[vertex] = length
                length += vertex.length + size_of_branch[vertex]
            has_changed = false
            for vertex in order
                for edge in vertex.edges
                    delta[edge] = start[edge] - (start + length(vertex.bytecode))
                if not branch_fits(vertex.branchtype, delta, size_of_branch[vertex])
                    has_changed = true
                    while not possible_branch_size(size_of_branch[vertex])
        while has_changed
        bytecode = empty
        for vertex in order
            length = 0
            for vertex in order
                start[vertex] = length
                length += vertex.length + size_of_branch[vertex]
            for edge in vertex.edges
                delta[edge] = start[edge] - (start + vertex.length)
            bytecode += vertex.bytecode
            bytecode += create_branch(vertex.branchtype, delta)
        return bytecode
    See you in part 3 which should be ready in 2009

    1 This is possible if it's an unconditional branch with a delta of 0 bytes: "jmp next; next:" is the same as "".
  11. Few words about Kraken

    Kraken is the word of the month for sure, but it has nothing to do with the beast from an old nice book written by Jules Verne, Twenty Thousand Leagues Under the Sea.
    The word refers to a series of malwares, something like the Storm trojan, but with much more strength. Kraken seems to be out from August 2006, but until today I’ve never heard about it. Some days ago I read an article (,289142,sid14_gci1308645,00.html) about it, the interesting part is here:
    “One somewhat interesting feature of the code is that the binary is not packed, as many malware binaries tend to be. However, Royal said that the code does have some other forms of obfuscation that make it difficult to analyze completely.”. I decided to look at it.

    I’m not going to give out a detailed explanation about the sample I’m working on (MD5 = 592523a88df3d043d61a14b11a79bd55), but I’ll spend some words on the “forms of obfuscation” used by the malware.

    Detectors are not able to recognize any specific packer/protector. The file is not packed, but from the first lines of code it’s pretty easy to understand that a sort of obfuscation/encryption was included inside the file. I have not found interesting imports/strings, so I tried running the malware. Just to be sure to retrieve some useful information I started logging all API(s) called by the malware.
    The malware calls some nice functions. Almost all the code of the binary file has been decrypted at runtime. The malware spawns one file and it deletes itself, you can spy the decrypted code but I didn’t get anything useful from it. The best thing to do is to look at the code trying to identify a general obfuscation scheme or a decryption routine. Don’t think to trace the entire exe, it’s madness!

    In case like this one, if you are able to see a light over your head you are lucky, otherwise you can step and look at each instruction for the eternity. I was lucky… the real code has been hidden behind a virtual machine. I’m not a virtual machine expert for sure, I only read some articles about this kind of protection.
    I won’t rebuild the entire machine, I’ll give out my findings only. If you think they are wrong and/or you want to add some more information about the virtual machine I’ll be happy to see a comment from you.

    Like every virtual machine out there, after a little initialization it goes into a semi-infinite loop that starts at 4012DA. It simply selects a virtual machine instruction and jump to the code to run. There are a lot of instructions inside the loop, avoiding some junk code you can see the snippet used to select (and then jump to) the next instruction to execute:
    004012E4 MOV AL,BYTE PTR DS:[ESI-1] // Byte pointed by esi-1 decides everything
    004012F3 ADD AL,BL
    0040F807 DEC AL
    004103D9 DEC ESI   // Shift to the next byte
    004103E7 ROL AL,2
    004103F7 DEC AL
    0040F590 XOR AL,0CF
    0040F594 SUB AL,6B
    004104A6 ADD BL,AL
    004104AF MOVZX EAX,AL
    004104B7 MOV ECX,DWORD PTR DS:[EAX*4+40FABB]   // EAX = index of the selected instruction
    004104C6 NOT ECX
    0040129C ROR ECX,1C
    00410213 SUB ECX,4DCBE90C
    0041021F ROL ECX,7
    00410229 INC ECX
    0041070D BSWAP ECX
    00401195 ADD ECX,5E1E81EF
    0040119C XOR ECX,77B911BC
    004011AE NOT ECX
    0041071B ADD ECX,60334BE6   // ECX = address of the selected instruction
    0040FFFF RETN 4C   // Go to the selected instruction

    Everything starts from the value stored inside the buffer pointed by (esi-1), the buffer contains a series of bytes and they are used to select the virtual machine instruction to execute (Moreover they are used to retrieve one or more vm_instruction’s operand). The new value stored inside EAX (obtained after some minor operations) is used to retrieve a dword value, EAX represents the index of the vector that starts at 0×40FABB. As you can see from the code above the new value is used to obtain the address of the vm_instruction to execute.
    Unlike a classical virtual machine this one doesn’t have a clear Instruction Table, spying the dead list from your favorite disassembler you won’t see the address of every single vm_instruction. The Instruction Table has been crypted and the first entry is located at 0×40FABB (there are 256 entries).
    The virtual machine has 16 registers (from r_0 to r_15), they can be used to store byte, word or dword data. EDI register points to the first one, the registers are stored in memory consecutively starting from r_0 to r_15.
    The virtual machine has a stack with a fixed size, EBP register contains the vm_esp value. After almost all push vm_instructions there’s a stack overflow check. The alignment is two bytes, “push byte_value” is not allowed and to push a single byte the virtual machine will extend the byte to a word value.

    Is there a cmp/test instruction inside the snippet? Is there a reference to a vm_eip register? Seems like this virtual machine doesn’t need them. vm_eip is replaced by (esi-1), it’s not an eip per se but it *guides* the virtual machine. I haven’t all the vm_instructions on my notes but I think there are no direct cmp/test instructions. Seems like they are not included inside the virtual machine, strange.

    From what I have seen there are more than 45 vm_instructions included in the virtual machine, to identify each vm_instruction you have to remove a lot of junk code. Once you have all the vm_instructions it’s not immediate to understand what the malware is trying to do.
    Example: here are the vm_instructions used to patch a dword at 0×41CE06 (1° column represents the initial address of the vm_instruction, 2° column represents the name I gave to the vm_instruction):
    401028: push_dword val      //    push F440C1CB
    401028: push_dword val      //    push 8040414A
    40F5BE: nor_stack           //    The value at vm_esp+4 is updated with a nor(vm_esp+4, vm_esp) operation
    4105FA: pop_dword r_i       //    r_15 = 0×00000202
    40F36F: push_dword r_i      //    r_0 = 0×0041CE05
    401028: push_dword val      //    push 98754A9F
    401028: push_dword val      //    push 43179031
    40F198: push_dword vm_esp   //    push vm_esp
    401396: mov_stack_pstack    //    mov dword ptr [vm_esp], dword ptr [dword ptr [vm_esp]]
    40F25C: pop_word r_i        //    r_14 = 0×00009031
    401028: push_dword val      //    push 678AB562
    40F198: push_dword vm_esp   //    push vm_esp
    40FEF3: push_bdword val     //    push 0×00000006, push a dword but the last 24 bits are 0, so it’s like a push byte extended to dword
    410452: add_stack           //    add dword ptr [vm_esp+4], dword ptr [vm_esp]
    4105FA: pop_dword r_i       //    r_15 = 0×216
    40F0A0: pp_mov_dword        //    mov dword ptr [pop t1], (pop t2)
    40F25C: pop_word r_i        //    r_11 = 0×015E4317
    410452: add_stack           //    add dword ptr [vm_esp+4], dword ptr [vm_esp] <– 98754A9F + 678AB562 = 1
    4105FA: pop_dword r_i       //    r_14
    410452: add_stack           //    add dword ptr [vm_esp+4], dword ptr [vm_esp] <– 41CE05 + 1 = 41CE06
    4105FA: pop_dword r_i       //    r_15
    410171: mov_stack_pstack    //    mov dword ptr [dword ptr [vm_esp]], dword ptr [vm_esp+4] <– patch

    Quite a simple patch operation, but the author didn’t use the straight way for sure. Believe it or not, this is the nature of the malware. Now you can understand the phrase: “Don’t think to trace the entire exe, it’s madness!”.

    I tried inspecting some more samples of the same Kraken family. There are some similarities/differences:
    - they are protected by a virtual machine too
    - the routine used to select the next vm_instruction is not the same
    - (I think) the vm_instructions are equal, but they are not defined in the same way. I mean, the code used to define a push is not the same but the result is the same infact in both cases you have a push vm_instruction
    - the (encrypted)Instruction Table is not the same. At index i you won’t have the same vm_instruction for malware_x and malware_y
    - the vm protection exists for the spawned file too

    Now I fully understand the words used by the author of the interview, it’s complex to understand what’s going on…
  12. Ollydbg v1.10 and 6E/6F/A6 opcodes, a little oversight

    Just yesterday a new version of Ollydbg was released, but I’m still using the old 1.10 version. It’s a really good debugger and until some days ago I didn’t hit on few errors inside the disasm engine, nothing compared with Ida's bug btw. Look here:

    0047C720 6E OUTS DX,BYTE PTR ES:[EDI]
    0047C721 6F OUTS DX,DWORD PTR ES:[EDI]

    According to Intel Manual’s opcode map 0×6E is defined as “OUTS/OUTSB DX, Xb”.
    The first operand is DX register, and the second one is defined as an “Xb” operand.
    X: memory addressed by DS: (E)SI
    b : byte, regardless of operand-size attribute
    The error is obvious, Ollydbg shows EDI instead of ESI.

    There’s something similar with A6 opcode. Ollydbg v1.10 shows:
    but the right line is:

    It’s an oversight on X and Y addressing method.
    The errors occour in v1.10 only, v2 shows the right instructions. I asked to Olly (Oleh Yuschuk) and he kindly replied: “Unfortunately, I will not correct it in 1.10…This project is closed, and I don’t want to make any modifications.”. Ok, I’ll switch to v2.
  13. DynLogger

    DynLogger logs all dynamically retrieved functions by reporting the module name and the requested function. It can come very handy when one wants to know a "hidden" function used by an application.

    I recycled the code of a bigger project to write this little application. It's a very small utility, but it might be of use after all. It was tested on XP and Vista, both x86 and x64. It works for .NET application as well. Just start the logging process, the log will be saved after you quit the monitored application.

    I wasn't really sure if I should have posted it here or not. But a friend of mine needed it, so I figured out that maybe even other people might need it.
  14. Trojan-PSW.Win32.OnLineGames.eos Reversing

    Win32.OnLineGames is a PSW Trojan, which works as a Password Stealer, specifically written to steal online gaming passwords.

    00401314 add eax, esi
    00401316 lea eax, ds:401442h
    0040131C jmp eax ;00401442

    At the entry point, code flow jumps to 00401442

    00401442 push ebp
    00401443 mov ebp, esp
    00401445 sub esp, 52Ch
    0040144B call ds:GetCurrentThreadId
    00401451 push eax
    00401452 call ds:GetThreadDesktop
    00401458 test eax, eax
    0040145A jnz short loc_40145D
    0040145C int 3 ; Trap to Debugger
    0040145D push ebx
    0040145E push esi
    0040145F push edi
    00401460 mov edi, offset aCzxsderdaksiic ; "CZXSDERDAKSIICS_MX"
    00401465 xor esi, esi
    00401467 push edi ; String
    00401468 push esi ; NULL
    00401469 push EVENT_ALL_ACCESS
    0040146E call ds:OpenEventA

    Obtains the handle to the desktop associated to the executable itself and opens the handle of an existing event called CZXSDERDAKSIICS_MX, if event exists its own handle is closed, else a new event (called CZXSDERDAKSIICS_MX9 is created with standard SecurityAttributes.

    00401486 mov [ebp-10h], eax
    00401489 mov edi, offset off_401154 ;Edi points to an array of strings, that are a list of executables
    0040148E mov ecx, [edi]
    00401490 call sub_401798 ;Check if the searched process is running
    00401495 cmp eax, esi
    00401497 jz short loc_4014B2 ; If no, go to the next process
    00401499 push eax
    0040149A push esi
    0040149B push 1F0FFFh
    004014A0 call ds:OpenProcess
    004014A6 cmp eax, esi
    004014A8 jz short loc_4014B2
    004014AA push esi
    004014AB push eax
    004014AC call ds:TerminateProcess
    004014B2 add edi, 4
    004014B5 cmp edi, offset dword_40115C ;Next process to search
    004014BB jl short loc_40148E
    004014BD call sub_40131E ;AdjustTokenPrivilege

    The searched executables: Twister.exe, FilMsg.exe

    0040151B call ds:GetSystemDirectoryA
    00401521 mov edx, offset asc_401204 ; "\\"
    00401526 lea ecx, [ebp-11Ch] ;points to the System Directory
    0040152C call sub_40174A
    00401543 call ds:GetModuleHandleA
    00401549 push offset aMndll ; "MNDLL"
    0040154E push 65h
    00401550 push eax
    00401551 mov [ebp+8], eax
    00401554 call ds:FindResourceA
    0040155A push eax ;00402048
    0040155B mov [ebp-4], eax
    0040155E push dword ptr [ebp+8]
    00401561 call ds:SizeofResource
    00401567 push dword ptr [ebp-4]
    0040156A mov [ebp-18h], eax
    0040156D push dword ptr [ebp+8]
    00401570 call ds:LoadResource
    00401576 push eax ;00402070
    00401577 call ds:LockResource
    0040157D cmp eax, esi
    0040157F mov [ebp-4], eax
    00401582 jnz short loc_40158E
    00401584 push dword ptr [ebp-10h]
    00401587 call edi ; CloseHandle
    00401589 jmp loc_4016C6

    The code here is clear, after enstablishing the System Directory, searches for a Resource type "MNDLL" and next loads it, the LoadResource give us an intersing location 00402070, that's an executable image, exploring this executable we can see some intersing strings ConfigAreaName game.ini

    004015A6 add esp, 0Ch
    004015A9 lea edx, [ebp-428h]
    004015AF lea ecx, [ebp-11Ch]
    004015B5 call ScansFor ;call sub_40176F (searches for csavpw0.dll)
    004015BA lea edx, [ebp-324h] ; SystemDirectory
    004015C0 lea ecx, [ebp-11Ch] ; csavpw0.dll
    004015C6 call sub_40174A
    004015CB lea eax, [ebp-11Ch]
    004015D1 push eax
    004015D2 call dseleteFileA
    004015D8 push esi
    004015D9 push 80h
    004015DE push 2
    004015E0 push esi
    004015E1 push esi
    004015E2 lea eax, [ebp-11Ch]
    004015E8 push 40000000h
    004015ED push eax
    004015EE call ds:CreateFileA
    004015F4 cmp eax, 0FFFFFFFFh
    004015F7 mov [ebp-14h], eax
    004015FA jnz short loc_401605
    004015FC inc dword ptr [ebp+8]
    004015FF cmp dword ptr [ebp+8], 0Ah
    00401603 jb short loc_401591 ;Go to the next cycle

    If there is another csavpw0.dll, is firstly deleted and next recreated, if creation fails is performed the same routine for csavpw1.dll, csavpw2.dll.

    In my case csavpw2.dll is founded

    00401608 push esi
    00401609 push ecx
    0040160A push dword ptr [ebp-18h] ; Size: 4C00
    0040160D push dword ptr [ebp-4] ; Buffer: 00402070
    00401610 push eax
    00401611 call ds:WriteFile
    0040161A call CloseHandle
    0040161C push ebx
    0040161D call ds:Sleep
    00401623 lea ecx, [ebp-11Ch] ;C:\WINDOWS\system32\csavpw2.dll

    csavpw2.dll is filled up with the discovered Resource.

    00401630 push ebx
    00401631 lea eax, [ebp-220h]
    00401637 push offset aCzxsderdaksi_0 ; "CZXSDERDAKSIICS_%d"
    0040163C push eax
    0040163D call ds:wsprintfA
    00401643 add esp, 0Ch
    00401646 lea eax, [ebp-220h]
    0040164C push eax ;CZXSDERDAKSIICS_0
    0040164D push esi
    0040164E push 1F0003h
    00401653 call ds:OpenEventA
    00401659 cmp eax, esi
    0040165B jz short loc_401666
    0040165D push eax
    0040165E call CloseHandle
    00401660 inc ebx
    00401661 cmp ebx, 0Ah
    00401664 jb short loc_401630

    As usual it searches for CZXSDERDAKSIICS_0, CZXSDERDAKSIICS_1, CZXSDERDAKSIICS_2 when the OpenEvent FAILS we have this:

    0040166C push 104h
    00401671 push eax
    00401672 push esi
    00401673 call ds:GetModuleFileNameA
    00401679 lea eax, [ebp-220h] ;CZXSDERDAKSIICS_2
    0040167F lea edx, [ebp-52Ch] ;Path of our virus executable
    00401685 push eax ;CZXSDERDAKSIICS_2
    00401686 lea eax, [ebp-11Ch]
    0040168C push eax ;C:\WINDOWS\system32\csavpw2.dll
    0040168D mov ecx, offset a8dfa290443ae89 ; "{8DFA2904-43AE-8929-9664-4347554D24B6}"
    00401692 call sub_40124E

    -> call sub_40124E Creates a RegKey in HKEY_CLASSES_ROOT with CLSID\{8DFA2904-97C43AE-8929-9664-4347554D24B6} and setted some values as ExeModuleName, DllModuleName, SobjEventName

    004016B5 push eax ; csavpw2.dll
    004016B6 call edi ; LoadLibraryA
    004016B8 push esi
    004016B9 call ds:ExitProcess
    004016BF push eax
    004016C0 call ds:CloseHandle

    Trojan Removal

    1) Delete the Trojan file: csavpw0/1/2/etc.dll

    2) Delete the following CLSID CLSID\{8DFA2904-97C43AE-8929-9664-4347554D24B6}

    See you to the next post..
    Reverse Engineering
  15. IDA disasms reserved opcodes, is it a bug?

    Few days ago I was inspecting a malware using my disassembler, and I stumbled on this piece of code:

    I use “!?!?!” string for undefined/reserved opcode. I had some problems testing reserved opcodes so I decided to check this case carefully. The first check is given by a comparative method, I loaded the malware into IDA. Look here:

    The first thing I thought of was: “Damn, there’s a bug inside my disasm engine”.

    I took a look at the printed version of my “Intel® IA-32 Architectures Software Developer’s Manual - Volume 2B: Instruction Set Reference, N-Z”. According to one-byte opcode map, C6 opcode is defined as a “Grp 11 (1A) - MOV”.

    What does it mean?
    The opcode can’t give me the exact meaning of the instruction. I need some extra information, which are given by the opcode extension: ModR/M byte (0×22 in the example). To retrieve the necessary information about this opcode I have to check a new table: “Opcode Extensions for One- and Two-byte Opcodes by Group Number”. I’m interested in row denoted as Group_11:

    This is only a part of the entire table, it shows the header and the row of the group I’m focused on.

    ModR/M byte is divided into 3 parts: mod, nnn and r/m.
    0×22 = 00100010b
    mod = 00 (bit 7, 6)
    nnn = 100 (bit 5, 4, 3)
    r/m = 010 (bit 2,1,0)

    These numbers help you to locate the right instruction definition into the opcode extension’s table. To make things short, nnn value identifies the right cell to pick out. In this case 100b points to a blank cell, what does it mean? According to Intel manual: “All blanks in all opcode maps are reserved and must not be used. Do not depend on the operation of undefined or reserved opcodes“.

    Is it really an invalid instruction? All my initial investigations were done using the printed version of the Intel manual, and since of I had found some errors in it I decided to look at the most recent online version.
    This new check doesn’t change anything, seems like IDA is able to disassemble an invalid instruction. Weird.

    Now the question is: is this a bug or do they (IDA’s developers) know how to handle undocumented opcodes? To answer this question I have two options:
    1. try loading the malware into some more disassemblers
    2. try stepping the instruction using a debugger

    Option number 1
    Windbg’s output:

    Ollydbg’s output

    The result is the same, it’s an invalid instruction.

    Option number 2
    This is the last check I did. I wrote a new exe file including an instruction with C6 opcode in it. The program is really simple and the source is right here:
    .text:00401000 BA B2 10 40 00 mov  edx, offset word_4010B2
    .text:00401005 C6 22 FB       mov  byte ptr [edx], 0FBh
    .text:00401008 6A 00          push 0
    .text:0040100A 68 1D 30 40 00 push offset Caption
    .text:0040100F 68 55 30 40 00 push offset Text
    .text:00401014 6A 00          push 0
    .text:00401016 E8 91 00 00 00 call MessageBoxA
    .text:0040101B C3             retn

    According to Ida it should move a byte inside 0×4010B2 address (it has full access) showing a simple messagebox, nothing more. Unfortunately the result is not the same.

    If you run the file without a debugger it crashes and the classic error box appears. Spying inside the message error’s box I see that the error occours at offset 0×1005, C6 opcode!
    If you run the file with Ollydbg you’ll get almost the same result, the debugger stops signalling the error “Illegal instruction” at 0×401005. Again, C6 opcode!
    If you run the file using IDA’s debugger you’ll get a simple warning: “An attempt was mode to execute an illegal instruction (0×401005)”. After that you’ll get a sequence of error boxes, seems like Ida’s debugger is not fully able to handle execution of illegal instruction…this is another story, btw.

    I did some more test and seems like the problem occours with all the *blank cells*; I tried with all the possible C6 combinations and with some different opcodes too. The result is always the same, Ida shows a disassembled instruction which is totally wrong!!!

    I tried reading Ida’s help file but there was no mention about the problem, I don’t think there’s an hidden option to set. I tried googling without luck. Due to this fact I’m not 100% sure but… I think it’s a bug!