前言
上次写了一个pyd逆向,在文章末尾讲了hook模块等方法。现在来完善一下。众所周知,python打包的exe,如果没加任何加密的话,源码是可以很容易被轻松逆向出来的。所以就会有人会将python代码打包成pyd文件。其实就是一种dll文件。来增加破解难度。
1.hook模块
一.首先,我们手动写一个例子
import base64 key = input("请输入密码:") print(str(base64.b64encode(key.encode()),'utf-8')) key = str(base64.b64encode(key.encode()),'utf-8') if key == "MTIzNDU2": print("成功") else: print("失败")
这个是个很简单的例子,就是对输入的字符串进行base64编码,再进行比较。我们将这个例子打包成pyd,来测试一下
import test1 test1
我们可以得到以下结果
请输入密码:123456 MTIzNDU2 成功
这个是成功的状态
请输入密码:12345 MTIzNDU= 失败
这个失败的状态。
现在我们来尝试hook一下base64模块,当然,这个是我们自己写的代码,我们知道引用那些模块,别人写的,我们肯定是不知道的。那咋办?
二.将pyd拿到ida里面进行分析,找到导入了那些模块
这里我们可以看到,里面有些字符串都出来了,甚至密码都出来了,当然我们这里是个例子是很简单的,就是一个测试。一般验证不会这样简单。我们看到了base64这个字符串,我们就有理由怀疑,他是不是引用了base64模块,这里我们做一个测试,我们将这个base64这个字符串改一下名字,引入我们自己的模块
这里我们改成base66。然后再运行一下我们的代码。那肯定会报错,会说没有base66这个模块。
三.搭建自己的模块base66
在和pyd相同文件夹下,创建base66.py文件。里面先不写任何代码。然后再运行一下代码。看看效果
他说base66这个模块没有b64encode这个属性。那当然,我们啥代码没有写,那肯定是没有这个属性的,但是不打紧。我们知道他是一个base64加密,我们就在里面调用base64.b64encode
它接收字节,那我们就这样写
import base64 def b64encode(s, altchars=None): print(s) return base64.b64encode(s)
很简单的,运行一下看看
请输入密码:1234 b'1234' MTIzNA== b'1234' 失败
可以得到我们输入的参数,我们hook的目的就达到了。
2.修改if返回
pyd验证正不正确,里面肯定会用到if语句,我们能不能改一下if语句返回了?那当然是肯定的。那如何修改了。这里参考了这篇文章(https://www.keepnight.com/archives/767/)。我们将py编译成pyd的时候,多出来了一个c文件,那个我们可以参考参考。
找到这个函数__Pyx_PyUnicode_Equals,看样子就是比较字符串的。这个pyd也就是这个c语言编译的,那么到ida里面也能找到。
在ida里面找到这样的函数,看样子就是了。那我们改一下汇编语言
将第一个分叉,jz改成jmp。这个if就只会返回true了。当然你也可以改成本来是true返回flase,false返回true的。改完保存一下。再运行一下,看看效果
请输入密码:1212121 b'1212121' MTIxMjEyMQ== b'1212121' 成功
接下来就会发现,不论输入什么,都会返回成功了。改if返回也成功了。
OK,今天就到这里了,有啥问题可以加一群342096685,二群902854353。