Flag: Tornado! Hurricane!

Technical Analysis of MS06-001

Monday, February 6 2006 18:48.06 CST
Author: stephanc # Views: 22405 Printer Friendly ...

Microsoft Windows is vulnerable to remote code execution in GDI32.dll (Graphical Device Interface). This vulnerability was assigned Microsoft security bulletin MS06-001 Vulnerability in Graphics Rendering Engine Could Allow Remote Code Execution (912919). An exploit containing this vulnerability was found in the wild by Websense Security Labs on 12/27/2005.

This vulnerability was exploited in the wild as early as 12/15/2005 to install various malicious programs. In order to successfully exploit this vulnerability, an attacker is only required to lure the victim to an infected website. The number of websites currently hosting malicious code has steadily increased since the exploit was made public.

In this article, Stephan Chenette walks through the disassembly of GDI32.dll, providing a detailed analysis of the code flow leading to the vulnerability. Readers are expected to be familiar with x86 assembly instructions to follow this document.


Windows Meta Files (WMF) files contain GDI commands/functions in the form of meta records. The malicious code is executed by using a special meta record called a "SetAbortProc" escape metafile record. This record instructs GDI32.dll to execute arbitrary user-supplied code.

This vulnerability is unique in that it is not a standard security vulnerability, such as a buffer or integer overflow. This vulnerability is triggered because the WMF file can contain error handling code directly located in a special escape meta record that GDI32.dll will execute.

Exploit code was publicly published for this vulnerability on 12/28/2005. A third-party patch was provided 12/31/2005 and Microsoft addressed this vulnerability with the release of MS06-001 on 01/05/2006. A number of public exploit generators have been released that allow malicious WMF files to be created with little programming knowledge.

An explanation of the disassembled code is found below.

 Technical Details

GDI32.dll (5.1.2600.2770) was disassembled on Windows XP SP2 using Interactive Disassembler (IDA) v4.9.

The execution path begins with a call to gdi32_PlayMetaFile, which will then call CommonEnumMetaFile to enumerate all meta records in the WMF file.

CommonEnumMetaFile then calls gdi32_PlayMetaFileRecord on each meta record to retrieve the meta record information. Each record contains a record size, a function code, and a variable number of function parameters. gdi32_PlayMetaFileRecord sets the higher 8 bits of every function code to zero for each meta record (i.e. 0x626 becomes 0x26).

If the new function code is 0x26, PlayIntoAMetafile will be called.

gdi32_PlayMetaFileRecord then checks the escape code, the first function parameter. gdi32_Escape will be called if the escape code is anything other than 0x0F (for example: 0x09).

If the escape code is 0x09, gdi32_SetAbortProc will be called to retrieve the GDI entry from the GDISharedHandleTable and set pUserInfo->0x14 for that GDI entry to the address of the abort function, which is also supplied as a parameter.

Upon enumeration of the next record, CommonEnumMetaFile will check to see if pUserInfo->0x14 was set from the analysis of the last meta record. If an address was set at this offset, that address will be called and executed. This address points to arbitrary user-supplied code within the WMF file.

77F2595E ; BOOL __stdcall gdi32_PlayMetaFile(HDC,HMETAFILE)
77F2595E                 public gdi32_PlayMetaFile
77F2595E gdi32_PlayMetaFile proc near          ; CODE XREF: sub_4ECB5604+B7
77F2595E                                       ; sub_4ECB5604+CE ...
77F2595E arg_0  = dword ptr  8
77F2595E arg_4  = dword ptr  0Ch
77F2595E mov     edi, edi
77F25960 push    ebp
77F25961 mov     ebp, esp
77F25963 push    0
77F25965 push    0
77F25967 push    [ebp+arg_4]
77F2596A push    [ebp+arg_0]
77F2596D call    _CommonEnumMetaFile@16 ; CommonEnumMetaFile(x,x,x,x)
77F25972 pop     ebp
77F25973 retn    8
77F25973 gdi32_PlayMetaFile endp

_pldcGet returns the pUserInfo field for a particular GDI HDC. The address of pUserInfo is then stored in var_44.

77F23FDE call    _pldcGet@4      ; pldcGet(x)
77F23FE3 mov     [ebp+var_44], eax

Jumps to loop that enumerates each meta record

77F240DF jz      loc_77F25912

This is the meta record loop. This code enumerates each meta record and then plays the meta record. If the previous meta record sets pUserInfo->0x14 to a value other than zero, CommonEnumMetaFile will execute the code at the set address.

77F25912 ; START OF FUNCTION CHUNK FOR _CommonEnumMetaFile@16
77F25912 loc_77F25912:    ; CODE XREF: CommonEnumMetaFile(x,x,x,x)+198
77F25912                  ; CommonEnumMetaFile(x,x,x,x)+1A10j
77F25912 cmp     esi, ebx ; loop for each meta record (loop start)
77F25914 jz      loc_77F24134
77F2591A cmp     esi, 0FFFFFFFFh
77F2591D jz      short loc_77F25988
77F2591F cmp     [ebp+var_20], ebx
77F25922 jnz     short loc_77F2592D
77F25924 mov     eax, [ebp+var_24]
77F25927 test    byte ptr [eax+5], 8
77F2592B jz      short loc_77F25988
77F2592D ;
77F2592D ; [ebp+var_44] contains the address of pUserInfo for the GDI Entry
77F2592D ;
77F2592D ; The entry was set at 77F23FE3
77F2592D loc_77F2592D:           ; CODE XREF: CommonEnumMetaFile(x,x,x,x)+19DB
77F2592D mov     eax, [ebp+var_44]
77F25930 cmp     eax, ebx        ; ebx = 0x0
77F25932 jz      short loc_77F2593F
77F25934 ; [eax+14h] (pUserInfo+0x14) contains the address of escape shellcode
77F25934 ; This was set in SetAbortProc.
77F25934 mov     eax, [eax+14h]
77F25937 ; If ebx is 0x0. If eax is not 0x0 it will contain the address
77F25937 ; of the escape function where the shellcode is located
77F25937 cmp     eax, ebx
77F25939 ; If pUserInfo+0x14 is not zero then code at this address will be executed
77F25939 ; Else the next meta record will be parsed
77F25939 jnz     loc_77F333FE
77F2593F loc_77F2593F:           ; CODE XREF: CommonEnumMetaFile(x,x,x,x)+19EB
77F2593F                         ; CommonEnumMetaFile(x,x,x,x)+F4BDj
77F2593F push    [ebp+var_30]    ; UINT
77F25942 push    esi             ; LPMETARECORD
77F25943 push    [ebp+hMem]      ; LPHANDLETABLE
77F25946 push    edi             ; HDC
77F25947 call    gdi32_PlayMetaFileRecord
77F2594C push    esi
77F2594D push    [ebp+var_2C]
77F25950 call    _GetEvent@8     ; GetEvent(x,x)
77F25955 mov     esi, eax
77F25957 ; Loop to next meta file record 
77F25957 jmp     short loc_77F25912  ; jmp back to start of loop
77F25957 ; END OF FUNCTION CHUNK FOR _CommonEnumMetaFile@16

77F11788 ; ---------------------------------------------------------------------------
77F11788 ; START OF FUNCTION CHUNK FOR gdi32_PlayMetaFileRecord
77F11788 loc_77F11788:  ; CODE XREF: gdi32_PlayMetaFileRecord+Fj
77F11788 mov     eax, ___security_cookie
77F1178D mov     [ebp+var_1C], eax
77F11790 mov     eax, [ebp+arg_0]
77F11793 mov     [ebp+var_7C], eax
77F11796 mov     eax, [ebp+arg_4]
77F11799 loc_77F11799:                           ; CODE XREF: _GUID_D3DCallbacks2j
77F11799 mov     [ebp+var_88], eax
77F1179F mov     ebx, [ebp+arg_8]
77F117A2 xor     esi, esi
77F117A4 mov     [ebp+var_80], esi
77F117A7 mov     [ebp+hMem], esi
77F117AD mov     edi, [ebx]
77F117AF mov     [ebp+var_E4], edi
77F117B5 xor     ecx, ecx
77F117B7 mov     cx, [ebx+4]
77F117BB mov     [ebp+var_8C], ecx
77F117C1 movzx   ecx, cx
77F117C4 ; var_B4 holds the full function code
77F117C4 mov     [ebp+var_B4], ecx
77F117CA ; The higher 8 bits of the function code are set to zero
77F117CA ; (i.e. 0x626 is now 0x26)
77F117CA ; The value is stored in ecx
77F117CA and     ecx, 0FFh
77F117D0 mov     edx, 0F0h ; '='
77F117D5 cmp     ecx, edx
77F117D7 jg      loc_77F23EB7
77F117DD jmp     loc_77F23E84
77F117DD ; END OF FUNCTION CHUNK FOR gdi32_PlayMetaFileRecord
77F117DD ; ---------------------------------------------------------------------------

After the higher 8 bits of the function code are set to zero, there is a switch statement on the new function code to determine the code path.

77F23E84 ; START OF FUNCTION CHUNK FOR gdi32_PlayMetaFileRecord
77F23E84 loc_77F23E84:  ; CODE XREF: gdi32_PlayMetaFileRecord-1266F
77F23E84 jz      loc_77F25043
77F23E8A cmp     ecx, 49h ; 'I'  ; switch 74 cases
77F23E8D ja      loc_77F25067    ; default
77F23E93 jump table for truncated function code (i.e. 0x26)
77F23E93 jmp     ds:off_77F254E0[ecx*4] ; switch jump

This is the jump table for the switch statement of the new function code.

77F254E0 off_77F254E0
77F254E0 dd offset loc_77F25067  ; DATA XREF: gdi32_PlayMetaFileRecord+47
77F254E0                         ; jump table for switch statement
77F254E4 dd offset loc_77F25780  ; case 0x1
77F254E8 dd offset loc_77F2578D  ; case 0x2
77F254EC dd offset loc_77F24E7F  ; case 0x3
77F254F0 dd offset loc_77F25BAB  ; case 0x4
77F254F4 dd offset loc_77F25067  ; default
77F254F8 dd offset loc_77F24EA3  ; case 0x6
77F254FC dd offset loc_77F24EB5  ; case 0x7
77F25500 dd offset loc_77F24E1A  ; case 0x8
77F25504 dd offset loc_77F257B6  ; case 0x9
77F25508 dd offset loc_77F24EDE  ; case 0xA
77F2550C dd offset loc_77F25683  ; case 0xB
77F25510 dd offset loc_77F2569C  ; case 0xC
77F25514 dd offset loc_77F24DB6  ; case 0xD
77F25518 dd offset loc_77F24DCF  ; case 0xE
77F2551C dd offset loc_77F24DE8  ; case 0xF
77F25520 dd offset loc_77F24D70  ; case 0x10
77F25524 dd offset loc_77F24E01  ; case 0x11
77F25528 dd offset loc_77F24D93  ; case 0x12
77F2552C dd offset loc_77F2579F  ; case 0x13
77F25530 dd offset loc_77F25767  ; case 0x14
77F25534 dd offset loc_77F24F37  ; case 0x15
77F25538 dd offset loc_77F24F58  ; case 0x16
77F2553C dd offset loc_77F24FA4  ; case 0x17
77F25540 dd offset loc_77F24EF5  ; case 0x18
77F25544 dd offset loc_77F24D37  ; case 0x19
77F25548 dd offset loc_77F2500E  ; case 0x1A
77F2554C dd offset loc_77F24F16  ; case 0x1B
77F25550 dd offset loc_77F24F79  ; case 0x1C
77F25554 dd offset loc_77F25738  ; case 0x1D
77F25558 dd offset loc_77F24E45  ; case 0x1E
77F2555C dd offset loc_77F24D0D  ; case 0x1F
77F25560 dd offset loc_77F24EC7  ; case 0x20
77F25564 dd offset loc_77F248F2  ; case 0x21
77F25568 dd offset loc_77F2422B  ; case 0x22
77F2556C dd offset loc_77F2422B  ; case 0x22
77F25570 dd offset loc_77F25B78  ; case 0x24
77F25574 dd offset loc_77F25B78  ; case 0x24
77F25578 dd offset loc_77F256F2  ; case 0x26
77F2557C dd offset loc_77F24CFB  ; case 0x27
77F25580 dd offset loc_77F249D5  ; case 0x28

case 0x26 (escape function code): PlayIntoAMetafile is called and the escape code is checked (i.e. 0x09=SetAbortProc)

77F256F2 ; ---------------------------------------------------------------------------
77F256F2 ; START OF FUNCTION CHUNK FOR gdi32_PlayMetaFileRecord
77F256F2 loc_77F256F2: ; CODE XREF: gdi32_PlayMetaFileRecord+47
77F256F2               ; DATA XREF: 77F25578
77F256F2  push    [ebp+var_7C]    ; case 0x26
77F256F5  push    ebx
77F256F6  call    _PlayIntoAMetafile@8 ; PlayIntoAMetafile(x,x)
77F256FB  mov     [ebp+var_80], eax
77F256FE  test    eax, eax
77F25700  jz      loc_77F24914    ; leads to SetAbortProc
77F25706  jmp     loc_77F258FD
77F2570B ; ---------------------------------------------------------------------------

word ptr [ebx+6] and eax hold the value of the escape code (i.e. 0x09). If the escape code is anything other than 0x0F, gdi32_Escape will be called.

77F24914 ; ---------------------------------------------------------------------------
77F24914 get escape number
77F24914 loc_77F24914:   ; CODE XREF: gdi32_PlayMetaFileRecord+18B4j
77F24914 movzx   eax, word ptr [ebx+6]
77F24918 cmp     eax, 0Fh
77F2491B jz      loc_77F25067    ; default
77F24921 ; We will get here once eax does not equal 0x0F (i.e. when eax equals 0x09)
77F24921 push    0               ; LPVOID
77F24923 lea     ecx, [ebx+0Ah]
77F24926 push    ecx             ; LPCSTR
77F24927 movzx   ecx, word ptr [ebx+8]
77F2492B push    ecx             ; int
77F2492C push    eax             ; int
77F2492D push    [ebp+var_7C]    ; HDC
77F24930 call    gdi32_Escape
77F24935 jmp     loc_77F23F23
77F2493A ; ---------------------------------------------------------------------------

A small switch statement determines the code path for the escape code. The execution jumps to 0x77F33EEF if the escape code is 0x09.

77F2695C jz      loc_77F346AB
77F26962 cmp     eax, 8
77F26965 jnz     loc_77F33E5B
77F33EC4 ; If the escape code is equal to 0x09, jump to 0x77F33EEF.
77F33EC4 sub     eax, 6
77F33EC7 jz      short loc_77F33EEF ; leads to call of SetAportProc

gdi32_SetAbortProc is called at 0x77F33EF3.

77F33EEF loc_77F33EEF:  ; CODE XREF: gdi32_Escape+D5A6
77F33EEF push    esi             ; ABORTPROC
77F33EF0 push    [ebp+var_8]     ; HDC
77F33EF3 call    gdi32_SetAbortProc
77F33EF8 jmp     loc_77F34525

gdi32_SetAbortProc calls _pldcGet to get the pUserInfo address of the HDC. It then sets pUserInfo->0x14 to the address of the abort procedure, which is the address of the shellcode.

77F43942 ; int __stdcall gdi32_SetAbortProc(HDC,ABORTPROC)
77F43942   public gdi32_SetAbortProc
77F43942 gdi32_SetAbortProc proc near   ; CODE XREF: gdi32_Escape+D5D2
77F43942 arg_0_HDC       = dword ptr  8
77F43942 arg_4_ABORTPROC = dword ptr  0Ch
77F43942 mov     edi, edi
77F43944 push    ebp
77F43945 mov     ebp, esp
77F43947 mov     ecx, [ebp+arg_0_HDC]
77F4394A and     ecx, 7F0000h
77F43950 or      eax, 0FFFFFFFFh
77F43953 cmp     ecx, 10000h
77F43959 push    esi
77F4395A jz      short loc_77F439A9
77F4395C cmp     ecx, 660000h
77F43962 jz      short loc_77F439A9
77F43964 push    [ebp+arg_0_HDC]
77F43967 ; _pldcGet@4 returns the address to pUserinfo that will be used
77F43967 ; to store the escape function address of the shellcode
77F43967 call    _pldcGet@4      ; pldcGet(x)

For references purposes, the code of _pldcGet is displayed below. The purpose of this function is to return the address of pUserInfo for a given HDC.

77F159B4 ; __stdcall pldcGet(x)
77F159B4 _pldcGet@4      proc near   ; CODE XREF: gdi32_GdiReleaseDC+13p
77F159B4                             ; InternalDeleteDC(x,x)+22p ...
77F159B4 arg_0_HDC       = dword ptr  8
77F159B4 mov     edi, edi
77F159B6 push    ebp
77F159B7 mov     ebp, esp
77F159B9 mov     edx, [ebp+arg_0_HDC]
77F159BC mov     ecx, edx
77F159BE ; Put the lower 16 bits of HANDLE into ecx so we can
77F159BE ; use it to get the index in the table.
77F159BE and     ecx, 0FFFFh
77F159C4 xor     eax, eax
77F159C6 ; Test if the handle index is below the first 10,000h entries.
77F159C6 ; If it is not, go to the end of the function.
77F159C6 cmp     ecx, 10000h
77F159CC jnb     short loc_77F159FD
77F159CE ; Shift right the lower 16 bits indicating the index
77F159CE ; into the table to the higher 16 bits in ecx.
77F159CE ; 
77F159CE ; We do this because each entry is 16 bytes (2^4).
77F159CE ; By shifting we are accounting for the entry size
77F159CE shl     ecx, 4
77F159D1 ; GdiSharedHandleTable (PEB contains ptr to this table)
77F159D1 ;
77F159D1 ; This is a table where GDI stores its handles,
77F159D1 ; even those created by other processes.
77F159D1 ; 
77F159D1 ; This is the structure of a GDI entry on Windows 2000/XP:
77F159D1 ; 
77F159D1 ; typedef struct
77F159D1 ; {
77F159D1 ;    DWORD pKernelInfo; (offset=00h)
77F159D1 ;    WORD  ProcessID; (offset=04h)
77F159D1 ;    WORD  _nCount; (offset=06h)
77F159D1 ;    WORD  nUpper; (offset=08h)
77F159D1 ;    WORD  nType; (offset=0Ah)
77F159D1 ;    DWORD pUserInfo; (offset=0Ch)
77F159D1 ; } GDITableEntry;
77F159D1 ; 
77F159D1 ; Each entry stores the details of a GDI handle.
77F159D1 ; Its lower 16 bits are the index in the table, 
77F159D1 ; its upper 16 bits are saved in the nUpper field,
77F159D1 ; the ProcessID field contains the ID of the process that created the object.
77F159D1 ; 
77F159D1 ; ecx holds the offset*gdi_entry_size into the table.
77F159D1 ; The operation below adds the address of
77F159D1 ; pGdiHandleTable and the offset held in ecx
77F159D1 add     ecx, _pGdiSharedHandleTable
77F159D7 ; Check to see if the nType (offset 0Ah) is equal to 1 
77F159D7 cmp     byte ptr [ecx+0Ah], 1
77F159DB jnz     short loc_77F159FD
77F159DD ; Shift right 16 bits, now edx contains the upper 16bits (nUpper)
77F159DD shr     edx, 10h
77F159E0 ; Verify that nUpper in [ecx+08h] matches nUpper in dx
77F159E0 cmp     [ecx+8], dx
77F159E4 jnz     short loc_77F159FD
77F159E6 ; Move the ProcessID into edx
77F159E6 mov     edx, [ecx+4]
77F159E9 and     edx, 0FFFFFFFEh
77F159EC ; Compare ProcessID (should be equal)
77F159EC ; (Note: _gW32PID comes from TEB-->clientID&FFFFFFFCh)
77F159EC cmp     edx, _gW32PID
77F159F2 jnz     short loc_77F159FD
77F159F4 ; [ecx+0ch] = pUserInfo
77F159F4 mov     ecx, [ecx+0Ch]
77F159F7 ; Test if ecx is zero
77F159F7 test    ecx, ecx
77F159F9 jz      short loc_77F159FD
77F159FB ; Move the 4 byte value ecx contains into eax.
77F159FB ; The 4 byte value is the address of pUserInfo
77F159FB mov     eax, [ecx]
77F159FD loc_77F159FD: ; CODE XREF: pldcGet(x)+18
77F159FD               ; pldcGet(x)+27 ...
77F159FD pop     ebp
77F159FE retn    4
77F159FE _pldcGet@4      endp

After the return of _pldcGet, gdi32_SetAbortProc sets the abort procedure (shellcode) and returns.

77F4396C ; eax holds the address of pUserInfo from the GDI entry from the GDISharedHandleTable.
77F4396C ; esi also now contains the address of pUserInfo.
77F4396C mov     esi, eax
77F4396E ; Test to make sure esi is not zero.
77F4396E test    esi, esi
77F43970 jz      short loc_77F4399F
77F43972 push    edi
77F43973 ; SetAbortProc sets edi to abort function address.
77F43973 mov     edi, [ebp+arg_4_ABORTPROC]
77F43976 ; Verify that the address is not NULL.
77F43976 test    edi, edi
77F43978 jz      short loc_77F43992
77F4397A ; eax will now hold the 4 byte value at [esi+4]
77F4397A ; (Note: esi contains the address of pUserInfo)
77F4397A mov     eax, [esi+4]
77F4397D test    al, 40h
77F4397F jz      short loc_77F43996

77F43996 loc_77F43996: ; CODE XREF: gdi32_SetAbortProc+3D
77F43996               ; gdi32_SetAbortProc+4E
77F43996 xor     eax, eax
77F43998 ; edi holds the address of the escape shellcode.
77F43998 ; edi is copied into the memory at [esi+14h].
77F43998 ; 
77F43998 ; esi holds an address pUserInfo.
77F43998 ; [esi+14h] will contain the address of the abort procedure.
77F43998 mov     [esi+14h], edi
77F4399B ; eax was zero and now will become one.
77F4399B inc     eax
77F4399C pop     edi
77F4399D jmp     short loc_77F439A9
77F439A9 loc_77F439A9: ; CODE XREF: gdi32_SetAbortProc+18
77F439A9               ; gdi32_SetAbortProc+20 ...
77F439A9 pop     esi
77F439AA pop     ebp
77F439AB retn    8
77F439AB gdi32_SetAbortProc endp

var_44 holds the address of pUserInfo which was set at the beginning of the function. Offset 0x14 of this variable is compared against ebx, which is always zero. If the address at pUserInfo->0x14 is not zero, then the supplied address at this offset is executed.

77F25912 cmp     esi, ebx
77F25914 jz      loc_77F24134
77F2591A cmp     esi, 0FFFFFFFFh
77F2591D jz      short loc_77F25988
77F2591F cmp     [ebp+var_20], ebx
77F25922 jnz     short loc_77F2592D
77F25924 mov     eax, [ebp+var_24]
77F25927 test    byte ptr [eax+5], 8
77F2592B jz      short loc_77F25988
77F2592D ; [ebp+var_44] contains the address of pUserInfo for the GDI Entry.
77F2592D ; 
77F2592D ; The entry was set at 0x77F23FE3. ebx is always 0h.
77F2592D loc_77F2592D: ; CODE XREF: CommonEnumMetaFile(x,x,x,x)+19DB
77F2592D mov     eax, [ebp+var_44]
77F25930 cmp     eax, ebx
77F25932 jz      short loc_77F2593F
77F25934 ; [eax+14h] contains the address of escape shellcode.
77F25934 ; This was set in SetAbortProc.
77F25934 mov     eax, [eax+14h]
77F25937 ; ebx is 0x0. If eax is not 0x0, it will contain the address of the 
77F25937 ; escape function where the shellcode is located.
77F25937 cmp     eax, ebx
77F25939 ; This makes us jump to our escape shellcode.
77F25939 jnz     loc_77F333FE

0x77F33400 is the address where the user-supplied shellcode will be called.

77F333FE loc_77F333FE: ; CODE XREF: CommonEnumMetaFile(x,x,x,x)+19F2
77F333FE push    ebx
77F333FF push    edi
77F33400 ; Arbitrary shellcode payload is called and executed here.
77F33400 call    eax


Websense Security Labs: MS06-001 Analysis
Websense Security Labs Blog

Article Comments Write Comment / View Complete Comments

    Username Comment Excerpt Date
sefo For a description of the exploit itself: [url]... Saturday, March 4 2006 05:42.35 CST
stephanc Mohammad, I'm glad you enjoyed the article. ... Monday, February 20 2006 12:19.50 CST
MohammadHosein thank you for this detailed and technical artic... Wednesday, February 15 2006 14:08.19 CST

There are 30,995 total registered users.

Recently Created Topics
let 'IDAPython' impo...
set 'IDAPython' as t...
GuessType return une...
About retrieving the...
How to find specific...
How to get data depe...
Identify RVA data in...
Immunity Debugger Re...
Question about memor...
How can i find conne...

Recent Forum Posts
How to find specific...
Problem with ollydbg
How can I write olly...
New LoadMAP plugin v...
Intel pin in loaded ...
OOP_RE tool available?
OOP_RE tool available?
Should binaries be n...
Problem with ollydbg
!findtrampoline Immu...

Recent Blog Entries
Android Application Reversing

Breaking IonCUBE VM

Anatomy of a code tracer

IAT Patcher - new tool for ...

CryptoShark: code tracer ba...

More ...

Recent Blog Comments
nieo on:
IAT Patcher - new tool for ...

djnemo on:
Kernel debugger vs user mod...

acel on:
Kernel debugger vs user mod...

pedram on:
frida.github.io: scriptable...

capadleman on:
Using NtCreateThreadEx for ...

More ...

SoySauce Blueprint
Jun 6, 2008

[+] expand

View Gallery (11) / Submit