Entries with no category

  1. Some notes on how to find out hidden callbacks

    Can I blog an incomplete solution or an incomplete analysis? Why not! That’s the spirit of this blog entry!

    More than one year ago I started a project with Kayaker, we decided to write a tool able to show hidden callbacks. If I remember correctly the idea was born while we were putting our hands on a rootkit. In the same days I bet there were many reversers around thinking the same thing because the same tool was developed by others. As you can imagine our tool never see the light, but not because there are similar tools available online; mostly because we are two old lazy reversers!

    I bet you are thinking: why the hell are you writing this stupid intro? Well, the tools I mentioned before were bugged and some months ago I discovered the same thing, they are still bugged (I don’t know if they have solved their problems right now…). Strange that no one else noticed it yet.
    Anyway, we won’t complete the tool, but with this blog post I would like to tell you some notes about our investigations. At the beginning I wanted to write a detailed and complete article about the subject, but I don’t know when I’ll be able to end this project so I decided to spread out some of my notes.

    It’s a sort of two minds work so credit goes to Kayaker too!

    The idea is to try to retrieve hidden callbacks that has been installed via CmRegisterCallback, PsSetCreateProcessNotifyRoutine, PsSetCreateThreadNotifyRoutine and PsSetLoadImageNotifyRoutine. After that it would be good to deregister one or more of them.

    Where to start?
    First of all you have to understand what’s behind functions like CmRegisterCallback, and others. Then, you’ll have something to work on. I’ll start with CmRegisterCallback (from XP SP2), the function is used to register a RegistryCallback routine, and I think the XP version is the most simple one to fully undestand the principles behind the function. There are some differencies between XP and 7 versions, but I think you’ll be able to fully understand 7 structure too! Here is the disassembled function (without useless parts of course):
    487E6B  push   'bcMC'                          ; Pool Tag: "CMcb" 
    487E70  xor    ebx, ebx 
    487E72  push   38h                             ; NumberOfBytes: 0x38 
    487E74  inc    ebx 
    487E75  push   ebx                             ; PoolType: PAGEDPOOL 
    487E76  call   ExAllocatePoolWithTag           ; ExAllocatePoolWithTag(x,x,x): allocates pool memory 
    487E7B  mov    esi, eax                        ; eax is the pointer to the allocated pool memory, PCM_CALLBACK_CONTEXT_BLOCK 
    487E7D  xor    edi, edi 
    487E7F  cmp    esi, edi                        ; Is PCM_CALLBACK_CONTEXT_BLOCK a NULL pointer? 
    487E81  jz     cmRegisterCallback_fails        ; yes: function fails... 
    487E87  push   esi 
    487E88  push   [ebp+Function]                  ; PEX_CALLBACK_FUNCTION, pointer to callback function 
    487E8B  call   _ExAllocateCallBack             ; allocates and fill EX_CALLBACK_ROUTINE_BLOCK structure (more on this later...) 
    487E90  cmp    eax, edi                        ; ExAllocateCallback success or not? 
    487E92  mov    [ebp+PEX_CALLBACK_ROUTINE_BLOCK], eax ; store the pointer to the allocated pool memory 
    487E95  jnz    short _ExAllocateCallBack_success   
        ...                                         ; fill CM_CALLBACK_CONTEXT_BLOCK fields 
    487EDC  mov    ebx, offset CmpCallBackVector 
    487EE1  mov    [ebp+i], edi                    ; i = 0 
    487EE4 try_next_slot: 
    487EE4  push   edi                             ; OldBlock: NULL 
    487EE5  push   [ebp+PEX_CALLBACK_ROUTINE_BLOCK] ; NewBlock with information to add 
    487EE8  push   ebx                             ; CmpCallbackVector[i] 
    487EE9  call   _ExCompareExchangeCallBack   ; try to *insert* the new callback inside CmpCallBack vector 
    487EEE  test   al, al                       ;check the result... 
    487EF0  jnz    short free_slot_has_been_found    ; jump if the vector has an empty space for the new entry 
    487EF2  add    [ebp+i], 4                      ; i++, increase the counter 
    487EF6  add    ebx, 4                          ; shift to the next item of the vector to check 
    487EF9  cmp    [ebp+i], 190h                   ; is the end of the vector? 
    487F00  jb     short try_next_slot             ; no: try another one. yes: no free slot!    
    487F11 cmRegisterCallback_fails: 
    487F16 end_CmRegisterCallback:    
    487F1A  retn   0Ch    
    487F1D free_slot_has_been_found: 
    487F1D  mov    eax, 1 
    487F22  mov    ecx, offset _CmpCallBackCount   ; CmpCallBackCount: number of not NULL item inside the vector 
    487F27  xadd   [ecx], eax                      ; there's a new callback, it increases the number of item inside the vector 
    487F2A  xor    eax, eax 
    487F2C  jmp    short end_CmRegisterCallback
    As you can see the idea behind the function is really simple!
    Basically, it tries to add a new entry inside a vector named CmpCallBackVector, and when the entry is correctly inserted the registration process will end with a success.
    How do I know is it using a vector? The add instruction at 0x487EF6 represents a clear clue, and the cmp at 0x487EF9 reveals the fixed length of the vector (the vector has 100 items (0×190/4…)). Now that I have this information I’m going to try to explain the entire procedure in detail. The algorithm could be divided into 5 big blocks:

    1: try to allocate 0×38 bytes for a structure named CM_CALLBACK_CONTEXT_BLOCK
    2: try to allocate 0x0C bytes for a structure named EX_CALLBACK_ROUTINE_BLOCK
    3: fill CM_CALLBACK_CONTEXT_BLOCK fields
    4: look for an empty slot, insert a sort of PEX_CALLBACK_ROUTINE_BLOCK in it and update CmpCallBackCount
    5: notify success or error and exit

    Point #1 is pretty simple to understand, it’s only a call to ExAllocatePoolWithTag.

    To understand point #2 you have to see what’s going on behind ExAllocateCallBack procedure. Let’s start taking a look at it:
    52AB35  push   'brbC'                              ; Pool Tag: Cbrb
    52AB3A  push   0Ch                                 ; NumberOfBytes: 0x0C 
    52AB3C  push   1                                   ; PoolType: PAGED_POOL 
    52AB3E  call   ExAllocatePoolWithTag               ; alloc a EX_CALLBACK_ROUTINE_BLOCK structure 
    52AB43  test   eax, eax                            ; ExAllocatePoolWithTag success or not? 
    52AB45  jz     short _ExAllocateCallBack_fails 
    52AB47  mov    ecx, [ebp+_pex_callback_function]   ; pointer to callback function (PEX_CALLBACK_FUNCTION) 
    52AB4A  and    dword ptr [eax], 0                  ; 1° field: 0 
    52AB4D  mov    [eax+4], ecx                        ; 2° field: _pex_callback_function 
    52AB50  mov    ecx, [ebp+_pool_allocated_memory]   ; PCM_CALLBACK_CONTEXT_BLOCK 
    52AB53  mov    [eax+8], ecx                        ; 3° field: _pcm_callback_context_block 
    52AB56 _ExAllocateCallBack_fails:   
    The procedure is used to allocate and fill a special structure:

    typedef struct _EX_CALLBACK_ROUTINE_BLOCK
           EX_RUNDOWN_REF             RundownProtect;
           PEX_CALLBACK_FUNCTION      Function;
    As you can see from the lines above the first field has been setted to 0 while the other fields are filled with two pointers: the function to register and the context containing info about the callback.

    While point #3 is just a series of mov instructions used to fill CM_CALLBACK_ROUTINE_BLOCK structure, point #4 gives some usefull information to us: CmpCallBackVector has 100 elements and this part of code is used to scan the entire vector until an empty element is found. A failure leads us to a non-registration of the callback. What happens when there’s a empty slot inside the vector? The new entry will be added inside the vector. Most of the job is done by the function named ExCompareExchangeCallBack, here is the core of the function:

    52AB81  mov    eax, [ebp+CmpCallbackVector]    ; vector at the current position 
    52AB84  mov    ebx, [eax]                      ; ebx is a PEX_CALLBACK_ROUTINE_BLOCK, the item could be NULL or not 
    52AB86  mov    eax, ebx 
    52AB88  xor    eax, [ebp+OldBlock]             ; OldBlock is NULL for a registration process 
    52AB8B  mov    [ebp+current_pex_callback_routine_block], ebx 
    52AB8E  cmp    eax, 7                          ; check used to see if the current item is NULL or not 
    52AB91  ja     short loc_52ABB5                ; jump if not NULL 
    52AB93  test   esi, esi                        ; is NewBlock NULL? 
    52AB95  jz     short loc_52ABA1                ; jump if it's NULL 
    52AB97  mov    eax, esi                        ; esi, NewBlock pointer (changed...) 
    52AB99  or     eax, 7                          ; PAY ATTENTION HERE: or 7 !?! 
    52AB9C  mov    [ebp+NewBlock], eax             ; change NewBlock pointer: NewBlock = NewBlock OR 7 
    52AB9F  jmp    short loc_52ABA5    
    52ABA5  mov    eax, [ebp+var_4]               ; here if CmpCallbackVector's item is null 
    52ABA8  mov    ecx, [ebp+CmpCallbackVector]    ; current empty slot 
    52ABAB  mov    edx, [ebp+NewBlock]             ; new pointer to insert 
    52ABAE  cmpxchg [ecx], edx                     ; insert the new pointer inside the empty slot! 
    52ABB1  cmp    eax, ebx
  2. Bridge them all

    Today I’m going to tell you something about the last malware I checked (MD5 0C17E03F41289E47EEB5D0F3F1F48C9C).

    The exe file imports few functions only, but the malware calls a lot of APIs. The author uses a special trick to call an API function, he creates a sort of bridge between the first instruction and the rest of the code of the function itself. The first instruction is executed directly from the stack, then a jmp instruction (the bridge) will lead you to the second instruction (and the rest of the code) of the function. I think I’ve already seen the trick somewhere but unfortunately I don’t remember where… maybe a specific packer or just something similar, I don’t know. If you have seen this trick before just drop me a comment, thx!

    The malware is packed, but inside the unpacked file there’s something strange:

    The exe is full of calls to NULL value. I’m pretty sure that it’s not an error occorred during the unpacking process; there’s something at the beginning of the exe able to fix the addresses. I started my analysis from the first lines of the unpacked file.

    The Import Table is really small but spying inside the strings window I found a lot of common API strings. There’s a big list of functions, and they are divided into some groups; one group containing kernel32 functions, another one with user32 and so on. Working a little with some cross references I got the point I was looking for. It’s time to describe how the malware changes all the “call NULL” instructions.

    First of all the malware gains access to kernel32 base address:

    4013D5    mov  edi, large fs:30h  ; PEB
    4013DC    mov  edi, [edi+0Ch]     ; PEB+0x00c   Ldr : Ptr32 _PEB_LDR_DATA
    4013DF    mov  edi, [edi+0Ch]     ; +0x00c InLoadOrderModuleList : _LIST_ENTRY
    4013E2    jmp  short loc_401404
    4013E4 check_current_module:
    4013E4    mov  eax, edi    ; eax points to current _LDR_MODULE structure
    4013E6    add  eax, 2Ch
    4013E9    push [ebp+arg_0]        ; unicode "kernel32.dll"
    4013EC    push dword ptr [eax+4]  ; current module name inside InLoadOrderModuleList
    4013EF    call Compare_UNICODE_Strings
    4013F4    or   eax, eax
    4013F6    jnz  short strings_are_not_equal
    4013F8    mov  eax, edi           ; LDR_MODULE of the module I was looking for
    4013FA    mov  eax, [eax+18h]     ; He gets the BaseAddress!!!
    4013FD    pop  edi
    4013FE    leave
    4013FF    retn 4
    401402 strings_are_not_equal:
    401402    mov  edi, [edi]        ; jump to next module structure
    401404 loc_401404:
    401404    cmp  dword ptr [edi+18h], 0          ; Is BaseAddress 0?
    401408    jnz  short check_current_module
    40140A    xor  eax, eax
    40140C    pop  edi
    40140D    leave
    40140E    retn 4
    Quite common way, but quite uncommon inside a malware… at least from my not so experienced perspective. Anyway, once it has the right BaseAddress tha malware starts bridge-ing all the necessary functions.

    It’s everything inside this call. It takes four parameters, we can ignore the first one pushed into the stack. What about the others?
    - eax represents the BaseAddress of a module, in this case ntdll
    - 404040 points to a sequence of strings, in this case the first one is “RtlZeroMemory”
    - 406000 represents an address inside the malware
    The procedure is called each time the malware needs to bridge a group of functions, all of them belong to a specific module. In this specific case it works with ntdll’s functions. The list of the functions starts from 0×404040 address:

    The routine contains a loop running until all the functions inside the current group are not all bridged. Here is how the first function is bridged (the sub routine starts at 0×401411):
    1. It takes VirtualAlloc starting address via Kernel32’s ExportTable
    2. It gets the number of bytes of the first instruction of VirtualAlloc. On my XP machine VirtualAlloc starts with a two byte length instruction “MOV EDI, EDI”
    3. It subtracts 7 from ESP value. 7 is obtained adding 5 (a fixed value) to the number of bytes of VirtualAlloc first instruction (2+5=7)
    4. It copies the first two bytes of VirtualAlloc’s code inside the word pointed by the new stack pointer value
    5. If the length of the first instruction is one byte only the malware checks for a possible active breakpoint comparing the byte with 0xCC value; quite useless check at this point…
    6. It sets the byte pointed by ESP+2 to 0xE9
    7. It fills the final 4 of 7 bytes obtaining:

    You have the first instruction of VirtualAlloc at 0×12FDF5, then the jump instruction will lead you directly at the second instruction of VirtualAlloc. Now you understand why it decreases ESP value by 7, two bytes for the first instruction and 5 for the jump. Starting from 0×12FDFC you have the old untouched stack.
    8. It gets the length of the first instruction of the function to bridge. In this specific case the name of the function is RtlZeroMemory and the length is 1
    9. It adds 5 to the obtained value
    10. It calls VirtualAlloc passing trought the stack. It calls 0×12FDF5, and it allocs 6 bytes. 6 is the value that comes from point #9 (5+1=6)
    11. It copies the first instruction of RtlZeroMemory inside the allocated memory space
    12. An anti breakpoint check occours this time because the first instruction is one byte only
    13. It sets the second byte inside the allocated memory space to 0xE9 (again, a jmp instruction)
    14. It fills the rest of the bytes:

    Here is the bridge! It’s like what happened to VirtualAlloc, the allocated memory space contains the first instruction of RtlZeroMemory and a jump to the rest of the code
    15. It restores the original stack pointer value simply adding 7 to the current ESP value
    16. It returns the starting address of the allocated memory space (in this case 0×320000)

    To sum up, the routine bridges the function and returns a memory address. The address will be saved starting from 0×406000 which is another parameter passed to the routine. If you don’t remind all the parameters you can take a look some lines above.
    So, starting from 0×406000 you’ll have a series of dwords, each one containing a pointer to a memory allocated space; these are the values used to replace all the NULL calls. Now I finally know why after the unpacking process I still had a series of “call NULL” instructions.

    Is it really necessary to bridge everything?
    Yes if the author wants to fool an automatic analysis. I don’t know if the trick works or not, but it’s the only reasonable thing I can think of.
    On the other hand, he can’t stop a complete human analysis because once you know how it works it’s pretty easy to convert all the “call NULL” instructions into the right ones; a simple idc script will solve the puzzle.

    It’s a nice piece of malware to analyse btw, it has some interesting routines inside!
  3. CVE-2006-5758: better late than ever

    I put my hands on a malware linked from one of the online malware repositories (md5: 57127815d6864a495151e49c7bf7d192). From a quick glance at it I had the impression it’s an interesting malware to play with. It’s recognizable by almost all the antivirus products out there, and to have an idea about what it does I read some technical descriptions from some random antivirus pages.
    In this post I won’t describe what the malicious file does, but I’ll spend few words on a specific behaviour only: CVE-2006-5758. I didn’t check all the sites, but seems like no one is reporting information about the exploit used inside this malware. It tries to exploit a GDI Local Elevation of Privilege vulnerability, patched on April 2007 (MS07-017); yes, more than one year and a half old. From what I have seen there’s only one article on the web talking about this malicious file, it’s available here http://cyberinsecure.com/malware-uses-gdi-local-elevation-of-privilege-vulnerability-to-install-untraceable-rootkit/ .
    The article doesn’t refer to a specific malware, and I don’t know if I have the same file, but the quick description reveals almost the same characteristics of the file I’m working on:
    After remapping the memory, the malware will initialize a CPalette object. It will then search for the palette object in the shared kernel memory structure. Since the memory is now writable, it can be altered to include a pointer to a special function that will remove any existing SST hooks. Finally, a call to GetNearestPaletteIndex will indirectly cause the function to be executed. Afterwards, the palette object is restored leaving no trace of the attack.“.
    I’ll use this comment to guide you through the post.

    I wasn’t able to identify the packer used to protect the malware, it’s not such a problem indeed because the exe file is debug-able and it’s not hard to step through the code. You can try rebuilding the file, but in general I prefer to work on untouched files so my best choice it’s a simple dump. After that, in order to view all runtime retrieved functions I use my Ida plugin named Reveal Imports. In this way you can easily navigate through the disasmed file. Looking at the revealed imports I noticed some weird functions:

    Quite unusual functions for a malware. The first thing to do is to check if they are used or not. These functions are called by the malware, and now I have to understand why. From my non professional experience with malwares in general, I know that most of the time the unusual code you see inside a malware comes from a source code available online. Google is a good friend, and a simple search reveals something interesting at http://www.milw0rm.com/exploits/3755 .
    It’s the source code of the exploit that is used inside the malware (not the source of the malware!). I think it’s quite useful for newbies to disasm a routine having an eye on the source code, this malware represents a good exercize.

    After remapping the memory…
    The *exploit* routine starts at 40293E, and there’s an interesting loop at the beginning of the routine:
    40296C search_right_handle:
    40296C    cmp  [ebp+hFileMappingObject], 0FFFFh   ; hFileMappingObject is initially 0
    402973    jnb  short loc_4029C1
    402975    xor  eax, eax
    402977    mov  [ebp+var_28], eax
    40297A    push eax                             ; dwNumberOfBytesToMap
    40297B    push eax                             ; dwFileOffsetLow
    40297C    push eax                             ; dwFileOffsetHigh
    40297D    push FILE_MAP_ALL_ACCESS             ; dwDesiredAccess
    402982    push [ebp+hFileMappingObject]        ; hFileMappingObject
    402985    call ds:MapViewOfFile
    40298B    mov  [ebp+lpBaseAddress], eax
    40298E    test eax, eax
    402990    jz   short MapView_fails
    402992    lea  ecx, [ebp+var_2C]
    402995    push 0                          ; ResultLength
    402997    push 10h                        ; SectionInformationLength
    402999    push ecx                        ; SectionInformation
    40299A    push 0                          ; SectionInformationClass
    40299C    push [ebp+hFileMappingObject]   ; SectionHandle
    40299F    call NtQuerySection             ; Retrieves information about the section object
    4029A5    cmp  [ebp+var_28], SEC_COMMIT
    4029AC    jz   short section_found
    4029AE    push [ebp+lpBaseAddress]        ; lpBaseAddress
    4029B1    call ds:UnmapViewOfFile         ; Wrong handle, unmap!
    4029B7    xor  eax, eax
    4029B9    mov  [ebp+lpBaseAddress], eax
    4029BC MapView_fails:
    4029BC    inc  [ebp+hFileMappingObject]   ; Increments hFileMappingObject
    4029BF    jmp  short search_right_handle
    It repeatedly calls MapViewOfFile function using handle from 0 to 0xFFFF. If it finds the right handle it goes on with the rest of the code. As you can see from the snippet the malware restores the state of a wrong mapped view calling UnMapViewOfFile. That’s because it needs one and only one specific kind of section. It’s the first important step to complete.
    On my XP machine the malware locates the right mapped view at 0xC30000, if you look at Ollydbg’s “Memory map” window you’ll see it only after MapViewOfFile was called; you should know why.

    …the malware will initialize a CPalette object…
    4029CC call RtlAllocateHeap_bridge   ; Allocates memory space
    4029D1 test eax, eax
    4029D3 jz   loc_402AA4
    4029D9 mov  [ebp+var_14], eax
    4029DC mov  word ptr [eax+2], 1    ; palNumEntries
    4029E2 mov  word ptr [eax], 300h   ; palVersion
    4029E7 push eax                    ; Logical palette
    4029E8 call CreatePalette          ; Creates a logical palette
    Pretty easy to understand.

    …It will then search for the palette object in the shared memory structure…
    The mapped view is then used by the malware inside a new loop. The malware looks for a PGDI_TABLE_ENTRY through the new memory space:
    402A04 search_object:
    402A04    mov  eax, [ebp+lpBaseAddress]
    402A07    add  eax, [ebp+var_24]
    402A0A    cmp  [ebp+GDI_Structure], eax         ; Is it inside the mapped memory?
    402A0D    jnb  short loc_402A37
    402A0F    mov  eax, [ebp+GDI_Structure]
    402A12    xor  ecx, ecx
    402A14    mov  cx, [eax+4]
    402A18    mov  edx, [ebp+Pid]                   ; pGdiEntry->ProcessID
    402A1B    cmp  ecx, edx
    402A1D    jnz  short try_next_structure
    402A1F    xor  ecx, ecx
    402A21    mov  cx, [eax+0Ah]                    ; pGdiEntry->nType
    402A25    cmp  ecx, 8                           ; PAL_TYPE
    402A28    jnz  short try_next_structure
    402A2A    mov  eax, [eax]                       ; pGdiEntry->pKernelInfo
    402A2C    mov  [ebp+original_KernelInfo], eax   ; Saves the original value
    402A2F    jmp  short loc_402A37
    402A31 try_next_structure:
    402A31    add  [ebp+GDI_Structure], 10h         ; Moves on the next structure to check
    402A35    jmp  short search_object
    It saves the original value of KernleInfo field which contains a pointer to something stored at ring0. You can imagine why it’s saving that value.. it will replace the address with something else for sure.

    …it can be altered to include a pointer to a special function…
    402A3E call _RtlAllocateHeap_bridge
    402A4E push [ebp+hO]
    402A51 pop  dword ptr [eax]              ; Stores handle obtained calling CreatePalette
    402A53 mov  dword ptr [eax+14h], 1
    402A5A push [ebp+hook_hidden_function]   ; push 402AC0
    402A5D pop  dword ptr [eax+3Ch]          ; Stores the real function to call
    402A6B mov  eax, [ebp+GDI_Structure]     ; Address of the original structure to replace
    402A6E push [ebp+fake_structure]         ; Push the fake structure address
    402A71 pop  dword ptr [eax]              ; To tamper!
    It replaces the original data with something else. It’s more or less always the same trick, you exchange the old value with a new preferred one!

    …Finally, a call to GetNearestPaletteIndex will indirectly cause the function to be executed…
    The next call to GetNearestPaletteIndex will call what I have named hook_hidden_function, the hidden dangerous routine. To understand how the trick works you have to look inside win32k.sys, here’s part of GetNearestPaletteIndex:
    00402A73 push 0
    00402A75 push [ebp+hO]
    00402A78 call GetNearestPaletteIndex
    BF94B4AF mov  esi, [ebp+8]          ; esi -> fake structure created between 402A4E and 402A6E
    BF94B4E0 call dword ptr [esi+3Ch]   ; esi+3C points to hook_hidden_function!!!
    The malware will call the hidden function, you ignore it until you’ll realize that the machine is compromised. Nice trick indeed.
    The malware seems to have some more interesting features, I hope to write something else about it in the next days.
  4. Malware and initial stack pointer value

    An old blog entry I forgot to import from my blog at Wordpress...

    Here are the first lines of a malware I was looking at some days ago (MD5: DA4B7EF93C588AD799F1A1C5AFB6CFAD). The malware is packed, I think with an home made packer; 40107C is the entry point, the first line of the loader’s code. The code is filled with useless instructions, nothing hard but if you want to study the entire loader you have to pay attention on every single lines of code. This time I’m not interested in the loader itself, but I’ll focus my attention on a strange behaviour, something I have never noticed before. The malware crashes at 4010AC on XP sp3 machine but it works fine on XP with service pack 1 or 2.
    40107C ADD ECX,DWORD PTR SS:[ESP]   ; useless
    40107F MOV ESI,-70                  ; useless
    401084 ADD EDI,EAX                  ; useless
    401086 MOV ECX,2AFFC5C8             ; useless
    40108B ROL ECX,1                    ; useless
    40108E ROR EDX,15                   ; useless
    401091 MOV EDI,ESP                  ; edi = 12FFC4
    401093 MOV EDX,FE000001             ; edx = 0xFE000001
    401098 ROL EDX,7                    ; edx = 0xFF
    40109B SUB EAX,EBX                  ; useless
    40109D AND EDI,EDX                  ; edi = 0x12FFC4 && 0xFF = 0xC4
    40109F MOV EDX,25FE0                ; edx = 0x25FE0
    4010A4 ROL EDX,3                    ; edx = 0x12FF00
    4010A7 ADD EDX,EDI                  ; edx = 0x12FFC4
    4010A9 SAL ECX,11                   ; useless
    4010AC MOV EAX,DWORD PTR DS:[EDX]   ; eax = 0x77E5EB69
    The comments are taken from a XP sp1 debugging session. At the end of the snippet eax points to ExitThread’s parameter, the one inside BaseProcessStart. There’s nothing interesting in these few lines of code, but it’s always better to open your eyes when there are hardcoded values around. I’m referring to value 0×12FF00 (hardcoded is not totally right but the sense is the same). It’s not obvious but this piece of code could not work on every single machine. Seems like the author was sure about the initial stack address value. I don’t know when the malware was written, but this piece of code crashes on XP machine with Service Pack 3. Maybe the malware was written before the final release of the latest service pack, I dont know. Here is the same code tested on a machine running XP sp3 :
    401091 MOV EDI,ESP                  ; edi = 13FFC4
    401093 MOV EDX,FE000001             ; edx = 0xFE000001
    401098 ROL EDX,7                    ; edx = 0xFF
    40109D AND EDI,EDX                  ; edi = 0x13FFC4 && 0xFF = 0xC4
    40109F MOV EDX,25FE0                ; edx = 0x25FE0
    4010A4 ROL EDX,3                    ; edx = 0x12FF00
    4010A7 ADD EDX,EDI                  ; edx = 0x12FFC4
    The initial stack address is not the same, this time it’s 0×13FFC4. The malware was expecting to see 0×12FFC4, but the value it was looking for is stored inside 0×13FFC4 address.

    Who decide which kind of value should be assigned to esp? 12FFC4 or 13FFC4?
    My investigation started from kernel32.CreateProcessInternalW function. All the code refers to a XP sp3 machine, but sp1 code is almost equal.
    7C819DE1  mov  eax, [ebp+MaximumStackSize]
    7C819DE7  lea  ecx, [ebp+InitialTEB]
    7C819DED  push ecx                          ; InitialTEB
    7C819DEE  push eax                          ; MaximumStackSize
    7C819DEF  push [ebp+StackSize]              ; StackSize
    7C819DF5  push [ebp+hProcess]               ; hProcess
    7C819DFB  call _BaseCreateStack@16          ; BaseCreateStack(x,x,x,x)
    7C819E00  mov  [ebp+var_9EC], eax           ; eax = 0 means SUCCESS
    7C819E06  cmp  eax, ebx                     ; ebx = 0
    7C819E08  jl   _BaseSetLastNTError          ; Jump to error check
    7C819E0E  push ebx                          ; NULL
    7C819E0F  push [ebp+InitialSP]              ; Stack pointer
    7C819E15  push [ebp+InitialPC]              ; Program counter
    7C819E1B  push [ebp+Parameter]              ; Parameter
    7C819E21  lea  eax, [ebp+Context]
    7C819E27  push eax                          ; Context
    7C819E28  call _BaseInitializeContext@20    ; BaseInitializeContext(x,x,x,x,x)
    This is where the new process’s context will be initialized. This is only an initialization, you won’t see the final values (values at EP of the new process) of each register, but it’s enough to understand why the esp values are not equal.
    There are two functions in the snippet above, BaseCreateStack is used to create a stack for the process to run. BaseInitializeContext, as suggested by the name, initializes the context structure using some values obtained by the previous function. Let’s start with the first one: BaseCreateStack.
    Firstly, it checks two values: MaximumStackSize and StackSize. Both of them are loaded from the process to run using NtQuerySection. Among all the information of a PE header there are two fields named SizeOfStackReserve and SizeOfStackCommit that are taken and saved by the system as MaximumStackSize and StackSize. Msdn has a description of the fields:
    SizeOfStackReserve: the number of bytes to reserve for the stack. Only the memory specified by the SizeOfStackCommit member is committed at load time; the rest is made available one page at a time until this reserve size is reached.
    SizeOfStackCommit: the number of bytes to commit for the stack.
    Ok, now the system is going to check if they are valid or not:
    7C8102B5 mov  eax, large fs:18h               ; eax = TEB
    7C8102BB mov  ecx, [eax+30h]                  ; ecx = PEB
    7C8102D2 push dword ptr [ecx+8]               ;  PEB->ImageBaseAddress
    7C8102DB call ds:__imp__RtlImageNtHeader@4    ; RtlImageNtHeader(x)
    7C8102E1 test eax, eax
    7C8102E3 jz   failure
    7C8102E9 mov  ecx, [ebp+MaximumStackSize]
    7C8102EC test ecx, ecx                      ; is MaximumStackSize zero?
    7C8102EE mov  edx, [eax+IMAGE_NT_HEADERS.OptionalHeader.SizeOfStackCommit]
    7C8102F1 jnz  short MaximumStackSize_not_zero
    7C8102F3 mov  ecx, [eax+IMAGE_NT_HEADERS.OptionalHeader.SizeOfStackReserve]
    7C8102F6 mov  [ebp+MaximumStackSize], ecx
    If MaximumStackSize has a not zero value the flow goes on otherwise it’s necessary to set a value to this variable. Which is this value? It’s the one taken from the process’s PE header pointed by PEB->ImageBaseAddress.
    Ok, now it’s time for a check over the other variable; the check is pretty similar to the previous one:
    7C8102F9 MaximumStackSize_not_zero:
    7C8102F9 mov  eax, [ebp+StackSize]
    7C8102FC test eax, eax                ; Is StackSize zero?
    7C8102FE push edi
    7C8102FF mov  edi, 0FFF00000h
    7C810304 jnz  StackSize_not_zero
    7C81030A mov  eax, edx
    If StackSize is zero the content of the variable is filled with the value taken some lines above at 7C8102EE: SizeOfStackCommit. It’s almost the same check I described for MaximumStackSize.
    If the values are not zero, the system checks them again, just to be sure they are valid:
    7C80AFC2 cmp  eax, ecx             ; compare between StackSize and MaximumStackSize
    7C80AFC4 jb   loc_7C81030C
    7C80AFCA lea  ecx, [eax+0FFFFFh]           ;
    7C80AFD0 and  ecx, edi                     ; fix MaximumStackSize
    7C80AFD2 mov  [ebp+MaximumStackSize], ecx  ;
    7C80AFD5 jmp  loc_7C81030C
    StackSize must be minor than MaximumStackSize, if it doesn’t happen the system raise up MaximumStackSize. Now that the initial check is complete the function proceeds working on some alignment stuff, not so interesting per se. I can pass over this part reaching an interesting snippet:
    7C81036F mov  ebx, ds:__imp__NtAllocateVirtualMemory@24 ; NtAllocateVirtualMemory(x,x,x,x,x,x)
    7C81037A push PAGE_READWRITE                  ; Protect: PAGE_READ_WRITE
    7C810380 push MEM_RESERVE                     ; AllocationType: MEM_RESERVE
    7C810385 lea  eax, [ebp+MaximumStackSize]
    7C810388 push eax                             ; RegionSize = MaximumStackSize
    7C810389 push 0                               ; ZeroBits = 0
    7C81038B lea  eax, [ebp+_BaseAddress]
    7C81038E push eax                             ; BaseAddress = 0;
    7C81038F push [ebp+hProcess]                  ; ProcessHandle
    7C810392 mov  [ebp+MaximumStackSize], ecx
    7C810395 call ebx                             ; NtAllocateVirtualMemory
    The system reserves the right address space for the stack. It reserves MaximumStackSize bytes starting from an address chosen by the system; the address is the first available address inside the virtual space. The chosen address is stored inside BaseAddress and it’s used to update the content of InitialTeb->StackAllocationBase field:

    7C81039F mov  edi, [ebp+InitialTEB]
    7C8103A2 mov  ecx, [ebp+_BaseAddress]
    7C8103A5 mov  eax, [ebp+MaximumStackSize]
    7C8103A8 and  [edi+INITIAL_TEB.PreviousStackBase], 0
    7C8103AB and  [edi+INITIAL_TEB.PreviousStackLimit], 0
    7C8103AF mov  [edi+INITIAL_TEB.AllocateStackBase], ecx
    The stack is created, there are 3 fields to set and for now the system updates the bottom of the stack only.
    7C8103B2 add  ecx, eax
    7C8103B4 mov  [edi+INITIAL_TEB.StackBase], ecx
    InitialTeb->StackBase = BaseAddress + MaximumStackSize
    The system sets up the stack area by giving the upper and lower bound. The initial stack value is StackBase ...
  5. Funny coded malware

    Some days ago I had the opportunity to check one of the last msn malware. I think there’s often something interesting inside a malware, no matter what it does and this is a perfect example!

    The malware is able to infect only right handed people! I’m not kidding...
    Among all the windows settings there’s one made for left handed people. The option I’m referring to is located under the Mouse control panel, labelled “Switch primary and secondary buttons”. It lets you exchange the functions performed by the right and left mouse button. Don’t know if this setting is usefull or not, most of the left handed friends I have are still using the mouse like a right handed. Maybe they don’t even know the existence of such an option. Anyway, look at this code:

    It’s a simple query on a registry key named SwapMouseButtons.
    result_value is sent back to the caller, and the caller checks the value. If the value is equal to 0×30 (right handed) the malware goes on running the rest of the code, but if the value is 0×31 (left handed) the malware ends immediately. All the nasty things performed by the malware are executed after this check, it means that a left handed won’t get infected!

    I’ve seen some malwares using SwapMouseButton function in the past, but never something like that. I bet the author is left handed and he wrote the check just to be sure to avoid a possible infection… I can’t think of anything else. Quite funny!!!

    The malware is not really interesting per se, but it has something I’ve never noticed before. It’s not a cool and dangerous new technique, but a coding behaviour. Look at the graph overview:

    The image represents the content of a malware procedure. Nothing strange per se, except the fact that it contains 657 instructions in it, too many for a simple malware. It’s a big routine and I was surprised at first because you can do a lot of things with so many instructions. I started analysing the code, nothing is passed to the routine and nothing is returned back to the original caller. I tought it should be an important part of the malware, but I was disappointed by the real content of the routine. After few seconds I realized what’s really going on: 657 lines of code for doing something that normally would require around 50 lines…
    The function contains a block of 17 instructions repeated 38 times. When I’m facing things like that I always have a little discussion with my brain. The questions are:
    - why do you need to repeat each block 38 times?
    - can’t you just use a while statement?
    - is this a sort of anti-disassembling trick?
    - can you produce such a procedure setting up some specific compiler’s options?

    The repeated block contains the instruction below:
    00402175    push 9                       ; Length of the string to decrypt
    00402177    push offset ntdll_dll        ; String to decrypt
    0040217C    push offset aM4l0x123456789  ; key: "M4L0X123456789"
    00402181    call sub_401050              ; decrypt "ntdll.dll"
    00402186    add  esp, 0Ch
    00402189    mov  edi, eax
    0040218B    mov  edx, offset ntdll_dll
    00402190    or   ecx, 0FFFFFFFFh
    00402193    xor  eax, eax
    00402195    repne scasb
    00402197    not  ecx
    00402199    sub  edi, ecx
    0040219B    mov  esi, edi
    0040219D    mov  eax, ecx
    0040219F    mov  edi, edx
    004021A1    shr  ecx, 2
    004021A4    rep movsd
    004021A6    mov  ecx, eax
    004021A8    and  ecx, 3
    004021AB    rep movsb
    It’s only a decryption routine, nothing more. The string is decrypted by the “call 401050″, the rest of the code simply moves the string in the right buffer.
    Ok, let’s try answering the initial questions.

    According to some PE scanners the exe file was produced by Microsoft Visual C++ 6.0 SPx.
    It’s possible to code the big procedure just using a loop (while, for, do-while) containing the snippet above. I don’t think the author used one of these statements because as far as I know it’s not possible to tell the compiler to explode a cycle into a sequence of blocks. At this point I have to options:
    - he wrote the same block for 38 times
    - he defined a macro with the block’s instructions repeating the macro for 38 times
    I won’t code something like that, but the macro option seems to be the most probable choice.
    Is it an anti-disassembling trick? My answer is no because it’s really easy to read such a code. You don’t have to deal with variables used inside a for/while; to understand what’s going on you only have to compare three or four blocks.
    I don’t have a valid answer to the doubt I had at first….

    Trying to find out some more info I studied the rest of the code. I was quite surprised to see another funny diagram.

    This time the image represents the content of the procedure used to retrieve the address of the API functions. Again, no while/for/do-while statement. The rectangle on the upper part of the image it’s a sequence of calls to GetProcAddress, and the code below it’s just a sequence of checks on the addresses obtained by GetProcAddress.
    It’s a series of:

    address = GetProcAddress(hDLL, "function_name");

    followed by a series of:

    if (!address) goto _error;

    Apart the non-use of a loop there’s something more this time, something that I think reveals an unusual coding style; tha author checks errors at the end of the procedure. I always prefer to check return values as soon as I can, it’s not a rule but it’s something that help you to avoid oversight and potential errors… The procedure has a little bug/oversight at the end, the author forgot to close an opened handle. Just a coincidence?
    Anyway, two procedures without a single loop. Seems like the author didn’t use any kind of loop for choice. In case you still have some doubts here’s another cool pictures for you:

    The routine inside the picture contains the code used to check if the API(s) are patched or not. The check is done comparing the first byte with 0xE8 and 0xE9 (call and jump). If the functions are not patched the malware goes on, otherwise it ends. As you can see no loops are used.

    In summary: it’s not jungle code, it’s not an anti-disasm code and it’s not a specific compiler setting. I think it’s only a personal choice, but I would really like to know why the author used this particular style.
    Do you have any suggestions?

    Beyond the coding style, the malware has some more strange things. As pointed out by *asaperlo*, the code contains a bugged RC4 implementation.
    It also has a virtual machine check. The idea is pretty simple, the malware checks the nick of the current user. If the nick is “sandbox” or “vmware” you are under a virtual machine…
    This malware spawns another one (it’s encrypted inside the file), it might be material for another post.

    That’s a funny coded malware for sure!
  6. Vmware snapshot and SSDT

    Some time ago I blogged about Vmware snapshots (http://zairon.wordpress.com/2007/08/31/find-out-hidden-files-comparing-vmwares-snapshots/) introducing a way to recognize hidden files by simply comparing two snapshots. I wanted to extend my research on the subject a little bit more, but I didn’t. I got the opportunity to put my hands on some snapshots again in these days. I haven’t anything on my mind, but I was surprised by some coincidences. Look at the information below:
    80544bc0: 804fc624 00000000 0000011c 804fca98
    80544bd0: bf995ba8 00000000 0000029a bf98f5f8
    80544be0: 00000000 00000000 00000000 00000000
    80544bf0: 00000000 00000000 00000000 00000000

    00544BC0: 24C6 4F80 0000 0000 1C01 0000 98CA 4F80 $.O………..O.
    00544BD0: A85B 99BF 0000 0000 9A02 0000 F8F5 98BF .[..............
    00544BE0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
    00544BF0: 0000 0000 0000 0000 0000 0000 0000 0000 ................


    First 4 lines are taken from Windbg while I was debugging an XP sp1 virtual machine running under Vmware; last 4 lines are taken from a saved Vmware snapshot (same os of course).
    Do you see anything useful? These are KeServiceDescriptorTable[0],[1],[2],[3] and they have of course the same bytes, but there’s something else. There’s a connection between the addresses on the first lines and the offsets on the second ones, just remove the first 2 digits from the address. Do you see it? Look here: 80544BC0/544BC0, 80544BD0/544BD0, 80544BE0/544BE0, 80544BF0/544BF0.

    Seems like the kernel memory is stored inside the snapshot. It’s not totally true indeed, there’s only a part of the kernel memory stored inside a Vmware’s snapshot. All the KeServiceDescriptorTable entries are present btw.
    SSDT is inside the snapshot I have and it’s complete; SSDT Shadow seems to be inside the snapshot too, but there’s no real connection between kernel memory/snapshot addresses and it’s not complete (it needs some more research btw).

    Is it only a coincidence? I tried with some XP machines and the result is the same, it’s possible to obtain real information of SSDT. According to Kayaker’s test it should work on win2k (don’t remember the service pack he was using. Thx K.).

    With this new information it’s pretty easy to code a SSDT revealer. I gave it a try and here is a result:

    You can use the program to display SSDT entries and to find out modified entries too by simply comparing an original snapshot with another one.

    To retrieve information from a snapshot you have to provide the address of KeServiceDescriptorTable[0] (something like 80544BC0, no “0x” prefix), and you have to select the OS of the virtual machine. After that you can:
    1. save an untouched SSDT using the button labelled “Create untouched SSDT”
    2. retrieve SSDT information from a snapshot by simply pushing the button labelled “Get snapshot SSDT”. Checking “Load untouched SSDT data” you can compare the original table (previously saved) with the one from the snapshot you’ll select. If a service has been changed you’ll read the word “YES” in the last column.

    I got the name of the services from this table: http://metasploit.com/users/opcode/syscalls.html
    I can’t test all the OS, if you find one or more errors drop me a mail.
    Following this method it’s also possible to get the list of the running processes/modules, more about this later.

    SSDT from snapshot available here: http://www.box.net/shared/static/bun81inksk.zip
  7. 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:
    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…
  8. 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.
  9. 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!
  10. Idc script and stack frame variables length

    Among all the precious information retrieved by Ida there’s something I always use when I need to study a target: stack frame. It’s quite useful when you want to see the list of parameters and local variables, but it would be great to see the size of each item. Yes, you can get the length but you have to calculate it each time. I sometimes need this kind of information, especially when I have to deal with fixed length buffers. I tried inspecting through some Ida’s menu without luck, it’s strange that Ida doesn’t provide such information so I decided to write a little idc script able to retrieve local *big* buffers. (If there’s an Ida hidden feature please tell me…)
    I wanted to attach the original script I wrote here, but I think it’s much more useful to explain some details about the functions I used leaving the script to you as an exercize. In this simple example I’ll show you how to find out the length of each item inside a stack frame. Let’s start with a simple function:

    The stack frame created by Ida is divided into some parts, it looks like a sequence of fields:
    - local variables
    - saved registers
    - return address
    - function parameters

    Looking at the picture above is pretty easy to locate local variables (ObjectAttributes, KeyValueInformationLength, ResultLength) and function parameters (Handle, ValueName). Moreover you can guess the length of each item. According to the four parts I mentioned above there are some more items that are not specified by Ida, I’m referring to “saved registers” and “return address”. If you look at the offset of each item you’ll surely find out something odd. Look at the gap between ResultLength and Handle: 0×0C bytes. 4 bytes are reserved for ResultLength variable, but there are 8 unreferenced bytes. It’s time to take a look at the stack frame window (ctrl-k):

    Here is the answer. Ida uses two special fields named ” r” and ” s”, the length of each field is 4 bytes. They are the “return address” and the “saved registers”.

    Ok, how to get the size of the items using an idc script? As you can see from the picture the stack frame looks like a structure definition, the idea is to read each item in sequence.
    #include <idc.idc>
    static main()
       auto id, i, firstM, lastM, address;
       auto mName, mSize, mFlag;
       address = 0×00013C92;        //    Address of the function to check
       id = GetFrame(address);
       firstM = GetFirstMember(id);
       lastM = GetLastMember(id);
          mName = GetMemberName(id,i);   // Get the name
          mSize = GetMemberSize(id, i);  // Get the size (in byte)
          mFlag = GetMemberFlag(id, i);  // Get the flag
          Message(”\n%s   %d   %x”, mName, mSize, mFlag);
    First of all I need to get the function frame structure. I use GetFrame, it returns the id of the function frame structure. It’s the first information to retrieve because you need the id when you’ll have to deal with the internal fields of the structure. Once you have the id you can start scanning the entire structure from the first till the last item. GetFirstMember and GetLastMember functions give you the first and the last offset. At this point you can retrieve all the information you need, in this example I get name, size and flag value from every item. The functions I used are GetMemberName, GetMemberSize and GetMemberFlag; pretty intuitive and easy to use. An output line will look like:
    ObjectAttributes   24   60000400
    where name=ObjectAttributes, size=24 and flag=60000400. Which kind of information are hidden inside the flag value? idc.idc file contains all the necessary definitions:
    #define FF_DATA 0x00000400L             // Data ?
    #define FF_STRU 0×60000000L             // Struct ?
    The field contains data and it’s a structure (OBJECT_ATTRIBUTES). And, what about Handle field?
    Handle   4   25500400
    Browsing idc.idc file you’ll get:
    #define FF_DATA  0x00000400L            // Data ?
    #define FF_0OFF  0×00500000L            // Offset?
    #define FF_1OFF  0×05000000L            // Offset?
    #define FF_DWRD  0×20000000L            // dword
    Ok, there’s only a little behaviour to fix inside the script. Run the script and you’ll see some repeated lines, here’s a snippet taken from the output:
    ObjectAttributes   24   60000400
    ObjectAttributes   24   60000400
    ObjectAttributes   24   60000400
    KeyValueInformationLength   4   20000400
    KeyValueInformationLength   4   20000400
    KeyValueInformationLength   4   20000400
    KeyValueInformationLength   4   20000400
    ResultLength   4   20000400
    ResultLength   4   20000400
    ResultLength   4   20000400
    Ida repeats the field information on every byte of the field itself. To display only one item per field you can update the ‘i’ variable inside the for statement, add the next line after the Message instruction:
    i = i + GetMemberSize(id, i) - 1;
    The example ends here. It works almost fine, but it goes into an infinite loop with certain functions. From what I’ve seen the problem occours when Ida is not able to understand which kind of variable has been declared. Look at this simple example:
    INIT:BF9B0786 var_1A4         = dword ptr -1A4h
    INIT:BF9B0786 var_18E         = byte ptr -18Eh
    INIT:BF9B0786 var_4           = dword ptr -4
    var_18E is marked as byte but there’s a big gap between var_18E and var_4. Stack frame windows reveals an interesting thing:
    -0000018E var_18E         db ?
    -0000018D                 db ? ; undefined
    -0000018C                 db ? ; undefined
    -0000018B                 db ? ; undefined
    -0000018A                 db ? ; undefined
    -00000189                 db ? ; undefined
    -00000188                 db ? ; undefined
    -00000187                 db ? ; undefined
    -00000186                 db ? ; undefined
    -00000185                 db ? ; undefined
    -00000184                 db ? ; undefined
    -00000183                 db ? ; undefined
    var_18E length is 394 byte and as you can see Ida doesn’t collapse the definition into a single line, but it “explodes” the variable through the 394 bytes.
    How can you solve this problem? You can use my initial script adding some more checks. Nothing hard of course, you have all the necessary functions, just use your brain defining a good algo. Hint: take a look at the value returned by GetMemberSize.

    Once you have a working script you can extend it covering all the declared functions and filtering the information you’ll get.

    Good luck and let me know if you are not able to solve this exercize!!!
  11. HP printer and cpu at 100%

    I’ll be in New York City from Thursday, I have too many things to prepare right now, and I don’t have time to end this story. Anyway, I thought it might be interesting to write something about this strange behaviour. It’s only a sort of preview, I hope to complete it in the near future.

    I have a new printer, it’s an hp c4380. Don’t know if it’s good or not, I don’t print too much. It was really easy to install and it works fine for me, I have nothing to complain about it… until some days ago when I noticed something strange. When the system starts, I sometimes happen to see the cpu at 100%:

    As you can see it happens when the system starts. It’s one of the starting process for sure. I opened ProcessExplorer just to have an idea about what’s going on:

    Svchost is used to load one or more services, there’s a specific list of services to load inside the registry. The problem doesn’t reside in svchost process, but it’s inside the specific loaded service. How to find it? ProcessExplorer is a great tool, it gives out a lot of information. Just click on the process item and you will have all the necessary information about the process. I’m interested in the command line section which is: “C:\WINDOWS\system32\svchost.exe -k HPService”. Ok, the problem should be inside HPService. To locate the name of the dll you can browse through the process properties, you’ll easily find out the dll: HPSLPSVC32.DLL

    This service belongs to hp printer and it’s used to check hp’s peripherals connected through the net. The service is automatically started (have a look at services.msc utility). I made some tries discovering that the problem arises when one or more computers connected to the lan are offline. I’m pretty sure there’s an error inside the dll, but how to find out where the problem is located at? In case like that, when the cpu works at 100%, the problem resides inside a loop. The process is waiting for something that won’t be received; it’s impossible to quit from it due to of a programming error. It could be an error on a variable initialization/update but there are many possibilities, there’s not a general explaination.

    What I did is to attach a debugger to the right svchost process hinstance. It’s pretty easy to locate the guilty loop, you only have to break on dll access. Here’s a snippet taken from the loop I was talking before:
    10025D00  mov    eax, dword_100AC550
    10025D05  mov    ecx, [edi+4]
    10025D08  push   eax ; dwMilliseconds: 1000 ms
    10025D09  push   ecx ; hHandle
    10025D0A  call   ebx ; WaitForSingleObject
    10025D0C  mov    edx, [edi+10h]
    10025D0F  push   edx ; hEvent = 0
    10025D10  mov    esi, eax ; eax = WAIT_FAILED
    10025D12  call   ebp ; SetEvent
    10025D14  cmp    esi, WAIT_TIMEOUT
    10025D1A  jnz    short loc_10025D27
    10025D1C  mov    eax, [edi]
    10025D1E  mov    edx, [eax+24h]
    10025D21  mov    ecx, edi
    10025D23  call   edx ; call sub_100255E0
    10025D25  jmp    short loc_10025D00
    10025D27  cmp    esi, WAIT_FAILED
    10025D2A  jnz    short loc_10025D3A
    10025D2C  mov    eax, dword_100AC550
    10025D31  push   eax ; dwMilliseconds
    10025D32  call   ds:Sleep
    10025D38  jmp    short loc_10025D00
    Well, as you can see from the comments there are two problems:
    1. WaitForSingleObject returns WAIT_FAILED
    2. SetEvent’s parameter is 0

    I tried to call GetLastError after the two calls and the result was an ERROR_INVALID_HANDLE system error code. Pretty obvious eh!
    I don’t know where to look for now, an error on CreateEvent’s return value could be an answer. After a quick glance everything seems to be ok, but I need to check carefully.

    The problem occours to many people out there. It was reported on HP forum support in March 2007, but the problem still exists. To solve (momentarily) it, it’s pretty easy: just set the service from automatic to manual… Anyway it could be interesting to find out where the problem resides, I’ll try to check when my trip will end.
  12. Dvd movie and easter egg

    I like to go to the cinema, I adore movies. I have a lot of dvd movies at home. Special features included in almost all dvd are something I like particularly. What I dislike are the easter eggs included in the disc. There are often small and stupid clips behind easter eggs. They are nowadays documented everywhere around the net, but the question is: how did they find them?

    The common way is trying to push every buttons on your remote control hoping to see something strange around the dvd menu. This is the most easiest way, you have only to spend some time with a remote control in your hand. Otherwise, you can try inspecting the files stored inside the dvd. I don’t have any experience with this kind of things so I did some searches on the net. From all the programs I tried I was impressed by one: PgcEdit. As stated in the documentation “PgcEdit offers an easy to understand view of the DVD’s programming. It allows you to edit, via easy to use GUIs, all the DVD’s commands with their legal values, without any limitations except those imposed by the DVD standard.
    There’s a little problem, I have no idea about the dvd standard… Anyway, I gave it a try.

    When you open a disc PcgEdit extracts all the necessary information filling two edit boxes. The image below represents a snippet taken from one of the two boxes.

    Don’t know what you think but these are only some meaningless items for me. When you click on an item the other box is filled with some other information which are much more understandable. Here are some of them:

    I’m not able to fully understand the instructions above, but I can get the general meaning of each line. It’s like a dead list produced by a disassembler, a series of commands.

    Reading through the help I’ve found something interesting, PgcEdit has a debugger inside; it lets you see what happens when a dvd is launched. I don’t know the meaning of the information retrieved by PgcEdit, but I do know how to use a debugger, and this one seems to be really simple. I’ll try to find out an easter egg using PgcEdit’s debugger. I only spent some time on this debugger and I don’t know anything about dvd standard, anyway I’ll try to explain my adventure using the right words.

    The dvd film I’m going to inspect is titled Big fish, aTim Burton’s movie. An easter egg could be everywhere inside the dvd, I’ll try to find something inside the main menu title which is showed in the next image:

    It’s an animated menu and you can navigate through the 6 options, from “Play movie” to “Trailers”, seems like you can’t move the cursor outside these items.

    To start a debugging session you have to select “Trace mode” from one of the PgcEdit’s menu items (using Ctrl-T is much more easy). The debugger is really simple but it has almost everything. It’s possible to set a breakpoint on GPRM (Global Parameter Registers), on SPRM (System Parameter Registers), pre/post PGC (Program Chain), all menus and all titles. It’s possible to watch all the registers and log almost everything. It’s the only dvd debugger I have tried so far, but it seems to be quite complete.

    When you are in Trace mode the debugger is stopped at the first instruction:
    1 (JumpSS) Jump to VMGM PGC 1
    which is inside “VMG, First Play PGC” item. VMGM stands for Video Manager Menu.
    The dvd video structure is divided into some levels, I’m at the the first one and it’s used to play an introductive video or some preliminary information. After that the main menu appears. In this case there is nothing before the main menu and the instruction (it’s clearly a jump instruction to “VMGM PGC 1″) will bring me to the dvd main menu.

    LU should be Language Unit and I think the number inside brackets represents the item’s length, 14 seconds.

    How to proceed? I tried stepping some commands but it’s not so interesting so it’s better if you use some clever breakpoints. Right click on an item from the left box and a popup menu will appear. From this popup menu it’s possible to set a breakpoint on the selected item. When the program flow reaches the item the debugger should break. There are many items inside the box, they are divided into 3 groups:
    - VMGM
    - VTSM
    - VTST
    How to identify the right item? The main menu’s length is 52 seconds so I did a scan over the items trying to locate the one with length equals to 52. There are some items with the same length (52 seconds); I’m not totally sure about the meaning of the 0:52 value so I decided to take another way. Spying through the debugger’s menu I found an interesting option: “Break at all menus”. When you set this option the debugger will break every time it encounters a menu. I had 3 breaks and then a new box appeared (it doesn’t mean that there are 3 menu to be shown). The box contains the information about the main menu. The breaks occurred on these items:

    - VMGM LU 1 (en), 1 (0:14)
    - VTSM 4, LU 1 (en), 1 (dummy) RootM
    - VTSM 4, LU 1 (en), 6 (0:52) 16b.

    VTSM stands for Video Title Set Menu and it contains all the information about a specific menu. This one seems to be the menu I was looking for and now I’m pretty sure about the fact that 52 is the length (in seconds) of the animated menu. When the time reaches 52 the animated menu starts again, like an infinite loop. So, I’m interested in the last entry, if you click on this item you’ll see the commands inside the dead list box. There are some pre and post commands; pre commands are executed before the reproduction (post commands are executed after…):

    “gprm(i)” refers to a register, there are 16 Global Parameter Registers and they can contain a value in the 0/65535 range. From what I have seen they are often filled with SPRM values; there are 24 System Parameter Registers and they contain the current player settings. That’s why gprm registers get information from sprm registers, the dvd internal programming code needs to know where is running on.
    The words inside brackets (mov, and, or) define the operation. i.e.: Instruction number 2 is used to store 0 into register 8, pretty simple. Ok, back to the box now:

    This is the box that is shown, it’s the main menu (I edited the image adding the text). As you can see it shows the *gui* without pictures of course. It’s pretty easy to identify the buttons at the bottom of the image, they represent the 6 options. There are two more buttons (7 and 8) at the top of the picture, btw. You can navigate through the buttons using the keyboard or mouse, the highlighted button is the current selected one. When you switch from a button to another PgcEdit’s debugger is able to show what kind of commands will be executed, you can see the next instruction that will be performed. After some tries I understood how to reach button number 8, just click on keyboard’s key-up from button 5. When you switch to button number 8 nothing is shown; some commands are executed but I had the impression that it’s only a check routine used to see which kind of button has been pressed. Button 7 is another story because when you press it the current post commands are executed. Anyway, without looking at the post commands it’s obvious that there’s something behind button number 7, which is our easter egg for sure!
    Why did they (dvd’s authors) use button number 8? As far as I know there aren’t dvd player with a mouse control, if you want to move through the menu you can only use your remote control. With a remote control you have 4 direction’s buttons and you can move the pointer from a voice to another using them. Button number 8 is a bridge from button number 5 to 7. I think it’s used because they wanted to hide the easter egg a little bit more.

    It’s time to see the hidden feature, load the film with your preferred player. Move the pointer over the hat and a red star magically appears. Click and enjoy the clip (nothing special btw).

    My dvd adventure ends here, It was a nice unusual debugging session. Is there another way to discover an easter egg? Don’t know and I don’t care about it, I think I’ll check for easter eggs browsing the net in the future… haha!
  13. Windbg “dt” output converter

    How many times did you create a structure starting from Windbg's dt command output? It sometimes happens especially if you use Ida or if you need to code something. It’s something that makes me feel unhappy. It’s a boring job for sure, particularly when you have to deal with big structures (i.e. ethread). There are some ready made definitions online, but there’s not a standard definition for a single structure. Most of the time it depends on the OS you are running on.

    All I want to do is to convert dt’s output into a struct definition. The output to convert is something like (obtained by Windbg using “dt _list_entry” command):
    +0×000 Flink            : Ptr32 _LIST_ENTRY
    +0×004 Blink            : Ptr32 _LIST_ENTRY
    And this is what I want to generate:
    typedef struct _LIST_ENTRY
    struct _LIST_ENTRY* Flink;    // 0×000
    struct _LIST_ENTRY* Blink;    // 0×004
    I’m not a Windbg guru and I don’t know if there is a quickest way, so the idea is to write something able to perform (almost all) the convertion.

    The gui is pretty simple, it contains two edit boxes and two buttons, nothing more. The convertion process starts by pressing the “Convert” button, the program converts the data stored inside the clipboard. The left box will be filled with the clipboard’s contents while the other box will contain the converted structure. What to store inside the clipboard? Look at the picture below:

    Selected text is what you have to store into clipboard, everything starts from ‘_’ character. Once you have saved the text you can convert the structure. Here’s the result:

    The edit box is editable, it’s necessary because most of the time it’s hard to predict the right type to display. I don’t know if it’s possible to perform a perfect convertion, the aim of this tool is to speed up the convertion process. With some minor changes you should be able to obtain a perfect convertion.

    This tool is not totally complete, I have some more things to add. As usual I didn’t test it too much because I prefer to fix it when a bug occours. Anyway, it seems to work fine and you can contact me for comment/criticism/suggestion/etcetc.

    ps. HAPPY NEW YEAR!!!
    Attached Thumbnails Attached Files
  14. Beware of int 2c instruction

    In the last days I played a little with Win32.Virtob virus, thanks to Kayaker for passing it out to me. It’s a nice virus with some interesting tricks. You can read a detailed analysis made by Kayaker from his recent blog entries.
    In this post I’m not going to talk about the malware itself, I simply focus my attention on an single instruction: int 2c. The instruction is located in the beginning of the virus and I spent some time on it trying to answer Kayaker’s question: is “int 2c” used as an antidebug trick? I don’t have an answer for the question, but after some tries I came up with something that can be interesting.

    execution changes the content of some registers, but one of them (in particular edx) is always changed in the same way. edx contains the address of the instruction that follows the int 2c instruction.
    100: mov edx, 80   <– edx = 0×80
    105: int 2c   <– it changes edx value
    107: xor eax, eax   <– here: edx = 0×107
    Pretty weird. To know why you have to look at ntoskrnl code (starting from KiSetLowWaitHighThread), it’s pretty easy to find out why. Here’s the last part of the int2c code:
    804d4f95 pop     edx   <-- edx is changed here
    804d4f96 add     esp,8
    804d4f99 pop     ecx
    804d4f9a sti
    804d4f9b sysexit
    Sysexit is the key of this snippet. The function is used when there’s a transition from ring0 to ring3 code. ring3.eip is updated with ring0.edx value. That’s why edx contains the magic value, if you want to go back into ring3 world you have to put the return address into edx.
    Is this fact important? Not really, per se. There’s a interesting use of this behaviour btw, infact it could be used inside an obfuscation engine or as an anti Ollydbg trick.

    Look at this simple and stupid sample I wrote (attached at the end of the post):
    00401000 LEA EDX,DWORD PTR DS:[403000]      ; 403000 -> "easy sample"
    00401006 PUSH EDX
    00401007 INT 2C
    00401009 PUSH 0                             ; Style = MB_OK|MB_APPLMODAL
    0040100B INT 2C
    0040100D SUB BYTE PTR DS:[EDX+6],9          ; 403006 = ‘X’
    00401011 LEA EAX,DWORD PTR DS:[403015]      ; 403015 -> “I’m the caption”
    00401017 PUSH EAX                           ; Title_1: “I’m the caption”
    00401018 INT 2C
    0040101A XOR BYTE PTR DS:[EDX+6],1D         ; 403006 = ‘E’
    0040101E LEA EAX,DWORD PTR DS:[403038]      ; 403038 -> “I’m the text”
    00401024 PUSH EAX                           ; Text_1: “I’m the text”
    00401025 INT 2C
    00401027 PUSH 0                             ; hOwner = NULL
    00401029 INT 2C
    0040102B CALL <JMP.&user32.MessageBoxA>     ; MessageBoxA, display the 1° message box
    00401030 POP EDX                            ; edx -> “easy sEmple”
    00401031 PUSH 0                             ; Style = MB_OK|MB_APPLMODAL
    00401033 PUSH msgbox.0040300C               ; Title_2: “Int2c…”
    00401038 PUSH EDX                           ; Text_2: “easy sEmple” (”sEmple” and not “sample”)
    00401039 PUSH 0                             ; hOwner = NULL
    0040103B CALL <JMP.&user32.MessageBoxA>     ; MessageBoxA, display the 2° message box
    00401040 PUSH 0                             ; ExitCode = 0
    00401042 CALL <JMP.&kernel32.ExitProcess>   ; ExitProcess
    This is the static analysis of the snippet above, it’s not right! Try running the attached exe (I can assure you it’s not dangerous) and you’ll see the real behaviour of this piece of code. It displays two message boxes with the real messages, the first one with:
    caption: “Int2c…”
    text: “Obfusction sample”
    and the second with:
    caption: “Int 2c…”
    text: “easy sample” (it’s not “sEmple”)

    Why? Well, it’s pretty simple:
    0040100B  CD 2C          INT 2C                          ; int2c changes edx value
    0040100D  806A 06 09     SUB BYTE PTR DS:[EDX+6],9       ; edx = 40100D, it changes 403015 into 40300C
    00401011  8D05 15304000  LEA EAX,DWORD PTR DS:[403015]   ; eax = 40300C, 40300C -> “Int2c…”
    Execution of int 2c changes edx value, and if you don’t know anything about it you’ll have a wrong static analysis. It’s a simple code obfuscation, but you have to take care of it for sure.

    Now, try loading the attached exe file into Ollydbg. These are the results I got from my tests based on an XP sp1 and sp2 machines.

    Ollydbg and XP sp1
    The file runs fine when you launch it with F9 key, it shows the real messages.
    The problems arise when you step through the code with “step into”(F7) or “step over”(F8) modes. No matter if you are stepping with F7 or F8, executing an int 2c instruction the debugger won’t break unless you have inserted a bpx onto one of the next instructions. A perfect trick for those who don’t know how to deal with it, you step the instruction and the malware performs all his nasty operations…

    Ollydbg and XP sp2
    The file runs fine when you launch it with F9 key, it shows the real messages.
    F7 and F8 modes have the same behaviour, Ollydbg stops at the second instruction after “int 2c“; the problem is that edx value is not updated with the correct address value. Here’s what happen:
    00401006 PUSH EDX                    ; edx = 403000
    00401007 INT 2C                      ; F7 or F8 here and Ollydbg
    00401009 PUSH 0                      ; will break at 40100B
    0040100B INT 2C                      ; F7 or F8 here and Ollydbg will
    0040100D SUB BYTE PTR DS:[EDX+6],9   ; break here due to the exception:
    ; “Access violation when writing to [00000005]”

    The exception occours because (at 40100D) edx value is 0xFFFFFFFF. edx value was changed by “int 2c” at 40100B.
    The only way to obtain a correct edx value is to use F9 setting a bpx at 40100D.

    I tried the same exe with Ida debugger on a XP sp2 machine. You can step using F8 without problem, but not with F7 because you’ll get the same access violation.

    I think it’s definitely something to take care of, what do you think?

    (File available here: http://www.box.net/shared/static/zebzmt8srt.zip)
  15. 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:
    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:

    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:

    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:

    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.

    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:

    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:

    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:

    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);
    else if (LOWORD(wParam) == VK_ESCAPE)
    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

Page 1 of 2 12 LastLast