Home > Games, Programming, Windows > WoWMimic Adds Window Finding API Hooks

WoWMimic Adds Window Finding API Hooks

While doing the reversing for my previous post (In-process WoWMimic Detection) I noticed something funny. It seems the WoWMimic team took my ‘joke’ detection quite seriously and started hooking the Window finding APIs. Here’s the code:

___:10021860 ; =============== S U B R O U T I N E =======================================

___:10021860

___:10021860

___:10021860 HookWindowFinders proc near             ; CODE XREF: DllMain(x,x,x)+40p

___:10021860

___:10021860 var_4           = byte ptr -4

___:10021860

___:10021860                 push    ecx

___:10021861                 push    ebx

___:10021862                 push    ebp

___:10021863                 push    esi

___:10021864                 mov     esi, GetModuleHandleW

___:1002186A                 push    edi

___:1002186B                 push    offset aFindwindoww ; “FindWindowW”

___:10021870                 push    offset aUser32_dll ; “user32.dll”

___:10021875                 call    esi ; GetModuleHandleW

___:10021877                 mov     edi, GetProcAddress

___:1002187D                 push    eax

___:1002187E                 call    edi ; GetProcAddress

___:10021880                 mov     ebp, GetCurrentProcess

___:10021886                 mov     dword_10072238, eax

___:1002188B                 call    ebp ; GetCurrentProcess

___:1002188D                 mov     ecx, dword_10072238

___:10021893                 mov     ebx, WriteProcessMemory

___:10021899                 mov     dword_10072224, eax

___:1002189E                 mov     byte_10072230, 0E9h

___:100218A5                 mov     edx, [ecx]

___:100218A7                 mov     dword_10072228, edx

___:100218AD                 movzx   edx, byte ptr [ecx+4]

___:100218B1                 mov     byte_1007222C, dl

___:100218B7                 mov     edx, offset dword_10021120

___:100218BC                 sub     edx, ecx

___:100218BE                 sub     edx, 5

___:100218C1                 mov     dword_10072231, edx

___:100218C7                 lea     edx, [esp+14h+var_4]

___:100218CB                 push    edx

___:100218CC                 push    5

___:100218CE                 push    offset byte_10072230

___:100218D3                 push    ecx

___:100218D4                 push    eax

___:100218D5                 call    ebx ; WriteProcessMemory

___:100218D7                 push    offset aFindwindowa ; “FindWindowA”

___:100218DC                 push    offset aUser32_dll ; “user32.dll”

___:100218E1                 call    esi ; GetModuleHandleW

___:100218E3                 push    eax

___:100218E4                 call    edi ; GetProcAddress

___:100218E6                 mov     dword_10072254, eax

___:100218EB                 call    ebp ; GetCurrentProcess

___:100218ED                 mov     ecx, dword_10072254

___:100218F3                 mov     dword_10072240, eax

___:100218F8                 mov     byte_1007224C, 0E9h

___:100218FF                 mov     edx, [ecx]

___:10021901                 mov     dword_10072244, edx

___:10021907                 movzx   edx, byte ptr [ecx+4]

___:1002190B                 mov     byte_10072248, dl

___:10021911                 mov     edx, offset dword_10021200

___:10021916                 sub     edx, ecx

___:10021918                 sub     edx, 5

___:1002191B                 mov     dword_1007224D, edx

___:10021921                 lea     edx, [esp+14h+var_4]

___:10021925                 push    edx

___:10021926                 push    5

___:10021928                 push    offset byte_1007224C

___:1002192D                 push    ecx

___:1002192E                 push    eax

___:1002192F                 call    ebx ; WriteProcessMemory

___:10021931                 push    offset aFindwindowexw ; “FindWindowExW”

___:10021936                 push    offset aUser32_dll ; “user32.dll”

___:1002193B                 call    esi ; GetModuleHandleW

___:1002193D                 push    eax

___:1002193E                 call    edi ; GetProcAddress

___:10021940                 mov     dword_10072270, eax

___:10021945                 call    ebp ; GetCurrentProcess

___:10021947                 mov     ecx, dword_10072270

___:1002194D                 mov     dword_1007225C, eax

___:10021952                 mov     byte_10072268, 0E9h

___:10021959                 mov     edx, [ecx]

___:1002195B                 mov     dword_10072260, edx

___:10021961                 movzx   edx, byte ptr [ecx+4]

___:10021965                 mov     byte_10072264, dl

___:1002196B                 mov     edx, offset dword_100212E0

___:10021970                 sub     edx, ecx

___:10021972                 sub     edx, 5

___:10021975                 mov     dword_10072269, edx

___:1002197B                 lea     edx, [esp+14h+var_4]

___:1002197F                 push    edx

___:10021980                 push    5

___:10021982                 push    offset byte_10072268

___:10021987                 push    ecx

___:10021988                 push    eax

___:10021989                 call    ebx ; WriteProcessMemory

___:1002198B                 push    offset aFindwindowexa ; “FindWindowExA”

___:10021990                 push    offset aUser32_dll ; “user32.dll”

___:10021995                 call    esi ; GetModuleHandleW

___:10021997                 push    eax

___:10021998                 call    edi ; GetProcAddress

___:1002199A                 mov     dword_1007228C, eax

___:1002199F                 call    ebp ; GetCurrentProcess

___:100219A1                 mov     ecx, dword_1007228C

___:100219A7                 mov     dword_10072278, eax

___:100219AC                 mov     byte_10072284, 0E9h

___:100219B3                 mov     edx, [ecx]

___:100219B5                 mov     dword_1007227C, edx

___:100219BB                 movzx   edx, byte ptr [ecx+4]

___:100219BF                 mov     byte_10072280, dl

___:100219C5                 mov     edx, offset dword_100213E0

___:100219CA                 sub     edx, ecx

___:100219CC                 sub     edx, 5

___:100219CF                 mov     dword_10072285, edx

___:100219D5                 lea     edx, [esp+14h+var_4]

___:100219D9                 push    edx

___:100219DA                 push    5

___:100219DC                 push    offset byte_10072284

___:100219E1                 push    ecx

___:100219E2                 push    eax

___:100219E3                 call    ebx ; WriteProcessMemory

___:100219E5                 push    offset aEnumwindows ; “EnumWindows”

___:100219EA                 push    offset aUser32_dll ; “user32.dll”

___:100219EF                 call    esi ; GetModuleHandleW

___:100219F1                 push    eax

___:100219F2                 call    edi ; GetProcAddress

___:100219F4                 mov     dword_100722A8, eax

___:100219F9                 call    ebp ; GetCurrentProcess

___:100219FB                 mov     ecx, dword_100722A8

___:10021A01                 mov     dword_10072294, eax

___:10021A06                 mov     byte_100722A0, 0E9h

___:10021A0D                 mov     edx, [ecx]

___:10021A0F                 mov     dword_10072298, edx

___:10021A15                 movzx   edx, byte ptr [ecx+4]

___:10021A19                 mov     byte_1007229C, dl

___:10021A1F                 mov     edx, offset dword_10021660

___:10021A24                 sub     edx, ecx

___:10021A26                 sub     edx, 5

___:10021A29                 mov     dword_100722A1, edx

___:10021A2F                 lea     edx, [esp+14h+var_4]

___:10021A33                 push    edx

___:10021A34                 push    5

___:10021A36                 push    offset byte_100722A0

___:10021A3B                 push    ecx

___:10021A3C                 push    eax

___:10021A3D                 call    ebx ; WriteProcessMemory

___:10021A3F                 push    offset aEnumchildwindo ; “EnumChildWindows”

___:10021A44                 push    offset aUser32_dll ; “user32.dll”

___:10021A49                 call    esi ; GetModuleHandleW

___:10021A4B                 push    eax

___:10021A4C                 call    edi ; GetProcAddress

___:10021A4E                 mov     dword_100722C4, eax

___:10021A53                 call    ebp ; GetCurrentProcess

___:10021A55                 mov     ecx, dword_100722C4

___:10021A5B                 mov     esi, eax

___:10021A5D                 mov     dword_100722B0, esi

___:10021A63                 mov     byte_100722BC, 0E9h

___:10021A6A                 mov     eax, [ecx]

___:10021A6C                 mov     dword_100722B4, eax

___:10021A71                 movzx   edx, byte ptr [ecx+4]

___:10021A75                 mov     byte_100722B8, dl

___:10021A7B                 lea     edx, [esp+14h+var_4]

___:10021A7F                 push    edx

___:10021A80                 push    5

___:10021A82                 push    offset byte_100722BC

___:10021A87                 mov     eax, offset dword_100216C0

___:10021A8C                 sub     eax, ecx

___:10021A8E                 push    ecx

___:10021A8F                 sub     eax, 5

___:10021A92                 push    esi

___:10021A93                 mov     dword_100722BD, eax

___:10021A98                 call    ebx ; WriteProcessMemory

___:10021A9A                 pop     edi

___:10021A9B                 pop     esi

___:10021A9C                 pop     ebp

___:10021A9D                 pop     ebx

___:10021A9E                 pop     ecx

___:10021A9F                 retn

___:10021A9F HookWindowFinders endp

_

Just for the laughs, I might release some code that can detect the windows despite the hooks, but that’s something for another day. I just wanted to point out the fact they had gone to the trouble of doing it, which is kinda funny really. It’s kinda like having a huge gaping hole in your ship, the size of a basketball, and also a tiny hole the size of a pinhead. So what would a normal person do? You’d try to plug up the basketball sized hole of course. But not WoWMimic, pinhead is their middle name.
  1. amadmonk
    May 15th, 2009 at 06:37 | #1

    I read something interesting about stealthing windows by creating another desktop and putting things there (can’t remember if the term I’m looking for is desktop or winstation).

    I’ve been pondering the possibility of using my second monitor as a second desktop and seeing if this truly does hide windows from all but kernel code.

  2. May 15th, 2009 at 06:50 | #2

    @amadmonk
    I too recall hearing something like that. Then again though, afaik CSRSS can be (ab)used to bypass that restriction. But again, not something I personally have ever looked into, just heard ‘on the grapevine’. More research is required.

    Thanks for the reminder though.

  1. No trackbacks yet.