对于python源码编译的exe及pyc的逆向

以2024SCTF中的ez_cython为例

ez_cython提供了一个python源码编译的exe

image-20241001010850082

image-20241001011155377

用这个exe在直接IDA中看 会发现得不到什么有效的信息 基本都是fail

需要用到三个工具

  1. pyinstxtractor.py

  2. 任意一个Hex编辑器

  3. uncompyle库

pyinstxtractor.py 工具的下载地址:

https://sourceforge.net/projects/pyinstallerextractor/

https://download.csdn.net/download/qq_63585949/86509791

Hex编辑器wxMEdit下载地址:
https://wxmedit.github.io/downloads.html

https://download.csdn.net/download/qq_63585949/86509705

uncompyle库为第三方库,可以使用pip命令安装:

1
pip install uncompyle6

image-20241001014132180

将pyinstxtractor.py与exe置于同一个目录下

然后在当前目录打开终端,输入python pyinstxtractor.py 文件名.exe

运行后会生成一个ez_cython.exe_extracted

image-20241001014319200

在这个文件中会存在struct和ez_cython两个文件 需要自己添加文件后缀pyc

image-20241001014606890

同时获得的ez_cython.pyc是没有magic number的 一般可以通过strcut. pyc来获取 但是本题中两个都没有 这个时候就需要去获取对应python版本的magic number

本题中为3.8版本的python

E3之前即为magic number

image-20241001015915616

然后回到目录下,打开控制台,输入命令uncompyle6 文件名.pyc > 文件名.py回车执行,就可以看到目录下生成了.py文件了:

image-20241001020246299

3.8以下可以使用uncompyle6 3.9及以上的使用pycdc

pycdc的使用参考:

Python 反编译:pycdc工具的使用-CSDN博客

ez_cython源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import cy

def str_hex(input_str):
return (lambda .0: [ ord(char) for char in .0 ])(input_str)


def main():
print('欢迎来到猜谜游戏!')
print("逐个输入字符进行猜测,直到 'end' 结束。")
guess_chars = []
char = input("请输入一个字符(输入 'end' 结束):")
if char == 'end':
pass
elif len(char) == 1:
guess_chars.append(char)
continue
print('请输入一个单独的字符。')
continue
guess_hex = str_hex(''.join(guess_chars))
if cy.sub14514(guess_hex):
print('真的好厉害!flag非你莫属')

print('不好意思,错了哦。')
retry = input('是否重新输入?(y/n):')
if retry.lower() != 'y':
pass

print('游戏结束')

if __name__ == '__main__':
main()

但是获取到源码对于我们帮助并不是非常的大(原本以为获取到源码 就距离flag不远了 ,没想到只是刚开始)

在这个源码中我们缺少了sub14514 py.cy

这两个存在于cy.pyd中

image-20241001230730657

将这个dll直接扔进IDA

image-20241001230853918

F12可以看到很多是我们需要的字符串 、

image-20241001230925631

主要的加密过程(没看懂 就只看出一个hash哈希)

image-20241001231013023

来自大佬的分析

image-20241001231225248

注重偏向观察导入表number的函数

image-20241001233301229

这些字符串就是密文(从wp推出来的)

接着用xxtea解一下就可以获得flag

pyc的反编译大概就这样