侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

python逆向入门教程

Python  /  管理员 发布于 7年前   565

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/#section=windows

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.cdllctypes.oledllctypes.windllctypes.pydllctypes.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.msvcrtmessage = 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, EBX0x44332211: CCC3 MOV EAX, EBX

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

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


  • 上一条:
    Python操作mysql数据库实现增删查改功能的方法
    下一条:
    Python3一行代码实现图片文字识别的示例
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客