首页
社区
课程
招聘
[原创]anti-od1.1的分析。
发表于: 2009-1-9 15:41 11389

[原创]anti-od1.1的分析。

2009-1-9 15:41
11389

[LEFT]昨天刚刚看到了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
                                        [/LEFT]


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

收藏
免费 7
支持
分享
最新回复 (22)
雪    币: 209
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
奇文共欣赏!感谢楼主
2009-1-9 15:45
0
雪    币: 1632
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
把函数名和DLL名称
的总长度求出来,然后动态分配内存。

OK123456
2009-1-9 15:46
0
雪    币: 398
活跃值: (343)
能力值: (RANK:650 )
在线值:
发帖
回帖
粉丝
4
虽然你感谢我
但你这个解决方法是治标不治本啊
strongod才素王道
2009-1-9 15:55
0
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
5
膜拜海风月影
2009-1-9 16:51
0
雪    币: 398
活跃值: (343)
能力值: (RANK:650 )
在线值:
发帖
回帖
粉丝
6
太偏心了,我的怎么没有精华啊
2009-1-9 16:57
0
雪    币: 424
活跃值: (10)
能力值: ( LV9,RANK:850 )
在线值:
发帖
回帖
粉丝
7
dachongGG


初级会员

资 料:
注册日期: Sep 2008
帖子: 1
精华: 1


武汉科锐学员 :dachongGG


2009.1.09


我帮楼主醒目一下,顺便 支持
2009-1-9 17:02
0
雪    币: 7309
活跃值: (3788)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
8
有这么长名字的dll和函数名吗
2009-1-9 17:09
0
雪    币: 398
活跃值: (343)
能力值: (RANK:650 )
在线值:
发帖
回帖
粉丝
9
我自己写的dll有很长的函数名字
2009-1-9 17:10
0
雪    币: 7309
活跃值: (3788)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
10
太强了,我写不出来
2009-1-9 17:16
0
雪    币: 357
活跃值: (3403)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
11
按你这个逻辑,我可以写4G长的函数名字,没意义
2009-1-9 17:39
0
雪    币: 398
活跃值: (343)
能力值: (RANK:650 )
在线值:
发帖
回帖
粉丝
12
你4G长的函数名能编译么?
我的超长函数名实实在在能编译链接的啊
2009-1-9 17:58
0
雪    币: 334
活跃值: (22)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
dachongGG
一看名就知道是个泡MM的高手
2009-1-9 18:18
0
雪    币: 357
活跃值: (3403)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
14
你的anti.exe是编译出来的吗?给个代码观赏下
2009-1-9 18:33
0
雪    币: 398
活跃值: (343)
能力值: (RANK:650 )
在线值:
发帖
回帖
粉丝
15
请再看一遍我9楼的贴子内容,想清楚再回贴
不要跑题
2009-1-9 21:58
0
雪    币: 357
活跃值: (3403)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
16
潜水123456
2009-1-9 22:15
0
雪    币: 398
活跃值: (343)
能力值: (RANK:650 )
在线值:
发帖
回帖
粉丝
17
是我表达能力差还是你理解能力差?
我9楼说的是
"我自己写的dll有很长的函数名字“

这句话表达2个意思
1. 我自己能写的是dll文件
2. 我dll里有很长的函数名字

这两层意思和我的anti.exe一点关系都没有
#include <windows.h>
#pragma comment (linker, "/subsystem:windows")
#pragma comment (linker, "/dll")

__declspec(dllexport) aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
{
}
2009-1-9 22:21
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
菜鸟隆重地走过!!!!
2009-1-9 22:51
0
雪    币: 82
活跃值: (526)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
顶dachongGG
2009-1-9 22:57
0
雪    币: 82
活跃值: (10)
能力值: (RANK:210 )
在线值:
发帖
回帖
粉丝
20
噢噢噢噢初来地球,大概不知道.
因为我的语言能力比较落后,所以从很久以前就开始就只看贴不发贴了
2009-1-10 05:39
0
雪    币: 33
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
这个是怎么断出来的?
2009-1-10 09:51
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
代码中还是得禁止使用sprintf.
2009-1-10 11:02
0
雪    币: 1349
活跃值: (485)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
膜拜学习~~~~
2009-1-10 21:16
0
游客
登录 | 注册 方可回帖
返回
//