浅谈一下pyd文件的逆向

Posted 黑剑客与剑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈一下pyd文件的逆向相关的知识,希望对你有一定的参考价值。

1.何为pyd文件

​ .pyd 文件是由非 Python,其它编程语言编写 (或直接把 .py 文件转换成 .c 中间文件) 编译生成的 Python 扩展模块,是类似 .so .dll 动态链接库的一种 Python 文件。(当然,python代码也可以打包为pyd)

​ 为啥要打包成pyd文件呢?因为pyd文件可以更好的防止反编译,只能反汇编。如果你直接打包将python代码直接打包为exe,是可以直接反编译源代码的。还有可以将c++,c等编译为pyd给python调用。

2.浅浅试一下逆向hello,world

​ 开始第一次,一般都是从hello,world开始学习,这里我们也用hello来进行逆向。

from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules=cythonize("test1.py"))

这个main.py代码是用来将python代码编译为pyd的代码

#-*- coding : utf-8-*-
def say_hello():
    print("hello")
def say_sorry():
    print("sorry")

这个test.py我写了两个函数,一个say_hello,一个say_sorry。我们的目标就是改变函数功能,将say_hello输出sorry,say_sorry输出hello。

我们现在运行main.py。会直接生成test1.cp38-win_amd64.pyd的文件,这里我们新开一个py文件,名字叫测试.py。在这个代码里面输入这样的代码。其实这个pyd就是和python的模块差不多。可以通过import调用里面的函数。

import test1
test1.say_hello()
test1.say_sorry()
#hello
#sorry

这样就会输出hello和sorry。当然,我们可能开始不知道这个里面有啥函数,我们可以利用help命令来开里面的函数

help(test1)

可以看到以下输出。

Help on module test1:

NAME
    test1

FUNCTIONS
    say_hello()
    
    say_sorry()

DATA
    __test__ = 

FILE
    e:\\xxxx\\xxxxx\\test1.cp38-win_amd64.pyd

None

里面的FUNCTIONS我们可以进行调用。

3.开始逆向

​ 这里,我们要用ida进行逆向。将pyd文件拿到ida里面。

点击这个view,选择里面对的string。查看字符串

这里我们以GCTL为界限,我们查看以上的字符串。

可以看到,我们看到了sorry和hello这两个字符串。以及我们的函数名字。这里我们点击进入hello。

可以看到这个玩意,我们现在的任务就是修改掉这个hello改成sorry。再保存到pyd文件就行。

4.修改字节


点击这个edit,选择这个

选出change byte。

这里是使用的16进制,我们随便找个网站,将sorry转为16进制

转完之后,将16进制填上去

填完毕后,可以看到。hello已经变成了sorry了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ThoW633U-1659422415677)(C:/Users/zha/AppData/Roaming/Typora/typora-user-images/image-20220802142222550.png)]

这里我们保存一下,还是再patch program里面,选择apply xxxx input file 保存文件。保存完成后。

5.测试一下修改的pyd

还是同样的代码。

import test1
test1.say_hello()
test1.say_sorry()

可以看到输出的两个sorry。可以看到我们的修改成功了。

6.其他方法

​ 当然,除了这个ida修改字符串等,还有其他方法,比如hook python代码。获取传参等。比如,你通过dir函数看到这个pyd文件用了base64模块。那你可以直接hook base64模块。来获取传参。这里就不展开了,有兴趣,可以自己写个python代码打包成pyd,自己逆向看看。

python中调用用C++写的dll

    最近要逆向一个pyd文件,无意中要用到用boost库生成的pyd文件,这其中的环境配置过程很漫长,特意将配置或者说安装使用的过程记录一下。python中使用C++生成的动态库方法我知道的现在是两种,(1)通过boost库生成dll,然后改名成后缀名pyd给python使用,(2)通过python的ctypes库直接加载dll文件使用。

    先说一下第二种方式,这种比较简单,不用怎么配置环境,网上能搜到很多ctypes使用的方法,唯一需要注意的是,在32位的python使用32位的dll,64位的python中使用64位的dll,如果生成的dll在加载时老是提示找不到dll,是因为这个dll依赖于其它的dll,如果没依赖自己写的其他库,则可能是VS的环境变量没装好,配置好环境变量或者重装一遍VS。

    着重说下第一种方式,过程如下:

1) 下载boost库,下载时有压缩文件格式,也有exe格式,我使用的压缩文件格式;

2) 安装boost库:解压缩,然后通过VS的开发工具命令提示(

Win键,然后从VS程序下选择,想要生成32位的pyd文件,则选择32位的工具,如果是生成64位的pyd文件,则选择64位兼容的工具,VS2015下选择VS2015 x86 x64 兼容工具命令提示符

)来运行bootstrap.bat脚本文件,会生成bjam.exe和b2.exe,其实二者是完全一样的文件,运行其中一个即可,运行直到结束需要花至少20多分钟,64位的更长,直接运行时,会将生成的文件全部放到bjam.exe当前目录,当然也可以指定存放目录,命令如下:

x86安装则输入命令:
b2.exe --prefix=D:oostx86 --build-type=complete --build-dir=build_tmp toolset=msvc-14.0 address-model=32 install
("D:oostx86"是将要生成32位的include和lib文件夹放置的位置,build_tmp是位于安装包中用于放置中间生成物的文件夹)

x64安装则输入命令:
b2.exe --prefix=D:Boostx64 --build-type=complete --build-dir=build_tmp_x64 toolset=msvc-14.0 address-model=64 install

(msvc-14.0指的是一个平台,这里是VS2015, msvc-12.0是VS2013,什么VS版本就指定什么平台)。

3)使用配置好的boost库

    用对应版本的VS创建一个dll工程,在其中写入一些使用boost库的代码,网上很多,这里就不再记录。加入代码后,直接运行会报各种错的,因为找不到头文件和链接库,所以要在:项目——属性——C/C++——常规中的附加库目录中加入***Python36include和 ***oost_1_66_0目录,项目——属性——链接库——常规——附加库目录中加入***Python36libs 和  D:Boostx64lib(如果是直接运行b2.exe或者bjam.exe则是在当前目录的stagelib目录,如:E:Program Files (x86)oost_1_63_0stagelib)。虽然有些麻烦,但最后成功的那一下是很喜悦的。




以上是关于浅谈一下pyd文件的逆向的主要内容,如果未能解决你的问题,请参考以下文章

Python 怎么调用 pyd文件?

Python生成pyd文件

浅谈python的第三方库——numpy

python 文件扩展名 .pyc .pyd .pyo 代表啥?

Python关于.pyd文件无法import的问题的解决方法

python学习之pyc,pyo,pyd文件