,, MMP""MM""YMM `7MM P' MM `7 MM MM MMpMMMb. .gP"Ya MM MM MM ,M' Yb MM MM MM 8M"""""" MM MM MM YM. , .JMML. .JMML JMML.`Mbmmd' `7MMF' `7MF' `7MMF' `7MMF' `MA ,V MM MM VM: ,V `7M' `MF' MM MM .gP"Ya ,6"Yb.`7M' `MF'.gP"Ya `7MMpMMMb. MM. M' `VA ,V' MMmmmmmmMM ,M' Yb 8) MM VA ,V ,M' Yb MM MM `MM A' XMX MM MM 8M"""""" ,pm9MM VA ,V 8M"""""" MM MM :MM; ,V' VA. MM MM YM. , 8M MM VVV YM. , MM MM VF .AM. .MA..JMML. .JMML.`Mbmmd' `Moo9^Yo. W `Mbmmd'.JMML JMML. ,, ,, ,, .g8"""bgd `7MM `7MM mm db .dP' `M MM MM MM dM' ` ,pW"Wq. MM MM .gP"Ya ,p6"bo mmMMmm `7MM ,pW"Wq.`7MMpMMMb. MM 6W' `Wb MM MM ,M' Yb 6M' OO MM MM 6W' `Wb MM MM MM. 8M M8 MM MM 8M"""""" 8M MM MM 8M M8 MM MM `Mb. ,'YA. ,A9 MM MM YM. , YM. , MM MM YA. ,A9 MM MM `"bmmmd' `Ybmd9'.JMML..JMML.`Mbmmd' YMbmd' `Mbmo.JMML.`Ybmd9'.JMML JMML. -- Contact -- https://twitter.com/vxunderground vxug@null.net

What is it?

Everyone knows about Structured Exception Handling these days. First demonstrated in the Cabanas virus in 1998 by jqwerty, now many viruses and other applications use it for obfuscating code and anti-debugging tricks. It usually looks something like this:

        call    set_seh
        ;handler code would go here
set_seh:
        push    dword ptr fs:[0]
        mov     dword ptr fs:[0], esp
        ;code to produce exception would go here
 

So now if we see such a code sequence we know to expect an anti-debugging trick is coming soon. Probably some emulators have recogniser code for this thing and trigger some heuristics, too. So I tried to think of a way to register a Structured Exception Handler without obvious write to fs:0. Here are some of those ways. First way gets base of fs from TIB.

        mov     eax, dword ptr fs:[tibSelf]
        call    set_seh
        ;handler code would go here
set_seh:
        push    dword ptr ds:[eax]
        mov     dword ptr ds:[eax], esp
        int     3                       ;cause exception
 

Second way gets base of fs from descriptor table.

        lea     eax, dword ptr [esp - 2]
        push    eax
        push    fs
        push    -2                      ;GetCurrentThread()
        call    GetThreadSelectorEntry
        pop     eax                     ;bits 00-23 of base
        bswap   eax
        mov     al, byte ptr [esp + 1]  ;bits 24-31 of base
        bswap   eax
        call    set_seh
        ;handler code would go here
set_seh:
        push    dword ptr ds:[eax]
        mov     dword ptr ds:[eax], esp
        int     3                       ;cause exception
 

Third way gets base of fs from descriptor table, using hard-coded fs value, so there is no fs reference.

        call    skip_k32
        db      "kernel32", 0
skip_k32:
        call    GetModuleHandleA
        call    skip_iswow
        db      "IsWow64Process", 0
skip_iswow:
        push    eax
        call    GetProcAddress
        xchg    ecx, eax
        jecxz   not_xp                  ;XP and later only
        push    eax
        push    esp
        push    -1
        call    ecx
        pop     ecx
not_xp:
        lea     eax, dword ptr [esp - 2]
        push    eax
        push    3bh                     ;all 32-bit Windows
        jecxz   not_v64
        pop     eax
        push    53h                     ;Vista64
not_v64:
        push    -2                      ;GetCurrentThread()
        call    GetThreadSelectorEntry
        pop     eax
        bswap   eax
        mov     al, byte ptr [esp + 1]
        bswap   eax
        call    set_seh
        ;handler code would go here
set_seh:
        push    dword ptr ds:[eax]
        mov     dword ptr ds:[eax], esp
        int     3                       ;cause exception
 

but all of these ways have obvious push and mov using esp. There are some other ways, too, such as NtSetLdtEntries(), but I was told that it does not work on 64-bit Windows. Anyway, altering fs or gs introduces race condition against thread switch. When switch occurs, fs and gs values are restored to their proper values. Then I found another way. This way writes to fs using ss:esp. The code must be in writable memory because it is also used for stack. Altering ss has no race condition because only an exception (including debugger single-step, heh!) will change the value back.

        push    8               ;replaced by "previous SEH"
        pop     eax             ;replaced by "previous SEH"
        call    delta           ;instruction must end on dword-aligned offset
                                ;replaced by handler address
ife DEP                         ;you must define this variable 0 or 1
        push    -1              ;set "previous SEH"
                                ;if hardware DEP is not enabled by Windows for process, then stack chain is checked
                                ;all entries must be on stack, and finish with -1 entry
else
        push    eax             ;set "previous SEH", just saves one byte, no other effect
                                ;if hardware DEP is enabled by Windows for process, then stack chain is not checked
                                ;Windows assumes that data execution will cause exception
endif
        mov     ecx, fs         ;push would require extra dword before previous SEH
        mov     ss, ecx         ;emulator killer, and anti-single-step, too ;)
        xchg    esp, eax        ;fs:8
        call    set_seh         ;change stack limit so our code looks like stack
set_seh:
        push    eax             ;set new SEH
                                ;cannot appear after actual handler, otherwise handler looks like is on stack
                                ;can restore ss here if you want to delay exception
        mov     esp, ebp        ;esp must be valid on except. Windows will restore ss for us
                                ;cannot use leave to pop from stack because current ss limit is too small
                                ;to delay exception, add jmp here to somewhere else
delta:
        pop     esp             ;cause exception on second pass
        call    esp             ;set handler address
        ;handler code would go here
 

No obvious memory writes.

Greets to friendly people (A-Z):

Active - Benny - izee - Malum - Obleak - Prototype - Ratter - Ronin - RT Fishel - sars - SPTH - The Gingerbread Man - Ultras - uNdErX - Vallez - Vecna - VirusBuster - Whitehead

rgb/defjam jun 2009
iam_rgb@hotmail.com