Python灰帽子学习笔记(二)——Immunity Debugger部署硬钩子
来源:互联网 发布:php 判断是否是移动端 编辑:程序博客网 时间:2024/05/21 17:11
一、引言
下面是学习python灰帽子第六章Immunity Debugger部署硬钩子部分的学习笔记。
目前对Immunity Debugger软件使用不熟悉,为了深入探索软件的功能,所以下面的部分并没有严格按照书本的套路走,而是利用书本上代码的框架,完成对另一软件(realese后的printf_loop.exe)的硬钩子部署工作。
首先有必要说明一下系统环境和工具版本:
- win10教育版
- VS2012
- python v2.7.9
- Immunity Debugger v1.85
二、实现及过程
首先在VS2012上编译如下C++代码,生成printf_loop.exe。
# printf_loop.cpp#include <iostream> using namespace std;int main(){ int counter = 0; while(1) { printf("Loop iteration %d:\n", counter); _sleep(2*1000);//延时2秒 counter += 1; } return 0;}
接下来对python灰帽子书上源代码进行修改,获取printf函数的入口和出口钩子。因为Immunity Debugger版本的不同,笔者发现书本上代码的一些方法名和实际Immunity Debugger库并不一致,存在一些方法名大小写不一致的问题。经过繁琐的查找和修改过程,初版的Pycommand代码如下(当然问题比较多,后面一步一步调试修改)。
# hippie_easy.py# -*- coding: utf-8 -*- import immlibimport immutils# 搜索包含特定ret指令的基本块,# 寻找函数中合适的挂钩点def getRet(imm, printf_addr, max_opcodes = 300): addr = printf_addr for a in range(0, max_opcodes): op = imm.disasmForward(addr) if op.isRet(): if op.getImmConst() == 0xC: op = imm.disasmBackward(addr, 3) return op.getAddress() addr = op.getAddress() return 0x0# 打印钩子所记录下来的数据信息,def showresult(imm, a ,printfEndAddr, extra = ""): if a[0] == printfEndAddr: imm.log("PrintfStartAddr (0x%08x, 0x%08x) <- 0x%08x %s" % (a[1][0], a[1][1], a[1][2], extra), address = a[1][2]) return "done" else: imm.log("PrintfEndAddr (0x%08x, 0x%08x) %s" % (a[1][0], a[1][1], extra))def main(args): imm = immlib.Debugger() Name = "hippie" fast = imm.getKnowledge(Name) if fast: # 记录我们之前设置下的钩子,打印钩子函数所记录下来的数据信息 hook_list = fast.getAllLog() printfStartAddr, printfEndAddr = imm.getKnowledge("FuncNames") for a in hook_list: ret = showresult(imm, a, printfEndAddr) return "Logged: %d hook hits. Results output to log window." %len(hook_list) # 暂停调试器 imm.pause() printfStartAddr = imm.getAddress("msvcrt.printf") module = imm.getModule("msvcrt.dll") if not module.isAnalysed(): imm.analyseCode(module.getCodebase()) # 寻找合适的函数出口点 printfEndAddr = getRet(imm, printfStartAddr, 1000) imm.log("PrintfEnd hook: 0x%08x" % printfEndAddr) # 保存挂钩点 imm.addKnowledge("FuncNames", (printfStartAddr, printfEndAddr)) # 构建钩子 fast = immlib.STDCALLFastLogHook(imm) # 在尾部布置钩子 imm.log("Logging on PrintfEnd 0x%08x" %printfEndAddr) fast.logFunction(printfEndAddr) fast.logBaseDisplacement("EBP", 8) fast.logBaseDisplacement("EBP", 0xc) fast.logRegister("EAX") #在头部布置钩子 imm.log("Logging on PrintfStart 0x%08x" % printfStartAddr) fast.logFunction(printfStartAddr, 2) # 设立钩子 fast.Hook() #保存钩子对象,以便取回数据记录结果 imm.addKnowledge(Name, fast, force_add = 1) return "Hooks set, press F9 to continue the process."
运行,出现了第一个值得研究的问题,如下图。
看提示,应该是module = imm.getModule(“msvcrt.dll”)这一句没有成功返回,是否msvcrt.dll不存在呢?我们不妨去Immunity Debbuger(太长了,后面简写为ID)里检查一下printf_loop.exe运行时是否导入 msvcrt.dll。
显然,程序运行没有导入 msvcrt.dll,但是我们发现有一个 MSVCR110.dll,和 msvcrt.all 很像。没错,就是它啦,这是VS12版本的运行库。所以,作如下修改:
................. # 暂停调试器 imm.pause() printfStartAddr = imm.getAddress("MSVCR110.printf") module = imm.getModule("MSVCR110.dll") if not module.isAnalysed(): imm.analyseCode(module.getCodebase()) ................
再次运行,成功了。ID的log窗口显示如下:
显然,printf函数尾部的位置没有正确找出,table size 为1,表明只部署了一个钩子。出现这个问题是因为,初版代码里的寻找函数出口的代码直接copy了书本上的,没有针对printf函数的实际情况进行改写。
利用上面找到的printf函数入口的地址,查找汇编代码,可以找到printf函数出口处的汇编代码如下:
上图红框里的就是printf函数的最后五条汇编指令。实际上,IB要做的事情就是在633FEE76(函数出口倒数第五个指令地址)的位置上做点手脚。上面代码里的检索原理就是找到第一个 RETN ,然后判断后面的操作数是否为 OC(适用于 RtlAllocateHeap 函数),而对 printf 函数而言,RETN 的操作数为 0。因此,继续修改:
............... if op.isRet(): if op.getImmConst() == 0x0: op = imm.disasmBackward(addr, 3) return op.getAddress() addr = op.getAddress() ..............
运行,成功。log输出如下:
可以发现在刚才提到的那个位置(printf函数汇编代码倒数第五个指令处)打上了钩子。恢复执行 printf_loop.exe 进程,一定时间后暂停进程,再次运行脚本,log输出如下:
printf函数入口与出口钩子获取的信息成对出现,且与 printf_loop.exe 进程输出一致。没毛病。
至此,实现了对 printf_loop.exe 的硬钩子部署。
三、总结
实现自己的功能远比照着别人的例程学习要难的多,期间会遇到各种奇怪的状况,但是一旦完成了这一过程,势必对使用的工具和脚本思路有更深刻的认识和理解。
本次尝试断断续续,历时七八个小时,感觉最大的收获在于ID软件的使用上,真心觉得这款软件很强大,而且一旦熟练,操作起来也很简单。
- Python灰帽子学习笔记(二)——Immunity Debugger部署硬钩子
- Python灰帽子学习笔记(一)—— pydbg软钩子部署
- 【转】immunity debugger Pycmmands添加模块--Python灰帽子
- Python笔记---Immunity Debugger
- Python笔记---Immunity Debugger
- Python灰帽子笔记二
- 灰帽子python学习(1)
- Python灰帽子笔记一
- 《python灰帽子》笔记四
- python灰帽子学习感想
- 关于Python灰帽子中debugger.attach()不成功解决方法
- 灰帽子python学习(2)--ctypes的了解
- Python 灰帽子笔记之调试器
- 灰帽子python 学习记录 3
- 灰帽子Python 学习记录 4
- 灰帽子Python 学习记录 5
- 灰帽子Python 学习记录 6
- 2014/9/30 《Python 灰帽子—黑客与逆向工程师的Python编程之道》学习
- 操作系统(二)进程&线程
- quartz初步认识。
- angular中的过滤使用浅析
- 密码检测密码强度
- 网站流量统计工具介绍
- Python灰帽子学习笔记(二)——Immunity Debugger部署硬钩子
- ACM-ICPC 常用算法刷题网站整理
- 编程第二十一天
- java实现SHA1签名加密
- (2)puppet单机测试命令apply
- Truffle 3.0部署智能合约至Ethereum节点(区别truffle部署智能合约到testrpc)
- UBUNTU 解决非正常关闭APT-GET的锁
- [学习笔记]用户界面优化之Android侧滑菜单(DrawerLayout使用)
- 句柄的理解