用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进行交互,以获取或修改这些寄存器中的值。

 

 

 

 

posted on 2013-12-19 12:43 代码一刀 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/zengdan-develpoer/p/3481955.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值