首页
社区
课程
招聘
15
[原创]pyd文件逆向
发表于: 2025-2-11 00:53 9173

[原创]pyd文件逆向

2025-2-11 00:53
9173

在Python生态中,.pyd文件作为动态链接库形式的扩展模块,因其高效性和隐蔽性被广泛应用于代码保护、性能优化及跨语言开发。本文主要结合静态反汇编工具,剖析.pyd文件逆向的要点。

https://cython.readthedocs.io/en/latest/src/quickstart/build.html

https://cython.org/

大致流程为: 编写py源代码以及对应的编译脚本-> 生成对应的.c 之类的中间文件 -> 调用编译器编译.c文件 -> 生成pyd文件可供使用

用户只需要配置好第一步即可

按照官方文档编译一个 pyd 文件:

python pip 安装模块cython

编写一个hello.pyx 脚本, 里面随便写一个函数

在同目录编写一个 setup.py 脚本,里面的文件名为固定的内容,文件名为刚刚写的py脚本完整名称

在命令行执行命令,来编译这个文件

编译成果后会在同级目录下生成很多东西:

build 目录 存放一些编译生成的中间文件

xxxx.c py文件到c源码文件,中间包含了完整的c代码(该文件并不会公布)

xxxxx.cpyyyy-win_amd64.pyd 编译好的文件xxxx 为py文件的命名 yyyy 为python的版本号 ,这个文件可只保留原始文件名和后缀.pyd 例如 bbbbb.cp312-win_amd64.pyd -> bbbbb.pyd

如果两个文件在同时在同级目录下,python会优先选择带版本号的,如果没有再选择不带版本号的文件

如何调用?

在同级目录下,直接打开python使用 import xxxx 即可调用

查看xxxx.c

里面有非常多的结构,并且有python代码转换的c源代码,我们可以在这里看到cython的转换规则,和大体的逻辑

这里编译的没有带符号,所以逆向的话,ida载入,很多函数都是没有函数名称的

在Linux下默认带有符号,Windows下默认不带符号,需要增加参数来生成详细的PDB,并ida加载PDB才能看到更详细内容

我们可以通过修改setup.py 来编译一个带符号的

也可以在命令行编译时,增加 --debug 参数,但需要在安装Python时勾选 Download debug binaries ,否则会提示 104: 无法打开文件“python312_d.lib”

linux 默认情况下,编译出来带有符号,我们可以通过调整编译选项来编一个一个不带符号的pyd文件

默认情况下, 对外函数,可以搜索名称, 因为是全局变量,所以,变量都会放在一起

查找引用,可以发现结构体:

windows 下会多出一层调用 pw -> pf , pf 是真正的地址

Windows Release 版本也是一致: 就是符号没有这么明显,要稍微熟悉一点pyd的结构体。

Linux 默认情况下没有,可能被编译器优化掉 了,但c语言源码上基本一致,pw->pf 函数名

函数的结构体大多都放在一起的,可以上下查找有没有其他的函数,直接搜索函数名,有时候可能会搜不到

在模块中调用模块的内容,会先调用 PyDict_GetItem_KnownHash 中获取,

寻找引用,一般是在 pymod_exec 完成初始化, xxxx+38) + 24

可以看到确实是 get_list 这个函数

对比有符号的发现,+24 是 ob_type v2 是函数地址

调用后的模块地址在v6, 然后又传给v10, 就可以跟着v10,看看有没有发生其他动作 一般来说,会使用 PyObject_GetAttr 来获取属性

这种模块调用会有引用计数的特性, 可以看到 v17 为属性, 其中经过了 ob_refcnt ,比较经典。

再经过 Pyx_PyObject_FastCallDict 来调用,参数为 v21 v26

有时候ida 可能识别的参数不对,数组大小不对,需要手动判别,更改。

可以看到v21的具体内容为 AF_INET

v26 的内容为 SOCK_STREAM

基本上可以通过静态大致识别出一些关键代码

编写测试函数

ida 打开,找到相关函数

说明,紫色的变量/函数名为从别处导入的内容,在抹除符号情况下也能被识别出来

加法 +1 PyNumber_Add(__pyx_self, _pyx_mstate_global->__pyx_int_1); 如果是原地的话, 即 al += 1; 则可能会调用到 PyNumber_InPlaceAdd

-10 PyNumber_Subtract(pyx_int_1, _pyx_mstate_global->__pyx_int_10);

乘以 998 _Pyx_PyInt_MultiplyObjC(v21, _pyx_mstate_global->__pyx_int_998, 998i64, v19);

这里的乘法是经过了一层封装的,无符号情况下需要进入到里面才能看到实际的从导入表中调用的函数 PyNumber_Multiply(op1, op2, intval); 这里其他的运算函数也可能会这么封装,注意用此方法识别。

除以100 不取整 真除 PyNumber_TrueDivide(v28, _pyx_mstate_global->__pyx_int_100);

乘以200 _Pyx_PyInt_MultiplyObjC(v36, _pyx_mstate_global->__pyx_int_200, 200i64, v35);

地板除 30 即 整除 30 PyNumber_FloorDivide(v42, _pyx_mstate_global->__pyx_int_30);

3次方 PyNumber_Power(v42, _pyx_mstate_global->__pyx_int_3, _Py_NoneStruct, pyx_int_30);

左移 3 PyNumber_Lshift(v52, _pyx_mstate_global->__pyx_int_3);

xor PyNumber_Xor(v52, __pyx_self, v63, pyx_int_3);

FastCall 调用 内建函数 hex _Pyx_PyObject_FastCallDict(_pyx_builtin_hex, &args, 0x8000000000000001ui64, v70);

FastCall不是导入函数,进入到该函数内部可以看到调用了 PyObject_VectorcallDict ,可以依此为特征

切片操作 从2 开始 PySlice_New(v83, _Py_NoneStruct, _Py_NoneStruct);

字符串加法,加"00" PyNumber_Add(v80, _pyx_mstate_global->__pyx_kp_s_00);

强转类型, _Pyx_PyObject_Call(PyLong_Type, v76, v91); 第一个参数为类型 PyLong_Type 整型 int。

类型强转函数在无符号情况下,没有符号,需要进入到里面识别一下, 特征也是非常明显,传递的第一个参数是类型名,是一个紫色的被导入的函数/变量,函数内部也会有一些字符串来辅助识别,最后也是调用 PyObject_Call

右移 4 PyNumber_Rshift(v94, _pyx_mstate_global->__pyx_int_4);

或操作 PyNumber_Or(v94, _pyx_mstate_global->__pyx_int_15, v81, pyx_int_4);

与操作, 与 31 PyNumber_And(pyx_int_15, _pyx_mstate_global->__pyx_int_31, v81, pyx_int_4);

取反 (_typeobject *)PyNumber_Invert(v109);

技巧: 有些会运算先执行一遍,做一些判断?最终的运算还是调用导入的函数。所以需要仔细观察导入的函数和被调用的函数。

其中还会穿插一些引用计数的内容。

在无符号情况下,_pyx_mstate_global 结构体是不会识别出来的,需要手动从数据初始化部分来识别。

rsa 相关

PyNumber_Power(__pyx_self, _pyx_mstate_global->__pyx_int_65537, _pyx_mstate_global->__pyx_int_10403, __pyx_self); pow 参数 第一个原始数,第二个e次方,第三个 mod数

第二个运算形式是先有一个pow 取次幂,再有一个取模

v13 = PyNumber_Power(__pyx_self, _pyx_mstate_global->__pyx_int_65537, _Py_NoneStruct);

PyNumber_Remainder(v13, _pyx_mstate_global->__pyx_int_10455);

第三个就是取参数

取上面函数的例子:

部分汇编代码,三个变量的由来,最后的组成

可以看到,元组的第三个qword才是真实的数据存储, 初始化时会调用 PyTuple_New 函数

列表初始化, 基本上也差不多,很有规律

切片,上面的运算里面稍微提到了一点

PySlice_New(从哪开始,到哪结束, 步进)

_Py_NoneStruct 参数表示留空

例如 l[2:] PySlice_New(2, _Py_NoneStruct,_Py_NoneStruct)

字典初始化, 使用 PyDict_SetItem 函数, 第一个参数为字典的地址,第二个为key,第三个为值

集合初始化, 使用 PySet_Add 新增

字典的函数

items

values

在生成的源码里发现,有两种调用形式,大版本大于3和不大于3

这个无符号的话没办法,只能靠硬猜,通过交叉引用,可以获得变量类型

无符号的调用展示:

向上寻找qword_180012208 的交叉引用

发现 qword_180012208 被写入的内容为 PyDict_Type

循环结构,一般,就是因为代码过长,直接f5 可能会忽略掉 循环结构,可以先看流程图,观察大致结构,再对功能做简单分析

直接遍历列表使用 PyObject_GetIter(obj);

range 是一个内建函数,以这个FastCall的方式来进行调用, len 则使用 PyLong_FromSsize_t 来进行获取,当然,不一样的len可能会有不一样的方式。

基本没区别,调用内置 open, 获取 属性 read 然后Fastcall 执行

pyd的初始化主要分为三个部分,分别为 常量/整数的初始化 Pyx_InitConstants , 字符串的初始化 Pyx_CreateStringTabAndInitStrings ,其他的初始化 pyx_pymod_exec

其中 Pyx_InitConstants 的开头包含了字符串的初始化 Pyx_CreateStringTabAndInitStrings(如果没有代码比较简单,没有常量,则不会有Pyx_InitConstants 生成)

pyx_mod_exec 也有可能会调用到 Pyx_CreateStringTabAndInitStrings 函数,但不在开头

并且他们会围绕着一个变量走: pyx_mstate_global

注意, pyx_mstate_global 每一个变量的长度都为一个QWORD,如果被ida识别成了 void* 则需要手动更改。

每一个用户自写函数,都会在前几行代码中生成引用 pyx_mstate_global 的代码

并且调用最多的也就是 用户的自写函数/代码

我们观察生成的源码中 pymod_exec 的函数代码

会将我们定义的函数 设置为 __pyx_d 字典的键值对,就是说会调用用户定义的函数的首地址。

__Pyx_InitConstants __Pyx_InitGlobals 初始化常量,初始化全局变量

__Pyx_CreateStringTabAndInitStrings 被 __Pyx_InitConstants 调用

当然还有一种情况,pyd模块不定义任何函数,那么就不会有函数导出,代码会在 pymod_exec 的后面执行,望周知。

首先我们根据pyd文件生成的特点,先确定pyx_pymod_exec ,常量初始化函数 __Pyx_InitConstants 和 字符串初始化函数 __Pyx_CreateStringTabAndInitStrings

pyx_pymod_exec 确定的方法:

函数中有一些字符串可助力快速定位

用户定义的函数结构体会被pymod_exec引用一次

__Pyx_InitConstants 确定方法:

PyLong_FromLong 会被多次调用,在有很多常量的情况下

__Pyx_CreateStringTabAndInitStrings 确定方法:

字符串会被引用, 比如说 main 之类的一些 内容,还有一些代码残片。

根据这些函数解析 _pyx_mstate_global 的结构

然后再开始搜索函数名字符串,寻找函数的真正地址, 配合 pyx_mstate_global 来对代码进行解释

根据上面的技巧,识别原始的python代码,来完成逆向。

参考前辈: https://bbs.kanxue.com/thread-285349.htm 提供的方法

调用前,先使用input暂停python 进程,然后下断点附加python进程,开始调试。

linux 和 windows 上的方法基本一致,但要注意ida和实际加载的模块名称必须一致,否则不能顺利断下。

ida 打开查看字符串,发现有两个 rand0m 和 check 猜测为两个函数

查找真实的函数地址:

观察函数 sub_1800017E0 确定 off_18000B688 为 __pyx_mstate

重命名,check2 为真实函数

先确定 pymod_exec 和一些初始化函数位置,上文分析时,我们也可以通过函数结构体来确定 pymod_exec 函数,因为pymod_exec 会初始化这些函数

PyLong_FromLong 函数调用最多的就是 init_constra (当然不完全准确,有时候并不存在这个函数)

将这些函数重命名,我们就能拿到大部分的常量了。

pymod_exec 的 19, rand0m

可以f5 还原的更快一点

再分析check函数 创建8长度的列表

分别用到了_pyx_mstate 的 [40,43,41,47,39,45,42,46]

向下走,看到了一个 乘以 8 , 观察 mstate 34 也是 8

然后有一个 +1

乘8

分割 段为: (?*8:(?+1)*8)

然后获取了 _pyx_mstate 第 19个的变量,确定是 rand0m 函数

向下走,调用了 sub_180004660,点进去发现存在 PyObject_VectorcallDict, 确定为 FastCall

结合上下文判断 sub_180004790(v52, 1i64, v53, 0); 为 获取元组中的某个元素,下面还有一个调用,参数为 0

乘以 2

根据索引获取值,并比较 v34 来自 sub_180004790 的值,它的参数是调用了模块内函数返回的值

判断是否为真

再调用 v39 = sub_180004790(v55, 0i64, v63, 0);

乘以2

sub_1800044A0 分析出来是加法, +1

sub_1800044A0 内部为 add

getValueWithIndex 传入 v82 和 v34, v34 是上面计算出来的值, v82 是一开始的那个List 列表

判断是否成功比较

再有一个加法 _pyx_mstate[30] 即为 1,注意 这里判断 v74 ,再进行加法的

大于 4 就 break 退出循环

这里check函数的一个循环逻辑走完了,趁热打铁把代码还原一下

继续向下, 判断 v77 是否等于 v19 , v77 为 pyx_mstate[32]

最后返回 v78

继续完善代码:

现在找到 rand0m函数的逻辑逆向出来

也是和上面一样的方法搜索字符串寻找该函数

创建一个元组

传入的参数做类型转换 int(x,0x10)

做 xor 2654435769 和 右移 5

v6 = v14 = PyNumber_Xor(v12, _pyx_mstate[44])

v3 = v15 = Pyx_Rshift(v12, _pyx_mstate[33], 5, 0)

左移 4

v8 = v12 = v21 = PyNumber_Lshift(v12, _pyx_mstate[32]);

与运算 4198170623

v22 = (int *)PyNumber_And(v12, v16[48], v17, v18);// & 4198170623

右移运算 加法运算

v24 = Pyx_Rshift((__int64)v3, _pyx_mstate[37], 23, 0);

v3 = v25 = PyNumber_Add(v22, v24); // v22 + v24

右移 11, 次方 0x10001

v6 = v28 = v27 = Pyx_Rshift((__int64)v6, _pyx_mstate[35], 11, 1);

v8 = v30 = PyNumber_Power(v28, _pyx_mstate[38], Py_NoneStruct);

模 4294967293

v31 = (int *)PyNumber_Remainder(v30, _pyx_mstate[49]);

再创建一个元组

(v31, v3)

返回该元组

现在逻辑基本上清晰

整理:

解法

这里 v31 是rsa 可以求出来 ,但缺失 数据 0xb 位, v3 刚好可以补上缺失的位, 但要注意结合 check 函数,他们比较的时候,是先源[0] == res[1] 源[1] == res[0]

文章讲解了pyd的一些特性,希望能够助力师傅们在pyd逆向中如鱼得水。当然作者水平有限,可能没办法讲解更深的内容,文章也可能存在错误及不足之处,感谢理解。<抱拳>

pip install Cython
pip install Cython
def say_hello_to(name):
    print(f"Hello {name}!")
def say_hello_to(name):
    print(f"Hello {name}!")
from setuptools import setup
from Cython.Build import cythonize
 
setup(
    name='Hello world app',
    ext_modules=cythonize("hello.pyx"),
)
from setuptools import setup
from Cython.Build import cythonize
 
setup(
    name='Hello world app',
    ext_modules=cythonize("hello.pyx"),
)
python setup.py build_ext --inplace
python setup.py build_ext --inplace
import hello
from hello import say_hello_to
import hello
from hello import say_hello_to
static PyObject *__pyx_pf_5bbbbb_say_hello_to(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_name) {
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  PyObject *__pyx_t_1 = NULL;
  PyObject *__pyx_t_2 = NULL;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("say_hello_to", 1);
 
  /* "bbbbb.pyx":4
 *
 * def say_hello_to(name):
 *  print(f"Hello {name}")             # <<<<<<<<<<<<<<
 */
  __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_v_name, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Hello, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
  /* "bbbbb.pyx":3
 *
 *
 * def say_hello_to(name):             # <<<<<<<<<<<<<<
 *  print(f"Hello {name}")
 */
 
  /* function exit code */
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_AddTraceback("bbbbb.say_hello_to", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
static PyObject *__pyx_pf_5bbbbb_say_hello_to(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_name) {
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  PyObject *__pyx_t_1 = NULL;
  PyObject *__pyx_t_2 = NULL;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("say_hello_to", 1);
 
  /* "bbbbb.pyx":4
 *
 * def say_hello_to(name):
 *  print(f"Hello {name}")             # <<<<<<<<<<<<<<
 */
  __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_v_name, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Hello, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
  /* "bbbbb.pyx":3
 *
 *
 * def say_hello_to(name):             # <<<<<<<<<<<<<<
 *  print(f"Hello {name}")
 */
 
  /* function exit code */
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_AddTraceback("bbbbb.say_hello_to", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
from setuptools import setup, Extension
from Cython.Build import cythonize
 
ext_module = [
    Extension(
        name="www",
        sources=["www.py"],
        extra_compile_args=["/Zi"],
        extra_link_args=["/DEBUG"]
    )
]
 
setup(
    name = "www",
    ext_modules = cythonize(ext_module,annotate=True)
)
from setuptools import setup, Extension
from Cython.Build import cythonize
 
ext_module = [
    Extension(
        name="www",
        sources=["www.py"],
        extra_compile_args=["/Zi"],
        extra_link_args=["/DEBUG"]
    )
]
 
setup(
    name = "www",
    ext_modules = cythonize(ext_module,annotate=True)
)
from setuptools import setup, Extension
from Cython.Build import cythonize
 
 
extensions = [
    Extension(
            sources=["xxx.py"],
            name="xxx"
            extra_link_args=["-Wl,--strip-all"]
        ),
]
 
setup(
    ext_modules=cythonize(extensions),
)
from setuptools import setup, Extension
from Cython.Build import cythonize
 
 
extensions = [
    Extension(
            sources=["xxx.py"],
            name="xxx"
            extra_link_args=["-Wl,--strip-all"]
        ),
]
 
setup(
    ext_modules=cythonize(extensions),
)
def get_list():
    return [1,2,3,4,991,776,229, 12.22]
 
def get_list1(index,end):
    a= get_list()
        return a
def get_list():
    return [1,2,3,4,991,776,229, 12.22]
 
def get_list1(index,end):
    a= get_list()
        return a
import socket
import subprocess
 
socket.socket(socket.AF_INET,socket.SOCK_STREAM)
import socket
import subprocess
 
socket.socket(socket.AF_INET,socket.SOCK_STREAM)
def test_calc(a):
    res = a + 1
    res = res -10
    res = res * 998
    res = res / 100
    res = res * 200
    res = res // 30
    res = res ** 3
    res = res << 3
    res = res ^ a
    res = hex(res)[2:]
    res = res + '00'
    res = int(res, 16)
    res = res >> 4
    res = res | 0xf
    res = res & 0x1f
    res = ~rsa
    return res
    
def test_calc(a):
    res = a + 1
    res = res -10
    res = res * 998
    res = res / 100
    res = res * 200
    res = res // 30
    res = res ** 3
    res = res << 3
    res = res ^ a
    res = hex(res)[2:]
    res = res + '00'
    res = int(res, 16)
    res = res >> 4
    res = res | 0xf
    res = res & 0x1f
    res = ~rsa
    return res
    
_typeobject *__fastcall _pyx_pf_5bbbbb_10test_calc(_object *__pyx_v_a, _object *__pyx_self, __int64 a3)
{
  _typeobject *v3; // r12
  _typeobject *v5; // rbx
  _object *pyx_int_1; // r9
  _typeobject *ob_type; // rax
  unsigned __int64 ob_refcnt; // r8
  __int64 v9; // rax
  unsigned __int64 v10; // r8
  const char *v11; // rsi
  int v12; // edi
  int v13; // ebp
  _object *p_ob_base; // rax
  unsigned __int64 v15; // rdx
  __int64 v16; // rax
  __int64 v17; // rdx
  __int64 v18; // r8
  __int64 v19; // r9
  unsigned __int64 v20; // rdx
  _object *v21; // rdi
  int *v22; // rcx
  bool v23; // zf
  _object *v24; // rax
  __int64 v25; // rdx
  __int64 v26; // r8
  __int64 v27; // r9
  _object *v28; // rdi
  int *v29; // rcx
  _object *pyx_int_100; // r8
  _object *v31; // rax
  __int64 v32; // rax
  __int64 v33; // rdx
  __int64 v34; // r8
  __int64 v35; // r9
  _object *v36; // rdi
  int *v37; // rcx
  _object *v38; // rax
  __int64 v39; // rdx
  __int64 v40; // r8
  __int64 v41; // r9
  __int64 v42; // rdi
  int *v43; // rcx
  _object *v44; // r8
  _object *pyx_int_30; // r9
  unsigned __int64 v46; // rdx
  int *v47; // rcx
  __int64 v48; // rax
  __int64 v49; // rdx
  __int64 v50; // r8
  __int64 v51; // r9
  __int64 v52; // rdi
  int v53; // r8d
  unsigned int v54; // ecx
  int v55; // edx
  unsigned int v56; // r8d
  __int64 v57; // rax
  signed __int64 v58; // r8
  unsigned __int64 v59; // rcx
  __int64 v60; // rdx
  unsigned __int64 v61; // r8
  int *v62; // rcx
  _object *v63; // r8
  _object *pyx_int_3; // r9
  unsigned __int64 v65; // rdx
  int *v66; // rcx
  __int64 v67; // rax
  __int64 v68; // rdx
  __int64 v69; // r8
  _object *v70; // r9
  _object *v71; // rdi
  unsigned __int64 v72; // rcx
  __int64 v73; // rax
  int *v74; // rcx
  _object *v75; // rax
  _object *v76; // r14
  _typeobject *v77; // r8
  PyMappingMethods *tp_as_mapping; // r15
  __int64 v79; // rdx
  _typeobject *v80; // rdi
  __int64 v81; // r8
  __int64 v82; // r9
  __int64 v83; // rax
  int *v84; // rdi
  int *v85; // rsi
  int *v86; // rcx
  __int64 v87; // rax
  __int64 v88; // rdx
  __int64 v89; // r8
  __int64 v90; // r9
  _object *v91; // r8
  __pyx_mstate *v92; // rdx
  _object *pyx_int_16; // rcx
  _object *v94; // rdi
  int *v95; // rcx
  _object *pyx_int_4; // r9
  unsigned __int64 v97; // rdx
  int *v98; // rcx
  _object *pyx_int_15; // rsi
  unsigned __int64 v100; // rcx
  __int64 v101; // rax
  unsigned __int64 v102; // rdx
  __int64 v103; // rax
  int v104; // ecx
  __int64 v105; // rax
  __int64 v106; // rdx
  __int64 v107; // r8
  __int64 v108; // r9
  int *v109; // rdi
  __int64 v110; // rdx
  __int64 v111; // r8
  __int64 v112; // r9
  _typeobject *v113; // r14
  _object *args; // [rsp+38h] [rbp-30h] BYREF
 
  v3 = 0i64;
  v5 = 0i64;
  pyx_int_1 = _pyx_mstate_global->__pyx_int_1;
  ob_type = __pyx_self->ob_type;
  if ( ob_type != (_typeobject *)PyLong_Type )
  {
    if ( ob_type == (_typeobject *)PyFloat_Type )
      v9 = PyFloat_FromDouble(__pyx_v_a, __pyx_self, a3, pyx_int_1);
    else
      v9 = PyNumber_Add(__pyx_self, _pyx_mstate_global->__pyx_int_1);
LABEL_14:
    pyx_int_1 = (_object *)v9;
    goto LABEL_15;
  }
  ob_refcnt = __pyx_self[1].ob_refcnt;
  if ( (ob_refcnt & 1) == 0 )
  {
    if ( ob_refcnt >= 0x10 )
    {
      v10 = ob_refcnt >> 3;
      switch ( v10 * (1 - (__pyx_self[1].ob_refcnt & 3)) )
      {
        case 0xFFFFFFFFFFFFFFFEui64:
          v9 = PyLong_FromLongLong(
                 1 - (LODWORD(__pyx_self[1].ob_type) | ((unsigned __int64)HIDWORD(__pyx_self[1].ob_type) << 30)),
                 __pyx_self,
                 v10,
                 pyx_int_1);
          break;
        case 2ui64:
          v9 = PyLong_FromLongLong(
                 (LODWORD(__pyx_self[1].ob_type) | ((unsigned __int64)HIDWORD(__pyx_self[1].ob_type) << 30)) + 1,
                 __pyx_self,
                 v10,
                 pyx_int_1);
          break;
        default:
          v9 = (**((__int64 (__fastcall ***)(_object *, _object *))&PyLong_Type + 12))(
                 __pyx_self,
                 _pyx_mstate_global->__pyx_int_1);
          break;
      }
    }
    else
    {
      v9 = PyLong_FromLong(LODWORD(__pyx_self[1].ob_type) * (1 - (unsigned int)(ob_refcnt & 3)) + 1);
    }
    goto LABEL_14;
  }
  if ( pyx_int_1->ob_refcnt_split[0] != -1 )
    ++pyx_int_1->ob_refcnt_split[0];
LABEL_15:
  if ( !pyx_int_1 )
  {
    v11 = _pyx_f[0];
    v12 = 42;
    v13 = 3937;
    goto LABEL_204;
  }
  v5 = (_typeobject *)pyx_int_1;
  p_ob_base = &pyx_int_1->ob_type->ob_base.ob_base;
  if ( p_ob_base == PyLong_Type )
  {
    v15 = pyx_int_1[1].ob_refcnt;
    if ( (v15 & 1) != 0 )
    {
      v16 = PyLong_FromLong(0xFFFFFFF6i64);
    }
    else if ( v15 >= 0x10 )
    {
      v20 = v15 >> 3;
      switch ( v20 * (1 - (pyx_int_1[1].ob_refcnt & 3)) )
      {
        case 0xFFFFFFFFFFFFFFFEui64:
          v16 = PyLong_FromLongLong(
                  -(__int64)(LODWORD(pyx_int_1[1].ob_type) | ((unsigned __int64)HIDWORD(pyx_int_1[1].ob_type) << 30))
                - 10,
                  v20,
                  ob_refcnt,
                  pyx_int_1);
          break;
        case 2ui64:
          v16 = PyLong_FromLongLong(
                  (LODWORD(pyx_int_1[1].ob_type) | ((unsigned __int64)HIDWORD(pyx_int_1[1].ob_type) << 30)) - 10,
                  v20,
                  ob_refcnt,
                  pyx_int_1);
          break;
        default:
          v16 = (*(__int64 (__fastcall **)(_object *, _object *))(*((_QWORD *)&PyLong_Type + 12) + 8i64))(
                  pyx_int_1,
                  _pyx_mstate_global->__pyx_int_10);
          break;
      }
    }
    else
    {
      v16 = PyLong_FromLong(LODWORD(pyx_int_1[1].ob_type) * (1 - (unsigned int)(v15 & 3)) - 10);
    }
  }
  else if ( p_ob_base == (_object *)PyFloat_Type )
  {
    v16 = PyFloat_FromDouble(__pyx_v_a, __pyx_self, ob_refcnt, pyx_int_1);
  }
  else
  {
    v16 = PyNumber_Subtract(pyx_int_1, _pyx_mstate_global->__pyx_int_10);
  }
  v21 = (_object *)v16;
  if ( !v16 )
  {
    v11 = _pyx_f[0];
    v12 = 43;
    v13 = 3949;
    goto LABEL_204;
  }
  v22 = (int *)v5;
  v5 = (_typeobject *)v16;
  if ( *v22 >= 0 )
  {
    v23 = (*(_QWORD *)v22)-- == 1i64;
    if ( v23 )
      _Py_Dealloc(v22, v17, v18, v19);
  }
  v24 = _Pyx_PyInt_MultiplyObjC(v21, _pyx_mstate_global->__pyx_int_998, 998i64, v19);
  v28 = v24;
  if ( !v24 )
  {
    v11 = _pyx_f[0];
    v12 = 44;
    v13 = 3961;
    goto LABEL_204;
  }
  v29 = (int *)v5;
  v5 = (_typeobject *)v24;
  if ( *v29 >= 0 )
  {
    v23 = (*(_QWORD *)v29)-- == 1i64;
    if ( v23 )
      _Py_Dealloc(v29, v25, v26, v27);
  }
  pyx_int_100 = _pyx_mstate_global->__pyx_int_100;
  v31 = &v28->ob_type->ob_base.ob_base;
  if ( v31 == PyLong_Type )
  {
    if ( v28[1].ob_refcnt >= 0x10ui64 )
      v32 = (*(__int64 (__fastcall **)(_object *, _object *))(*((_QWORD *)&PyLong_Type + 12) + 240i64))(
              v28,
              _pyx_mstate_global->__pyx_int_100);
    else
      v32 = PyFloat_FromDouble(v28[1].ob_refcnt & 3, PyLong_Type, pyx_int_100, v27);
  }
  else if ( v31 == (_object *)PyFloat_Type )
  {
    v32 = PyFloat_FromDouble(v29, PyLong_Type, pyx_int_100, v27);
  }
  else
  {
    v32 = PyNumber_TrueDivide(v28, _pyx_mstate_global->__pyx_int_100);
  }
  v36 = (_object *)v32;
  if ( !v32 )
  {
    v11 = _pyx_f[0];
    v12 = 45;
    v13 = 3973;
    goto LABEL_204;
  }
  v37 = (int *)v5;
  v5 = (_typeobject *)v32;
  if ( *v37 >= 0 )
  {
    v23 = (*(_QWORD *)v37)-- == 1i64;
    if ( v23 )
      _Py_Dealloc(v37, v33, v34, v35);
  }
  v38 = _Pyx_PyInt_MultiplyObjC(v36, _pyx_mstate_global->__pyx_int_200, 200i64, v35);
  v42 = (__int64)v38;
  if ( !v38 )
  {
    v11 = _pyx_f[0];
    v12 = 46;
    v13 = 3985;
    goto LABEL_204;
  }
  v43 = (int *)v5;
  v5 = (_typeobject *)v38;
  if ( *v43 >= 0 )
  {
    v23 = (*(_QWORD *)v43)-- == 1i64;
    if ( v23 )
      _Py_Dealloc(v43, v39, v40, v41);
  }
  v44 = PyLong_Type;
  pyx_int_30 = _pyx_mstate_global->__pyx_int_30;
  if ( *(_object *const *)(v42 + 8) == PyLong_Type )
  {
    v46 = *(_QWORD *)(v42 + 16);
    if ( (v46 & 1) != 0 )
    {
      if ( *(_DWORD *)v42 != -1 )
        ++*(_DWORD *)v42;
      goto LABEL_60;
    }
    if ( v46 >= 0x10 )
    {
      switch ( (*(_QWORD *)(v42 + 16) >> 3) * (1 - (*(_QWORD *)(v42 + 16) & 3ui64)) )
      {
        case 0xFFFFFFFFFFFFFFFEui64:
          v58 = -(__int64)(*(unsigned int *)(v42 + 24) | ((unsigned __int64)*(unsigned int *)(v42 + 28) << 30));
          goto LABEL_72;
        case 2ui64:
          v58 = *(unsigned int *)(v42 + 24) | ((unsigned __int64)*(unsigned int *)(v42 + 28) << 30);
LABEL_72:
          v59 = 0i64;
          v60 = v58 / 30;
          v61 = v58 % 30;
          if ( v61 )
            v59 = v61 >> 63;
          v57 = PyLong_FromLongLong(v60 - v59, v60 - v59, v61, pyx_int_30);
          break;
        default:
          v57 = (*(__int64 (__fastcall **)(__int64, _object *))(*((_QWORD *)&PyLong_Type + 12) + 232i64))(
                  v42,
                  _pyx_mstate_global->__pyx_int_30);
          break;
      }
    }
    else
    {
      v53 = *(_DWORD *)(v42 + 24) * (1 - (v46 & 3));
      v54 = 0;
      v55 = v53 / 30;
      v56 = v53 % 30;
      if ( v56 )
        v54 = v56 >> 31;
      v57 = PyLong_FromLong(v55 - v54);
    }
  }
  else
  {
    v57 = PyNumber_FloorDivide(v42, _pyx_mstate_global->__pyx_int_30);
  }
  v42 = v57;
  if ( !v57 )
  {
    v11 = _pyx_f[0];
    v12 = 47;
    v13 = 3997;
    goto LABEL_204;
  }
LABEL_60:
  v47 = (int *)v5;
  v5 = (_typeobject *)v42;
  if ( *v47 >= 0 )
  {
    v23 = (*(_QWORD *)v47)-- == 1i64;
    if ( v23 )
      _Py_Dealloc(v47, v46, v44, pyx_int_30);
  }
  v48 = PyNumber_Power(v42, _pyx_mstate_global->__pyx_int_3, _Py_NoneStruct, pyx_int_30);
  v52 = v48;
  if ( !v48 )
  {
    v11 = _pyx_f[0];
    v12 = 48;
    v13 = 4009;
    goto LABEL_204;
  }
  v62 = (int *)v5;
  v5 = (_typeobject *)v48;
  if ( *v62 >= 0 )
  {
    v23 = (*(_QWORD *)v62)-- == 1i64;
    if ( v23 )
      _Py_Dealloc(v62, v49, v50, v51);
  }
  v63 = PyLong_Type;
  pyx_int_3 = _pyx_mstate_global->__pyx_int_3;
  if ( *(_object *const *)(v52 + 8) != PyLong_Type )
  {
LABEL_102:
    v73 = PyNumber_Lshift(v52, _pyx_mstate_global->__pyx_int_3);
    goto LABEL_103;
  }
  v65 = *(_QWORD *)(v52 + 16);
  if ( (v65 & 1) != 0 )
  {
    if ( *(_DWORD *)v52 != -1 )
      ++*(_DWORD *)v52;
    goto LABEL_86;
  }
  if ( v65 < 0x10 )
  {
    LODWORD(v72) = *(_DWORD *)(v52 + 24) * (1 - (v65 & 3));
    if ( (_DWORD)v72 == (8 * (int)v72) >> 3 || !(_DWORD)v72 )
    {
      v73 = PyLong_FromLong((unsigned int)(8 * v72));
      goto LABEL_103;
    }
    v72 = (int)v72;
LABEL_99:
    if ( v72 == (__int64)(8 * v72) >> 3 )
    {
      v73 = PyLong_FromLongLong(8 * v72, 8 * v72, PyLong_Type, pyx_int_3);
      goto LABEL_103;
    }
    goto LABEL_102;
  }
  switch ( (*(_QWORD *)(v52 + 16) >> 3) * (1 - (*(_QWORD *)(v52 + 16) & 3ui64)) )
  {
    case 0xFFFFFFFFFFFFFFFEui64:
      v72 = -(__int64)(*(unsigned int *)(v52 + 24) | ((unsigned __int64)*(unsigned int *)(v52 + 28) << 30));
      goto LABEL_99;
    case 2ui64:
      v72 = *(unsigned int *)(v52 + 24) | ((unsigned __int64)*(unsigned int *)(v52 + 28) << 30);
      goto LABEL_99;
    default:
      v73 = (*(__int64 (__fastcall **)(__int64, _object *))(*((_QWORD *)&PyLong_Type + 12) + 88i64))(
              v52,
              _pyx_mstate_global->__pyx_int_3);
      break;
  }
LABEL_103:
  v52 = v73;
  if ( !v73 )
  {
    v11 = _pyx_f[0];
    v12 = 49;
    v13 = 4021;
    goto LABEL_204;
  }
LABEL_86:
  v66 = (int *)v5;
  v5 = (_typeobject *)v52;
  if ( *v66 >= 0 )
  {
    v23 = (*(_QWORD *)v66)-- == 1i64;
    if ( v23 )
      _Py_Dealloc(v66, v65, v63, pyx_int_3);
  }
  v67 = PyNumber_Xor(v52, __pyx_self, v63, pyx_int_3);
  v71 = (_object *)v67;
  if ( !v67 )
  {
    v11 = _pyx_f[0];
    v12 = 50;
    v13 = 4033;
    goto LABEL_204;
  }
  v74 = (int *)v5;
  v5 = (_typeobject *)v67;
  if ( *v74 >= 0 )
  {
    v23 = (*(_QWORD *)v74)-- == 1i64;
    if ( v23 )
      _Py_Dealloc(v74, v68, v69, v70);
  }
  args = v71;
  v75 = _Pyx_PyObject_FastCallDict(_pyx_builtin_hex, &args, 0x8000000000000001ui64, v70);
  v76 = v75;
  if ( !v75 )
  {
    v11 = _pyx_f[0];
    v12 = 51;
    v13 = 4045;
    goto LABEL_204;
  }
  v77 = v75->ob_type;
  tp_as_mapping = v77->tp_as_mapping;
  if ( !tp_as_mapping || !tp_as_mapping->mp_subscript )
  {
    PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", v77->tp_name);
    goto LABEL_200;
  }
  if ( _pyx_mstate_global == (__pyx_mstate *)-656i64 )
  {
    v83 = PyLong_FromSsize_t(2i64);
    v84 = (int *)v83;
    if ( !v83 )
      goto LABEL_200;
    v85 = (int *)PySlice_New(v83, _Py_NoneStruct, _Py_NoneStruct);
    if ( *v84 >= 0 )
    {
      v23 = (*(_QWORD *)v84)-- == 1i64;
      if ( v23 )
        _Py_Dealloc(v84, v79, v81, v82);
    }
    if ( !v85 )
      goto LABEL_200;
    v80 = (_typeobject *)tp_as_mapping->mp_subscript(v76, (_object *)v85);
    if ( *v85 >= 0 )
    {
      v23 = (*(_QWORD *)v85)-- == 1i64;
      if ( v23 )
        _Py_Dealloc(v85, v79, v81, v82);
    }
  }
  else
  {
    v80 = (_typeobject *)tp_as_mapping->mp_subscript(v75, _pyx_mstate_global->__pyx_slice__4);
  }
  if ( !v80 )
  {
LABEL_200:
    v12 = 51;
    v13 = 4047;
    goto $__pyx_L1_error_2;
  }
  if ( (v76->ob_refcnt_split[0] & 0x80000000) == 0 )
  {
    v23 = v76->ob_refcnt-- == 1;
    if ( v23 )
      _Py_Dealloc(v76, v79, v81, v82);
  }
  v86 = (int *)v5;
  v5 = v80;
  if ( *v86 >= 0 )
  {
    v23 = (*(_QWORD *)v86)-- == 1i64;
    if ( v23 )
      _Py_Dealloc(v86, v79, v81, v82);
  }
  v87 = PyNumber_Add(v80, _pyx_mstate_global->__pyx_kp_s_00);
  if ( !v87 )
  {
    v11 = _pyx_f[0];
    v12 = 52;
    v13 = 4060;
    goto LABEL_204;
  }
  v5 = (_typeobject *)v87;
  if ( (v80->ob_base.ob_base.ob_refcnt_split[0] & 0x80000000) == 0 )
  {
    v23 = v80->ob_base.ob_base.ob_refcnt-- == 1;
    if ( v23 )
      _Py_Dealloc(v80, v88, v89, v90);
  }
  v76 = (_object *)PyTuple_New(2i64);
  if ( !v76 )
  {
    v11 = _pyx_f[0];
    v12 = 53;
    v13 = 4072;
    goto LABEL_204;
  }
  if ( v5->ob_base.ob_base.ob_refcnt_split[0] != -1 )
    ++v5->ob_base.ob_base.ob_refcnt_split[0];
  v92 = _pyx_mstate_global;
  v76[1].ob_type = v5;
  pyx_int_16 = v92->__pyx_int_16;
  if ( pyx_int_16->ob_refcnt_split[0] != -1 )
    ++pyx_int_16->ob_refcnt_split[0];
  v76[2].ob_refcnt = (__int64)v92->__pyx_int_16;
  v94 = _Pyx_PyObject_Call(PyLong_Type, v76, v91);
  if ( !v94 )
  {
    v12 = 53;
    v13 = 4080;
$__pyx_L1_error_2:
    v11 = _pyx_f[0];
    if ( (v76->ob_refcnt_split[0] & 0x80000000) == 0 )
    {
      v23 = v76->ob_refcnt-- == 1;
      if ( v23 )
        _Py_Dealloc(v76, v79, v81, v82);
    }
LABEL_204:
    v113 = v5;
    _Pyx_AddTraceback("bbbbb.test_calc", v13, v12, v11);
    if ( !v5 )
      return v3;
    goto LABEL_205;
  }
  if ( (v76->ob_refcnt_split[0] & 0x80000000) == 0 )
  {
    v23 = v76->ob_refcnt-- == 1;
    if ( v23 )
      _Py_Dealloc(v76, v79, v81, v82);
  }
  v95 = (int *)v5;
  v5 = (_typeobject *)v94;
  if ( *v95 >= 0 )
  {
    v23 = (*(_QWORD *)v95)-- == 1i64;
    if ( v23 )
      _Py_Dealloc(v95, v79, v81, v82);
  }
  pyx_int_4 = _pyx_mstate_global->__pyx_int_4;
  if ( (_object *const)v94->ob_type == PyLong_Type )
  {
    v97 = v94[1].ob_refcnt;
    if ( (v97 & 1) != 0 )
    {
      if ( v94->ob_refcnt_split[0] != -1 )
        ++v94->ob_refcnt_split[0];
      goto LABEL_152;
    }
    if ( v97 >= 0x10 )
    {
      v102 = v97 >> 3;
      switch ( v102 * (1 - (v94[1].ob_refcnt & 3)) )
      {
        case 0xFFFFFFFFFFFFFFFEui64:
          v101 = PyLong_FromLongLong(
                   -(__int64)(LODWORD(v94[1].ob_type) | ((unsigned __int64)HIDWORD(v94[1].ob_type) << 30)) >> 4,
                   v102,
                   v81,
                   pyx_int_4);
          break;
        case 2ui64:
          v101 = PyLong_FromLongLong(
                   (__int64)(LODWORD(v94[1].ob_type) | ((unsigned __int64)HIDWORD(v94[1].ob_type) << 30)) >> 4,
                   v102,
                   v81,
                   pyx_int_4);
          break;
        default:
          v101 = (*(__int64 (__fastcall **)(_object *, _object *))(*((_QWORD *)&PyLong_Type + 12) + 96i64))(
                   v94,
                   _pyx_mstate_global->__pyx_int_4);
          break;
      }
    }
    else
    {
      v101 = PyLong_FromLong((unsigned int)((int)(LODWORD(v94[1].ob_type) * (1 - (v97 & 3))) >> 4));
    }
  }
  else
  {
    v101 = PyNumber_Rshift(v94, _pyx_mstate_global->__pyx_int_4);
  }
  v94 = (_object *)v101;
  if ( !v101 )
  {
    v11 = _pyx_f[0];
    v12 = 54;
    v13 = 4093;
    goto LABEL_204;
  }
LABEL_152:
  v98 = (int *)v5;
  v5 = (_typeobject *)v94;
  if ( *v98 >= 0 )
  {
    v23 = (*(_QWORD *)v98)-- == 1i64;
    if ( v23 )
      _Py_Dealloc(v98, v97, v81, pyx_int_4);
  }
  pyx_int_15 = _pyx_mstate_global->__pyx_int_15;
  if ( (_object *const)v94->ob_type != PyLong_Type )
  {
    v103 = PyNumber_Or(v94, _pyx_mstate_global->__pyx_int_15, v81, pyx_int_4);
LABEL_175:
    pyx_int_15 = (_object *)v103;
    goto LABEL_176;
  }
  v100 = v94[1].ob_refcnt;
  if ( (v100 & 1) == 0 )
  {
    if ( v100 >= 0x10 )
    {
      switch ( (v100 >> 3) * (1 - (v94[1].ob_refcnt & 3)) )
      {
        case 0xFFFFFFFFFFFFFFFEui64:
          v103 = PyLong_FromLongLong(
                   -(__int64)(LODWORD(v94[1].ob_type) | ((unsigned __int64)HIDWORD(v94[1].ob_type) << 30)) | 0xF,
                   v97,
                   v81,
                   pyx_int_4);
          break;
        case 2ui64:
          v103 = PyLong_FromLongLong(
                   LODWORD(v94[1].ob_type) | ((unsigned __int64)HIDWORD(v94[1].ob_type) << 30) | 0xF,
                   v97,
                   v81,
                   pyx_int_4);
          break;
        default:
          v103 = (*(__int64 (__fastcall **)(_object *, _object *, _QWORD, _object *))(*((_QWORD *)&PyLong_Type + 12)
                                                                                    + 120i64))(
                   v94,
                   _pyx_mstate_global->__pyx_int_15,
                   *((_QWORD *)&PyLong_Type + 12),
                   pyx_int_4);
          break;
      }
    }
    else
    {
      v103 = PyLong_FromLong((LODWORD(v94[1].ob_type) * (1 - (v100 & 3))) | 0xF);
    }
    goto LABEL_175;
  }
  if ( pyx_int_15->ob_refcnt_split[0] != -1 )
    ++pyx_int_15->ob_refcnt_split[0];
LABEL_176:
  if ( !pyx_int_15 )
  {
    v11 = _pyx_f[0];
    v12 = 55;
    v13 = 4105;
    goto LABEL_204;
  }
  v5 = (_typeobject *)pyx_int_15;
  if ( (v94->ob_refcnt_split[0] & 0x80000000) == 0 )
  {
    v23 = v94->ob_refcnt-- == 1;
    if ( v23 )
      _Py_Dealloc(v94, v97, v81, pyx_int_4);
  }
  if ( (_object *const)pyx_int_15->ob_type == PyLong_Type )
  {
    v104 = 0x40000000 - LODWORD(pyx_int_15[1].ob_type);
    if ( (pyx_int_15[1].ob_refcnt & 3) == 0 )
      v104 = (int)pyx_int_15[1].ob_type;
    v105 = PyLong_FromLong(v104 & 0x1F);
  }
  else
  {
    v105 = PyNumber_And(pyx_int_15, _pyx_mstate_global->__pyx_int_31, v81, pyx_int_4);
  }
  v109 = (int *)v105;
  if ( !v105 )
  {
    v11 = _pyx_f[0];
    v12 = 56;
    v13 = 4117;
    goto LABEL_204;
  }
  v5 = (_typeobject *)v105;
  if ( (pyx_int_15->ob_refcnt_split[0] & 0x80000000) == 0 )
  {
    v23 = pyx_int_15->ob_refcnt-- == 1;
    if ( v23 )
      _Py_Dealloc(pyx_int_15, v106, v107, v108);
  }
  v113 = (_typeobject *)PyNumber_Invert(v109);
  if ( !v113 )
  {
    v11 = _pyx_f[0];
    v12 = 57;
    v13 = 4129;
    goto LABEL_204;
  }
  if ( *v109 >= 0 )
  {
    v23 = (*(_QWORD *)v109)-- == 1i64;
    if ( v23 )
      _Py_Dealloc(v109, v110, v111, v112);
  }
  if ( v113->ob_base.ob_base.ob_refcnt_split[0] != -1 )
    ++v113->ob_base.ob_base.ob_refcnt_split[0];
  v3 = v113;
LABEL_205:
  if ( (v113->ob_base.ob_base.ob_refcnt_split[0] & 0x80000000) == 0 )
  {
    v23 = v113->ob_base.ob_base.ob_refcnt-- == 1;
    if ( v23 )
      _Py_Dealloc(v113, v110, v111, v112);
  }
  return v3;
}
_typeobject *__fastcall _pyx_pf_5bbbbb_10test_calc(_object *__pyx_v_a, _object *__pyx_self, __int64 a3)
{
  _typeobject *v3; // r12
  _typeobject *v5; // rbx
  _object *pyx_int_1; // r9
  _typeobject *ob_type; // rax
  unsigned __int64 ob_refcnt; // r8
  __int64 v9; // rax
  unsigned __int64 v10; // r8
  const char *v11; // rsi
  int v12; // edi
  int v13; // ebp
  _object *p_ob_base; // rax
  unsigned __int64 v15; // rdx
  __int64 v16; // rax
  __int64 v17; // rdx
  __int64 v18; // r8
  __int64 v19; // r9
  unsigned __int64 v20; // rdx
  _object *v21; // rdi
  int *v22; // rcx
  bool v23; // zf
  _object *v24; // rax
  __int64 v25; // rdx
  __int64 v26; // r8
  __int64 v27; // r9
  _object *v28; // rdi
  int *v29; // rcx
  _object *pyx_int_100; // r8
  _object *v31; // rax
  __int64 v32; // rax
  __int64 v33; // rdx
  __int64 v34; // r8
  __int64 v35; // r9
  _object *v36; // rdi
  int *v37; // rcx
  _object *v38; // rax
  __int64 v39; // rdx
  __int64 v40; // r8
  __int64 v41; // r9
  __int64 v42; // rdi
  int *v43; // rcx
  _object *v44; // r8
  _object *pyx_int_30; // r9
  unsigned __int64 v46; // rdx
  int *v47; // rcx
  __int64 v48; // rax
  __int64 v49; // rdx
  __int64 v50; // r8
  __int64 v51; // r9
  __int64 v52; // rdi
  int v53; // r8d
  unsigned int v54; // ecx
  int v55; // edx
  unsigned int v56; // r8d
  __int64 v57; // rax
  signed __int64 v58; // r8
  unsigned __int64 v59; // rcx
  __int64 v60; // rdx
  unsigned __int64 v61; // r8
  int *v62; // rcx
  _object *v63; // r8
  _object *pyx_int_3; // r9
  unsigned __int64 v65; // rdx
  int *v66; // rcx
  __int64 v67; // rax
  __int64 v68; // rdx
  __int64 v69; // r8
  _object *v70; // r9
  _object *v71; // rdi
  unsigned __int64 v72; // rcx
  __int64 v73; // rax
  int *v74; // rcx
  _object *v75; // rax
  _object *v76; // r14
  _typeobject *v77; // r8
  PyMappingMethods *tp_as_mapping; // r15
  __int64 v79; // rdx
  _typeobject *v80; // rdi
  __int64 v81; // r8
  __int64 v82; // r9
  __int64 v83; // rax
  int *v84; // rdi
  int *v85; // rsi
  int *v86; // rcx
  __int64 v87; // rax
  __int64 v88; // rdx
  __int64 v89; // r8
  __int64 v90; // r9
  _object *v91; // r8
  __pyx_mstate *v92; // rdx
  _object *pyx_int_16; // rcx
  _object *v94; // rdi
  int *v95; // rcx
  _object *pyx_int_4; // r9
  unsigned __int64 v97; // rdx
  int *v98; // rcx
  _object *pyx_int_15; // rsi
  unsigned __int64 v100; // rcx
  __int64 v101; // rax
  unsigned __int64 v102; // rdx
  __int64 v103; // rax
  int v104; // ecx
  __int64 v105; // rax
  __int64 v106; // rdx
  __int64 v107; // r8
  __int64 v108; // r9
  int *v109; // rdi
  __int64 v110; // rdx
  __int64 v111; // r8
  __int64 v112; // r9
  _typeobject *v113; // r14
  _object *args; // [rsp+38h] [rbp-30h] BYREF
 
  v3 = 0i64;
  v5 = 0i64;
  pyx_int_1 = _pyx_mstate_global->__pyx_int_1;
  ob_type = __pyx_self->ob_type;
  if ( ob_type != (_typeobject *)PyLong_Type )
  {
    if ( ob_type == (_typeobject *)PyFloat_Type )
      v9 = PyFloat_FromDouble(__pyx_v_a, __pyx_self, a3, pyx_int_1);
    else
      v9 = PyNumber_Add(__pyx_self, _pyx_mstate_global->__pyx_int_1);
LABEL_14:
    pyx_int_1 = (_object *)v9;
    goto LABEL_15;
  }
  ob_refcnt = __pyx_self[1].ob_refcnt;
  if ( (ob_refcnt & 1) == 0 )
  {
    if ( ob_refcnt >= 0x10 )
    {
      v10 = ob_refcnt >> 3;
      switch ( v10 * (1 - (__pyx_self[1].ob_refcnt & 3)) )
      {
        case 0xFFFFFFFFFFFFFFFEui64:
          v9 = PyLong_FromLongLong(
                 1 - (LODWORD(__pyx_self[1].ob_type) | ((unsigned __int64)HIDWORD(__pyx_self[1].ob_type) << 30)),
                 __pyx_self,
                 v10,
                 pyx_int_1);
          break;
        case 2ui64:
          v9 = PyLong_FromLongLong(
                 (LODWORD(__pyx_self[1].ob_type) | ((unsigned __int64)HIDWORD(__pyx_self[1].ob_type) << 30)) + 1,
                 __pyx_self,
                 v10,
                 pyx_int_1);
          break;
        default:
          v9 = (**((__int64 (__fastcall ***)(_object *, _object *))&PyLong_Type + 12))(
                 __pyx_self,
                 _pyx_mstate_global->__pyx_int_1);
          break;
      }
    }
    else
    {
      v9 = PyLong_FromLong(LODWORD(__pyx_self[1].ob_type) * (1 - (unsigned int)(ob_refcnt & 3)) + 1);
    }
    goto LABEL_14;
  }
  if ( pyx_int_1->ob_refcnt_split[0] != -1 )
    ++pyx_int_1->ob_refcnt_split[0];
LABEL_15:
  if ( !pyx_int_1 )
  {
    v11 = _pyx_f[0];
    v12 = 42;
    v13 = 3937;
    goto LABEL_204;
  }
  v5 = (_typeobject *)pyx_int_1;
  p_ob_base = &pyx_int_1->ob_type->ob_base.ob_base;
  if ( p_ob_base == PyLong_Type )
  {
    v15 = pyx_int_1[1].ob_refcnt;
    if ( (v15 & 1) != 0 )
    {
      v16 = PyLong_FromLong(0xFFFFFFF6i64);
    }
    else if ( v15 >= 0x10 )
    {
      v20 = v15 >> 3;
      switch ( v20 * (1 - (pyx_int_1[1].ob_refcnt & 3)) )
      {
        case 0xFFFFFFFFFFFFFFFEui64:
          v16 = PyLong_FromLongLong(
                  -(__int64)(LODWORD(pyx_int_1[1].ob_type) | ((unsigned __int64)HIDWORD(pyx_int_1[1].ob_type) << 30))
                - 10,
                  v20,
                  ob_refcnt,
                  pyx_int_1);
          break;
        case 2ui64:
          v16 = PyLong_FromLongLong(
                  (LODWORD(pyx_int_1[1].ob_type) | ((unsigned __int64)HIDWORD(pyx_int_1[1].ob_type) << 30)) - 10,
                  v20,
                  ob_refcnt,
                  pyx_int_1);
          break;
        default:
          v16 = (*(__int64 (__fastcall **)(_object *, _object *))(*((_QWORD *)&PyLong_Type + 12) + 8i64))(
                  pyx_int_1,
                  _pyx_mstate_global->__pyx_int_10);
          break;
      }
    }
    else
    {
      v16 = PyLong_FromLong(LODWORD(pyx_int_1[1].ob_type) * (1 - (unsigned int)(v15 & 3)) - 10);
    }
  }
  else if ( p_ob_base == (_object *)PyFloat_Type )
  {
    v16 = PyFloat_FromDouble(__pyx_v_a, __pyx_self, ob_refcnt, pyx_int_1);
  }
  else
  {
    v16 = PyNumber_Subtract(pyx_int_1, _pyx_mstate_global->__pyx_int_10);
  }
  v21 = (_object *)v16;
  if ( !v16 )
  {
    v11 = _pyx_f[0];
    v12 = 43;
    v13 = 3949;
    goto LABEL_204;
  }
  v22 = (int *)v5;
  v5 = (_typeobject *)v16;
  if ( *v22 >= 0 )
  {
    v23 = (*(_QWORD *)v22)-- == 1i64;
    if ( v23 )
      _Py_Dealloc(v22, v17, v18, v19);
  }
  v24 = _Pyx_PyInt_MultiplyObjC(v21, _pyx_mstate_global->__pyx_int_998, 998i64, v19);
  v28 = v24;
  if ( !v24 )
  {
    v11 = _pyx_f[0];
    v12 = 44;
    v13 = 3961;
    goto LABEL_204;
  }
  v29 = (int *)v5;
  v5 = (_typeobject *)v24;
  if ( *v29 >= 0 )
  {
    v23 = (*(_QWORD *)v29)-- == 1i64;
    if ( v23 )
      _Py_Dealloc(v29, v25, v26, v27);
  }
  pyx_int_100 = _pyx_mstate_global->__pyx_int_100;
  v31 = &v28->ob_type->ob_base.ob_base;
  if ( v31 == PyLong_Type )
  {
    if ( v28[1].ob_refcnt >= 0x10ui64 )
      v32 = (*(__int64 (__fastcall **)(_object *, _object *))(*((_QWORD *)&PyLong_Type + 12) + 240i64))(
              v28,
              _pyx_mstate_global->__pyx_int_100);
    else
      v32 = PyFloat_FromDouble(v28[1].ob_refcnt & 3, PyLong_Type, pyx_int_100, v27);
  }
  else if ( v31 == (_object *)PyFloat_Type )
  {
    v32 = PyFloat_FromDouble(v29, PyLong_Type, pyx_int_100, v27);
  }
  else
  {
    v32 = PyNumber_TrueDivide(v28, _pyx_mstate_global->__pyx_int_100);
  }
  v36 = (_object *)v32;
  if ( !v32 )
  {
    v11 = _pyx_f[0];
    v12 = 45;
    v13 = 3973;
    goto LABEL_204;
  }
  v37 = (int *)v5;
  v5 = (_typeobject *)v32;
  if ( *v37 >= 0 )
  {
    v23 = (*(_QWORD *)v37)-- == 1i64;
    if ( v23 )
      _Py_Dealloc(v37, v33, v34, v35);
  }
  v38 = _Pyx_PyInt_MultiplyObjC(v36, _pyx_mstate_global->__pyx_int_200, 200i64, v35);
  v42 = (__int64)v38;
  if ( !v38 )
  {
    v11 = _pyx_f[0];
    v12 = 46;
    v13 = 3985;
    goto LABEL_204;
  }
  v43 = (int *)v5;
  v5 = (_typeobject *)v38;
  if ( *v43 >= 0 )
  {
    v23 = (*(_QWORD *)v43)-- == 1i64;
    if ( v23 )
      _Py_Dealloc(v43, v39, v40, v41);
  }
  v44 = PyLong_Type;
  pyx_int_30 = _pyx_mstate_global->__pyx_int_30;
  if ( *(_object *const *)(v42 + 8) == PyLong_Type )
  {
    v46 = *(_QWORD *)(v42 + 16);
    if ( (v46 & 1) != 0 )
    {
      if ( *(_DWORD *)v42 != -1 )
        ++*(_DWORD *)v42;
      goto LABEL_60;
    }
    if ( v46 >= 0x10 )
    {
      switch ( (*(_QWORD *)(v42 + 16) >> 3) * (1 - (*(_QWORD *)(v42 + 16) & 3ui64)) )
      {
        case 0xFFFFFFFFFFFFFFFEui64:
          v58 = -(__int64)(*(unsigned int *)(v42 + 24) | ((unsigned __int64)*(unsigned int *)(v42 + 28) << 30));
          goto LABEL_72;
        case 2ui64:
          v58 = *(unsigned int *)(v42 + 24) | ((unsigned __int64)*(unsigned int *)(v42 + 28) << 30);
LABEL_72:
          v59 = 0i64;
          v60 = v58 / 30;
          v61 = v58 % 30;
          if ( v61 )
            v59 = v61 >> 63;
          v57 = PyLong_FromLongLong(v60 - v59, v60 - v59, v61, pyx_int_30);
          break;
        default:
          v57 = (*(__int64 (__fastcall **)(__int64, _object *))(*((_QWORD *)&PyLong_Type + 12) + 232i64))(
                  v42,
                  _pyx_mstate_global->__pyx_int_30);
          break;
      }
    }
    else
    {
      v53 = *(_DWORD *)(v42 + 24) * (1 - (v46 & 3));
      v54 = 0;
      v55 = v53 / 30;
      v56 = v53 % 30;
      if ( v56 )
        v54 = v56 >> 31;
      v57 = PyLong_FromLong(v55 - v54);
    }
  }
  else
  {
    v57 = PyNumber_FloorDivide(v42, _pyx_mstate_global->__pyx_int_30);
  }
  v42 = v57;
  if ( !v57 )
  {
    v11 = _pyx_f[0];
    v12 = 47;
    v13 = 3997;
    goto LABEL_204;
  }
LABEL_60:
  v47 = (int *)v5;
  v5 = (_typeobject *)v42;
  if ( *v47 >= 0 )
  {
    v23 = (*(_QWORD *)v47)-- == 1i64;
    if ( v23 )
      _Py_Dealloc(v47, v46, v44, pyx_int_30);
  }
  v48 = PyNumber_Power(v42, _pyx_mstate_global->__pyx_int_3, _Py_NoneStruct, pyx_int_30);
  v52 = v48;
  if ( !v48 )
  {
    v11 = _pyx_f[0];
    v12 = 48;
    v13 = 4009;
    goto LABEL_204;
  }
  v62 = (int *)v5;
  v5 = (_typeobject *)v48;
  if ( *v62 >= 0 )
  {

[招生]科锐逆向工程师培训(2025年3月11日实地,远程教学同时开班, 第52期)!

最后于 2025-2-28 18:58 被mingyuexc编辑 ,原因: 补充前言,编译pyd流程
上传的附件:
收藏
免费 15
支持
分享
赞赏记录
参与人
雪币
留言
时间
monkeycc
+1
谢谢你的细致分析,受益匪浅!
2025-3-9 10:04
sky东
为你点赞!
2025-3-5 15:54
coneco
+10
感谢你分享这么好的资源!
2025-3-5 14:12
冷却器
+2
谢谢你的细致分析,受益匪浅!
2025-2-24 11:48
SnowFox
+1
感谢你分享这么好的资源!
2025-2-22 09:27
逆天而行
感谢你的贡献,论坛因你而更加精彩!
2025-2-17 14:07
mb_cdwccpxe
这个讨论对我很有帮助,谢谢!
2025-2-14 15:57
点中你的心
谢谢你的细致分析,受益匪浅!
2025-2-14 11:51
Je2em1ah
非常支持你的观点!
2025-2-13 20:48
Light紫星
+10
感谢你的积极参与,期待更多精彩内容!
2025-2-13 10:40
AEVE
+2
你的分享对大家帮助很大,非常感谢!
2025-2-12 10:26
令狐双
这个讨论对我很有帮助,谢谢!
2025-2-11 15:58
wangxukang
非常支持你的观点!
2025-2-11 08:47
Gagma
+6
你的帖子非常有用,感谢分享!
2025-2-11 08:37
魏济
+10
谢谢你的细致分析,受益匪浅!
2025-2-11 01:08
最新回复 (10)
雪    币: 104
活跃值: (5273)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
6666666666666666
2025-2-11 02:52
0
雪    币: 4328
活跃值: (4681)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
先收藏,感谢分享。
2025-2-11 12:47
0
雪    币: 708
活跃值: (1329)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
pyd很难搞,先收藏了,以后慢慢学习
2025-2-13 10:40
0
雪    币: 225
活跃值: (458)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
能不能搞一个pyd的ida sig签名文件,这样没有符号也可以快速识别函数
2025-2-14 11:15
1
雪    币: 13112
活跃值: (4364)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
先收藏,感谢分享。 
2025-2-14 11:19
0
雪    币: 8735
活跃值: (5519)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
太强了 ,收藏点赞,精华
2025-2-14 15:10
0
雪    币: 239
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
太牛了师傅????
2025-2-15 09:56
0
雪    币: 807
活跃值: (2171)
能力值: ( LV7,RANK:105 )
在线值:
发帖
回帖
粉丝
9
rock 能不能搞一个pyd的ida sig签名文件,这样没有符号也可以快速识别函数

师傅好想法,但我测试了一下,没能成功用ida的flair工具生成sig。

最后于 2025-2-15 23:15 被mingyuexc编辑 ,原因:
2025-2-15 23:14
0
雪    币: 0
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
感谢分享,写的很牛,其实代码应该混淆,每个函数先调用主程序的加密数据进行验证,修改cython的编译算法, 几个步骤下来应该能提高pyd逆向的成本
2025-3-9 10:11
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册