python逆向入门教程

yipeiwu_com5年前Python基础

1、开发环境

我们在Windows 10上开始python逆向之旅,首先开始搭建开发环境,python解释器使用最新的3.6.1,IDE使用PyCharm社区版2017.1.3,下载地址如下所示,下载完成后直接双击安装包安装即可,随后设置PyCharm的Project Interpreter为刚才安装的Python解释器就可以了。

【Python】https://www.python.org/downloads/
【PyCharm】http://www.jetbrains.com/pycharm/download/

2、ctypes

首先介绍一下ctypes,它是一个用于Python的外部函数库,提供了与C语言兼容的数据类型,允许调用动态链接库或共享库中的函数,还可以包装这些库。下面是ctypes中的数据类型与C语言、Python中的数据类型的对应关系。

ctypes中的数据类型全部通过class来实现,在Python中加载C库涉及如下几个类。

  1. class ctypes.CDLL 加载共享库,使用标准C函数调用惯例即cdecl,返回类型为int。
  2. class ctypes.OleDLL 加载共享库,只用于Windows平台,使用stdcall函数调用惯例,返回类型为HRESULT。
  3. class ctypes.WinDLL 加载共享库,只用于Windows平台,使用stdcall函数调用惯例,返回类型为int。
  4. class ctypes.PyDLL 类似于CDLL,与前面三个不同的是,在函数调用期间不会释放GIL,Global Interpreter Lock。
  5. class ctypes.LibraryLoader(dlltype) dlltype为CDLL、OleDLL、WinDLL、PyDLL,这个类有一个加载共享库的函数LoadLibrary。

加载C库更简单的方法是使用如下几个预先创建的类实例。

ctypes.cdll
ctypes.oledll
ctypes.windll
ctypes.pydll
ctypes.pythonapi

上面提到了函数调用惯例cdecl和stdcall,cdecl的意思是函数的参数从右往左依次压入栈内,函数的调用者在函数执行完成之后负责函数的平衡,常用于X86架构的C语言里,返回值存储在EAX寄存器中,从汇编代码的角度来看,函数参数从右往左依次压栈,然后调用函数,最后修改栈指针ESP为原来的位置。stdcall,参数传递的顺序也是从右到左,不过栈的平衡处理由函数自己完成,而不是调用者,返回值同样存储在EAX中,也就是说,函数参数压栈、函数调用之后没有像cdecl一样的栈指针ESP移动。

下面的例子在Python中调用C的printf函数,printf属于“C:\Windows\System32\msvcrt.dll”,也就是Linux上的“libc.so”。

from ctypes import *

msvcrt = cdll.msvcrt
message = b"Hello World\n"
msvcrt.printf(b"Message is %s", message)

上面的代码输出“Message is Hello World”。另外,ctypes还允许在Python中定义结构和联合等其它高级功能,详细介绍请参考https://docs.python.org/3.6/library/ctypes.html?highlight=ctypes#。

3、调试原理

使用调试器,能够对程序进行动态跟踪和分析,特别是涉及到exploit、fuzzer和病毒分析的时候,动态分析程序的能力就显得非常重要了。调试程序时,如果可以获得源代码,调试起来就容易一些,也就是透明的白盒测试,如果没有源代码,也就是黑盒测试,想要得到理想的结果,那就必须拥有高超的逆向技术和逆向工具的帮助。黑盒测试包括用户模式与内核模式两种情况,两者有不同的权限。

CPU的寄存器能够对少量的数据进行快速的存取访问,在X86指令集里,一个CPU有八个通用寄存器:EAX、EDX、ECX、ESI、EDI、EBP、ESP和EBX,以及其它的寄存器,下面逐个介绍。
EAX:累加寄存器,除了用于存储函数的返回值外也用于执行计算的操作,许多优化的X86指令集都专门设计了针对EAX寄存器的读写和计算指令。

EDX:数据寄存器,本质上是EAX寄存器的延伸,辅助EAX寄存器完成更多复杂的计算操作。
ECX:计数寄存器,用于循环操作,计算是向下而不是向上的,由大减到小。
ESI:Source Index,源操作数指针,存储着输入的数据流的位置,用于读,高效地处理循环操作的数据。
EDI:Destination Index,目的操作数指针,存储了计算结果存储的位置,用于写,高效地处理循环操作的数据。
ESP:Stack Pointer,栈指针,负责函数的调用和栈的操作,函数调用时压栈参数和返回地址,指向栈顶即返回地址。
EBP:Base Pointer,基指针,负责函数的调用和栈的操作,函数调用时压栈参数和返回地址,指向栈底。
EBX:唯一一个没有特殊用途的寄存器,作为额外的数据存储器。
EIP:Instruction Pointer,指令指针,总是指向马上要执行的指令。

熟悉调试器的朋友们都知道断点,断点其实就是一个调试事件,其它事件如经典的段错误(Segment Fault)等。断点包括软件断点、硬件断点和内存断点,用于暂停被执行程序。

软件断点:一个单字节的指令,将控制权转移给调试器的断点处理函数。汇编指令是CPU执行的指令的高级表示方法,如下面的汇编指令MOV EAX, EBX,告诉CPU把存储在EBX寄存器里的东西放到EAX寄存器,然而CPU并不明白这个汇编指令,必须转化为能够让CPU识别的操作码8BC3,假设这一操作发生在地址0x44332211,为了在这个地址设置断点,暂停CPU,需要从2个字节的操作码8BC3中换出一个单字节的操作码,这个单字节的操作码也就是3号中断指令,INT3,一条能让CPU暂停的指令,对应的操作码为0xCC,具体如下面的代码片段所示。当调试器被告知在目标地址设置一个断点时,它首先读取目标地址的第一个字节的操作码然后保存起来,同时把地址存储在内部的中断列表中,接着,调试器把3号中断指令对应的操作码0xCC写到刚才的地址,当CPU执行到替换后的操作码的时候,CPU暂停,并触发一个INT3事件,此时调试器就能捕捉到这个事件,然后调试器通过EIP判断这个中断地址是否是我们设置的断点,如果是,就把对应的操作码写回以恢复程序的正常运行。软件断点包括一次性断点和持续性断点,前者生效一次,后者一直生效,不生效后将其从中断列表移除。需要注意的是,当我们改变了被调试程序的内存数据时,同时改变了运行时软件的CRC即循环冗余代码校验和,CRC是一种校验数据是否被改变的机制,广泛应用于文件、内存、文本、网络数据包等任何想监视数据的地方,它将一定范围内的数据进行hash计算,然后将hash值同此前的hash值进行比较,判断数据是否改变,为了在这种特殊的情况下也能调试程序,就要使用下面介绍的硬件断点了。

地址: 操作码 汇编指令
0x44332211: 8BC3 MOV EAX, EBX
0x44332211: CCC3 MOV EAX, EBX

硬件断点:在小块区域内设置断点,属于CPU级别,使用了DR0到DR7共八个特殊的调试寄存器,这些寄存器专门用于管理硬件断点。DR0到DR3存储硬件断点地址,意味着同一时间内最多只能有4个硬件断点,DR4和DR5保留,DR6是状态寄存器,说明被断点触发的调试事件的类型,DR7是开关寄存器,同时也存储了断点的不同类型,包括指令执行时中断、数据可以写入时中断、有数据读或者写但不执行时中断。硬件断点使用1号中断指令INT1,负责硬件中断和步进事件。硬件断点的特点是同一时间只能设置四个断点,而且断点起作用的区域只有四个字节,如果想要跟踪一大块内存数据,请使用下面介绍的内存断点。

内存断点:用于大块区域,不是真正的断点,而是改变了内存中某个块或者页的权限。一个内存页是操作系统处理的最小的内存单位,一个内存页被申请成功后,就拥有了一个权限集,如可执行页、可读页、可写页,这些决定了内存该如何被访问,任何对保护页的访问都会引发异常,之后页面恢复访问前的状态。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持【听图阁-专注于Python设计】。

相关文章

python实现简单的文字识别

本文实例为大家分享了python实现简单的文字识别的具体代码,供大家参考,具体内容如下 Python版本:3.6.5 百度云提供的文字识别技术,准确率还是非常高的,而且每天还有5w次免...

Python将多个excel文件合并为一个文件

Python将多个excel文件合并为一个文件

利用Python,将多个excel文件合并为一个文件 思路 利用python xlrd包读取excle文件,然后将文件内容存入一个列表中,再利用xlsxwriter将内容写入到一个新...

pytorch打印网络结构的实例

pytorch打印网络结构的实例

最简单的方法当然可以直接print(net),但是这样网络比较复杂的时候效果不太好,看着比较乱;以前使用caffe的时候有一个网站可以在线生成网络框图,tensorflow可以用tens...

django之常用命令详解

Django 基本命令 本节主要是为了让您了解一些django最基本的命令,请尝试着记住它们,并且多多练习下 1. 新建一个 django project django-admin...

python结合shell查询google关键词排名的实现代码

python结合shell查询google关键词排名的实现代码

最近老婆大人的公司给老婆大人安排了一个根据关键词查询google网站排名的差事。老婆大人的公司是做seo的,查询的关键词及网站特别的多,看着老婆大人这么辛苦的重复着查询工作,心疼啊。所以...