用python开发调试器——起始篇
首先,你得准备一套python开发环境,正常情况下,一般是在windows下开发的,因为win系统应用广泛,再则就是要有个IDE,这里我选择我熟悉的Eclipse。环境搭建,网上都有,比如:http://www.jb51.net/article/34517.htm。
环境搭好后,再来说一下什么是调试器。
一般用python写黑客脚本,都会用到一个神库:ctype。兼具C语言的底层操作能力,同时具备动态语言的方便性,这种情况在编程语言里不多见吧?!ctype模块能使你轻而易举的调用动态链接库中的导出函数,更美妙的是你还可以通过ctype构建复杂的C数据类型,从而编写出具有底层内存操作功能的工具函数。
那么,什么是动态链接库呢?
动态链接库不过只是一些经过编译过的二进制文件,只有在运行时才会被链接到主进程。在win平台下这些二进制文件被称为DLL,而linux下这些文件是被叫做共享对象(SO)的。无论哪一种平台,这些二进制文件都是通过导出函数名称的方式来呈现它们所包含的函数。这些由链接库导出的函数名称可以被解析成为内存中实际的函数地址。
好了,切入正题,本章主要解释调试器。
调试器被称为“黑客之瞳”,望文生义,当然是好比人的眼睛。调试器能够跟踪一个进程的运行时状态,这种技术叫动态分析技术。动态分析技术在某些场合下必不可少。比如:开发基于安全漏洞实施攻击的exploit程序,或者作为fuzzing测试框架进行漏洞挖掘时的辅助工具,以及恶意软件分析等等。调试器为软件缺陷审计提供了一组极为有用的特性和功能。大多数调试器都具备的功能:运行、暂停和单步执行,除此外还包括:设置断点、修改寄存器与内存数据值,以及捕获发生在目标进程中的异常事件。
说了这么多,调试器对我们黑客来说到底有什么用,初看上面,貌似就是我们eclipse里面的调试器一样。(这个确实是这样,每个IDE都自带了调试器了)
我们先举个软件测试的例子,常说的白盒测试和黑盒测试。
绝大多数开发平台及IDE都自带一个内建调试器,用于帮助开发人员对他们的程序进行源码级别的跟踪和调试,这种源码级别的调试方式能够使用户对被调试的进程获取比较高级别的控制能力。这种调试器我们成为白盒调试器。然后不幸的是,对于逆向工程师以及漏洞挖掘人员来说,能够直接获取源代码的情况很少发生,因此必须利用黑盒调试器来对目标程序进行跟踪。黑盒调试器是基于一个假设,需要被分析的目标软件对于黑客来说是一个完全不透明的黑盒,黑客唯一获取信息的来源就是那些以汇编代码形式出现的反汇编结果。那些最终攻破软件体系的家伙应该要比软件开发者本人对系统具有更深层次的理解。
黑盒调试器分为两种:用户态调试器和内核调试器。用户态(通常被叫做ring3)是指CPU处理器在执行应用程序代码时所处的一种特定状态,用户态下的应用程序是以最低权限运行的。例如,当你试图启动calc.exe进行一些数学计算时,实际上所做的是生成一个用户态进程,并与之进行交互。如果你想跟踪这个进程,你需要一个用户态调试器。内核态(ring0)则代表了最高级别的权限,操作系统的内核代码,连同驱动程序等这一类底层组件正是在内核态下运行。当你使用Wireshark嗅探网络封包时,你实际上正在和一个工作在内核态下的网卡驱动程序进行交互。同上,如果想跟踪,那么就要借助一个内核态的调试器。
这里给出几个有名气的用户态调试器:微软推出的WinDbg和由Oleh Yuschuk开发并免费发布的OllyDbg。当你在linux下调试时,倾向于使用标准的GNU调试器(gdb)。
介绍了这么多,那么调试器的原理是什么呢?
首先我们需要了解CPU的体系结构。
1、通用寄存器
寄存器的作用想必学过计算机的人都知道。在X86指令集中,一个CPU具有8个通用寄存器:EAX、EDX、ECX、ESI、EDI、EBP、ESP、和EBX。这8个通用寄存器中的每一个都被安排了特定用途,因为CPU在执行某些特定指令时需要特定的寄存器协作以高效地完成其指令执行过程。那么下面来介绍下:
EAX 也被称为累加器,用于协助执行一些常见的运算操作以及用于传递函数调用的返回值。在X86指令集中很多经过优化的指令会优先将数据写入或读出EAX寄存器,再对数据进行进一步运算。大多数基本基本的运算操作:加法、减法和比较都会借助使用EAX寄存器来达到指令优化的效果。还有一些特殊的指令,如:乘法和除法则必须在EAX寄存器中进行。
有一点必须牢记,函数调用的返回值将被存储在EAX寄存器。这样,你可以通过存储在EAX中的值来判断一个函数调用所执行的操作时成功还是失败了。
EDX 是一个数据寄存器。这个寄存器可以被看成EAX寄存器的延伸部分,用于协助一些更为复杂的运算指令,如:乘法和除法,EDX被用于存储这些指令操作的额外数据结果。
ECX 也被称为计数器,用于支持循环操作。存储一个字符串或者进行计数就是典型的循环操作。需要注意的是ECX寄存器通常是反向计数,而不是正向计数。我们用Python代码来验证这个问题“
coun = 0
while coun < 10:
print "Loop number : %d" % coun
coun +=1
如果你将这段代码的逻辑用汇编语言来表示,那么在代码执行到第一次循环时ECX中的值会为10,当代码执行到第二次循环时,ECX中的值会递减到9,依此类推。
在X86汇编中,涉及到数据处理的循环操作依赖于ESI和EDI这两个寄存器,以实现高效的数据操作。ESI被称为源变址寄存器,这个寄存器存储着输入数据流的位置信息。EDI寄存器则指向相关数据操作结果的存放的位置,我们称为目的变址寄存器。可以简单理解为ESI用于读,EDI用于写。
ESP和EBP这两个寄存器分别被称为栈指正和基址指针。这些寄存器用于控制函数调用和相关栈操作。当一个函数被调用时,调用参数连同函数的返回地址将先后被压入函数栈中。ESP寄存器始终指向函数栈的顶端,由此得出在调用函数过程中的某一时刻,ESP指向了函数的返回地址。EBP寄存器始终指向函数栈的底端。
EBX寄存器是唯一一个没有指定特殊用途的寄存器。可以被作为额外的存储单元来使用。
另外一个EIP寄存器,这个寄存器始终指向当前正在执行的指令。当CPU穿行于二进制代码中,EIP中的值随之更新以实时反映当前代码所执行到的位置。
说了这么多寄存器,无非是想说明,调试器应当达到的目标之一:调试器应当能够轻易地读取和修改这些寄存器的内容。每个操作系统都会提供一组接口使得调试器能够与CPU进行交互,以获取或修改这些寄存器中的值。
用python开发调试器——起始篇的更多相关文章
- Python开发【第七篇】:面向对象 和 python面向对象进阶篇(下)
Python开发[第七篇]:面向对象 详见:<Python之路[第五篇]:面向对象及相关> python 面向对象(进阶篇) 上一篇<Python 面向对象(初级篇)> ...
- Python开发【第二十篇】:缓存
Python开发[第二十篇]:缓存redis&Memcache 点击这里 Python之路[第九篇]:Python操作 RabbitMQ.Redis.Memcache.SQLAlchemy ...
- 【转】Eclipse和PyDev搭建完美Python开发环境(Ubuntu篇)
原文网址:http://www.cnblogs.com/Realh/archive/2010/10/10/1847251.html 前两天在Windows下成功地搭好了一个Python开发环境,这次转 ...
- Python开发【第二十三篇】:持续更新中...
Python开发[第二十三篇]:持续更新中...
- Python开发【第二十一篇】:Web框架之Django【基础】
Python开发[第二十一篇]:Web框架之Django[基础] 猛击这里:http://www.cnblogs.com/wupeiqi/articles/5237704.html Python之 ...
- Python开发【第十三篇】:jQuery--无内容点击-不进去(一)
Python开发[第十三篇]:jQuery--无内容点击-不进去(一)
- Python开发【第十篇】:CSS --无内容点击-不进去(一)
Python开发[第十篇]:CSS --无内容点击-不进去(一)
- Pdb— Python的调试器
参考:Pdb- Python的调试器 pdb 模块定义了一个交互式源代码调试器,用于 Python 程序.它支持在源码行间设置(有条件的)断点和单步执行,检视堆栈帧,列出源码列表,以及在任何堆栈帧的上 ...
- 最全Pycharm教程(10)——Pycharm调试器总篇
最全Pycharm教程(1)--定制外观 最全Pycharm教程(2)--代码风格 最全Pycharm教程(3)--代码的调试.执行 最全Pycharm教程(4)--有关Python解释器的相关配置 ...
随机推荐
- 输入过滤器——InputFilter
一般情况下我们通过请求体读取器InputStreamInputBuffer获取的仅仅是源数据,即未经过任何处理发送方发来的字节.但有些时候在这个读取的过程中希望做一些额外的处理,并且这些额外处理可能是 ...
- 套接字输入缓冲装置——InternalInputBuffer
互联网的世界很复杂,信息从一端传向另一端过程也相当复杂,中间可能通过若干个硬件,为了提高发送和接收效率,在发送端及接收端都将引入缓冲区,所以两端的套接字都拥有各自的缓冲区,当然这种缓冲区的引入也带来了 ...
- 程序员高效Windows环境配置
个人比较追求高效.效率.以下是我常用的windows配置希望对大家有帮助.(身为程序员,我特别喜欢mac pro的retina屏,在那编程简直是一种享受.等我买了mac pro在发一篇 ...
- Hessian源码分析--HessianProxy
在上一篇博客 Hessian源码分析--HessianProxyFactory 中我们了解到,客户端获得的对象其实是HessianProxy生成的目标对象,当调用目标对象的方法时,会调用Hessian ...
- 打Patch实践
一.找到相应PATCH 确认系统已安装模块版本. SELECTapp.application_short_name, app.application_name, pi.patch_level FR ...
- Android进阶(二十六)MenuInflater实现菜单添加
MenuInflater实现菜单添加 前言 之前实现的Android项目中可以实现菜单的显示.但是再次调试项目时发现此功能已无法实现,很是令人费解.难道是因为自己手机Android系统的问题?尝试通过 ...
- Web Service进阶(一)运行原理
利用清明小假期,温习了一遍Web Service的相关内容,对其工作原理进行了简要总结.以供有需求的朋友和自己日后参考.文章若有不当之处,敬请朋友们提出宝贵建议,以求共勉. Web服务中,我们应该首先 ...
- Java 学习之反射机制“解刨”分解类,并获取内容!
正常情况下,单纯的做开发是接触不到反射机制的(额,当然并不排除例外的情况了).下面我就对我学到的反射方面的知识做一个小小的总结,旨在复习和以后的查看. 原理分析: 所谓反射就是将一个类当做我们研究的对 ...
- Android官方命令深入分析之虚拟机
Android SDK包含了一个运行在计算机上的移动设备虚拟机.这个虚拟机可以允许你在没有物理设备的情况下开发和测试Android应用. 键盘命令 虚拟设备按键 对应键盘按键 Home HOME 菜单 ...
- hive的map类型处理
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF#LanguageManualUDF-CollectionFunc ...