简介

什么是cython,我也不知道hh Cython 是一种编程语言,旨在减少用 C 语言创建 Python 扩展模块的工作量。 它的语言规范与 Python 的语言规范几乎相同(向上兼容),但它已被扩展为允许直接调用 C 函数以及声明 C 变量类型和类的能力。 在 Cython 处理系统中,源文件被转换为 C 代码,编译时,它被输出为 Python 扩展模块。 Cython 以这种方式无缝地混合了 C 和 Python,其优势之一是,它允许您通过简单地声明一些静态类型并重写快速限制循环,以与 C 一样快的速度运行现有的 Python 代码。 无需使用复杂的 C 语言接口。 编码的易用性和可读性与 Python 相同,即它们仍然是 Pythonic。 数值/数组作通常快 100 倍左右。 对于 Python 的 JIT 编译器 Psyco,它大约是 Python 的四倍。 Cython 源自 Pyrex 语言,与 Pyrex 相比,该语言具有多种功能和高级优化。 SAGE 是一个免费软件数值和公式处理系统,其部分内容是用 Cython 编写的。 Cython 的处理系统是用 Python 编写的,可以在 Windows、Linux 和 macOS 上运行 这是wiki百科里面的简介,可以看一下。 现在cython的逆向题越来越多了,这是一个跳过去的坎了可以说,下面我来一步步的阐述一下我对这玩意的心路历程 搜索的时候看到了一本书,《Cython: A Guide for Python Programmers》,不过我目前只是为了做题而做题,还未读,有兴趣的可以看看 # 编译 1.编译pyx文件 在Cython里定义一个C变量和C语言类似,不同的地方就是在声明的最前面要加上cdef,另外,末尾不用加分号

1
2
3
4
5
6
def fib(int n):
cdef int i
cdef double a=0.0, b=1.0
for i in range(n):
a, b = a + b, a
return a

或者直接写py:

1
2
3
4
5
6
7
8
9
10
def check(data):
code = []
key = [100, 111, 117, 121, 111, 117, 110, 111]
res = [31152828972, 32985348991, 29625729673, 31458249645, 37566646827, 36955807529, 30847409314, 35123287627, 19546873700, 33596188231, 33901608897, 38177487125]
for k in range(len(data)):
data[k] = (data[k] * 0x12345678) ^ (data[k] << 2)
code.append(data[k] ^ key[k % len(key)])
if code[k] != res[k]:
return 0
return 1
2.编写setup.py文件
1
2
3
from setuptools import setup
from Cython.Build import cythonize
setup(ext_modules=cythonize('test.pyx'))

1
2
3
4
5
6
7
8
9
10
 from setuptools import setup
from Cython.Build import cythonize
或者直接写py,然后用这个setup:
setup(
ext_modules=cythonize(
'enc.py', # 直接指向.py文件
compiler_directives={'language_level': "3"}, # 指定Python版本
annotate=True # 可选:生成编译分析报告
)
)
3.使用python setup.py build_ext –inplace命令编译 如图:

cython

然后我们就可以得到想对应的test.c文件以及test.cp312-win_amd64.pyd文件,然后我们就可以像调用python文件一样调用它了

指令

look this: https://xz.aliyun.com/news/15592?time__1311=CqIx9DBiqWwx2DBqDTl%3DDnDmrVi7wxGCerjeD&u_atoken=e4aa73b52950fd731d02ba0297d7e3e2&u_asig=0a47315217422184682142697e003d

例题

ciscn 2025 rand0m

ciscn 2025 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
import ez
flag = input('请输入flag:')
flag1 = list(flag)
value = []
b = 0
ck = 0

if len(flag1) == 24:
for i in range(0, len(flag1), 4):
# 每四个字符组合成一个32位整数
b = (ord(flag1[i]) << 24) | (ord(flag1[i + 1]) << 16) | (ord(flag1[i + 2]) << 8) | ord(flag1[i + 3])
value.append(b)

key = [102, 108, 97, 103] # 'flag'的ASCII码
flag_encrypt = []

# 每次处理两个value元素,步长为2(实际可能应为range(0, 6, 2))
for i in range(0, 6, 2):
res = ez.encrypt(value[i], value[i + 1], key)
flag_encrypt.append(res)

ck = ez.check(flag_encrypt)
if ck == 3:
print('yes!!!,you get right flag')
else:
print('wrong!!!')
else:
print('wrong!!!')

然后,很明显我们的目标就是ez.encrypt和ez.check。 然后我们可以知道,ez这个东西是一个pyd文件,好嘛,那就反汇编呗

2024春秋杯网络安全联赛冬季赛 cpy

总结