All Blog Entries

  1. Backdoor.Win32.UltimateDefender Reverse Engineering

    Hi,

    I've released Backdoor.Win32.UltimateDefender.gtz Reverse Engineering:

    http://evilcry.netsons.org/tuts/Mw/Backdoor-UltimateDefender.pdf

    Regards,
    Giuseppe 'Evilcry' Bonfa'
    Categories
    Reverse Engineering
  2. Qt Internals & Reversing

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

    Qt Internals & Reversing

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

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

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

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

    Categories
    Uncategorized
  3. 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:
    Code:
    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
    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Ö
    Code:
    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:
    Code:
    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Ö
    Code:
    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:
    Code:
    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.
    Categories
    Uncategorized
  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.
    Code:
    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 :
    Code:
    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
    4010AC MOV EAX,DWORD PTR DS:[EDX]   ; CRASH!!!
    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.
    Code:
    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:
    Code:
    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:
    Code:
    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:
    Code:
    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:
    Code:
    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:

    Code:
    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.
    Code:
    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 ...
    Categories
    Uncategorized
  5. Trojan.Zhelatin.pk

    Hello,

    Here a little overview of Trojan.Zhelatin.pk one of the first versions of this Malware.

    http://evilcry.netsons.org/tuts/Mw/Zhelatin.pdf

    Have a nice Read

    Regards,
    Giuseppe 'Evilcry' Bonfa'
    Categories
    Reverse Engineering
  6. On Analysis of Client-Server Software Applications

    Hi,

    Initially was a closed paper, now I rewritten it a bit. Here a little Abstract:

    The principal objective of this paper is to give a good detailed
    panoramic view of the Security aspects involved in Client-Server based
    Applications. The panoramics will be seen from the point of view of a
    Reverse Engineer that should be aware of the Security Problems that are
    directly releated to the Client-Server Software Structure.


    and here the link:

    http://evilcry.netsons.org/tuts/CSAnalysis.pdf

    Regards,
    Evilcry
    Categories
    TechLife , (In)Security
  7. Interesting Kernel32 Constant

    while i was doing some Research i stumpled on something which i found very interesting , i was attempting to Change the Location of Peb->ProcessHeap , which i did successfully , but the application still continued to use the Old Heap , which i dident want , so i startet digging and came across something ive never seen before.

    in the Api LocalAlloc i found that it keeps a Constant copy of Peb->ProcessHeap inside Kernel32 itself.

    7C809A63 FF35 A453887C PUSH DWORD PTR DS:[7C8853A4] -> contains copy of Peb->ProcessHeap

    so modifying the PEB only had limited success , but changeing this Value aswell . fixed my problem.

    i guess pretty clearly this Push ..should have been a call GetProcessHeap() instead , or somebody else has a view why windows would do like this ?

    enjoy

    Updated October 11th, 2008 at 07:39 by Arcane

    Categories
    Uncategorized
  8. custom gpa spy

    http://forums.accessroot.com/index.php?showtopic=7513

    read above topic to know how this idea was born well actually this idea was in my mind for almost a two years, but never found it useful to fully develop working code, but after reading this topic, and comments at posted link, I've decided to give it a go status.

    In short : at above link, you will find link to the other site which has statistic of used functions in common files. On other hand, many are missed due to GetProcAddress, and not to mention many being missed due to custom GetProcAddress. So how to spy custom GetProcAddress!?!? well read the code and you will see.

    This could be useful for protection profiling, and there are some other ways which I would use to deal with this, but for now, it seems ok, just so you get the basic idea. code is really messy, as I hate writing ring3 debuggers...

    full code and sample binary:
    http://deroko.phearless.org/export_log.rar
    Categories
    Uncategorized
  9. Debugger Detection Via NtSystemDebugControl

    Hi,
    NtSystemDebugControl() is a really powerful undocumented function, that allows you Direct Manipulation of System's Structures.

    Here a definition of NtSystemDebugControl:

    http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/Debug/NtSystemDebugControl.html

    The use of this function is only limited to the fancy of the coder

    I've rewritten some basical Anti Debugging Techniques with Direct Structure Reading with NtSystemDebugControl. Obviously there are shorter ways to implement these Anti-Dbg Apps, but I think that more reimplementations exists and more are possibilities to trick an attacker, that may not know/understands the application..especially if embedded in many..many.. Junk Code

    Here you can download the Source Code sample:

    http://evilcry.netsons.org/other/ntsd.zip

    Have a nice Day,
    Evilcry
  10. POP SS and Debuggers

    This little trick is very interesting, my first encounter with it was in a commercial protection, it left me wondering why a Push / Pop SS would implicit execute the next instruction without the Debugger knowing of it, i.e. raising a single-step exception, so Iíve decided to look into it and try to figure out why, and I believe I have found the explanation , but first let me show you how this technique can be used to detect debuggers relying on the Single Step flag for tracing.

    If a debugger executes something like this:

    PUSHFD -> push Efflags to Stack .

    debuggers such as Olly is kind enough to ďshadowĒ itself, And clean the result produced by this instruction and removing the trap flag from the EFflags pushed to stack.

    But if itís done like this:

    Push ss
    pop ss
    pushfd

    Olly will not remove the trap flag, which is very interesting and leaves it very vulnerable to trace detection. The Explanation seems to be pretty straight forward if you check out the Intel manuals and look up pop , you will find a passage similar to this :

    A POP SS instruction inhibits all interrupts, including the NMI interrupt, until after
    Execution of the next instruction. This action allows sequential execution of POP SS
    And MOV ESP, EBP instructions without the danger of having an invalid stack during
    An interrupt1. However, use of the LSS instruction is the preferred method of loading
    the SS and ESP registers.

    Well most of this can be boiled down to , if POP SS is executed , the CPU will prevent triggering of interrupts , as to avoid corruption of the stack. So why on earth is this affecting us when we are tracing using the single-step flag, well simply because when the Single-step flag is set , it triggers and interrupt in the CPU , but when a POP SS is executed it wonít trigger interrupts before it has executed the next instruction after it , and thus olly will never get a single-step exception for the PUSHFD and wonít know it has been executed , and thus wont clean out the trap-flag and leave us vulnerable to detection.

    Circumventing this trick , is tricky since simply patching it out is easy , but if implementet correctly it can prevent tracing of your code very effectively and be a pain in the ass.

    Comments and suggestions , are always welcome

    Updated August 21st, 2008 at 15:16 by Arcane

    Categories
    Uncategorized
  11. Fighting Oreans' VM (code virtualizer flavour)

    If you don't know what code virtualizer is, or how it works, you should read this first:
    http://rapidshare.com/files/16968098/Inside_Code_Virtualizer.rar
    (Inside Code Virtualizer by scherzo)

    Now, as you probably already know from paper by scherzo , one possible way recover virtualized code is to identify each mutated handler (find corresponding non-mutated version). After this done, we can trace virtual opcodes and "decompile" them to VM instructions. Having "clean" decompiled output, we can translate it to x86 assembly. I consider the last step, to be simple "find and replace" job with flex/yacc.

    The problem is, oreans' vm obfuscation engine can be a bitch. Consider this piece of code:

    Code:
    	push ebx 
    	mov ebx 0F06h
    	inc ebx 
    	shr ebx 15h
    	push ecx 
    	mov ecx 6156h
    	xor ebx ecx
    	pop ecx 
    	add ebx 4114h
    	shl ebx 7
    	push ecx 
    	mov ecx 51351Ch
    	xor ebx ecx
    	pop ecx 
    	add ebx edi
    	mov eax [ebx]
    	pop ebx 
    	push 67E0h 
    	mov [esp] edx
    	mov edx 1
    	and eax edx
    	mov edx [esp]
    	push edx 
    	mov edx esp
    	add edx 4
    	add edx 4
    	xchg edx [esp]
    	pop esp 
    	or eax eax
    	push eax 
    	mov eax 3B02h
    	not eax 
    	push ecx 
    	mov ecx 0FFFFC3FFh
    	sub eax ecx
    	pop ecx 
    	and [edi+1Ch] eax
    	mov eax [esp]
    	add esp 4
    	push 3328h 
    	mov [esp] ebx
    	mov ebx [esp]
    	push ecx 
    	mov ecx esp
    	add ecx 4
    	add ecx 4
    	xchg ecx [esp]
    	pop esp
    It's one of VM's handlers. Can you tell what it does? Me neither, so let's try to deobfuscate this crap.

    It turns out that simple strategies like contant folding (http://en.wikipedia.org/wiki/Constant_folding), dead code elimination (http://en.wikipedia.org/wiki/Dead_code), peephole optimisation (find and replace :P) plus some stack cleaning , suffice to recover obfuscated code:

    Code:
    NEW = 47, OLD = 0, -47 lines removed
    ################################ NEXT ROUND ###########################
    ################################ original
    push ebx 
    mov ebx 00000f06 
    inc ebx 
    shr ebx 00000015 
    push ecx 
    mov ecx 00006156 
    xor ebx ecx 
    pop ecx 
    add ebx 00004114 
    shl ebx 00000007 
    push ecx 
    mov ecx 0051351c 
    xor ebx ecx 
    pop ecx 
    add ebx edi 
    mov eax [ebx ] 
    pop ebx 
    push 000067e0 
    mov [esp ] edx 
    mov edx 00000001 
    and eax edx 
    mov edx [esp ] 
    push edx 
    mov edx esp 
    add edx 00000004 
    add edx 00000004 
    xchg edx [esp ] 
    pop esp 
    or eax eax 
    push eax 
    mov eax 00003b02 
    not eax 
    push ecx 
    mov ecx ffffc3ff 
    sub eax ecx 
    pop ecx 
    and [edi 0000001c ] eax 
    mov eax [esp ] 
    add esp 00000004 
    push 00003328 
    mov [esp ] ebx 
    mov ebx [esp ] 
    push ecx 
    mov ecx esp 
    add ecx 00000004 
    add ecx 00000004 
    xchg ecx [esp ] 
    pop esp 
    ################################ after constant propagation and folding
    push ebx 
    mov ebx 00000000 
    push ecx 
    mov ecx 00006156 
    xor ebx 00006156 
    pop ecx 
    add ebx 00004114 
    shl ebx 00000007 
    push ecx 
    mov ecx 0051351c 
    xor ebx 0051351c 
    pop ecx 
    add ebx edi 
    mov eax [ebx ] 
    pop ebx 
    push 000067e0 
    mov [esp ] edx 
    mov edx 00000001 
    and eax 00000001 
    mov edx [esp ] 
    push edx 
    mov edx esp 
    add edx 00000004 
    add edx 00000004 
    xchg edx [esp ] 
    pop esp 
    or eax eax 
    push eax 
    mov eax ffffc4fd 
    push ecx 
    mov ecx ffffc3ff 
    sub eax ffffc3ff 
    pop ecx 
    and [edi 0000001c ] eax 
    mov eax [esp ] 
    add esp 00000004 
    push 00003328 
    mov [esp ] ebx 
    mov ebx [esp ] 
    push ecx 
    mov ecx esp 
    add ecx 00000004 
    add ecx 00000004 
    xchg ecx [esp ] 
    pop esp 
    ################################ after dead code elimination
    push ebx 
    mov ebx 00000000 
    push ecx 
    xor ebx 00006156 
    pop ecx 
    add ebx 00004114 
    shl ebx 00000007 
    push ecx 
    xor ebx 0051351c 
    pop ecx 
    add ebx edi 
    mov eax [ebx ] 
    pop ebx 
    push 000067e0 
    mov [esp ] edx 
    and eax 00000001 
    mov edx [esp ] 
    push edx 
    mov edx esp 
    add edx 00000004 
    add edx 00000004 
    xchg edx [esp ] 
    pop esp 
    or eax eax 
    push eax 
    mov eax ffffc4fd 
    push ecx 
    sub eax ffffc3ff 
    pop ecx 
    and [edi 0000001c ] eax 
    mov eax [esp ] 
    add esp 00000004 
    push 00003328 
    mov [esp ] ebx 
    mov ebx [esp ] 
    push ecx 
    mov ecx esp 
    add ecx 00000004 
    add ecx 00000004 
    xchg ecx [esp ] 
    pop esp 
    ################################ after peephole optimisation
    push ebx 
    mov ebx 00000000 
    push ecx 
    xor ebx 00006156 
    pop ecx 
    add ebx 00004114 
    shl ebx 00000007 
    push ecx 
    xor ebx 0051351c 
    pop ecx 
    add ebx edi 
    mov eax [ebx ] 
    pop ebx 
    push edx 
    and eax 00000001 
    pop edx 
    or eax eax 
    push eax 
    mov eax ffffc4fd 
    push ecx 
    sub eax ffffc3ff 
    pop ecx 
    and [edi 0000001c ] eax 
    pop eax 
    push ebx 
    pop ebx 
    ################################ after stack cleaning
    mov ebx 00000000 
    xor ebx 00006156 
    add ebx 00004114 
    shl ebx 00000007 
    xor ebx 0051351c 
    add ebx edi 
    mov eax [ebx ] 
    and eax 00000001 
    or eax eax 
    mov eax ffffc4fd 
    sub eax ffffc3ff 
    and [edi 0000001c ] eax 
    NEW = 11, OLD = 47, 36 lines removed
    ################################ NEXT ROUND ###########################
    ################################ original
    mov ebx 00000000 
    xor ebx 00006156 
    add ebx 00004114 
    shl ebx 00000007 
    xor ebx 0051351c 
    add ebx edi 
    mov eax [ebx ] 
    and eax 00000001 
    or eax eax 
    mov eax ffffc4fd 
    sub eax ffffc3ff 
    and [edi 0000001c ] eax 
    ################################ after constant propagation and folding
    mov ebx 0000001c 
    add ebx edi 
    mov eax [ebx ] 
    and eax 00000001 
    or eax eax 
    mov eax 000000fe 
    and [edi 0000001c ] 000000fe 
    ################################ after dead code elimination
    mov ebx 0000001c 
    add ebx edi 
    mov eax [ebx ] 
    and eax 00000001 
    or eax eax 
    and [edi 0000001c ] 000000fe 
    ################################ after peephole optimisation
    mov ebx 0000001c 
    add ebx edi 
    mov eax [ebx ] 
    and eax 00000001 
    or eax eax 
    and [edi 0000001c ] 000000fe 
    ################################ after stack cleaning
    mov ebx 0000001c 
    add ebx edi 
    mov eax [ebx ] 
    and eax 00000001 
    or eax eax 
    and [edi 0000001c ] 000000fe 
    NEW = 5, OLD = 11, 6 lines removed
    ################################ NEXT ROUND ###########################
    ################################ original
    mov ebx 0000001c 
    add ebx edi 
    mov eax [ebx ] 
    and eax 00000001 
    or eax eax 
    and [edi 0000001c ] 000000fe 
    ################################ after constant propagation and folding
    mov ebx 0000001c 
    add ebx edi 
    mov eax [ebx ] 
    and eax 00000001 
    or eax eax 
    and [edi 0000001c ] 000000fe 
    ################################ after dead code elimination
    mov ebx 0000001c 
    add ebx edi 
    mov eax [ebx ] 
    and eax 00000001 
    or eax eax 
    and [edi 0000001c ] 000000fe 
    ################################ after peephole optimisation
    mov ebx 0000001c 
    add ebx edi 
    mov eax [ebx ] 
    and eax 00000001 
    or eax eax 
    and [edi 0000001c ] 000000fe 
    ################################ after stack cleaning
    mov ebx 0000001c 
    add ebx edi 
    mov eax [ebx ] 
    and eax 00000001 
    or eax eax 
    and [edi 0000001c ] 000000fe
    Well almost . Above trash is the verbose output of my little "cleaner" tool. Cleaner is usable, it'll give nice results for most of included code samples. In handlers.clean folder (see link at bottom) there are nonmutated versions of CV handlers. After deobfuscation, few heuristics can be applied to match deobfuscated and clean versions: edit distance / rare instruction matching (for example rol, ror, rcr are rare and show up only in one handler).

    The problem is, I got bored with all of this, so if anyone would like to help, I will be more than happy

    Here is the code:
    http://www.orange-bat.com/oreans.rar

    compile with make, will work without problems under cygwin. it should work under linux. to use rip_handlers.py you will need idapython.

    There are some bugs in my code, beware .

    Updated August 19th, 2008 at 12:32 by _g_

    Categories
    Uncategorized
  12. PEiD imports parsing DoS

    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    - - Orange Bat advisory -

    Name : PEiD v0.94 exe File Parsing DoS
    Class : DoS
    Published : 2008-08-18
    Credit : g_ (g_ # orange-bat # com)

    - - Details -

    When parsing .exe files, PEiD will allocate memory to hold the
    file content. Size of this memory chunk will be divisible by
    0x1000 (4KB). If the file size is a multiple of 4KB and if
    the import table is located at the end of the file, import parsing
    procedure could try to read data off the heap -- to check if
    there are more valid import descriptors, memory pointer is advanced
    without bounds checking and this leads to access violation:

    .text:0043958B loc_43958B:
    .text:0043958B mov eax, [esi+10h] ;Oooops!
    .text:0043958E add esi, 14h
    .text:00439591 cmp eax, ebx
    .text:00439593 mov [esp+60h+var_4C], esi
    .text:00439597 jnz loc_4393FE

    Exe file can still run normally after modifing the IAT btw, see POC.

    - - Proof of concept -

    http://www.orange-bat.com/adv/2008/poc.08.18.peid.rar

    - - PGP -

    All advisories from Orange Bat are signed. You can find our public
    key here: http://www.orange-bat.com/g_.asc

    - - Disclaimer -

    This document and all the information it contains is provided "as is",
    without any warranty. Orange Bat is not responsible for the
    misuse of the information provided in this advisory. The advisory is
    provided for educational purposes only.

    Permission is hereby granted to redistribute this advisory, providing
    that no changes are made and that the copyright notices and
    disclaimers remain intact.

    (c) 2008 www.orange-bat.com


    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.9 (MingW32) - GPGshell v3.70

    iEYEARECAAYFAkiokJkACgkQIUHRVUfOLgUCcgCgxI1B4xeCqOV8prG6CisbRcTV
    ZZ8An1HSq/W4+Gx6gI9UeNCPqgwmo6jU
    =Ddln
    -----END PGP SIGNATURE-----
    Categories
    Uncategorized
  13. Nucleus Framework

    I just released the initial release of nucleus framework. You have to decide if you like it

    OHPen
    Categories
    coding
    Attached Thumbnails Attached Files
  14. SoftICE and KDExtensions

    Well I was writing one extension for softice, and I faced one serious problem which in turn might not be that big problem if softice authors decided to write softice code properly at some points. SoftICE manual doesn't provide us with concept how to write KDExtensions, but in turn it gives us tools which we might use to convert existing windbg extensions into softice extension. One of rules is that we may not use Exception Handling in KDExtension (taken from SoftICE manual), and silently it refuses usage of many exports from ntoskrnl.exe...

    KD2SYS.exe works simply by adding extra code to your dll, and changing it's entrypoint to code which looks like this:

    Code:
    .1000147F: B800000000                     mov         eax,0
    .10001484: C20800                         retn        8
    .10001487: 0010                           add         [eax],dl
    .10001489: 0000                           add         [eax],al
    when extension is loaded, it MUST have Debug symbols so softice will know that it should check EntryPoint for mov eax, 0/retn 8 using INT 2D (during driver loading ntoskrnl.exe will call -> DbgLoadImageSymbols which in turns will call int 2D, hooked by SoftICE which will examine entrypoint of driver and substitute mov eax, 0 with jmp __softice_code which will in turn call DllEntryPoint.

    Code:
    PAGE:004D7D27                 push    dword ptr [edi] ; ImageBase
    PAGE:004D7D29                 call    _CacheImageSymbols@4 ; CacheImageSymbols(x)   
    PAGE:004D7D2E                 test    eax, eax
    PAGE:004D7D30                 jz      __no_debug_symbols
    Upper code shows part of ntos which checks if Debug directory is used, and after that it will call DbgLoadImageSymbols.


    If you take a look at upper Disassm code, you may see that right after retn 08 is stored : 1000h which is RVA of DllEntryPoint... You may examine a little bit hook of int2D and you will see how loading of KD takes place in SoftICE, not a nuclear physics as you may trace Int2D hook in SoftICE without a problem, as it will be running at PASSIVE_LEVEL (level at which drivers are being loaded).

    Next step is to create such driver that will have similar if not the same code which will be handld by SoftICE. My walkaround was to define DriverEntry in asm code like this:

    Code:
    extern                  DllEntryPoint@12:dword 
    public  C               DriverEntry@8
    
    DriverEntry@8:          mov     eax, 0
                            ret     8
                            dd      0FFFFFFFFh
                            dd      offset DllEntryPoint@12
    Also make sure that TARGETTYPE=MINIPORT to link directly with DriverEntry@8 as your entrypoint, as DRIVER type will link using GsDriverEntry:

    Code:
    INIT:00011185                 public GsDriverEntry
    INIT:00011185 GsDriverEntry   proc near
    INIT:00011185                 mov     edi, edi
    INIT:00011187                 push    ebp
    INIT:00011188                 mov     ebp, esp
    INIT:0001118A                 mov     eax, __security_cookie
    INIT:0001118F                 test    eax, eax
    ...
    INIT:000111B8                 mov     __security_cookie_complement, eax
    INIT:000111BD                 pop     ebp
    INIT:000111BE                 jmp     DriverEntry
    Which is not what I want...

    Next step is to write convert.c/asm code which will:

    1. open your file
    2. locate entry point
    3. calculate relative offset of DllEntryPoint
    4. store it in placess of 0FFFFFFFF
    5. update checksum
    6. save changes

    Now you may have neet extension (at least that's how I write them). Kayaker probably has better solution

    Now comes funn part which I figgured after making dump of whole memory in VMWare, as minidump wasn't enough for me.

    I tried to call some procedures which require dropping of IRQL like ExAllocatePool, which will eventually endup in ExAcquireQueuedSpinLock, which will drop IRQL to DISPATCH_LEVEL. I've started receiving numerous BSODs, and I tought that IRQL was an issue... and those BSODs occured only, and only when I was breaking in softice from ring3 applications, so I figured something had to be wrong, but in my wildest dreams I wouldn't suspect that solution was that stupid...

    Let's have a look at code responsible for calling KDExtension in softice:

    Code:
    .text:A7AB9D3A si_callExtension proc near             
    .text:A7AB9D3A
    .text:A7AB9D3A ExtensionApi    = dword ptr  8
    .text:A7AB9D3A hCurrentProcess = dword ptr  0Ch
    .text:A7AB9D3A hCurrentThread  = dword ptr  10h
    .text:A7AB9D3A dwCurrentPc     = dword ptr  14h
    .text:A7AB9D3A dwProcessor     = dword ptr  18h
    .text:A7AB9D3A args            = dword ptr  1Ch
    .text:A7AB9D3A
    .text:A7AB9D3A                 push    ebp
    .text:A7AB9D3B                 mov     ebp, esp
    .text:A7AB9D3D                 push    ds
    .text:A7AB9D3E                 push    es
    .text:A7AB9D3F                 push    fs
    .text:A7AB9D41                 push    gs
    .text:A7AB9D43                 pusha
    .text:A7AB9D44                 pushf
    .text:A7AB9D45                 mov     edi, kd_extension_esp_start
    .text:A7AB9D4B                 mov     ecx, kd_extension_stack_size
    .text:A7AB9D51                 shr     ecx, 2
    .text:A7AB9D54                 xor     eax, eax
    .text:A7AB9D56                 cld
    .text:A7AB9D57                 rep stosd
    .text:A7AB9D59                 cli
    .text:A7AB9D5A                 mov     save_sice_esp, esp
    .text:A7AB9D60                 mov     save_sice_ebp, ebp
    .text:A7AB9D66                 mov     ErrorString_to_display, 0
    .text:A7AB9D70                 mov     si_extension_aborted_pagefault, 0
    .text:A7AB9D77                 mov     b_extension_executing, 1
    .text:A7AB9D7E                 mov     dl, 1
    .text:A7AB9D80                 call    Install_Reinsall_DivideOverflowHandler
    .text:A7AB9D85                 mov     esp, kd_extension_esp
    .text:A7AB9D8B                 sti
    .text:A7AB9D8C                 mov     fs, word ptr kd_extension_fs 
    .text:A7AB9D92                 call    sub_A7AB9C86    
    .text:A7AB9D97                 push    [ebp+args]
    .text:A7AB9D9A                 push    [ebp+dwProcessor]
    .text:A7AB9D9D                 push    [ebp+dwCurrentPc]
    .text:A7AB9DA0                 push    [ebp+hCurrentThread]
    .text:A7AB9DA3                 push    [ebp+hCurrentProcess]
    .text:A7AB9DA6                 call    [ebp+ExtensionApi]
    .text:A7AB9DA9 loc_A7AB9DA9:                           
    .text:A7AB9DA9                 cli
    .text:A7AB9DAA                 mov     esp, save_sice_esp
    .text:A7AB9DB0                 mov     ebp, save_sice_ebp
    .text:A7AB9DB6                 mov     b_extension_executing, 0
    .text:A7AB9DBD                 call    restore_SEH
    .text:A7AB9DC2                 xor     dl, dl
    .text:A7AB9DC4                 call    Install_Reinsall_DivideOverflowHandler
    .text:A7AB9DC9                 sti
    .text:A7AB9DCA                 mov     edi, kd_extension_esp_start
    .text:A7AB9DD0                 mov     ecx, kd_extension_stack_size
    .text:A7AB9DD6                 shr     ecx, 2
    .text:A7AB9DD9                 xor     eax, eax
    .text:A7AB9DDB                 cld
    .text:A7AB9DDC                 repe scasd
    .text:A7AB9DDE                 mov     eax, ecx
    .text:A7AB9DE0                 inc     eax
    .text:A7AB9DE1                 shl     eax, 2
    .text:A7AB9DE4                 popf
    .text:A7AB9DE5                 popa
    .text:A7AB9DE6                 pop     gs
    .text:A7AB9DE8                 pop     fs
    .text:A7AB9DEA                 pop     es
    .text:A7AB9DEB                 pop     ds
    .text:A7AB9DEC                 pop     ebp
    .text:A7AB9DED                 retn    18h
    .text:A7AB9DED si_callExtension endp
    Now comes funny part, really funny part!!!!

    Code:
    .text:A7AB9D8C                 mov     fs, word ptr kd_extension_fs
    This is not kd_extension_fs, this is FS of interupted TASK!!!!!!!!!! So if you are debugging ring3 code, KDExtension will be called with FS = 0x3B which points to TEB instead of KPCR, what most exports from ntoskrnl.exe will expect it to be!!! Of course, this is not the problem when you interupt TASK which is running in ring0, but I want my extension to work the same way no matter if interupted task is in ring0 or ring3.

    That's the reason why KeSetEvent, ExAllocatePool, KeInsertQueueDpc and many, many others will fail, as those at some point expect FS to point to KPCR instead of TEB!

    My solution was to create 2 functions, and call them, one at the beginning of exported function, and one at the end:

    Code:
    ULONG   old_fs;
    void    set_fs()
    {
            __asm{
                    xor     eax, eax
                    mov     ax, fs
                    mov     old_fs, eax
                    mov     eax, 30h
                    mov     fs, ax
            }
    }
    
    void    restore_fs()
    {
            __asm{
                    mov     eax, old_fs
                    mov     fs, ax
            }
    }
    Although those seem like not safe functions, remember that softice ...
    Categories
    Uncategorized
  15. Inside DeleteFiber() as Anti Debug Trick

    Hi,

    Malware is often really boring to reverse because in high percentage they implements basical well known mechanisms of infection and self protection.
    But sometimes there are really intersting malware that implements innovative techniques, this is the case of a trojan borned into 2006 that implemented DeleteFiber() as AntiĖDebug Trick in a really easy and smart way.

    To understand how it works, let's see whar DeleteFiber is, directly from MSDN:

    Deletes an existing fiber.

    Syntax

    Code:
    VOID WINAPI DeleteFiber(
      __in  LPVOID lpFiber
    );
    lpFiber is the address of the fiber to be deleted.

    Important to say that the DeleteFiber function deletes all data associated with the fiber. This data includes the stack, a subset of the registers, and the fiber data.

    Now let's see a basical use of DeleteFiber():

    Code:
    #define _WIN32_WINNT 0x0400
    #include <windows.h>
    
    int main(void)
    {
    	char fiber[1024] = {0};		
    	DeleteFiber(fiber);	
    	return EXIT_SUCCESS;
    }
    After showing the basical use of DeleteFiber let's see how can be implemented as Anti-Debug Trick, I insert here direcly the code:

    Code:
    #define _WIN32_WINNT 0x0400
    #include <windows.h>
    #include <stdio.h>
    
    int main(void)
    {
          char fib[1024] = {0};	
    	DeleteFiber(fib);
    
    	if(GetLastError() == 0x00000057)
    		MessageBoxA(NULL,"This process is NOT debugged","Info",MB_OK);
    	else
    		MessageBoxA(NULL,"This process IS debugged","Info",MB_OK);
    	
    	
    	return EXIT_SUCCESS;
    }
    As you can understant we can resume this trick into two cases:

    If the process is NOT debugged DeleteFiber give us an Error Code of 0x00000057 that corresponds to ERROR_INVALID_PARAMETER
    If the process IS debugged the error code is differs from 0x00000057

    What to say it's really easy to implement and really effective for all kind of debuggers, with a bit of junk code that confuses ideas the conditional check could be placed really distant from the DeleteFiber() itself.

    Inside DeleteFiber()


    Now we will see how DeleteFiber internally works to understand why this should be used as Anti-Debug trick.

    This is the Dead List:

    Code:
    00401000  PUSH DF.00403370
    00401005  CALL DWORD PTR DS:[<&KERNEL32.DeleteFiber>;  kernel32.DeleteFiber
    
    inside DeleteFiber()
    
    7C825A9F >   MOV EDI,EDI          ; DF.00403778
    7C825AA1     PUSH EBP
    7C825AA2     MOV EBP,ESP
    7C825AA4     PUSH ECX
    7C825AA5     PUSH ESI
    7C825AA6     MOV EAX,DWORD PTR FS:[18]     ;_TEB Struct
    7C825AAC     MOV ECX,DWORD PTR DS:[EAX+10] ;pointer to _TIB.FiberData field
    7C825AAF     MOV ESI,DWORD PTR SS:[EBP+8]  ;lpFiber
    7C825AB2     CMP ECX,ESI
    7C825AB4     JE kernel32.7C826596          ;ExitThread if( FiberData == lpfiber)
    7C825ABA     AND DWORD PTR SS:[EBP-4],0    ;Clears this Stack location
    7C825ABE     PUSH 8000                     ;MEM_RELEASE
    7C825AC3     LEA EAX,DWORD PTR SS:[EBP-4]  
    7C825AC6     PUSH EAX
    7C825AC7     LEA EAX,DWORD PTR DS:[ESI+10]
    7C825ACA     PUSH EAX
    7C825ACB     PUSH -1
    7C825ACD     CALL DWORD PTR DS:[<&ntdll.NtFreeVirtual>  ntdll.ZwFreeVirtualMemory
    7C825AD3     MOV EAX,DWORD PTR FS:[18]        ;_TEB Struct
    7C825AD9     MOV EAX,DWORD PTR DS:[EAX+30]    ;points to _PEB Struct
    7C825ADC     PUSH ESI                         ;lpFiber
    7C825ADD     PUSH 0                           ;0x00000000
    7C825ADF     PUSH DWORD PTR DS:[EAX+18]       ;PEB.ProcessHeap
    7C825AE2     CALL DWORD PTR DS:[<&ntdll.RtlFreeHeap>] ; ntdll.RtlFreeHeap
    7C825AE8     POP ESI
    7C825AE9     LEAVE
    7C825AEA     RETN 4

    In the first part of DeleteFiber is retrived the _TEB structure and specifically a member of _TIB structure located at 10h

    0:003> dt nt!_TEB -b
    ntdll!_TEB
    +0x000 NtTib : _NT_TIB
    +0x000 ExceptionList : Ptr32
    ...
    +0x00c SubSystemTib : Ptr32
    +0x010 FiberData : Ptr32

    and next if FiberData is equal to our Fiber's Address it means that Fiber is suicinding itself and system calls ExitThread(), next we can notice a NtFreeVirtualMemory call with the following parameters:

    Code:
    NtFreeVirtualMemory(NtCurrentProcess(), &pStackAllocBase,&nSize,MEM_RELEASE);
    The system deallocates the used stack and finally calls RtlFreeHeap in this manner:

    Code:
    RtlFreeHeap(GetProcessHeap(), 0, lpFiber);
    This last call clarifies totally the presence of ERROR_INVALID_PARAMETER because has we have seen DeleteFiber is directly correlated with Heap, and Heap Memory presents a set of Flags that characterize the Heap itself.
    These Flags differs in case the process IS debugged or NOT, so we can suppose that these flags are created when the exe itself is executed, in other words at Process Creation Time. Under Windows NT processes are created through PspUserThreadStartup and inside it we can found LdrInitializeThunk, that as Russinovich sais The LdrInitializeThunk routine initializes the loader, heap manager, NLS tables, thread-local storage (TLS) array, and critical section structures. By going more deep we can see that there is a specific function that fill the PEB Struct of the new process MmCreatePeb(), PEB is important because between his various fields are stored Heap Flags of our process. I'm talking about NtGlobalFlag, for a debugged process these flags are:

    #define FLG_HEAP_ENABLE_TAIL_CHECK 0x00000010
    #define FLG_HEAP_ENABLE_FREE_CHECK 0x00000020
    #define FLG_HEAP_VALIDATE_PARAMETERS 0x00000040


    Now if a process has these flags enabled ( HeapDebug ) RtlFreeHeap will fail the Heap freeing and this error will be propagated to DeleteFiber() that will exit with an ERROR_INVALID_PARAMETER.

    Anti Anti-Debug


    Due to the fact that the Heap Validation is accomplished at Processs Creation Time, one countermeasure against Anti-Debug will be to attach the debugger after that the process is created.
    If you are using WinDbg could be used the HeapDebug option ( -hd )
    Between the function involved in process creation we have also LdrQueryImageFileExecutionOptions that mantains trace of IFEO ( Image File Execution Options structure) this struct is located into Registry under the path [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\]
    The various possible values are:
    Debugger
    DisableHeapLookaside
    ShutdownFlags
    MinimumStackCommitInBytes
    ExecuteOptions
    GlobalFlag
    DebugProcessHeapOnly
    ApplicationGoo
    RpcThreadPoolThrottle
    GlobalFlag can be used to modify NtGlobalFlag, so if you set this key entry to NULL, Heap of the debugged program will looks as an undebugged one, read this as an Anti-Anti Debug Trick .

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\Target.exe]
    "GlobalFlag"=""



    Regards,
    Giuseppe 'Evilcry' Bonfa'