lldb python 脚本扩展之超级断点增强版
来源:互联网 发布:python可以开发游戏吗 编辑:程序博客网 时间:2024/05/17 01:40
lldb python 脚本扩展之超级断点增强版
引言
不知道各位在逆向ios用到lldb的时候是啥感觉,反正我是服了。没界面到算了,各种跳转和断点用起来不知道有多麻烦。所以我尽量用静态分析。不过越往后,越发现,光静态实在是不行。
- ios不知道有没有动态解密一说,就是把mach-o加密的部分在加载的时候再解密。android和windows上有一种方式叫做dump内存,可以把加载后解密的部分保存下来,但我在ios上用lldb memory read dump的时候发现限制了1024字节,后来又想把一堆1024字节拼起来,有发现不是所有的地址都能读。于是乎,我怀疑,ios内存读写存在限制。不知是否?有明白的希望留言告知。
- 网上有个python lldb的超级断点的脚本,本工具经该工具改编而来,原作者不详,大家可以查下。
- ios和window汇编上有个说法上的不同,模块的地址ios上叫ASLR偏移,而windows上叫基地址。我们反编译工具里的地址,ios叫做基地址,windows上叫偏移offset.好像正好相反,文中按照ios本来的叫法说明。
lldb 断点之困
lldb下断点之前都有一个偏移查找的过程,“image list -o -f”。其实其他平台也类是,超级断点这个工具的核心就是把模块偏移寻找的过程自动化,让我们只需要输入基地址就可以在目标地址下断点的脚本。当然这一切的前提是,lldb预留了python的接口,否则就悲催了。
简单介绍下代码:
def get_ASLR(): # 获取‘image list -o’命令的返回结果 interpreter = lldb.debugger.GetCommandInterpreter() returnObject = lldb.SBCommandReturnObject() interpreter.HandleCommand('image list -o', returnObject) output = returnObject.GetOutput(); # 正则匹配出第一个0x开头的16进制地址 match = re.search(r'(1\]\s)(0x[0-9a-fA-F]+)', output) if match: return match.group(2) else: return None
代码很简单,通过接口执行lldb命令得到返回的数据,正则匹配出用户模块偏移量。
def sbr(debugger, command, result, internal_dict): #用户是否输入了地址参数 if not command: print >>result, 'Please input the address!' return ASLR = get_ASLR() if ASLR: #如果找到了ASLR偏移,就设置断点 debugger.HandleCommand('br set -a "%s+%s"' % (ASLR, command)) else: print >>result, 'ASLR not found!'# And the initialization code to add your commands
同样利用接口把我们输入的基地址和偏移传入lldb执行命令。
用户态代码的锁定
这里到了我胡编乱造的时候,我在调试ios的发现,object-c反汇编后的代码有一个很大的特点,就是喜欢在汇编代码块里乱跳。可能是更object-c和arm的运行机制有关,导致我们的代码在用户模块里的过程很难捕捉到,一句话,单步走功能就是个坑。
为了解决这个问题,我在以上脚本的基础上,利用断点功能实现了两大扩展。
1.单步执行在本模块,坚决不跳到其他模块的单步走
2.多条指令一键式执行,只要输入执行指令数,一条命令立刻执行到位。同样执行过程锁定在同一个模块。
(你要想去其他模块,本身的命令就够了)
正真意义上的单步执行
首先,我们要获得当前指令的地址,很简单,“register read/x pc”
同样我们正则匹配出地址字符串返回。
def get_pc(): # 获取‘image list -o’命令的返回结果 interpreter = lldb.debugger.GetCommandInterpreter() returnObject = lldb.SBCommandReturnObject() interpreter.HandleCommand('register read/x pc', returnObject) output = returnObject.GetOutput(); # 正则匹配出第一个0x开头的16进制地址 match = re.match(r'.+(0x[0-9a-fA-F]+)', output) if match: return match.group(1) else: return None
然后在下一条指令的本模块下一条地址的地方下断点,并执行到断点
ADDRESS = get_pc() #增加断点 if not command: if ADDRESS: debugger.HandleCommand('br set -a "%s+4"' % (ADDRESS)) print 'br set success:"%s+4"'%ADDRESS #执行到断点 debugger.HandleCommand('c') NUM = getbrlistn()
执行完毕删除断点
NUM = getbrlistn() #删除断点 if NUM: debugger.HandleCommand('br dele %s' % (NUM)) print "br dele success:%s"%NUM else: print >>result, 'br list number not found!' else:
这里还有个获取上一步断点并删除的操作。同样正则。
#得到最后断点的标号def getbrlistn(): interpreter = lldb.debugger.GetCommandInterpreter() returnObject = lldb.SBCommandReturnObject() interpreter.HandleCommand('br list', returnObject) output = returnObject.GetOutput(); # 正则匹配出所有的断点代号 match = re.findall(r'(^\d{1,4})(:\saddress)', output,re.M) if match: num=len(match) strlast=match[num-1] brnum=strlast[0] #print brnum return brnum else: return None# Super breakpoint
单步基础上的多步执行
基本和单步执行的代码一样,不同之处在于我们需要传入执行步数,command.并转换到响应的地址下断点。
offby=int(command,16)*4 if ADDRESS: debugger.HandleCommand('br set -a "%s+%x"' % (ADDRESS,offby)) print 'br set success:"%s+%x"'%(ADDRESS,offby) #执行到断点 debugger.HandleCommand('c')
然后就是执行到断点和删除断点。
获得静态编译的地址
同样的,我们执行到某个位置后想在ida里静态查看下相应的代码,也给他自动化一下。
def idaposi(debugger, command, result, internal_dict): ASLR=get_ASLR() PCADD=get_pc() print "ASLR:",ASLR print "trueADDR:",PCADD if (ASLR!=None)&(PCADD!=None): #print ASLR #print PCADD addr=int(PCADD,16)-int(ASLR,16) print "idaposition_address:ox%x"%addr else: print "get info error"
这下齐全了。各位可以自己敲一下,把代码改成这样就能用了。
完整代码在下面。
#!/usr/bin/python#coding:utf-8'''执行以下脚本导入超级断点工具(lldb) command script import ~/workspace/3-lldb/subr.pyThe "sbr" python command has been installed and is ready for use.(lldb)输出安装成功,只需就收一个地址就可工作subr 地址(lldb) br deleteAbout to delete all breakpoints, do you want to do that?: [Y/n] yAll breakpoints removed. (1 breakpoint)(lldb) subr 0x00000001000093ddBreakpoint 2: where = Calculator`___lldb_unnamed_function161$$Calculator, address = 0x000000010cb033dd(lldb)对于经常使用的脚本,可以在lldb的初始化文件里添加命令加载脚本,启动自定义的命令修改~/.lldbinit文件,在文件里加入一行command script import ~/sbr.py'''import lldbimport commandsimport optparseimport shleximport re# 获取ASLR的偏移地址def get_ASLR(): # 获取‘image list -o’命令的返回结果 interpreter = lldb.debugger.GetCommandInterpreter() returnObject = lldb.SBCommandReturnObject() interpreter.HandleCommand('image list -o', returnObject) output = returnObject.GetOutput(); # 正则匹配出第一个0x开头的16进制地址 match = re.search(r'(1\]\s)(0x[0-9a-fA-F]+)', output) if match: return match.group(2) else: return Nonedef get_pc(): # 获取‘image list -o’命令的返回结果 interpreter = lldb.debugger.GetCommandInterpreter() returnObject = lldb.SBCommandReturnObject() interpreter.HandleCommand('register read/x pc', returnObject) output = returnObject.GetOutput(); # 正则匹配出第一个0x开头的16进制地址 match = re.match(r'.+(0x[0-9a-fA-F]+)', output) if match: return match.group(1) else: return None#得到最后断点的标号def getbrlistn(): interpreter = lldb.debugger.GetCommandInterpreter() returnObject = lldb.SBCommandReturnObject() interpreter.HandleCommand('br list', returnObject) output = returnObject.GetOutput(); # 正则匹配出所有的断点代号 match = re.findall(r'(^\d{1,4})(:\saddress)', output,re.M) if match: num=len(match) strlast=match[num-1] brnum=strlast[0] #print brnum return brnum else: return None# Super breakpointdef sni(debugger, command, result, internal_dict): ADDRESS = get_pc() #增加断点 if not command: if ADDRESS: debugger.HandleCommand('br set -a "%s+4"' % (ADDRESS)) print 'br set success:"%s+4"'%ADDRESS #执行到断点 debugger.HandleCommand('c') NUM = getbrlistn() #删除断点 if NUM: debugger.HandleCommand('br dele %s' % (NUM)) print "br dele success:%s"%NUM else: print >>result, 'br list number not found!' else: print >>result, 'ADDRESS not found!' else: offby=int(command,16)*4 if ADDRESS: debugger.HandleCommand('br set -a "%s+%x"' % (ADDRESS,offby)) print 'br set success:"%s+%x"'%(ADDRESS,offby) #执行到断点 debugger.HandleCommand('c') NUM = getbrlistn() #删除断点 if NUM: debugger.HandleCommand('br dele %s' % (NUM)) print "br dele success:%s"%NUM else: print >>result, 'br list number not found!' else: print >>result, 'ADDRESS not found!'def idaposi(debugger, command, result, internal_dict): ASLR=get_ASLR() PCADD=get_pc() print "ASLR:",ASLR print "trueADDR:",PCADD if (ASLR!=None)&(PCADD!=None): #print ASLR #print PCADD addr=int(PCADD,16)-int(ASLR,16) print "idaposition_address:ox%x"%addr else: print "get info error" def sni2(debugger, command, result, internal_dict): NUM = getbrlistn() #删除断点 if NUM: #print "%d"%NUM debugger.HandleCommand('br dele %s' % (NUM)) print NUM else: print >>result, 'br list number not found!'# And the initialization code to add your commands # Super breakpointdef sbr(debugger, command, result, internal_dict): #用户是否输入了地址参数 if not command: print >>result, 'Please input the address!' return ASLR = get_ASLR() if ASLR: #如果找到了ASLR偏移,就设置断点 debugger.HandleCommand('br set -a "%s+%s"' % (ASLR, command)) else: print >>result, 'ASLR not found!'# And the initialization code to add your commands def __lldb_init_module(debugger, internal_dict): # 'command script add sbr' : 给lldb增加一个'sbr'命令 # '-f sbr.sbr' : ¸该命令调用了sbr文件的sbr debugger.HandleCommand('command script add subr -f subr.sbr') debugger.HandleCommand('command script add sni -f subr.sni') debugger.HandleCommand('command script add idap -f subr.idaposi') print 'The "sbr" python command has been installed and is ready for use.'
- lldb python 脚本扩展之超级断点增强版
- LLDB中的Python脚本
- 使用Python脚本强化LLDB调试器
- 超级玛丽增强版
- memcache之增强版libmemcached扩展
- iOS开发之LLDB断点调试和常用命令
- windbg扩展python脚本
- LLDB在IOS断点调试
- GDB和LLDB断点调试指令
- [断点调试好助手]LLDB调试
- iOS LLDB调试器和断点调试
- iOS LLDB调试器和断点调试
- LoadRunner VuGen脚本增强之逻辑判断增强与事务
- LoadRunner VuGen 脚本增强之检查点
- LoadRunner VuGen脚本增强之参数化
- xcode使用lldb的python脚本查看WebKit的WTF::String和Vector等基础类
- Unity3d学习之脚本工程及脚本断点调试
- 让大蛇(Python)帮你找工作 之增强版
- 二叉排序树的创建与使用
- 乌镇AI论坛最全盘点:中国互联网半壁江山坐在了一起,他们怎么看AI
- docker-machine批量安装和配置 docker host
- 波浪号按位取反和叹号逻辑非取反
- Oracle 导出某一用户下数据,Table不全
- lldb python 脚本扩展之超级断点增强版
- JDBC详解
- 【中文教学视频】Android Oreo 中的后台进程
- vue中渲染数据可能有一个无限更新循环--You may have an infinite update loop in a component render function.
- jquery报错
- Google 开发者大会报名结果出炉
- 区块链中GAS介绍
- CentOS 7 Linux 安装Tomcat 8(咋个办呢 zgbn)
- 利用pytorch实现神经网络风格迁移Neural Transfer