一个简单的问题
2017-08-22 06:31
295 查看
在XP中通过注册表回调 CmRegisterCallback 注册注册表通知函数,在走 XP 的 RegNtPreCreateKey 分支的时候,会出现问题,
使用过的人可能会知道,这个问题就是,注册表路径拿不全,这怎么办,
路径拿不全,过滤就没法做啊,
很愁,
而这种情况下,如果又不想使用SSDT HOOK,那么就更愁了,怎么办,怎么解决,
我想了一个看似好办法的馊主意,但是可用,
就是,爬调用栈,
既然是XP下,那么内联汇编很容易,拿到EBP之后,直接就可以一层层爬调用栈了,
除非中间被人截断,否则可以爬出完整的调用栈,然后,就是爬到头,找到调用源,然后开干,
事先声明,因为这本身就是微软没有提供的一个不可能完成的任务,
所以为了完成它,所选择道路可能也不靠谱,这个很正常,
好了,这里说准备工作,
准备工作是,需要首先得到所有进程的PEB,然后拿到所有进程的模块链,枚举出advapi32模块,
然后得到模块基址和偏移,得到内部所需要用到的函数RVA,然后根据模块的BASE和RVA就能算出函数的具体位置,
然后就是开始无尽地爬调用栈,
趴到什么地方是个头呢,一边爬,一边计算,算 (char *)(*(DWORD*)(ebp + 4) - 5) ,这个东西的第0个元素是否是一个call,
然后后续的4个字节组成的地址是否是我们要找的函数的地址,如果是的话,
那么,好办了,这里就是入口点,
然后根据我们要找的函数,直接用ebp 来算参数就好了,参数1 是 +8 ,参数2是 +C,
到这里就简单多了,轻车熟路了。
不过,这个方案里面,还有几个地方需要想一下,
首先内核是在读应用层地址,所以需要prob 一下是否可读,然后验证一下是否有效,最重要的还要加一个异常处理在外面,保证不会崩掉,
如果有能力的,其实可以每读一次之前做个MDL,这样的话就不会有内存访问的问题。
OK,结束。
其实第二个方法和第一个方法思路相同,只不过点不同,路上有N 多函数可以找参数,
如果可以Mm出内核函数地址,爬内核函数的参数的话,很有可能风险更低一些。
简单的代码实现就是这样的
得到EBP之后,开始一步一步地往上爬,最后爬到一个指定的返回地址,则认为找到了函数,
找到函数之后,抓一下函数的参数,就可以了,
第一个参数是HKEY,第二个参数是一个字符串,就直接拿到了,
因为,这里是 ADVAPI32!RegCreateKeyW
使用过的人可能会知道,这个问题就是,注册表路径拿不全,这怎么办,
路径拿不全,过滤就没法做啊,
很愁,
而这种情况下,如果又不想使用SSDT HOOK,那么就更愁了,怎么办,怎么解决,
我想了一个看似好办法的馊主意,但是可用,
就是,爬调用栈,
既然是XP下,那么内联汇编很容易,拿到EBP之后,直接就可以一层层爬调用栈了,
除非中间被人截断,否则可以爬出完整的调用栈,然后,就是爬到头,找到调用源,然后开干,
事先声明,因为这本身就是微软没有提供的一个不可能完成的任务,
所以为了完成它,所选择道路可能也不靠谱,这个很正常,
好了,这里说准备工作,
准备工作是,需要首先得到所有进程的PEB,然后拿到所有进程的模块链,枚举出advapi32模块,
然后得到模块基址和偏移,得到内部所需要用到的函数RVA,然后根据模块的BASE和RVA就能算出函数的具体位置,
然后就是开始无尽地爬调用栈,
趴到什么地方是个头呢,一边爬,一边计算,算 (char *)(*(DWORD*)(ebp + 4) - 5) ,这个东西的第0个元素是否是一个call,
然后后续的4个字节组成的地址是否是我们要找的函数的地址,如果是的话,
那么,好办了,这里就是入口点,
然后根据我们要找的函数,直接用ebp 来算参数就好了,参数1 是 +8 ,参数2是 +C,
到这里就简单多了,轻车熟路了。
不过,这个方案里面,还有几个地方需要想一下,
首先内核是在读应用层地址,所以需要prob 一下是否可读,然后验证一下是否有效,最重要的还要加一个异常处理在外面,保证不会崩掉,
如果有能力的,其实可以每读一次之前做个MDL,这样的话就不会有内存访问的问题。
OK,结束。
其实第二个方法和第一个方法思路相同,只不过点不同,路上有N 多函数可以找参数,
如果可以Mm出内核函数地址,爬内核函数的参数的话,很有可能风险更低一些。
简单的代码实现就是这样的
得到EBP之后,开始一步一步地往上爬,最后爬到一个指定的返回地址,则认为找到了函数,
找到函数之后,抓一下函数的参数,就可以了,
第一个参数是HKEY,第二个参数是一个字符串,就直接拿到了,
因为,这里是 ADVAPI32!RegCreateKeyW
1 ULONG old_EBP = 0; 2 3 __asm mov old_EBP, ebp; // 当前函数栈帧 4 5 for (;;) 6 { 7 old_EBP = *(ULONG*)old_EBP; 8 9 if (((*(ULONG*)(old_EBP + 4)) == 0)) 10 { 11 DbgPrint("Have no find func \n"); 12 break; 13 } 14 if (((*(ULONG*)(old_EBP + 4)) == 0x77dcba74)) 15 { 16 old_EBP = *(ULONG*)old_EBP; 17 DbgPrint("Have find func : 0x%08X , %S\n" , (*(ULONG*)(old_EBP + 8)), (*(ULONG*)(old_EBP + 0xC))); 18 break; 19 } 20 }
相关文章推荐
- 你就是一个画家!你现在想绘制一幅画,但是你现在没有足够颜色的颜料。为了让问题简单,我们用正整数表示不同颜色的颜料。你知道这幅画需要的n种颜色的颜料,你现在可以去商店购买一些颜料,但是商店不能保证能供应所有颜色的颜料,所以你需要自己混合一些颜料。混合两种不一样的颜色A和颜色B颜料可以产生(A XOR B)这种颜色的颜料(新产生的颜料也可以用作继续混合产生新的颜色,XOR表示异或操作)。本着勤俭节约的
- 一个简单但值得深思的问题!
- 时间比较问题 举一个简单例子说明:比如一个论坛对当天发表的贴子用new图片标记一下
- 在ScrollView添加一个ListView造成的滚动问题的简单解决办法()
- 在自己的WSASOCKET服务端/客户端中做了一个简单的解包程序处理粘包的问题
- 发布一个史上最简单代码最少Javascript Timer,解决一切定时执行的问题
- “简单”和“勤奋”就是只围绕团队的理念和目标去工作,而不会因为其他的问题或内耗来分散团队的力量和注意力。为此,管理者要为团队创造一个积极向上、团队合作、充满激情的工作氛围。
- 小问题不简单,一个无线故障的排查过程
- 由一个简单的String c=a+b的Java问题引发一点想法
- 一个简单的优化例子(锁问题)
- 火车运煤问题 - 增加一个简单算法实现
- Eclipse RCP项目依赖一个简单java project的调试问题
- 一个简单的数学问题
- 简单记录一个PoupWindow使用时碰到的问题
- 一个简单的初始化问题
- 问题:关于贴友的一个书本页面简单布局(html+css)的实现
- 一个Apache CollectionUtils.intersection 方法的简单问题
- 菜鸟发问,请各位不吝赐教啊! 关于一个简单的程序的理解问题
- 一个简单的SQL问题