anti-od1.1的分析。
昨天刚刚看到了shoooo发的anti-od1.1。出于个人喜好便下来学习学习。在此感谢shoooo又给我一个学习的机会。
现在就把我的学习成果与各位分享。前辈们也请多多指教,指出不足谢谢。
用OD载入anti文件后果然OD挂掉了。
来看看出错的地址
004A4EE5 3A5B 17 cmp bl,byte ptr ds:[ebx+17]
大家会发现EBX的值是 0D0A0D0A.再看看EBP指向的栈空间是一堆■■■■的数据。
看来EBP是给被改掉了。
用二进制工具打开anti文件找到导入表的文件偏移。会发现ntdll后面跟了一串很长的0D0A0D0A最后以00结束。
ZwSetInformationProcess这个函数名也是如此。似乎他两就是罪魁祸首了。呵呵。
接下来就看看哪里把栈给溢出了。
从新加载OD。
0045F7E6 E8 89CBFFFF call <Ollydbg.sub_45C374>下断点。
OD加载文件后会断在0045F7E6处。F7跟进。
由于函数代码比较长就不全部贴出来了。
0045D120 6A 03 push 3
0045D122 68 04020000 push 204 ;指定读取的长度
0045D127 8B4D CC mov ecx,dword ptr ss:[ebp-34]
0045D12A 038D 3CF9FFFF add ecx,dword ptr ss:[ebp-6C4]
0045D130 51 push ecx
0045D131 8D85 78FDFFFF lea eax,dword ptr ss:[ebp-288]
0045D137 50 push eax
0045D138 E8 CF410000 call <Ollydbg._Readmemory>
0045D13D 83C4 10 add esp,10
0045D140 85C0 test eax,eax
0045D142 75 4E jnz short <Ollydbg.loc_45D192>
这里读取Dll的名称。
0045D192 > 8D85 78FAFFFF lea eax,dword ptr ss:[ebp-588]
0045D198 50 push eax
0045D199 8D95 78FCFFFF lea edx,dword ptr ss:[ebp-388]
0045D19F 52 push edx
0045D1A0 6A 00 push 0
0045D1A2 6A 00 push 0
0045D1A4 8D8D 78FDFFFF lea ecx,dword ptr ss:[ebp-288]
0045D1AA 51 push ecx
0045D1AB E8 0C800400 call <Ollydbg.j___fnsplit>
把后缀.dll 去掉。
0045D4F2 > 8B55 B8 mov edx,dword ptr ss:[ebp-48]
0045D4F5 2955 C4 sub dword ptr ss:[ebp-3C],edx
0045D4F8 8B4D C4 mov ecx,dword ptr ss:[ebp-3C]
0045D4FB 3B4D A4 cmp ecx,dword ptr ss:[ebp-5C]
0045D4FE 73 42 jnb short <Ollydbg.loc_45D542>
0045D500 8B45 88 mov eax,dword ptr ss:[ebp-78]
0045D503 0345 C4 add eax,dword ptr ss:[ebp-3C]
0045D506 83C0 02 add eax,2 ;得到函数名称
0045D509 50 push eax
0045D50A 8D95 78FCFFFF lea edx,dword ptr ss:[ebp-388]
0045D510 52 push edx
0045D511 E8 BE610400 call <Ollydbg._strlen>
0045D516 59 pop ecx
0045D517 8D95 78FDFFFF lea edx,dword ptr ss:[ebp-288]
0045D51D B9 00010000 mov ecx,100
0045D522 2BC8 sub ecx,eax
0045D524 8D85 78FCFFFF lea eax,dword ptr ss:[ebp-388]
0045D52A 83E9 02 sub ecx,2
0045D52D 51 push ecx
0045D52E 50 push eax
0045D52F 68 92C04B00 push Ollydbg.004BC092
0045D534 52 push edx
0045D535 E8 F2960400 call <Ollydbg._sprintf> ;这里格式化
0045D53A 83C4 14 add esp,14
0045D53D E9 AA000000 jmp <Ollydbg.loc_45D5EC>
上面的代码就是格式化字符串,把处理过的DLL名和函数名格式化成USER32.MessageBoxA的形式。
当格式化ntdll 和 ZwSetInformationProcess。注意看栈的变化。我是盯着EBP
的地址。果然当格式完后。EBP被覆盖了。 这里溢出的原因是DLL名做了处理,而函数名没有做处理或者说处理不好。导致了在调用sprintf函数格式化的时候把栈的溢出了。
问题找到了,花了不少时间。心里挺高兴的,就试着想把这个漏洞补补看。
心想既然栈溢出了,无非是栈空间给那两个超长的字符串给弄的。那把缓存弄得足够大,能装的下应该就可以了吧。
来到函数入口
0045C374 > 55 push ebp
0045C375 8BEC mov ebp,esp
0045C377 81C4 30F9FFFF add esp,-6D0
把ESP-6D0 改大吧。喜欢算准确点也行。我没算 直接改成 esp - 1500 够了吧。
空间是够大了。还要改缓存的地址。
原来是 [ebp-288]
以下是我修改的几个地方
0045D517 8D95 78FDFFFF lea edx,dword ptr ss:[ebp-1200]
0045D131 8D85 00EEFFFF lea eax,dword ptr ss:[ebp-1200]
0045D1A4 8D8D 00EEFFFF lea ecx,dword ptr ss:[ebp-1200]
0045D5EC 8D85 00EEFFFF lea eax,dword ptr ss:[ebp-1200]
修改完后再运行试试。哈哈。可以运行了吧。
这个解决方法还有明显缺陷 如果把函数名改更长,还是可以溢出的。
经过和同学讨论觉比较好的解决方法是,把函数名和DLL名称
的总长度求出来,然后动态分配内存。这样就能比较好解决内存溢出的问题。
而在调试过程中确实发现了比较好的时机获取到DLL名和函数名。
0045D511 E8 BE610400 call <Ollydbg._strlen>
当运行到这里的时候,栈顶的2个值正好是 DLL名称和函数名称的地址。这里我们就可以改到自己流程求出他们的长度,分配足够
的内存。
到此,整个分析和修改完成。欢迎各位朋友批评指正,再次感谢shoooo给一次了锻炼的机会。也希望能多向前辈们学习,共同进步。
有表述不清楚的地方请多多见谅。分析不足的地方和错误的地方也请各位朋友指正,谢谢。
武汉科锐学员 :dachongGG
2009.1.09
现在就把我的学习成果与各位分享。前辈们也请多多指教,指出不足谢谢。
用OD载入anti文件后果然OD挂掉了。
来看看出错的地址
004A4EE5 3A5B 17 cmp bl,byte ptr ds:[ebx+17]
大家会发现EBX的值是 0D0A0D0A.再看看EBP指向的栈空间是一堆■■■■的数据。
看来EBP是给被改掉了。
用二进制工具打开anti文件找到导入表的文件偏移。会发现ntdll后面跟了一串很长的0D0A0D0A最后以00结束。
ZwSetInformationProcess这个函数名也是如此。似乎他两就是罪魁祸首了。呵呵。
接下来就看看哪里把栈给溢出了。
从新加载OD。
0045F7E6 E8 89CBFFFF call <Ollydbg.sub_45C374>下断点。
OD加载文件后会断在0045F7E6处。F7跟进。
由于函数代码比较长就不全部贴出来了。
0045D120 6A 03 push 3
0045D122 68 04020000 push 204 ;指定读取的长度
0045D127 8B4D CC mov ecx,dword ptr ss:[ebp-34]
0045D12A 038D 3CF9FFFF add ecx,dword ptr ss:[ebp-6C4]
0045D130 51 push ecx
0045D131 8D85 78FDFFFF lea eax,dword ptr ss:[ebp-288]
0045D137 50 push eax
0045D138 E8 CF410000 call <Ollydbg._Readmemory>
0045D13D 83C4 10 add esp,10
0045D140 85C0 test eax,eax
0045D142 75 4E jnz short <Ollydbg.loc_45D192>
这里读取Dll的名称。
0045D192 > 8D85 78FAFFFF lea eax,dword ptr ss:[ebp-588]
0045D198 50 push eax
0045D199 8D95 78FCFFFF lea edx,dword ptr ss:[ebp-388]
0045D19F 52 push edx
0045D1A0 6A 00 push 0
0045D1A2 6A 00 push 0
0045D1A4 8D8D 78FDFFFF lea ecx,dword ptr ss:[ebp-288]
0045D1AA 51 push ecx
0045D1AB E8 0C800400 call <Ollydbg.j___fnsplit>
把后缀.dll 去掉。
0045D4F2 > 8B55 B8 mov edx,dword ptr ss:[ebp-48]
0045D4F5 2955 C4 sub dword ptr ss:[ebp-3C],edx
0045D4F8 8B4D C4 mov ecx,dword ptr ss:[ebp-3C]
0045D4FB 3B4D A4 cmp ecx,dword ptr ss:[ebp-5C]
0045D4FE 73 42 jnb short <Ollydbg.loc_45D542>
0045D500 8B45 88 mov eax,dword ptr ss:[ebp-78]
0045D503 0345 C4 add eax,dword ptr ss:[ebp-3C]
0045D506 83C0 02 add eax,2 ;得到函数名称
0045D509 50 push eax
0045D50A 8D95 78FCFFFF lea edx,dword ptr ss:[ebp-388]
0045D510 52 push edx
0045D511 E8 BE610400 call <Ollydbg._strlen>
0045D516 59 pop ecx
0045D517 8D95 78FDFFFF lea edx,dword ptr ss:[ebp-288]
0045D51D B9 00010000 mov ecx,100
0045D522 2BC8 sub ecx,eax
0045D524 8D85 78FCFFFF lea eax,dword ptr ss:[ebp-388]
0045D52A 83E9 02 sub ecx,2
0045D52D 51 push ecx
0045D52E 50 push eax
0045D52F 68 92C04B00 push Ollydbg.004BC092
0045D534 52 push edx
0045D535 E8 F2960400 call <Ollydbg._sprintf> ;这里格式化
0045D53A 83C4 14 add esp,14
0045D53D E9 AA000000 jmp <Ollydbg.loc_45D5EC>
上面的代码就是格式化字符串,把处理过的DLL名和函数名格式化成USER32.MessageBoxA的形式。
当格式化ntdll 和 ZwSetInformationProcess。注意看栈的变化。我是盯着EBP
的地址。果然当格式完后。EBP被覆盖了。 这里溢出的原因是DLL名做了处理,而函数名没有做处理或者说处理不好。导致了在调用sprintf函数格式化的时候把栈的溢出了。
问题找到了,花了不少时间。心里挺高兴的,就试着想把这个漏洞补补看。
心想既然栈溢出了,无非是栈空间给那两个超长的字符串给弄的。那把缓存弄得足够大,能装的下应该就可以了吧。
来到函数入口
0045C374 > 55 push ebp
0045C375 8BEC mov ebp,esp
0045C377 81C4 30F9FFFF add esp,-6D0
把ESP-6D0 改大吧。喜欢算准确点也行。我没算 直接改成 esp - 1500 够了吧。
空间是够大了。还要改缓存的地址。
原来是 [ebp-288]
以下是我修改的几个地方
0045D517 8D95 78FDFFFF lea edx,dword ptr ss:[ebp-1200]
0045D131 8D85 00EEFFFF lea eax,dword ptr ss:[ebp-1200]
0045D1A4 8D8D 00EEFFFF lea ecx,dword ptr ss:[ebp-1200]
0045D5EC 8D85 00EEFFFF lea eax,dword ptr ss:[ebp-1200]
修改完后再运行试试。哈哈。可以运行了吧。
这个解决方法还有明显缺陷 如果把函数名改更长,还是可以溢出的。
经过和同学讨论觉比较好的解决方法是,把函数名和DLL名称
的总长度求出来,然后动态分配内存。这样就能比较好解决内存溢出的问题。
而在调试过程中确实发现了比较好的时机获取到DLL名和函数名。
0045D511 E8 BE610400 call <Ollydbg._strlen>
当运行到这里的时候,栈顶的2个值正好是 DLL名称和函数名称的地址。这里我们就可以改到自己流程求出他们的长度,分配足够
的内存。
到此,整个分析和修改完成。欢迎各位朋友批评指正,再次感谢shoooo给一次了锻炼的机会。也希望能多向前辈们学习,共同进步。
有表述不清楚的地方请多多见谅。分析不足的地方和错误的地方也请各位朋友指正,谢谢。
武汉科锐学员 :dachongGG
2009.1.09
注意:上传附件及图片大小不得大于30M。
⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。
复制成功
