避免FindWindow/EnumWindows/EnumChildWindows的检测的试验手记

    怎么感觉自己在做病毒呐?最近对于悄悄地干坏事比较感兴趣,那么我离病毒还差什么呐?自定位的代码有了,但是书写一个自定位代码无疑是个非常麻烦的事情,所以我想或许我还需要自己完成LoadLibrary做的工作,这样可以达到代码隐藏的目的,也不会破坏把软件工程奉为圭臬的我的审美观。然后是尽量隐藏自己,这个隐藏的手段太多了,慢慢来吧,加油~至于传播和破坏倒不是我特别关心的,希望不要抓我。

    这里我想做的是避免FindWindow/EnumWindows/EnumChildWindows的检测,ollydebug里面有个插件叫做hideod,它就可以完成这个操作,我当时想ollydebug是比较流行的工具,大概有源代码或者手段分析之类的,就在看雪上面疯狂的搜索,居然未果。不过也得到一些启示,就是不光可以单独伺候FindWindow/EnumWindows/EnumChildWindows这三个API,还可以服侍支持这三个兄弟的底层大爷,比如获取窗口句柄数组的函数----如果有的话。OK,决定了方向就这么做下去。看看是不是能够验证我的猜想。

    交待下我的系统是windows xp sp2,因为涉及到底层函数,而不是API本身,所以可能各个系统不一样,大家请注意。另外既然是笔记就会比较冗杂,大家包涵。

    go on......

    随便写了个调用EnumWindows的程序,然后用OllyDbg加载运行.

EnumWindows入口:

77D1CD97 >  8BFF            mov     edi, edi
77D1CD99    
55                  push    ebp
77D1CD9A    8BEC            mov     ebp, esp
77D1CD9C    33C0            xor     eax, eax
77D1CD9E    
50                  push    eax
77D1CD9F    
50                  push    eax
77D1CDA0    FF75 0C       push    dword ptr [ebp
+C]                ; lParam
77D1CDA3    FF75 
08        push    dword ptr [ebp+8]                ; EnumWindowsProc
77D1CDA6    
50                  push    eax
77D1CDA7    
50                  push    eax
77D1CDA8    E8 D0FEFFFF     call    77D1CC7D
77D1CDAD    5D                 pop     ebp
77D1CDAE    C2 
0800       retn    8

 


    可以看到参数被转发到了77D1CC7D了,F7进去看看:

    可以看到77D184D0这个函数的调用得到窗口句柄列表(是一个数组),这里是可以动手脚的,如果FindWindow也用到这个函数的话,那么我们就可以!@#@$$%,那下面看看FindWindow是怎么实现的.

FindWindow

77D2E581 >  8BFF            mov     edi, edi
77D2E583    
55              push    ebp
77D2E584    8BEC            mov     ebp, esp
77D2E586    33C0            xor     eax, eax
77D2E588    
50              push    eax
77D2E589    FF75 0C         push    dword ptr [ebp
+C]                ; 这里传进去的是要寻找窗口的标题
77D2E58C    FF75 
08         push    dword ptr [ebp+8]                ; 这里传进去的是要寻找窗口的类名
77D2E58F    
50              push    eax
77D2E590    
50              push    eax
77D2E591    E8 4CFFFFFF     call    77D2E4E2
77D2E596    5D              pop     ebp
77D2E597    C2 
0800         retn    8

77D2E4E2函数里面主要是把窗口标题以及类名转换成Unicode编码,然后这里是关键
77D2E525    FF75 
18         push    dword ptr [ebp+18]
77D2E528    FF75 E8         push    dword ptr [ebp
-18]               ; 应该是窗口名unicode码。好像是个结构,开始是长度,然后是unicode指针
77D2E52B    FF75 F8         push    dword ptr [ebp
-8]                ; 应该是类名unicode码。好像是个结构,开始是长度,然后是unicode指针
77D2E52E    FF75 0C         push    dword ptr [ebp
+C]
77D2E531    FF75 
08         push    dword ptr [ebp+8]
77D2E534    E8 4CF7FEFF     call    77D1DC85

77D1DC85
==>
77D1DC85    B8 7A110000     mov     eax, 117A
77D1DC8A    BA 0003FE7F     mov     edx, 7FFE0300
77D1DC8F    FF12            call    [edx]                            ; ntdll.KiFastSystemCall,[edx] 
== 7C92EB8B
77D1DC91    C2 
1400         retn    14

7C92EB8B
==>
7C92EB8B 
>  8BD4            mov     edx, esp
7C92EB8D    0F34            sysenter

此时堆栈如下
0012E844   77D1DC91  RETURN to USER32.77D1DC91
0012E848   77D2E539  RETURN to USER32.77D2E539 from USER32.77D1DC85
0012E84C   
00000000
0012E850   
00000000
0012E854   0012E87C 这里指向一个结构,似乎包括unicode长度和unicode字符指针,这里指向
"ToFindClass"
0012E858   0012E86C 这里指向一个结构,似乎包括unicode长度和unicode字符指针,这里指向
"ToFindTitle"
0012E85C   
00000000
0012E860   0012ECBC
0012E864   0012E8B8
0012E868   
00000000
0012E86C   
00180016
0012E870   
00182930  UNICODE "ToFindTitle"
0012E874   0012E86C
0012E878   
00000001
0012E87C   
00180016
0012E880   0018EFD8  UNICODE 
"ToFindClass"


    看来FindWindow最后是到了调用系统中断里面来,可以肯定是在这个系统中断里面完成FindWindow操作的,因为KiFastSystemCall出来以后就开始销毁之前产生的窗口标题和类名的unicode码分配的空间了.这和我以前假设的不一样,但是似乎可以根据ntdll.KiFastSystemCall的中断号来干些坏事,那么我们回头来看EnumWindows更里面是否最终调用了系统中断.

    回顾一下,EnumWindows里面最关键的函数是

77D1CC87    50              push    eax
77D1CC88    FF75 
18           push    dword ptr [ebp+18]
77D1CC8B    C745 FC 
01000000  mov     dword ptr [ebp-4], 1
77D1CC92    FF75 1C           push    dword ptr [ebp
+1C]
77D1CC95    FF75 0C           push    dword ptr [ebp
+C]
77D1CC98    FF75 
08           push    dword ptr [ebp+8]
77D1CC9B    E8 
65000000       call    77D1CD05                        ; 填充窗口句柄结构,最后一个参数会保存返回的句柄数组,返回值是句柄总数

77D1CD05
==>里面有这么一个函数调用
77D1CD31    
50              push    eax
77D1CD32    
57              push    edi
77D1CD33    FF75 FC         push    dword ptr [ebp
-4]
77D1CD36    FF75 
14         push    dword ptr [ebp+14]
77D1CD39    FF75 
10         push    dword ptr [ebp+10]
77D1CD3C    FF75 0C         push    dword ptr [ebp
+C]
77D1CD3F    FF75 
08         push    dword ptr [ebp+8]
77D1CD42    E8 3C000000     call    77D1CD83                        ; 最后一个参数会保存返回的句柄数组

77D1CD83 
==>
77D1CD83    B8 
38110000    mov     eax, 1138
77D1CD88    BA 0003FE7F    mov     edx, 7FFE0300
77D1CD8D    FF12           call    [edx]                            ; ntdll.KiFastSystemCall
77D1CD8F    C2 1C00        retn    1C


    OK,总算有点成绩了,可见使用的都是系统调用,然后我们看看EnumChildWindows.

     EnumChildWindows的调试结果也类似,最好转到sysenter里面去了.......

    难道最好的屏蔽办法是拦截中断,继续研究......

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页