gdi32_PlayMetaFile: 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 77F2595E arg_0 = dword ptr 8 77F2595E arg_4 = dword ptr 0Ch 77F2595E 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 77F25973
CommonEnumMetaFile: 77F23FDE call _pldcGet@4 ; pldcGet(x) 77F23FE3 mov [ebp+var_44], eax
CommonEnumMetaFile: 77F240DF jz loc_77F25912
CommonEnumMetaFile: 77F25912 ; START OF FUNCTION CHUNK FOR _CommonEnumMetaFile@16 77F25912 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 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 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
gdi32_PlayMetaFileRecord: 77F11788 ; --------------------------------------------------------------------------- 77F11788 ; START OF FUNCTION CHUNK FOR gdi32_PlayMetaFileRecord 77F11788 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 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 ; ---------------------------------------------------------------------------
gdi32_PlayMetaFileRecord: 77F23E84 ; START OF FUNCTION CHUNK FOR gdi32_PlayMetaFileRecord 77F23E84 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
gdi32_PlayMetaFileRecord: 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
gdi32_PlayMetaFileRecord: 77F256F2 ; --------------------------------------------------------------------------- 77F256F2 ; START OF FUNCTION CHUNK FOR gdi32_PlayMetaFileRecord 77F256F2 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 ; ---------------------------------------------------------------------------
gdi32_PlayMetaFileRecord: 77F24914 ; --------------------------------------------------------------------------- 77F24914 get escape number 77F24914 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 ; ---------------------------------------------------------------------------
gdi32_Escape: 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_Escape: 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: 77F43942 ; int __stdcall gdi32_SetAbortProc(HDC,ABORTPROC) 77F43942 public gdi32_SetAbortProc 77F43942 gdi32_SetAbortProc proc near ; CODE XREF: gdi32_Escape+D5D2 77F43942 77F43942 arg_0_HDC = dword ptr 8 77F43942 arg_4_ABORTPROC = dword ptr 0Ch 77F43942 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)
_pldcGet: 77F159B4 ; __stdcall pldcGet(x) 77F159B4 _pldcGet@4 proc near ; CODE XREF: gdi32_GdiReleaseDC+13p 77F159B4 ; InternalDeleteDC(x,x)+22p ... 77F159B4 77F159B4 arg_0_HDC = dword ptr 8 77F159B4 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 77F159FD loc_77F159FD: ; CODE XREF: pldcGet(x)+18 77F159FD ; pldcGet(x)+27 ... 77F159FD pop ebp 77F159FE retn 4 77F159FE _pldcGet@4 endp
gdi32_SetAbortProc: 77F4396C ; eax holds the address of pUserInfo from the GDI entry from the GDISharedHandleTable. 77F4396C 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
gdi32_SetAbortProc: 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
CommonEnumMetaFile: 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 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
CommonEnumMetaFile: 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
There are 31,319 total registered users.
[+] expand