昨天写了个驱动,用vs2010编译不了,但是wdk可以编译。vs2010提示是
查了很多资料也不知道什么原因,有的说打开/Gs选项,然后链接上一个bufferoverflowU.lib文件,但是出错提示更多符号找不到,仔细看了下问题是链接ntoskrnl.lib的时候有个loadcfg.obj找不到__security_cookie的符号,其实这个符号很常见,用于检测堆栈是否被溢出的,/Gs开关就是控制是否做这个检测的。问题是我链接了那个提供这个符号lib还是不行。试了下xp却可以编译。在vs的目录搜索loadcfg,发现了loadcfg.c的文件,看了下里面用到了__security_cookie,用winhex打开ntoskrnl.lib也能搜到loadcfg.obj,所以问题出在这个.c文件,它也参加了编译和链接。用loadcfg.c里面的其他内容搜索到了原因,应该SafeSEH需要关闭,链接命令加上SafeSEH:NO就行了(还不懂求解释)。结合代码和资料复习了一下SEH,并学习了一下SafeSEH。不过后来搜其他结构的时候发现原来早就有这个资料了,但是就当笔记记录一下吧。
随便写个函数,然后Release编译下
1,SecurityCheck,这是普通的打开/Gs需要进行检查的
函数会用__security_cookie xor加密一下ebp,存放起来,也会加密一下scopetable的地址。ebp-10就是异常框架的起点了。在函数结尾,会将ebp ^ cookie的值异或上正确的ebp,用_security_check_cookie检查结果和cookie是否相等,不相等说明ebp-1c的位置被修改了,所以能简单地阻止被溢出。溢出我没研究过。。。还有xxxx的位置,是异常分发下来填写的,用GetExceptionInformation获取这个xxxx,xxxx,xxxx+4就是Context和ExceptionRecord的结构指针, r0分发的时候把2个结构打包到用户堆栈。
2,SafeSEH
异常分发到r3之后的顺序是KiUserExceptionDispatcher -> RtlDispatchException,不考虑VEH的话,会先判断这2个条件:异常处理的框架在堆栈,异常处理的Handler不在堆栈上,不满足就RaiseException。调用ZwQueryInformationProcess查看一下ProcessExecuteFlags属性,得到ExecuteOption。之后就是RtlIsValidHandler,来检测是否Handler是否正常, ExecuteOption作为参数参入RtlIsValidHandler。
RtlIsValidHandler-> RtlLookupFunctionTable,查看一下信息。
.text:77EE8B68 mov esi, _LdrpInvertedFunctionTable ; 这个是需要检查的模块数目。
.text:77EE8B6E cmp esi, ebx
.text:77EE8B70 jz loc_77EDD3F6
.text:77EE8B76 dec esi
.text:77EE8B77
.text:77EE8B77 loc_77EE8B77: ; CODE XREF: RtlLookupFunctionTable(x,x,x)+69 j
.text:77EE8B77 ; RtlLookupFunctionTable(x,x,x)+271 j
.text:77EE8B77 cmp esi, ebx
.text:77EE8B79 jl loc_77EDD3F6 ; 没找到,就跳走,之后会返回0
.text:77EE8B7F lea ecx, [esi+ebx] ; ebx=0,esi=count-1,这是二分查找,esi是high,ebx是low指针
.text:77EE8B82 sar ecx, 1
.text:77EE8B84 mov eax, ecx
.text:77EE8B86 shl eax, 4 ; 每一项对应的是16byte大小的结构。off0用于解密
.text:77EE8B89 add eax, offset unk_77F9AC0C ; 全局变量,是这个模块表的起点
.text:77EE8B8E mov edi, [eax+4] ; off4是模块映像基地址,off8是大小,offc是SafeSeh的数量
.text:77EE8B91 mov edx, [eax+8]
.text:77EE8B94 add edx, edi
.text:77EE8B96 cmp [ebp+Handler], edi
.text:77EE8B99 jb loc_77EE8DA4 ; 调整high的指针
.text:77EE8B9F cmp [ebp+Handler], edx
.text:77EE8BA2 jb short loc_77EE8BA9 ; 找到了
.text:77EE8BA4 lea ebx, [ecx+1] ; 调整low指针
.text:77EE8BA7 jmp short loc_77EE8B77
.text:77EE8BA9 ; ---------------------------------------------------------------------------
.text:77EE8BA9
.text:77EE8BA9 loc_77EE8BA9: ; CODE XREF: RtlLookupFunctionTable(x,x,x)+64 j
.text:77EE8BA9 mov ecx, edi
.text:77EE8BAB mov [ebp+var_1C], ecx
.text:77EE8BAE mov ecx, [eax+0Ch]
.text:77EE8BB1 mov edx, [ebp+arg_8] ; 第三个参数返回SafeSeh(handler)的个数
.text:77EE8BB4 mov [edx], ecx
.text:77EE8BB6 push dword ptr [eax] ; off0用于解密
.text:77EE8BB8 call _RtlDecodeSystemPointer@4 ; RtlDecodeSystemPointer(x)
.text:77EE8BBD mov esi, eax ; 得到的结果就是这个模块的SafeSeh表的地址,返回的也是这个值
.text:77EE8ADD call _RtlLookupFunctionTable@12 ; RtlLookupFunctionTable(x,x,x)
.text:77EE8AE2 xor edi, edi
.text:77EE8AE4 mov [ebp+SafeSehTable], eax
.text:77EE8AE7 cmp eax, edi
.text:77EE8AE9 jz ModDontHaveSehTable ; 不在模块内部
.text:77EE8AEF mov esi, [ebp+nCount]
.text:77EE8AF2 cmp esi, edi
.text:77EE8AF4 jz ModDontHaveSehTable ; 或者在模块内部,但是模块本身没有sehtable
.text:77EE8AFA cmp eax, 0FFFFFFFFh
.text:77EE8AFD jz loc_77F4DE4A
.text:77EE8B03
.text:77EE8B03 loc_77EE8B03: ; CODE XREF: RtlIsValidHandler(x,x)+65390 j
.text:77EE8B03 sub ebx, [ebp+pMouduleBase] ; 得到Handler的Rva
.text:77EE8B06 xor edx, edx
.text:77EE8B08 cmp esi, edi ; esi是high索引,edx是low索引
.text:77EE8B0A jl loc_77F37DAE ; 没有找到
.text:77EE8B10
.text:77EE8B10 loc_77EE8B10: ; CODE XREF: RtlIsValidHandler(x,x)+198 j
.text:77EE8B10 lea ecx, [edx+esi]
.text:77EE8B13 sar ecx, 1
.text:77EE8B15 mov edi, [eax+ecx*4] ; SafeSehTable里面的项
.text:77EE8B18 cmp ebx, edi
.text:77EE8B1A jb loc_77EE8D94 ; 调整一下索引
.text:77EE8B20 ja loc_77EE8C5F ; 调整一下索引
.text:77EE8B26
.text:77EE8B26 RetTrue: ; CODE XREF: RtlIsValidHandler(x,x)+4F5CF j
.text:77EE8B26 ; RtlIsValidHandler(x,x)+653C2 j ...
.text:77EE8B26 mov al, 1 ; Return True
.text:77EE8B28
.text:77EE8B28 Ret: ; CODE XREF: RtlIsValidHandler(x,x)+65398 j
.text:77EE8B28 ; RtlIsValidHandler(x,x)+65403 j
.text:77EE8B28 mov ecx, [ebp+var_4]
.text:77EE8B2B pop edi
.text:77EE8B2C pop esi
.text:77EE8B2D xor ecx, ebp
.text:77EE8B2F pop ebx
.text:77EE8B30 call @__security_check_cookie@4 ; __security_check_cookie(x)
.text:77EE8B35 leave
.text:77EE8B36 retn 8
.text:77F3807A ModDontHaveSehTable: ; CODE XREF: RtlIsValidHandler(x,x)+2D j
.text:77F3807A ; RtlIsValidHandler(x,x)+38 j
.text:77F3807A cmp [ebp+ExeOption], edi
.text:77F3807D jz loc_77F37D91
.text:77F38083
.text:77F38083 CmpExecuteOption: ; CODE XREF: RtlIsValidHandler(x,x)+4F2E7 j
.text:77F38083 ; RtlIsValidHandler(x,x)+653A8 j
.text:77F38083 mov eax, [ebp+ExeOption]
.text:77F38086 and eax, 30h
.text:77F38089 cmp al, 30h ; ExecuteDispatchEnable | ImageDispatchEnable
.text:77F3808B jz RetTrue ; Return True
.text:77F38091 jmp loc_77F4DE69
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课