首页
社区
课程
招聘
[原创]某驱动里的一处EAT Hook函数分析
发表于: 2013-4-13 17:22 9553

[原创]某驱动里的一处EAT Hook函数分析

2013-4-13 17:22
9553

对某驱动里的一处EAT Hook函数进行了分析,由于技术比较菜,费了大半天时间,不过也学到了不少,在此分享总结下。
EAT Hook的流程没什么好说的,找到EAT里需要Hook的函数地址,关掉页保护,原子写入,再恢复页保护。稍微有点特色的地方在于函数名匹配时的二分查找,这地方也是耗费我时间最多的地方。
不多说,直接上码:

.text:000104AC ; ULONG __stdcall EATHook(PVOID ImageBase, PANSI_STRING pstrExportName, ULONG HookFunc, ULONG* pFuncRVA)
.text:000104AC pNameOrdinals   = dword ptr -14h
.text:000104AC pszExportName   = dword ptr -10h
.text:000104AC pNames          = dword ptr -0Ch
.text:000104AC Size            = dword ptr -8
.text:000104AC i               = dword ptr -4
.text:000104AC ImageBase       = dword ptr  8
.text:000104AC pstrExportName  = dword ptr  0Ch
.text:000104AC HookFunc        = dword ptr  10h
.text:000104AC pFuncRVA        = dword ptr  14h
.text:000104AC
.text:000104AC                 mov     edi, edi
.text:000104AE                 push    ebp
.text:000104AF                 mov     ebp, esp
.text:000104B1                 sub     esp, 14h
.text:000104B4                 push    ebx
.text:000104B5                 push    esi
.text:000104B6                 push    edi
.text:000104B7                 lea     eax, [ebp+Size]
.text:000104BA                 push    eax             ; Size
.text:000104BB                 push    0               ; DirectoryEntry, 导出表
.text:000104BD                 push    1               ; MappedAsImage, 返回VA
.text:000104BF                 push    [ebp+ImageBase] ; ImageBase
.text:000104C2                 call    ds:RtlImageDirectoryEntryToData
.text:000104C8                 test    eax, eax
.text:000104CA                 jz      loc_10563       ; return 0
.text:000104D0                 mov     edx, [eax+20h]  ; _IMAGE_EXPORT_DIRECTORY.AddressOfNames
.text:000104D3                 mov     ecx, [eax+24h]  ; _IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals
.text:000104D6                 add     edx, [ebp+ImageBase] ; ImageBase + AddressOfNames
.text:000104D9                 add     ecx, [ebp+ImageBase] ; ImageBase + AddressOfNameOrdinals
.text:000104DC                 mov     edi, [eax+18h]  ; _IMAGE_EXPORT_DIRECTORY.NumberOfNames
.text:000104DF                 and     [ebp+i], 0      ; i = 0
.text:000104E3                 dec     edi             ; NumberOfNames - 1
.text:000104E4                 mov     [ebp+pNames], edx
.text:000104E7                 mov     [ebp+pNameOrdinals], ecx
.text:000104EA                 js      short loc_10563 ; NumberOfNames为0时return 0
.text:000104EC                 mov     ecx, [ebp+pstrExportName]
.text:000104EF                 mov     ecx, [ecx+4]    ; ANSI_STRING.Buffer
.text:000104F2                 mov     [ebp+pszExportName], ecx ; pszExportName = pstrExportName->Buffer
.text:000104F5                 jmp     short loc_104FA
.text:000104F7 ; ---------------------------------------------------------------------------
.text:000104F7
.text:000104F7 loc_104F7:
.text:000104F7                 mov     edx, [ebp+pNames]
.text:000104FA
.text:000104FA loc_104FA:
.text:000104FA                 mov     ecx, [ebp+i]
.text:000104FD                 add     ecx, edi
.text:000104FF                 sar     ecx, 1          ; 二分查找
.text:00010501                 mov     esi, [edx+ecx*4] ; _IMAGE_EXPORT_DIRECTORY.AddressOfNames数组
.text:00010504                 mov     edx, [ebp+pszExportName]
.text:00010507                 add     esi, [ebp+ImageBase] ; ImageBase + Export Name's RVA
.text:0001050A                 mov     [ebp+pstrExportName], edx
.text:0001050D
.text:0001050D loc_1050D:
.text:0001050D                 mov     edx, [ebp+pstrExportName] ; 字符串匹配, 每两个字节匹配
.text:00010510                 mov     bl, [edx]       ; 第一个字节
.text:00010512                 mov     dl, bl
.text:00010514                 cmp     bl, [esi]
.text:00010516                 jnz     short loc_10537 ; 不匹配则跳转, 注意这里的通过cf判断字符大小: cf=1表示导出表里的名字比参数的字符大
.text:00010518                 test    dl, dl
.text:0001051A                 jz      short loc_10533 ; 匹配结束结束则跳
.text:0001051C                 mov     edx, [ebp+pstrExportName]
.text:0001051F                 mov     bl, [edx+1]     ; 第二字节
.text:00010522                 mov     dl, bl
.text:00010524                 cmp     bl, [esi+1]
.text:00010527                 jnz     short loc_10537 ; 不匹配则跳
.text:00010529                 add     [ebp+pstrExportName], 2
.text:0001052D                 inc     esi
.text:0001052E                 inc     esi
.text:0001052F                 test    dl, dl
.text:00010531                 jnz     short loc_1050D ; 匹配未结束则跳
.text:00010533
.text:00010533 loc_10533:
.text:00010533                 xor     edx, edx        ; 匹配上了到这里
.text:00010535                 jmp     short loc_1053C
.text:00010537 ; ---------------------------------------------------------------------------
.text:00010537
.text:00010537 loc_10537:
.text:00010537                 sbb     edx, edx        ; 不匹配到这里
.text:00010539                 sbb     edx, 0FFFFFFFFh ; cf=0时edx=1, cf=1时edx=-1
.text:0001053C
.text:0001053C loc_1053C:
.text:0001053C                 test    edx, edx
.text:0001053E                 jge     short loc_10545 ; edx>=0时跳
.text:00010540                 lea     edi, [ecx-1]    ; 到这里意味这edx<0, 即上面edx=-1的情况, 即导出表中的名字比参数的字符大
.text:00010543                 jmp     short loc_1054D ; 导出表的名字按字母顺序排列, 因此要调整比较的Name, 通过这里的ecx - 1对Name数组下标-1
.text:00010545 ; ---------------------------------------------------------------------------
.text:00010545
.text:00010545 loc_10545:
.text:00010545                 jle     short loc_10552 ; 匹配到
.text:00010547                 lea     edx, [ecx+1]    ; 到这里意味着导出表Name数组下标要调整为+1
.text:0001054A                 mov     [ebp+i], edx    ; 参数字符串肯定是要比ecx + 1的下标Name大了, 故要更新最小下标值
.text:0001054D
.text:0001054D loc_1054D:
.text:0001054D                 cmp     edi, [ebp+i]    ; i其实是二分查找里的最小下标值
.text:00010550                 jge     short loc_104F7 ; edi为二分查找里的最大下标值, 因此edi >= i时继续二分查找
.text:00010552
.text:00010552 loc_10552:
.text:00010552                 cmp     edi, [ebp+i]
.text:00010555                 jl      short loc_10563 ; 二分查找没找到return 0
.text:00010557                 mov     edx, [ebp+pNameOrdinals]
.text:0001055A                 movzx   ecx, word ptr [edx+ecx*2]
.text:0001055E                 cmp     ecx, [eax+14h]  ; ecx为匹配到的函数Ordinal, 与_IMAGE_EXPORT_DIRECTORY.NumberOfFunctions作比较
.text:00010561                 jb      short loc_10567 ; 不小于则return 0
.text:00010563
.text:00010563 loc_10563:
.text:00010563                 xor     eax, eax
.text:00010565                 jmp     short loc_1059E
.text:00010567 ; ---------------------------------------------------------------------------
.text:00010567
.text:00010567 loc_10567:
.text:00010567                 mov     eax, [eax+1Ch]  ; _IMAGE_EXPORT_DIRECTORY.AddressOfFunctions
.text:0001056A                 add     eax, [ebp+ImageBase]
.text:0001056D                 mov     edx, [ebp+HookFunc]
.text:00010570                 lea     edi, [eax+ecx*4]
.text:00010573                 mov     esi, [edi]      ; 匹配到的函数的RVA
.text:00010575                 add     esi, [ebp+ImageBase]
.text:00010578                 test    edx, edx
.text:0001057A                 jz      short loc_10597
.text:0001057C                 call    PageProtectOff
.text:00010581                 sub     edx, [ebp+ImageBase] ; Value, 计算Hook函数相对ImageBase的RVA
.text:00010584                 mov     ecx, edi        ; Target, EAT Hook
.text:00010586                 call    ds:InterlockedExchange
.text:0001058C                 sti                     ; PageProtectOn
.text:0001058D                 push    eax
.text:0001058E                 mov     eax, OldCR0
.text:00010593                 mov     cr0, eax
.text:00010596                 pop     eax
.text:00010597
.text:00010597 loc_10597:
.text:00010597                 mov     eax, [ebp+pFuncRVA]
.text:0001059A                 mov     [eax], edi      ; 匹配到的函数的RVA
.text:0001059C                 mov     eax, esi        ; return匹配到的函数地址
.text:0001059E
.text:0001059E loc_1059E:
.text:0001059E                 pop     edi
.text:0001059F                 pop     esi
.text:000105A0                 pop     ebx
.text:000105A1                 leave
.text:000105A2                 retn    10h
.text:000105A2 EATHook         endp

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 6
支持
分享
最新回复 (7)
雪    币: 14829
活跃值: (158)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
上个样本瞧瞧?
2013-4-13 17:35
0
雪    币: 58782
活跃值: (21931)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
3
鼓励一下,继续努力
2013-4-14 13:14
0
雪    币: 58
活跃值: (72)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
4
具体就不透露是哪个驱动了,能学到东西是关键。
2013-4-14 13:31
0
雪    币: 58
活跃值: (72)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
5
感谢老大的精华
2013-4-14 13:32
0
雪    币: 112
活跃值: (56)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
6
学习了,感谢分享
2013-4-14 13:38
0
雪    币: 284
活跃值: (3824)
能力值: ( LV5,RANK:75 )
在线值:
发帖
回帖
粉丝
7
二分查找,我那边也碰到一例,是找ntoskrnl的导出函数时。
2013-4-14 15:30
0
雪    币: 30
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
来看看~~~~~~~~~~~
2013-4-15 19:32
0
游客
登录 | 注册 方可回帖
返回