Most Popular Blogs

  1. Why is secure development so important?

    Here's a conversation I had recently with somebody:
    A: Why do you check the length of your strings so often and do that much validation of inputs?
    Me: It's more secure that way.
    A: Why do you need to make you program secure?
    Me: Better secure than sorry.
    A: It's a useless loss of time.
    Me: Bah, it's surprising sometimes the unforeseen problems that it can save.

    Here's a good example of an unforeseen problem that might happen, somebody managed to exploit a buffer overflow in OllyDbg and ImpREC.
    http://forums.accessroot.com/index.php?showtopic=7278
    http://www.milw0rm.com/exploits/6031
    It happens when an export from a dll has a name longer than the buffer.

    CHimpREC does not get fooled by this trick:

    http://img234.imageshack.us/my.php?image=antidebugdn6.png

    Better secure than sorry...
    Categories
    Uncategorized
  2. Qt Internals & Reversing

    Today I took a break from the larger article I'm currently writing. To relax, I wrote a smaller article about the Qt framework. I hope you enjoy.

    Qt Internals & Reversing

    Half of the text of this article comes from my larger paper "Dynamic C++ Proposal". I decided that it was useful to take the part about Qt internals, put it into another article and extend it by adding a reversing part. Because of its nature, this is not the usual kind of article I write. In fact, I wrote the reversing part in less than a day. So, this is a very easy one. However, I think it is useful for people who need to reverse a Qt application and certainly wouldn't consider reading my other paper about Dynamic C++, which doesn't sound like a paper about Qt and, in fact, isn't a paper about Qt: the paragraph about Qt is only one among many others. Moreover, I haven't seen serious articles about this subject.

    The first thing which needs to be considered when reversing Qt applications is what Qt brought to the C++ language. Events (inside the Qt framework) are just virtual functions, so nothing new there. This is not a C++ reversing guide. What is new in Qt are signals and slots, which rely on the dynamism of the Qt framework.

    So, first thing I'm going to show how this dynamism works. The second part focus on reversing and, at that point, I will show how to obtain all the metadata one needs when disassembling a "Q_OBJECT" class.

    Updated November 27th, 2008 at 19:42 by Daniel Pistelli

    Categories
    Uncategorized
  3. VMprotect VM_logic (in v1.8 demo)

    Code:
    *******
    VM-protect hides CPU instruction by dividing single instruction into many VM_opcodes.
    But correct VM must fully reproduce CPU instructions and care about
    correct result in EFlags, so any kind simulation is not acceptable!
    lets look at VM_handlers
    
    VM_handlers ( ~71 )
    (SA = StackAdd , SS = StackSub)
    
    AddByteByte_SS2
    AddWordWord_SS2
    AddDwordDword
    Div168_SS2
    Div3216_SS2
    DIV6432
    ExitVM
    
    IDIV168_SS2
    IDIV3216_SS2
    IDIV6432
    
    IMUL88_SS2
    IMUL1616_SS4
    IMUL3232_SS4
    
    MUL88_SS2
    MUL1616_SS4
    MUL3232_SS4
    
    NotNotAndByte_SS2
    NotNotAndWord_SS2
    NotNotAndDword
    
    PopBP
    PopEBP
    PopfD_SA4  (mostly used on VM_STD, VM_CLD)
    LoadVmIP_SA4
    
    PopMemByte_SA6
    PopMemByteSS_SA6
    PopMemByteES_SA6
    PopMemWord_SA6
    PopMemWordSS_SA6
    PopMemWordES_SA6
    PopMemDword_SA8
    PopMemDwordSS_SA8
    PopMemDwordES_SA8
    (also can be for CS,FS,GS case)
    
    PopByteToVMRegsImmID_SA2
    PopWordToVMRegsImmID_SA2
    PopDwordToVMRegsOpcID_SA4
    ^^^^
    PushByteFromVMRegsImmID_SS2
    PushWordFromVMRegsImmID_SS2
    PushDwordFromVMRegsOpcID_SS4
    ^^^^for byte/word/dword parts access in VM-Registers ( EAX,  AX, AL)
    
    PushBP_SS2  (push VM_SP)
    PushEBP_SS4  (push VM_ESP)
    
    PushwImmUByte_SS2
    PushdImmSByte_SS4
    PushwImmWord_SS2
    PushdImmSWord_SS4
    PushImmDword_SS4
    
    PushMemByte_SA2
    PushMemByteSS_SA2
    PushMemByteES_SA2
    PushMemWord_SA2
    PushMemWordSS_SA2
    PushMemWordES_SA2
    PushMemDword
    PushMemDwordSS
    PushMemDwordES
    (also can be for CS,FS,GS case)
    
    RclByte_SS2
    RclWord_SS2
    RclDword_SS2
    RcrByte_SS2
    RcrWord_SS2
    RcrDword_SS2
    
    SHLD_SA2
    SHRD_SA2
    ShlByte_SS2
    ShlDword_SS2
    ShlWord_SS2
    ShrByte_SS2
    ShrDword_SS2
    ShrWord_SS2
    
    tool-handlers
    PushRDTSC_SS8
    PushCPUID_SS12 (value)
    CRCsum_SA4 (pmem, size)
    
    **
    all Logical & Arithmetic Handlers, which must care on EFlags, has code to store Eflags:
    
    pushfd
    pop    d, [ebp+0]
    
    then after such handler VM will always call PopDwordToVMRegsOpcID_SA4
    for store EFlags into VM-Registers (intermediate or main).
    so we can state, they are VM-opcode-pairs
    
    
    ***
    in VM_handlers we not see exact handlers for And/Or/Not/Xor/Sub/Rol... instructions;
    How are they emulated!?
    
    For Logical-instructions author builds main VM-handler "NotNotAnd";
    it's assembly  code looks so:
    
    Mov eax [ebp+0]
    Mov edx [ebp+4]
    Not  eax
    Not  edx
    And eax edx
    Mov [ebp+4] eax
    Pushfd
    Pop  d,[ebp+0]
    
    NotNotAnd (var1, var2) = And (Not var1) (Not var2)
    
    and seems it is NOR LOGIC GATE!
    (below i will leave name  "NotNotAnd"; I wrote this before did search,
     but you can search in internet for "NOR LOGIC" and see all in images!)
    
    Other main logical instuctions will done via this NOR LOGIC GATE.
    This sequence produces valid result in EFlags for emulated logical instructions,
    so no further works need on EFlags.
    
    VM_NOT (A) = NotNotAnd (A, A)
    
    PushEBP_SS4 + PushMemDwordSS  =  push dword[esp]
    usually uses in VM_NOT, to prevent dubble calculation
    
    VM_AND (A, B) = NotNotAnd {VM_NOT (A), VM_NOT (B)}
                  = NotNotAnd {NotNotAnd (A, A) , NotNotAnd (B, B)}
    
    VM_TEST  = VM_AND ; result value stored in intermediate VM-regs, discarded
    
    VM_OR (A, B) = VM_NOT [NotNotAnd (A, B)]
                 = NotNotAnd {NotNotAnd (A, B) ,  <SamePushed }
    
    VM_XOR (A, B) = NotNotAnd {NotNotAnd (A, B)} {VM_AND (A, B)}
                  = NotNotAnd {NotNotAnd (A, B)} {NotNotAnd [NotNotAnd (A, A) , NotNotAnd (B, B)]}
    
    VM_AND has also truncated variant, if one parameter is Immediate value.
    VMprotect compiles Immediate value already inverted, so part VM_NOT(Immediate) skipped
    in VM_AND construction. (see "AND ecx 7 " example; also in EFlags management)
    
    
    Rol,Ror,Sar are emulated via SHLD & SHRD  handlers;
    
    
    VM_RCL and VM_RCR will handled by RclDword_SS2 & RclDword_SS2 handlers,
    for which Carry-Flag should extracted from VM_regs_Eflags;
    then instuction in handler-code "SHR CH, 1" will load extracted CFlag & do RCL/RCR
    
    
    
    VM_ADD is normal Addition
    for other Arithmetic-instructions VM uses VM_ADD + logic constructions for EFlags management
    (but for decompiling they are useless junk!)
    
    VM_ADC (A, B) = VM_ADD(A, (B+Carry_flag))
    
    VM_SUB (A, B) = VM_NOT [VM_ADD {B, (VM_NOT A)}] 
                EFlags = [And(0815, VM_ADD>>EFlags)] + [And( {Not(0815) }, final-VM_NOT>>EFlags)]
    (virtualized into 36 VM-bytes)
    
    VM_SBB (A, B) = VM_SUB(A, (B+Carry_flag))
    
    VM_CMP = VM_SUB ; result value stored in intermediate VM-regs, discarded
    
    VM_NEG (A) = VM_SUB (0, A)  ;   (constant 0 is already  inverted)
    
    Inc & Dec instructions in CPU not affects Carry-flag, so Carry-flag should leaved in previous state.
    VM_INC (A) = VM_ADD(1, A)
    	Carry-flag restore in EFlags
    VM_DEC (A) = VM_ADD(-1, A)
    	Carry-flag restore in EFlags | Align-Flag managing
    
    ......
    VMprotect virtualizes also CPU's complex-instructions,
    if such can be represented by simple instructions.
    
    VM_SETLE (virtualized into 80 VM-bytes!)
    there will huge EFlags testing and produced result_byte will copied into destination.
    
    VM_CMOVLE
    same kind EFlags testing as SETLE, + VM_Conitional_Jump
    
    for example VM_MOVSB
    this complex-instruction is re-presented into simple instructions assembly group,
    then this group virtualized.
    
    VM_BSWAP is done in following way (27 VM-bytes)
    HiWord(result) = HiWord {Shl (LoWord_LoWord) 8}
    LoWord(result) = HiWord {Shl (HiWord_HiWord) 8}
    
    VM_XADD
    VM does same as CPU
    
    VM_XCHG !?
    while VMprotect author cares about LOCK prefix & not virtualizes instruction with it,
    author did mistake and virtualized XCHG instruction.. oops!
    to prevent XCHG virtualization, author recommends LOCK prefix
    
    ......
    for FLD, FSTP instructions memory content will copied on stack, & load-store from there.
    
    ......
    VM-Registers space is 16 dwords.
    8 of them are for Eax,Ecx,Edx,Ebx,Ebp,Esi,Edi,EFlags ;
    Esp is directly assigned to VM_stack(Ebp) ;
    2 used for Relocation-Difference & passed_Mem_pointer ;
    other  6  are used for temporal storage. mostly for intermediate EFlags,
    also for intermediate or temporal results (VM_TEST, VM_CMP), also for cleanup VM-stack;
    look at VM_SUB, where 2-intermediate Eflags will used in calculation.
    
     Place of real registers in this space is different not only for every other VM,
    but also can change inside one VM!
    Register read from one place, after CAN placed on intermediate place and
    old place become intermediate. so VM-Registers tracking need!
    
    
    ......
    VM-entry works so:
    
    we are at current stack; lets call it TOP-ESP
    at original Opcode place VMprotect puts call to VM:
    
    push offset-VM_IP
    call VM-StartCode
    ,,,,
    VM-StartCode:
    
    push Registers, EFlags ; << Order of push CAN be other then order of pop on ExitVM!
    push [passed_pointer_for_security  + "crypt-constant" ] 
    ; <<new from 1.8, passed from StartupVM, which  allocates this memory,
    ; resolves imports, does file CRC-check,
    push 0 ; Relocation-Difference
    mov  esi, [esp+030] ; offset-VM_IP
    mov  ebp, esp ; ebp will VM-stack
    sub  esp, 0C0 ; 040 bytes reserved for 16 VM-Registers, other free 080 byte space will used
                  ; for user-pushed-variables. if too low become VM-stack, then VM-Registers will
                  ; moved down
    mov  edi, esp ; edi holds VM-Registers pointer
    
    add  esi, [ebp+0] ; add Relocation-Difference to offset-VM_IP
    			; also here jumps LoadVmIP handler
    
    and now code is on VM_main_loop:
    {VM_main_loop has 2 variations, down-read VM-bytes as below, or inverse - up-read}
    
    mov    al,[esi]
    movzx  eax,al
    inc    esi
    jmp    [JumpTable + eax*4]
    
    here starts  VM_BLOCK execution,
    which will move all pushed by VM-StartCode Registers/EFlags/others to VM-Registers space,
    until VM-Stack(ebp) will reach TOP-ESP.
    
    now starts virtualized user-code execution;
    
     ......
    VM-exit works so:
    
    VM-stack(Ebp) is at TOP-ESP; (can be above start value, if Ret_nn emulated or Esp changed)
    now VM executes VM_BLOCK-Epilog-bytes, which will pop all required values (+ return_IP).
    from VM-Registers_space to stack and Ebp is ready for ExitVM-handler;
    then last VM-byte will call ExitVM-handler,
    which pops all from stack to Registers/EFlags and does Ret to return_IP.
    
    
    ......
     because of it's original way of Jump management,
    VMprotect
    ...
    Categories
    Uncategorized
    Attached Thumbnails Attached Files
  4. Debugging the Debugger - Reversing kldbgdrv.sys and Potential Usages

    After various articles on malware analysis I decided to talk about a little different topic, due to the fact that I'm involved into Kernel Mode Coding the Windows Internals Research become a truly important aspect of my Research. As the title suggests, this time I'm going to Study and Reverse a particular component used by the Windows Debugging System, more precisely a Device Driver involved into Local Kernel Debugging.

    Not many people is aware that is possible to perform Local Kernel Debugging, one of the most used Debugging Configurations is the Remote Debugging. Local Kernel Debugging can offer many important vantages, like valuable informations on the Status of the Kernel and Inspect Kmode Components. LKD (Local Kernel Debugging) can be acheived by booting in Debug Mode, both kd and windbg fully supports LKD.

    The essential question now is, How the Debugging Engine, let's consider for example Windbg, is able to obtain informations about the kernel by running from usermode?

    The reply to this question not only will uncover the problem itself but also will open new interesting questions and possibilities, such as:

    #1 - "It's possible to develop an application that can use the same
    technology ?"

    #2 - "How to access the involved components and what are parameter to
    have access?"

    To begin the study of this problem, we have in first instance to reproduce the environement necessary to start a Local Debugging Session.

    I've used for these tests Windows 7 32-Bits Ultimate Edition and Windbg.

    First step is to enable debug mode by running:

    bcdedit -debug on then reboot.

    At this point we have literally to debug our debugger to be able to reveal the mechanism and component involved in communication between the Debug Engine and Kernel.

    In the past Windows Editions, the function used was NtSystemDebugControl, but from Windows Vista to Higher Versions this function is not immediately available.

    To trace windbg activities I've used a great tool for professional API Tracing, called Blade API Monitor.

    The hypothesis was, if windbg runs at usermode and accesses a kernel component it's obvious that will be used a Device Driver, by assuming true this statement, every application that deals directly with Device Drivers will use:

    * CreateFile -> For Driver Opening
    * ReadFile / WriteFile -> Device Driver Communication
    * DeviceIoControl -> Data exchange between Driver and umode application
    * NtSystemDebugControl


    After setting the proper filter for these functions, let's run a Local Kernel Debugging Session and watch the results from API Monitor.

    When debugger is loaded, we can launch some command, like:

    !drvobj
    !irpfind
    !isr

    From API Log emerges an important result, we have two threads:

    #- First Thread

    DeviceIoControl(...)
    DeviceIoControl(...)
    CreateFileW(wchar_t* lpFileName = C:\Windows\Fonts\staticcache.dat,...)

    #- Second Thread

    CreateFileW( wchar_t* lpFileName = C:\Windows\system32\kldbgdrv.sys )
    return value -> void* return = 0x00000128

    WriteFile(void* hFile = 0x00000128, .., unsigned long nNumberOfBytesToWrite = 0x000031F0 )

    CreateFileW(wchar_t* lpFileName = \\.\kldbgdrv)
    return value -> void* return = 0x00000170

    DeviceIoControl(void* hDevice = 0x00000170)
    IOCTL -> unsigned long dwIoControlCode = 0x0022C007
    As you can see, from the second thread we obtain a valuable amount of informations.

    WinDbg creates a driver called kldbgdrv.sys placed in %\system32\ this file is 0x31F0 long.

    Successively this driver is openened and windbg starts to send IOCTL to this driver.

    The IO Control Code used is 0x0022C007.

    When debugging session finishes, kldbgdrv.sys it's deleted.

    To reverse this driver we have obviously to dump it, so the first operation is to locate where is placed and successively carve out this.

    The most probable location where can be located are the resources of windbg or kd executables, so let's explore their PE.

    Between resources of windbg.exe we can see that the last one called "17476" which contains another subdir called "30583" by opening also this last directory finally appears our wldbgdrv.sys (can be easly detected by watching between strings)

    From the starting address of this resource if we add the len of bytes ( nNumberOfBytesToWrite = 0x000031F0) we can easly into a new file kldbgdrv.sys

    Now let's reverse this driver.

    INIT:00010D1F push offset aKdsystemdebugc ; "KdSystemDebugControl"
    INIT:00010D24 lea eax, [ebp+DestinationString]
    INIT:00010D27 push eax ; DestinationString
    INIT:00010D28 call ds:RtlInitUnicodeString
    INIT:00010D2E lea ecx, [ebp+DestinationString]
    INIT:00010D31 push ecx ; SystemRoutineName
    INIT:00010D32 call ds:MmGetSystemRoutineAddress
    INIT:00010D38 mov [ebp+var_1C], eax
    INIT:00010D3B cmp [ebp+var_1C], 0
    INIT:00010D3F jnz short loc_10D4B
    INIT:00010D41 mov eax, STATUS_PROCEDURE_NOT_FOUND
    INIT:00010D46 jmp loc_10DF5

    this is a really interesting piece of code, here the driver attempts to obtain the Routine Address of the function KdSystemDebugControl()

    INIT:00010D4B mov edx, [ebp+DriverObject]
    INIT:00010D4E mov dword ptr [edx+34h], offset sub_10A10 ;DriverUnload
    INIT:00010D55 mov eax, [ebp+DriverObject]
    INIT:00010D58 mov dword ptr [eax+38h], offset sub_10A50 ;DriverObject->MajorFunction[0] = (PDRIVER_DISPATCH)sub_10A50
    INIT:00010D5F mov ecx, [ebp+DriverObject]
    INIT:00010D62 mov dword ptr [ecx+40h], offset sub_10A50 ;DriverObject->MajorFunction[0] = (PDRIVER_DISPATCH)sub_10A50
    INIT:00010D69 mov edx, [ebp+DriverObject]
    INIT:00010D6C mov dword ptr [edx+70h], offset sub_10A80 ;DriverObject->MajorFunction[14] = (PDRIVER_DISPATCH)sub_10A80
    INIT:00010D73 push offset aDeviceKldbgdrv ; "\\Device\\kldbgdrv"
    INIT:00010D78 lea eax, [ebp+DeviceName]
    INIT:00010D7B push eax ; DestinationString
    INIT:00010D7C call ds:RtlInitUnicodeString
    ..
    INIT:00010D96 call ds:IoCreateDevice

    Here the device it's created \\Device\\kldbgdrv and

    There are also four MajorFunctions associations:

    DriverObject->DriverUnload = (PDRIVER_UNLOAD)sub_10A10;
    DriverObject->MajorFunction[0] = (PDRIVER_DISPATCH)sub_10A50; // IofCompleteRequest(Irp, 0)
    DriverObject->MajorFunction[2] = (PDRIVER_DISPATCH)sub_10A50; // IofCompleteRequest(Irp, 0)
    DriverObject->MajorFunction[14] = (PDRIVER_DISPATCH)sub_10A80; // Suddenly Reversed
    Let's check the latest Dispatch Routine:

    PAGE:00010AEE push edx
    PAGE:00010AEF push eax ; PrivilegeValue
    PAGE:00010AF0 call ds:SeSinglePrivilegeCheck
    PAGE:00010AF6 movzx ecx, al
    PAGE:00010AF9 test ecx, ecx
    PAGE:00010AFB jnz short loc_10B09
    PAGE:00010AFD mov [ebp+var_3C], STATUS_ACCESS_DENIED
    PAGE:00010B04 jmp loc_10C5B
    PAGE:00010B09 mov [ebp+var_4], 0
    PAGE:00010B10 mov edx, [ebp+var_30]
    PAGE:00010B13 mov [ebp+var_48], edx
    PAGE:00010B16 cmp [ebp+var_48], 22C007h ; IOCTL = 22C007h
    PAGE:00010B1D jz short loc_10B24
    PAGE:00010B1F jmp loc_10C2B


    When the IOCTL = 22C007h it's sent the first operation is to check if the action has the proper privileges "SeSinglePrivilegeCheck", successively this dispatch routine validates and sanitizes parameters sent with the IOCTL, by using MmUserProbeAddress and ProbeForWrite.

    Finally we can say that kldbgdrv.sys works as wrapper for KdSystemDebugControl.

    This function belongs to NtSystemDebugControl but can be accessed only at kernel mode.

    Here it's prototipe:

    NTSTATUS
    NTAPI
    KdSystemDebugControl(
    SYSDBG_COMMAND Command,
    PVOID InputBuffer,
    ULONG InputBufferLength,
    PVOID OutputBuffer,
    ULONG OutputBufferLength,
    PULONG ReturnLength,
    KPROCESSOR_MODE PreviousMode
    );
    _SYSDBG_COMMAND it's an enum, let's suppose we want SysDbgReadVirtual we have the corresponding struct:

    typedef struct _SYSDBG_VIRTUAL
    {
    PVOID Address;
    PVOID Buffer;
    ULONG Request;
    } SYSDBG_VIRTUAL, *PSYSDBG_VIRTUAL;
    At this point we have all elements to use with success kldbgdrv.sys, that means the possibility to have access to the kernel ...
  5. Video #5 is up.

    New addition to the Reverse Code Engineering Community Forum video tutorial website:
    http://video.reverse-engineering.net

    Video #5: x64 Disassembling and Fixing obfuscated APIs with IDA

    In this one I compare two programs compiled in x86 PE format and x64 PE32+ format with GoAsm from the same source.

    Also previous download packages have been updated (some files were missing) and I added a warning about a bug when tracing with IDA 5.1 in video #3.

    Comments/Questions/Suggestions are always welcome.
    Categories
    Uncategorized
  6. Hello World

    Hey There,

    First blog entry here, hope good things will come up

    Wordpress unfortunaly does not have Code Wrappers, here code will have a better look

    Thanks for Blog Feature Woodmann!

    See you to the next post!
    Categories
    TechLife
  7. stuffz

    DDD - Deadline Driven Development :P

    Deadline approaching again, i'm supposed to deliver that great integration-synchronization-soap-service on monday, 56hrs of 60hr estimate used, 6 operations of 15 implemented.

    And then theres the problem of converting shit ("(C00-D48, E14.5-7)*; E23**; E25**; E27**; E89.3**; E89.6**; T86; Z94" stored in a varchar2 column) to gold (
    Code:
    	snip.....
    )... talk about data quality to these guys..

    going to be a long weekend

    Updated April 14th, 2008 at 15:30 by upb

    Categories
    Uncategorized
  8. Editable Listview control

    Few days ago I started renewing my PE editor's gui, I wanted to replace some edit box controls with a listview control. Everything was going well until I had to edit the value inside a cell. With the original listview control you can change the text of the first subitem of a row only, but I would like to edit every single subitem. How can I solve the problem? I didn't want to waste time solving the problem so I decided to take a look at the usual programming places starting from Code Project. Hm, nothing. I'm not so good in searching information through the net, but seems like there are working samples on mfc, .net and vb only. No win32 programming stuff... Well, I decided to give it a try subclassing the control.
    I have never subclass-ed a control before, it's my first try. I don't know if there's a better approach. I don't even know if it's the correct way to solve the problem, but it seems to works well. Let's start.

    The steps to follow are:
    1. Create an edit box that will be used to insert the new text
    2. Set the new window procedure able to handle edit control's messages
    3. Apply/abort text modification

    I use VS creating a win32 project. Add a listview control to your dialog setting "Edit labels" to FALSE. If you set the option to TRUE the OS will handle subitem modification, I prefer to avoid this behaviour.

    The idea is to change the subitem's text when a double click occours. I catch the event in the main window procedure calling the function (named SubClass_ListView_Editable) which subclasses the control.

    The first step consists of creating the edit box over the clicked subitem. To create the edit box I need to know where to put it. LVM_GETSUBITEMRECT returns information about the rectangle for a subitem of a listview control. With this information I can create the new control:
    Code:
    ListView_GetSubItemRect(hListView, _lParam->iItem, _lParam->iSubItem, LVIR_LABEL, &r);
    //    Time to create the new edit box
    hEditable = CreateWindowEx(0, "EDIT", "Edit me", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_MULTILINE, r.left, r.top, r.right-r.left, r.bottom-r.top, _lParam->hdr.hwndFrom, NULL, hInst, 0);
    "r" is defined as a RECT structure:

    Code:
    typedef struct _RECT {
    LONG left;        //      x-coordinate of the upper-left corner of the rectangle
    LONG top;        //    y-coordinate of the upper-left corner of the rectangle
    LONG right;      //    x-coordinate of the lower-right corner of the rectangle
    LONG bottom;   //    y-coordinate of the lower-right corner of the rectangle
    } RECT, *PRECT;
    As you can see I use "r" inside CreateWindowEx function specifying the coordinates of the new control.
    The third parameter of CreateWindowEx is the text that will be shown in the control. I use a static text but you can leave it blank or display the subitem's text, it's up to you. Now, the new control has been created and I'm going to set some features:

    Code:
    SendMessage(hEditable, EM_LIMITTEXT, 8, 0);        //    It accepts no more than 8 chars
    SendMessage(hEditable, EM_SETSEL, 0, 8);        //    Text selected
    SetFocus(hEditable);                    //    Focus to the new box
    If you don't need a particular behaviour (limit text, accept only numbers...) you can avoid the first two calls but I think the third one is useful, it gives the focus to the new edit box.

    The control is complete, I have to add the new window procedure. This can be done using SetWindoLong function:

    Code:
    LONG SetWindowLong(
    HWND hWnd,    //    Handle of the new edit control
    int nIndex,        //    The attribute to change
    LONG dwNewLong    //    The new value
    );
    The function changes an attribute of a specified window, in this case I'm going to change the address of the dialog procedure. The aim is to add a new window procedure for handling edit box's messages only. I'll pass over all the other messages forwarding them towards the old window procedure.

    Code:
    wpOld = (WNDPROC)SetWindowLong(hEditable, GWL_WNDPROC, SubClass_ListView_WndProc);
    SetProp(hEditable, "WP_OLD", (HANDLE)wpOld);
    SubClass_ListView_WndProc represents the new dialog procedure.
    I have to save the address of the original window procedure because I have to restore it when I'll destroy the edit box. To save the address I use SetProp function, but if you prefer you can use global variables. To end this piece of code I save some more useful information: row and column of the subitem to change:

    Code:
    SetProp(hEditable, "ITEM", (HANDLE)_lParam->iItem);
    SetProp(hEditable, "SUBITEM", (HANDLE)_lParam->iSubItem);
    Which kind of messages will I have to catch? WM_KEYDOWN and WM_DESTROY only, all the other messages are passed to the original window procedure in this way:

    Code:
    return CallWindowProc((WNDPROC)GetProp(hEditable, "WP_OLD"), hwnd, uMsg, wParam, lParam);
    I catch WM_KEYDOWN because I have to handle ENTER ans ESC key. When you hit ENTER the text will be saved in the subitem, and when you click ESC the operation will be aborted:

    Code:
    case WM_KEYDOWN:
    if (LOWORD(wParam) == VK_RETURN)
    {
    ...
    // Item and suibtem to change
    LvItem.iItem = GetProp(hEditable, "ITEM");
    LvItem.iSubItem = GetProp(hEditable, "SUBITEM");
    // Where to store the new text
    LvItem.pszText = text;
    // Get new text and set it in the subitem
    GetWindowText(hEditable, text, sizeof(text));
    SendMessage(hListView, LVM_SETITEMTEXT, (WPARAM)GetProp(hEditable, "ITEM"), (LPARAM)&LvItem);
    DestroyWindow(hEditable);
    }
    else if (LOWORD(wParam) == VK_ESCAPE)
    DestroyWindow(hEditable);
    break;
    If you press ESC the edit box will be destroyed without changing the subitem's text.
    When ENTER is pressed I simply get the text storing it in the subitem. After that I can destroy the edit box.
    There's something more to say about VK_RETURN. Look at CreateWindowEx parameters, there's a ES_MULTILINE value. The value is necessary otherwise the application refuses to catch ENTER.
    The last thing I check in the new window procedure is WM_DESTROY message, I simply remove the saved properties and then I restore the original window procedure calling SetWindowLong again.

    What about mouse click when I'm changing the subitem's value? It's like VK_ESCAPE key, I remove the edit box aborting the operation. See the attached source code for details.

    The picture represents the subclassing method in action:


    The code can be optimized for sure, just fix/change/remove/add everything you need.
    Feel free to post your comment/suggestion/criticism here.
    Download the VS project from http://www.box.net/shared/static/kcurtvm8v7.zip

    Game over!

    Updated November 6th, 2007 at 07:05 by ZaiRoN

    Categories
    Uncategorized
  9. Weird export forwarding thanks to Vista x64 SP1

    After installing the SP1 for Vista x64, I noticed that ImpREC stopped working properly on some files using DefWindowProcA and DefWindowProcW from user32.dll.
    These 2 APIs are forwarded as usual respectively to NtdllDefWindowProc_A and NtdllDefWindowProc_W from ntdll.dll but cannot be "unforwarded" back to user32.dll using the traditional method.

    I'll explain how the loader usually resolves forwarded exports, the unforwarding method used by ImpREC and why it fails on those 2 particular cases.

    Using the information provided by the Import Directory of the executable, the loader looks for a matching name or ordinal in the specified dll.
    After a match is found, the corresponding entry from the AddressOfFunctions array is retrieved from the Export Directory and augmented by the ImageBase of the dll.
    That value is then written to the IAT.

    Sometimes, for compatibility reasons, an import can be forwarded to another one from a different module.
    In that case, the AddressOfFunctions entry does not lead to code but to an ASCII string composed of the module name and the import name or ordinal.
    Code:
    .text:7DCA751E ; LRESULT __stdcall DefWindowProcA(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
    .text:7DCA751E DefWindowProcA  db 'NTDLL.NtdllDefWindowProc_A',0
    .text:7DCA7539 ; Exported entry 151. DefWindowProcW
    .text:7DCA7539                 public DefWindowProcW
    .text:7DCA7539 ; LRESULT __stdcall DefWindowProcW(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
    .text:7DCA7539 DefWindowProcW  db 'NTDLL.NtdllDefWindowProc_W',0
    The loader then restarts the whole process from the beginning, using the info from the forwarding string rather than the original info from the Import Directory of the executable.
    The Entry Point of the newly-found function is written to the IAT instead.

    ImpREC finds the IAT and goes through it to identify all the imports that it contains.
    Some entries belong to ntdll.dll and need to be "unforwarded" to their original location.
    DefWindowProcA should be unforwarded from NtdllDefWindowProc_A.


    http://img510.imageshack.us/my.php?image=presp1zr0.png

    If everything goes well, the original import is found by "bruteforcing" the Entry Point of every function until a forwarding string is found: NTDLL.DefWindowProc_A at the Entry Point of DefWindowProcA in user32.dll and then comes in some guesswork.

    Because an import could have been forwarded from another module, doesn't mean that it really was, there are some false-positives.
    The guesswork is based on a very crude probability analysis based on the module name of the previous import and the module name of the next import.
    EndDialog from user32.dll is almost never forwarded from shlwapi32.dll.

    Something changed with Vista x64 SP1 through some modifications of wow64.dll since the content of the \SysWOW64 directory should be the same as the standard Vista 32-bit SP1.
    Some hotfix is applied only during run-time by WoW64.


    http://img177.imageshack.us/my.php?image=postsp11vz2.png


    http://img177.imageshack.us/my.php?image=postsp12vf6.png

    During execution, the AddressOfFunctions entries of DefWindowProcA and DefWindowProcW from user32.dll are modified.
    The RVA based at the ImageBase becomes greater than the SizeOfImage and leads into the memory area of ntdll.dll rather than the usual forwarding string.
    Instead of 0x0001751E, the AddressOfFunctions becomes 0x015C3D42 or 0x01793D42 or 0x01B83D42 for DefWindowProcA.

    The same result is achieved but this method prevents the unforwarding of some imports through the traditional method since there is no forwarding string anymore.
    It leads into code now:
    Code:
    ntdll.dll:77C43D42 ntdll_NtdllDefWindowProc_A:
    ntdll.dll:77C43D42 jmp     ds:off_77CB6020
    ...
    ntdll.dll:77CB6020 off_77CB6020 dd offset loc_7669C0E7     ; DATA XREF: ntdll.dll:ntdll_NtdllDefWindowProc_Ar
    And jumps back to user32.dll:
    Code:
    user32.dll:7669C0E7 loc_7669C0E7:                           ; DATA XREF: ntdll.dll:off_77CB6020o
    user32.dll:7669C0E7 push    10h
    user32.dll:7669C0E9 push    offset unk_7669C158
    user32.dll:7669C0EE call    near ptr unk_766BC240
    user32.dll:7669C0F3 call    near ptr unk_766980D7
    ...
    Unforwarding is still possible anyway since a side-effect could be identified: the Entry Point of both imports become identical.
    GetProcAddress(DefWindowProcA) == GetProcAddress(NtdllDefWindowProc_A)
    GetProcAddress(DefWindowProcW) == GetProcAddress(NtdllDefWindowProc_W)

    To sum everything up:
    It doesn't really matter, the average user of Vista x64 SP1 would never notice the difference.
    Unpacking in a 32-bit VM instead is still more reliable than under WoW64.

    This will be a part of my proposed upcoming ReCon talk.
    Categories
    Uncategorized
  10. Guidelines to MFC reversing

    Tools - References
    Reversing Microsoft Visual C++ Part II: Classes, Methods and RTTI http://www.openrce.org/articles/full_view/23
    IDA http://www.hex-rays.com/idapro
    Crackme http://quequero.org/uicwiki/images/Lezione6.zip

    Prologue: What is MFC?
    The Microsoft Foundation Classes Library (also Microsoft Foundation Classes or MFC) is a library that wraps portions of the Windows API in C++ classes, including functionality that allows to use a default application framework. Classes are defined for many of the handle-managed Windows objects and also for predefined windows and common controls.

    Introduction
    Software developed with MFC may import MFC80U.dll (MFC80U is the name of the last version of the dll, as I'm writing), it depends on the type of compilation: as a static library or as a shared DLL.
    I'll analyze a software which imports the dll and has debug infos, just to make the job easier.
    Once you understand MFC in this way, you can analyze MFC software compiled statically just adding to IDA the signatures of MFC and VisualC.

    Essay
    This is a standard C source code for windows:
    Code:
    LRESULT CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
            switch(uMsg)
            {
            case WM_COMMAND:
                    switch(LOWORD(wParam))
                    {
    
                    case IDC_ABOUT:
                            DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)MainDialogProc, 0);
                            break;
                           
                            // ...
                    }
            }
    }
    Instead this is source code that uses MFC:
    Code:
    class CAboutDlg : public CDialog
    {
    public:
            CAboutDlg();
    
    // Dialog Data
            enum { IDD = IDD_ABOUTBOX };
    
    protected:
            virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    
    // Implementation
    protected:
            DECLARE_MESSAGE_MAP()
    };
    
    CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)  //CAboutDlg::IDD is dialog ID          
    {
    }
    
    void CAboutDlg::DoDataExchange(CDataExchange* pDX)
    {
            CDialog::DoDataExchange(pDX);
    }
    
    BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //Dialog Message Map: is like DialogProc
    END_MESSAGE_MAP()
    
    // App command to run the dialog
    void CProvaRevApp::OnAppAbout()
    {
            CAboutDlg aboutDlg;
            aboutDlg.DoModal();
    }
    How you can imagine the disasm of MFC software is harder to understand.

    MFC Main
    This is the Main disasm of our target:
    Code:
    .text:00401CBB                 public start
    .text:00401CBB                 call    ___security_init_cookie
    .text:00401CC0                 jmp     ___tmainCRTStartup
    
    .text:004019FB ___tmainCRTStartup proc near            ; CODE XREF: start+5�j
    .text:004019FB
    .text:004019FB                 push    5Ch
    .text:004019FD                 push    offset unk_403DD8
    .text:00401A02                 call    __SEH_prolog4
    ;... other initialization code
    .text:00401B3E                 push    ecx             ; nShowCmd
    .text:00401B3F                 push    eax             ; lpCmdLine
    .text:00401B40                 push    ebx             ; hPrevInstance
    .text:00401B41                 push    400000h         ; hInstance
    .text:00401B46                 call    _wWinMain@16    ; wWinMain(x,x,x,x)
    
    ; int __stdcall wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
    _wWinMain@16 proc near
            jmp     ?AfxWinMain@@YGHPAUHINSTANCE__@@0PA_WH@Z ; AfxWinMain(HINSTANCE__ *,HINSTANCE__ *,wchar_t *,int)
    _wWinMain@16 endp
    As you can see WinMain calls AfxWinMain.
    If you have VisualStudio you can see MFC source code, in this article I'll report only the functions we'll need.
    Code:
    int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
            _In_ LPTSTR lpCmdLine, int nCmdShow)
    {
            ASSERT(hPrevInstance == NULL);
    
            int nReturnCode = -1;
            CWinThread* pThread = AfxGetThread();
            CWinApp* pApp = AfxGetApp();
    
            // AFX internal initialization
            if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))
                    goto InitFailure;
    
            // App global initializations (rare)
            if (pApp != NULL && !pApp->InitApplication())
                    goto InitFailure;
    
            // Perform specific initializations
            if (!pThread->InitInstance())
            {
                    if (pThread->m_pMainWnd != NULL)
                    {
                            TRACE(traceAppMsg, 0, "Warning: Destroying non-NULL m_pMainWnd\n");
                            pThread->m_pMainWnd->DestroyWindow();
                    }
                    nReturnCode = pThread->ExitInstance();
                    goto InitFailure;
            }
            nReturnCode = pThread->Run();
    
    InitFailure:
            AfxWinTerm();
            return nReturnCode;
    }
    This is the disasm of AfxWinMain:
    Code:
    .text:7831D2D2                 public AfxWinMain
    .text:7831D2D2 AfxWinMain      proc near
    .text:7831D2D2                 push    ebx
    .text:7831D2D3                 push    esi
    .text:7831D2D4                 push    edi
    .text:7831D2D5                 or      ebx, 0FFFFFFFFh
    .text:7831D2D8                 call    AfxGetModuleThreadState
    .text:7831D2DD                 mov     esi, [eax+4] ;pThread
    .text:7831D2E0                 call    AfxGetModuleState
    .text:7831D2E5                 push    [esp+0Ch+arg_C]
    .text:7831D2E9                 mov     edi, [eax+4]  ;pApp
    .text:7831D2EC                 push    [esp+10h+arg_8]
    .text:7831D2F0                 push    [esp+14h+arg_4]
    .text:7831D2F4                 push    [esp+18h+arg_0]
    .text:7831D2F8                 call    AfxWinInit
    .text:7831D2FD                 test    eax, eax
    .text:7831D2FF                 jz      short loc_7831D33D
    .text:7831D301                 test    edi, edi    
    .text:7831D303                 jz      short loc_7831D313
    .text:7831D305                 mov     eax, [edi]
    .text:7831D307                 mov     ecx, edi
    .text:7831D309                 call    dword ptr [eax+98h]
    .text:7831D30F                 test    eax, eax
    .text:7831D311                 jz      short loc_7831D33D
    .text:7831D313
    .text:7831D313 loc_7831D313:
    .text:7831D313                 mov     eax, [esi]
    .text:7831D315                 mov     ecx, esi
    .text:7831D317                 call    dword ptr [eax+58h]
    .text:7831D31A                 test    eax, eax
    .text:7831D31C                 jnz     short loc_7831D334
    .text:7831D31E                 cmp     [esi+20h], eax
    .text:7831D321                 jz      short loc_7831D32B
    .text:7831D323                 mov     ecx, [esi+20h]
    .text:7831D326                 mov     eax, [ecx]
    .text:7831D328                 call    dword ptr [eax+68h]
    .text:7831D32B
    .text:7831D32B loc_7831D32B:
    .text:7831D32B                 mov     eax, [esi]
    .text:7831D32D                 mov     ecx, esi
    .text:7831D32F                 call    dword ptr [eax+70h]
    .text:7831D332                 jmp     short loc_7831D33B
    .text:7831D334
    .text:7831D334 loc_7831D334:
    .text:7831D334                 mov     eax, [esi]
    .text:7831D336                 mov     ecx, esi
    .text:7831D338                 call    dword ptr [eax+5Ch]
    .text:7831D33B
    .text:7831D33B loc_7831D33B:  
    .text:7831D33B                 mov     ebx, eax
    .text:7831D33D
    .text:7831D33D loc_7831D33D:
    .text:7831D33D                 call    AfxWinTerm
    .text:7831D342                 pop     edi
    .text:7831D343                 pop     esi
    .text:7831D344                 mov     eax, ebx
    .text:7831D346                 pop     ebx
    .text:7831D347                 retn    10h
    .text:7831D347 AfxWinMain      endp
    In the code there are calls as call [eax+XXh]: actually the call to AfxGetApp (and AfxGetThread) gives back a pointer to a structure that has offsets of all functions used by MFC framework.
    In this case edi (pApp) holds the offset of 405498, which value is 40349C VA, where the virtual functions table of CWinApp is stored:
    Code:
    .rdata:0040349C off_40349C      dd offset ?GetRuntimeClass@CWinApp@@UBEPAUCRuntimeClass@@XZ ;CWinApp::GetRuntimeClass(void)
    .rdata:004034A0                 dd offset sub_401010
    .rdata:004034A4                 dd offset nullsub_1
    .rdata:004034A8                 dd offset nullsub_2
    .rdata:004034AC                 dd offset nullsub_1
    .rdata:004034B0                 dd offset ?OnCmdMsg@CCmdTarget@@UAEHIHPAXPAUAFX_CMDHANDLERINFO@@@Z ; CCmdTarget::OnCmdMsg(uint,int,void *,AFX_CMDHANDLERINFO *)
    .rdata:004034B4                 dd offset ?OnFinalRelease@CCmdTarget@@UAEXXZ ; CCmdTarget::OnFinalRelease(void)
    .rdata:004034B8                 dd offset ?IsInvokeAllowed@CCmdTarget@@UAEHJ@Z ; CCmdTarget::IsInvokeAllowed(long)
    ...
    Categories
    Uncategorized
  11. Using nt!_MiSystemVaType to navigate dynamic kernel address space in Windows7

    32-bit Windows Vista and later use a feature known as Dynamic Kernel Address Space. To quote from a technical article - the Memory Manager dynamically manages the kernel's address space, allocating and deallocating space to various uses to meet the needs of the system. As a result, the amount of virtual memory being used for internal components, device drivers, the file system cache, kernel stacks, system PTE's, per-session code data structures as well as paged and nonpaged pool memory will grow and shrink based on system activity.

    The key to keeping track of all this dynamic memory lies in the unexported pointer nt!_MiSystemVaType, a mapped array of byte values that describes both the type of memory allocation, and by virtue of the indexed position within the array, the location and size of the memory block. Each time there is a new memory allocation, the MiSystemVaType array is updated.

    In this code project I will try to show how to use MiSystemVaType to navigate the dynamic kernel address space to get a complete mapping of the various allocation types. In addition, I'll give an example of how to use it to find and identify loaded drivers, as well as discuss how it might be used to conduct efficient memory pool searches.

    Here are a few background articles on the subject at hand:

    Understanding the kernel address space on 32-bit Windows Vista
    http://www.nynaeve.net/?p=261

    Inside the Windows Vista Kernel: Part 2
    http://technet.microsoft.com/en-us/magazine/2007.03.vistakernel.aspx

    Windowsģ Internals, Fifth Edition
    9.5.7 Dynamic System Virtual Address Space Management
    http://www.microsoft.com/learning/en/us/book.aspx?ID=12069&locale=en-us


    MiSystemVaType:

    nt!_MiSystemVaType is a pointer to an array of byte values of enum type MI_SYSTEM_VA_TYPE. Each byte in the array describes a single Large Page and maps, in sequential order, the entire upper 2GB of logical address space from 0x80000000 (MmSystemRangeStart) - 0xFFFFFFFF. The size of the byte array is either 0x400 when PAE is enabled, where the default size of a Large Page is 2MB, or 0x200 in non-PAE mode, which uses a Large Page size of 4MB.

    The enum type values can be listed with WinDbg/LiveKd:

    Code:
    kd> dt nt!_MI_SYSTEM_VA_TYPE
    
       MiVaUnused = 0n0
       MiVaSessionSpace = 0n1
       MiVaProcessSpace = 0n2
       MiVaBootLoaded = 0n3
       MiVaPfnDatabase = 0n4
       MiVaNonPagedPool = 0n5
       MiVaPagedPool = 0n6
       MiVaSpecialPoolPaged = 0n7
       MiVaSystemCache = 0n8
       MiVaSystemPtes = 0n9
       MiVaHal = 0n10
       MiVaSessionGlobalSpace = 0n11
       MiVaDriverImages = 0n12
       MiVaSpecialPoolNonPaged = 0n13
       MiVaMaximumType = 0n14


    PAE mode:


    The Physical Address Extension (PAE) processor feature enables use of 64-bit page table entries for physical addresses that are wider than 32 bits. If PAE is enabled, the size of page table entries (PTEs) are increased from 32 to 64 bits (4 to 8 bytes). Consequently, the size of a Large Page is reduced from 4MB to 2MB in PAE mode. One can determine the size of the PTE data structure, nt!_MMPTE, (and hence if PAE is enabled or not) with the command:

    Code:
    kd> dt -v nt!_MMPTE
    struct _MMPTE, 1 elements, 0x8 bytes
    To determine if PAE is enabled programmatically we can read the ProcessorFeatures field of KUSER_SHARED_DATA, a shared memory structure mapped to all processes and located at 0x7FFE0000 in usermode. This is equivalent to what the IsProcessorFeaturePresent API does.

    KUSER_SHARED_DATA is duplicated at 0xFFDF0000 in kernelmode. Fortunately ntddk.h gives us a handy macro with which to work with it. The snippet below will give us (by inference) the size of nt!_MMPTE, from which we can derive the size of a large page and the size of the MiSystemVaType array.

    PHP Code:
    #define KI_USER_SHARED_DATA         0xffdf0000
    #define SharedUserData  ((KUSER_SHARED_DATA * const)   KI_USER_SHARED_DATA)

    // Determine if PAE is enabled from  KI_USER_SHARED_DATA.ProcessorFeatures

    if(SharedUserData->ProcessorFeatures[PF_PAE_ENABLED])
    {
        
    DbgPrint ("PAE enabled\n");

        
    sizeof_MMPTE 8;

    } else {

        
    DbgPrint ("PAE not enabled\n");

        
    sizeof_MMPTE 4;

    In the registry the PAE status can be read from
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\PhysicalAddressExtension

    Here is a summary of the differences between PAE and non-PAE mode which are relevant to our code:

    Code:
    (PAGE_SIZE = 0x1000)
    
    PAE enabled:
    
        nt kernel version:
             ntkrnlpa.exe: 1 CPU, PAE
             ntkpamp.exe:  n CPU, SMP, PAE
    
        sizeof_MMPTE = 8
        
        LARGE_PAGE_SIZE = PAGE_SIZE * PAGE_SIZE / sizeof_MMPTE = 0x200000  (2MB)
        sizeof MiSystemVaType array = (0xFFFFFFFF+1 -  (ULONG)MmSystemRangeStart) / LARGE_PAGE_SIZE = 0x400
    
        0x400 * 0x200000 = 0x80000000 = (0x80000000 / 1024 /1024 /1024) =  2GB
            
            
    PAE disabled:
    
        nt kernel version:
            ntoskrnl.exe: 1 CPU
            ntkrnlmp.exe: n CPU, SMP
    
        sizeof_MMPTE = 4
        
        LARGE_PAGE_SIZE = PAGE_SIZE * PAGE_SIZE / sizeof_MMPTE = 0x400000  (4MB)
        sizeof MiSystemVaType array = (0xFFFFFFFF+1 -  (ULONG)MmSystemRangeStart) / LARGE_PAGE_SIZE = 0x200
    
        0x200 * 0x400000 = 0x80000000 = 2GB
    PAE is enabled by default in Windows 7, if you wish to test the included code in non-PAE mode use BCDEdit as follows:

    If DEP is enabled, PAE cannot be disabled. Use the following BCDEdit /set commands to disable both DEP and PAE:

    bcdedit /set nx AlwaysOff
    bcdedit /set pae ForceDisable


    To restore:

    bcdedit /set nx Optout (or one of [Optin |OptOut | AlwaysOn])
    bcdedit /set pae ForceEnable

    http://msdn.microsoft.com/en-us/library/aa366796(v=vs.85).aspx


    Finding the unexported pointer nt!_MiSystemVaType:


    We need to programmatically find the offset to nt!_MiSystemVaType. Since this is an unexported pointer we'll have to parse a known kernel function which makes use of the variable. Uh Oh. Production code need not apply . Oh well, this is an RCE forum, right? At least that's better than using a hard-coded value, not as good as using symbols.

    Rather than using a classic byte-pattern search that is often used to find unexported variables, I made use of a clever idea Zairon mentioned to me, that of looking for cross references between code and data sections in order to pick up instances of data variable usage. In essence, derive XREFS similar to IDA.

    I really like Zairon's idea of using XREF analysis over a byte-pattern search method because it's simple, highly adaptable, and is less susceptible to changing byte patterns between different OS kernel versions.

    The function I chose to parse for the offset of MiSystemVaType was the exported MmIsNonPagedSystemAddressValid procedure. The simple algorithm logic I used was: "Scan for the first data XREF to the section called '.data''"

    See the source code for the specific algorithm I implemented, plus a few suggestions for creating a more rigorous algorithm if desired, such as using a length disassembly engine (LDE) to avoid the possibility a false XREF could occur across instructions.

    The simple logic above should be valid for all current 32-bit nt* kernel versions in Windows 7 / Vista / Server 2008. Even better, MmIsNonPagedSystemAddressValid has been deemed to be obsolete and is exported to support existing drivers only, so it's more unlikely to change anytime soon.

    Code:
    _MmIsNonPagedSystemAddressValid@4 proc
    8B FF                             mov     edi, edi
    55                                push    ebp
    8B EC                             mov     ebp, esp
    53                                push    ebx
    56                                push    esi
    8B 35 18 57 97 82                 mov     esi, ds:_MmSystemRangeStart //  xref to ALMOSTRO
    57                                push    edi
    8B 7D 08                          mov     edi, [ebp+VirtualAddress]
    BB F8 3F 00 00                    mov     ebx, 3FF8h
    3B FE                             cmp     edi, esi
    72 25                             jb      short loc_828F17A8
    8B C6                             mov     eax, esi
    C1 E8 12                          shr     eax, 12h
    8B CF                             mov     ecx, edi
    C1 E9 12                          shr     ecx, 12h
    23 C3                             and     eax, ebx
    23 CB                             and     ecx, ebx
    2B C8                             sub     ecx, eax
    C1 F9 03                          sar     ecx, 3
    8A 81 60 51 95 82                 mov     al, _MiSystemVaType[ecx]  // xref to .data


    Making sense of MiSystemVaType:


    Now that we've got the pointer to nt!_MiSystemVaType, what do we do with it? The first obvious thing is just to list everything out.

    Let's take a look at the first 0x10 bytes of the MiSystemVaType array. Each byte maps a logical address block of LARGE_PAGE_SIZE, beginning at ...
    Categories
    Uncategorized
    Attached Thumbnails Attached Files
  12. Блогујем ја, блогујеш ти....

    Блогујем ја, блогујеш ти, блогујемо сви због изгубљене љубави... блогујем...

    Updated October 3rd, 2007 at 16:41 by deroko

    Categories
    Uncategorized
  13. IDC scripting a Win32.Virut variant - Part 2

    This post continues Part 1, which should be read first for reference.

    Some points of interest about the viral code itself:

    • There is a small RDTSC timing check at the start. If the difference between 2 RDTSC calls is greater than 0x100 then it's determined that you're in a VM or single step tracing the code (or have only 4K of memory maybe!). In that case the virus doesn't infect but instead returns to the default address of 0x40101D and only tries to connect to the irc server.

      Doing a little test I found that 2 RDTSC calls would return a difference of between 1000-1500 ticks under VMWare, but only 50 ticks under a real system. Not a sophisticated VM test, but it seems to work.

    • There is also apparently a Redpill type VM check which I found crashes under VMWare.

      Code:
      :0040323A RedPill:      ; CODE XREF: Main+2
      :0040323A       push    eax
      :0040323B       sidt    qword ptr [esp-2]
      :00403240       pop     eax
      :00403241       mov     eax, [eax+6]    ; invalid pointer, crashes under VMWare
      :00403241                               ; buggy code?!
      :00403244       shl     eax, 10h
      :00403247       jns     short Force_RDTSC_test_to_fail
    • The virus is Win9x/Me compatible. If the OS is Win2K or greater it hooks NtCreateFile / NtOpenFile. If Win9x, it hooks VWIN32_Int21Dispatch and monitors for the MS-DOS LFN (long file name) service 0x716C, which is used for open/create. The Win9x related stuff is "old school" and has been documented before. If interested see:

      The VxDCall backdoor http://vx.netlux.org/lib/vgy06.html
      VIRUS ANALYSIS 2 http://peterszor.com/hps.pdf

    • The virus copies itself to the last section of a file it infects, but the initial seed value for the Xor decryption routine is different for every infected file (uses an RDTSC randomization), showing its polymorphic nature. After copying itself from running memory into the file, the main Decrypt function is called once again, but this time it's encrypting itself in the file, the XOR routine being reversible.

    • After determining the system offsets for the Nt calls it hooks, the virus creates a section, maps itself into it, then immediately continues execution from this high memory mapping address. All further execution is run from this memory mapped image. This makes it a little more difficult when live tracing and comparing addresses to the disassembly, but the jump to high memory makes a great breakpoint when you get deeper into the live analysis.

      .data:004035FE lea eax, dword_403606
      .data:00403604 jmp eax
      .data:00403606 ... ; this is now running from high mem



    • One interesting (though not original) thing the virus does is how it disables Windows File Protection (WFP) so it can infect any file in any directory without being subverted.

      Immediately after beginning execution in the high memory mapped section that I just mentioned, it calls NtAdjustPrivilegesToken with SeDebugPrivilege privilege so it is able to call CreateRemoteThread() in the Winlogon process.

      How to obtain a handle to any process with SeDebugPrivilege
      http://support.microsoft.com/kb/131065

      Using a CreateToolhelp32Snapshot/Process32Next loop, it scans for the 4th process returned, or Winlogon. Then it hooks the 4 Nt calls within the winlogon address context by overwriting the Service Id of the relevant Zw ntdll KiFastSystemCall with a detour to its own hook routine (which is mapped into winlogon memory space).

      Once this is done it calls CreateRemoteThread followed by a short Sleep routine to let the remote thread execute within winlogon context. After the Sleep nap, the CreateToolhelp32Snapshot loop continues and hooks the 4 Nt calls in every other active process.

      The aforementioned CreateRemoteThread winlogon thread does a number of things besides disabling WFP. It sets up the Win9x/Me VxDCall file hook if applicable, writes the irc sites IP address to the Windows hosts file, accesses the registry, creates some Events, creates a couple more threads, one of which maps out ntoskrnl and the KeServiceDescriptorTable, tries to connect to the internet, etc.


      WFP is disabled by patching in a call to ExitThread immediately after a NtWaitForMultipleObjects call in an sfc.os.dll function called SfcWatchProtectedDirectoriesWorkerThread. The function name pretty much describes what it does, it's a worker thread which continually monitors for file changes from a protected dll list. After patching SfcWatchProtectedDirectoriesWorkerThread the virus calls SfcTerminateWatcherThread. (IDA + symbols is a wonderful thing )

      Here is what the function looks like in code:

      Code:
      // The search pattern in sfc.os.dll
      
      :00403CE4          Pattern_SFC_OS_DLL:    ; DATA XREF: Disable_WFP+F
      :00403CE4 6A 01       push    1
      :00403CE6 6A 01       push    1
      :00403CE8 FF 33       push    dword ptr [ebx]
      :00403CEA FF 73 04    push    dword ptr [ebx+4]
      :00403CEA          ; -----------------------------------------------
                            // part of call ds:NtWaitForMultipleObjects
      :00403CED FF 15       dw 15FFh   
      
      
      
      :00403CEF Disable_WFP     proc near
      
      // EAX = base address of sfc.os.dll returned from GetModuleHandleA
      
      :00403CEF       test    eax, eax
      :00403CF1       jz      short locret_403CE3
      :00403CF3       push    0Bh
      :00403CF8       mov     edx, eax
      :00403CFA       pop     ebx
      :00403CFB       add     edx, [eax+IMAGE_DOS_HEADER.e_lfanew]
      :00403CFE       lea     esi, Pattern_SFC_OS_DLL
            
                              // SectionTable.PointerToRawData .text section
      :00403D04       mov     edi, [edx+10Ch]
                              // SectionTable.SizeOfRawData .text section
      :00403D0A       mov     ecx, [edx+108h]
             
      :00403D10       add     edi, eax
      :00403D12       sub     ecx, ebx
      :00403D14
      :00403D14 Find_Pattern:           ; CODE XREF: Disable_WFP+2E
      :00403D14       pusha
      :00403D15       mov     ecx, ebx
      :00403D17       repe cmpsb
      :00403D19       popa
      :00403D1A       jz      short loc_403D21
      :00403D1C       inc     edi
      :00403D1D       loop    Find_Pattern
      :00403D1F       jmp     short locret_403CE3
      :00403D21 ; ----------------------------------------------------
      :00403D21
      :00403D21 loc_403D21:             ; CODE XREF: Disable_WFP+2B
      :00403D21       add     edi, 0Fh
      :00403D24       push    edi
      :00403D25       mov     edx, esp
      :00403D27       push    ebx
      :00403D28       mov     ecx, esp
      :00403D2A       push    eax
      :00403D2B       push    esp             ; OldProtect
      :00403D2C       push    40h             ; Protect
      :00403D2E       push    ecx             ; RegionSize
      :00403D2F       push    edx             ; BaseAddress
      :00403D30       push    0FFFFFFFFh      ; hProcess
      :00403D32       call    NtProtectVirtualMemory
      :00403D38       add     esp, 0Ch
      :00403D3B       mov     edx, ExitThread
      :00403D41       sub     edx, edi
      :00403D43       sub     edx, 7
      
      // Patch in ExitThread call immediately after
      // NtWaitForMultipleObjects in sfc.os function
      // SfcWatchProtectedDirectoriesWorkerThread
      
      // patch in push eax opcodes (6A00) + Call near, relative opcode (E8)
      :00403D46       mov     dword ptr [edi], 0E8006Ah  
            
      // patch in ExitThread displacement
      :00403D4C       mov     [edi+3], edx
                
      :00403D4F       retn
      :00403D4F Disable_WFP     endp ;
      Once I figured out what the code was doing I was able to do a search and found that the entire routine for disabling WFP was ripped from here:

      Win2k.SFPDisable
      http://www.hackemate.com.ar/ezines/29a/29a-6/Articles/29A-6.001



    • And finally, and congratulations if you're still reading this, there is a mysterious Int 0x2C interrupt call at the start of the program. This call is the main reason this virus held my interest for so long and is ultimately the genesis of this article. I was hoping a full analysis of the program would point out its purpose. Alas, I'm still as clueless as when I started.


      Therefore I open up to speculation (or reason or knowledge), the true function of this Int2C call, if there is one, to you Gentle Reader (may Asimov forgive me).


      Here is the start of the code once again showing the important bits. I've tried to outline the "normal" path of infection by highlighting in Blue. Under any condition that I can see, Int2C will always return STATUS_NO_EVENT_PAIR, so that particular path of execution is fixed.

      The question is then. is this just quirky code to confuse us, or can an Int2C call have a real purpose in Ring3 under certain conditions?


      Code:
      :00403200 start           proc near 
      :00403200                 cld
      :00403201                 call    Main
      :00403201 start           endp
      :00403201
      
      :0040321F popebp_ret:
      :0040321F                 pop     ebp
      :00403220                 retn
      .
      :00403221 Force_RDTSC_test_to_fail:
      :00403221                 push    ebp
      :00403222                 mov     eax, 8000h
      :00403227                 xor     ecx, ecx
      :00403229                 jmp     short loc_403255
    ...
    Categories
    Uncategorized
  14. 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
  15. 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 (http://searchsecurity.techtarget.com/news/article/0,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:
    Code:
    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
    0040FFF3 MOV DWORD PTR SS:[ESP+48],ECX
    0040FFFB PUSH DWORD PTR SS:[ESP+48]
    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):
    Code:
    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Ö
    Categories
    Uncategorized
Page 2 of 5 FirstFirst 12345 LastLast