首页
社区
课程
招聘
[原创]简单调用任意未导出SSDT函数方法
发表于: 2013-4-4 07:55 9205

[原创]简单调用任意未导出SSDT函数方法

2013-4-4 07:55
9205

SSDT未导出函数的调用,对于有SSDT导出表的32位系统来说,可以使用导出表+索引号的方式调用,没有导出的64位系统来说,一般都是各种硬编码。

实际上,还有兼容性和稳定性更好点的方法:

计算两个已知的导出函数的地址差值ulAddressDiff;

计算这两个函数的索引号差值ulIndexDiff;

计算每个索引号差值所占字节大小ulSizeInBytePerFunc=ulAddressDiff/ulIndexDiff;

根据已知导出函数的地址+索引号以及上一步的值,得出索引号是0的函数的地址pIndex0FuncAddress;

以后调用任何未导出函数时,pFuncAddress=pIndex0FuncAddress+ulSizeInBytePerFunc*ulFuncIndex;

ulFuncIndex最好从ntdll获取,这样比较稳定(即使64位系统,一样可以在32位进程按32位进程获取index的方法获取)。

原理:

Zw的函数,实际都是个Stub而已,所有Zw的函数除了索引号不一样,其他几乎完全一样。而且,所有Zw函数在几乎所有目前已知的系统上,都是按照索引号的顺序依次整齐排列的。
又因为Zw函数内部,使用了“相对call”,所以他们的顺序以及排列方式几乎不太可能变动而且实在也没有变动的必要。

so....上述方法稳定性和兼容性,我自认为比以往发现的其他调用未导出的SSDT函数的方法要稳定


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

收藏
免费 6
支持
分享
最新回复 (6)
雪    币: 220
活跃值: (721)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
最好是举例说明就好了,呵呵
2013-4-4 07:57
0
雪    币: 65
活跃值: (112)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
说的够清楚了
2013-4-4 08:00
0
雪    币: 608
活跃值: (648)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
我都是倾向搜索Zw*的函数,不过没楼主那么麻烦,你反汇编一下Zw*函数的内存你会发现所有的Zw*的函数从第一个到最后一个都在一段连续的内存里面,而且每个Zw*函数的开头都是MOV EAX,xxxxxxx  换成机器码就是B8 XXXXXXXX
我的办法是:
1.根据函数名从ntdll.dll中获取index     XX XX XX XX
2.从第一个导出的Zw*函数开始向下搜索 B8 XX XX XX XX 搜索到的地址 就是那个Zw*函数在内核的地址,不管导出与否
2013-4-4 10:12
0
雪    币: 65
活跃值: (112)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
你所谓的不麻烦,有兼容性可言吗?64位不需要单独处理吗?我叫你调用任意一个未导出函数,你可以不用每次调用前都搜索吗(究竟调用哪个是不定的,你根据我给的索引确定就是了)
2013-4-4 13:14
0
雪    币: 65
活跃值: (112)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
6
你那个才是真正麻烦至极……可能你都没看懂我那个方法究竟是如何操作……我那个方法实际上是:

PVOID* g_aFuncPtr[];

真正调用时,ulIndex是索引,那么就是

g_aFuncPtr[ulIndex]就得到函数地址了……取数组元素难不成比硬编码的各种搜索要快?
2013-4-4 13:25
0
雪    币: 1140
活跃值: (3166)
能力值: ( LV12,RANK:385 )
在线值:
发帖
回帖
粉丝
7
赞一个。

向楼主学习:这么好的原创的创新的思维。

有时间编码实验一下。
2014-1-7 09:06
0
游客
登录 | 注册 方可回帖
返回
//