• 向pycdc项目提的一个pr


    向pycdc项目提的一个pr

    前言

    pycdc这个项目,我之前一直有在关注,之前使用他反编译python3.10项目,之前使用的 uncompyle6无法反编译pyhton3.10生成的pyc文件,但是pycdc可以,但是反编译效果感觉不如uncompyle6。但是版本更新很快,支持的python版本很多。

    在issue看到别人提供的pyc文件

    我逛github的时候,看看这个项目有没有更新啥新特性,在issue里面看到别人提的issue,带了一个pyc文件。本着乐于助人的态度,也想学习一下这个项目是如何解析pyc文件到py文件的。就下载了这个pyc。看他提的pr。是报了一个Unsupported Node type: 27错误。但是看他发的报错。感觉不止这一个报错。

    1. E:\temp_vc\pycdc\build_v141\Release>pycdc.exe model.pyc >model.py
    2. Unsupported Node type27
    3. Unsupported Node type27
    4. Unsupported Node type27
    5. Unsupported argument found for LIST_EXTEND
    6. Unsupported opcode: LIST_TO_TUPLE
    7. Unsupported opcode: CALL_FUNCTION_EX
    8. Unsupported opcode: DICT_MERGE
    9. Unsupported Node type27
    10. Unsupported Node type27
    11. Unsupported argument found for LIST_EXTEND
    12. Unsupported opcode: LIST_TO_TUPLE
    13. Unsupported Node type27
    14. Unsupported Node type27
    15. Unsupported Node type27
    16. Unsupported Node type27
    17. Unsupported Node type27
    18. Unsupported Node type27
    19. Unsupported Node type27
    20. Warning: block stack is not empty!
    21. Unsupported Node type27
    22. Unsupported Node type27
    23. Warning: block stack is not empty!
    下载项目

    OK,先fork一下这个项目,fork完成之后了,这个项目就到你的仓库了。本地的话,就直接git clone一下自己fork的仓库。把项目先下载到本地,准备编译运行,这个pycdc项目是c++写的。用的是cmake进行编译的。

    环境说明:

    1. cmake

    2. vs2022

    3. python 3.9

    我这边的话,就是这么多了。编译的话很简单,下载cmake后,在项目目录,cmake一下就会自动生成vs项目,打开vs项目编译生成pycdc.exe和pycdas.exe后就行。这个pycdc是将pyc变成py,这个pycdas解析pyc文件,输出python的字节码。

    我们随便写个hello,保存为test.py测试一下效果

    print("hello,world")
    

    使用命令

    python -m py_compile test.py
    

    使用pycdc对生成的test2.cpython-39.pyc进行反编译

    可以看到结果,已经反编译成功了。

    OK,我们继续

    尝试调试程序

    我们修改一下这个接受参数,再pycdc.cpp里面。

    手动给他加上我们需要的参数,方便后期调试。好了,经过调试。发现问题。

    1. class t(test.t):
    2.  pass

    这样的代码就会报错,会错误的识别为

    1. def t():
    2.  pass

    并且会报错,Unsupported Node type: 27。

    经过调试,最终将问题集中到这里ASTree.cpp

    1.  while (TOS_type == ASTNode::NODE_NAME) {
    2.     bases.resize(basecnt + 1);
    3.     bases[basecnt] = TOS;
    4.     basecnt++;
    5.     stack.pop();
    6.     TOS = stack.top();
    7.     TOS_type
    8.     }

    这个地方,CALL_FUNCTION_A字节码这个位置。因为我们传参的是test.t。这个玩意被识别为NODE_BINARY。没有被识别为:NODE_NAME 。导致这个while循环没进入,这个NODE_NAME没有被清除,导致后面一些解析错误。变成这样就可以了

    1.  while (TOS_type == ASTNode::NODE_NAME || TOS_type == ASTNode::NODE_BINARY) {
    2.     bases.resize(basecnt + 1);
    3.     bases[basecnt] = TOS;
    4.     basecnt++;
    5.     stack.pop();
    6.     TOS = stack.top();
    7.     TOS_type = TOS.type();
    8.    }

    修改完毕后,

    1. git add ASTree.cpp
    2. git commit -m "fix"
    3. git push

    上传到我们自己的仓库。

    提交pr

    我们就可以向源项目提交pr了,说明一下自己的修改的原因,以及效果。就可以了。我这边的话,是自己提交了一个issue,在issue里面说了这个报错。提交的pr链接的这个issue。

    等待被合并

    我这边大概等了一个星期左右。(我猜是为python3.12做适配了,回复我那天就更新了python3.12适配,并且后面回复就很及时了)作者回复我了,让我加一些测试文件进去。我加了之后。因为有时差,作者回复一般都是晚上12点以后了。我加完测试文件后。第二天我的请求就被merge了。

    整个流程就完成了,我也成为这个项目的贡献者了,虽然实际修改代码只有一行(偷偷的笑)。


     今天就到这里,如果您觉得不错,欢迎关注。如有错误,欢迎私聊指正。

  • 相关阅读:
    批量kill进程
    代码改成多线程,竟有 这些问题
    Leetcode 1662. 检查两个字符串数组是否相等
    网页头部的声明应该是用 lang="zh" 还是 lang="zh-CN"?
    【matplotlib基础】--绘图配置
    kafka属性说明
    netty系列之:channel,ServerChannel和netty中的实现
    单目标应用:麻雀搜索算法(SSA)优化RBF神经网络实现数据预测(RBF隐藏层神经元个数可以自行设定)
    MybatisPlus高级特性
    AcWing 899. 编辑距离 线性dp
  • 原文地址:https://blog.csdn.net/qq_59848320/article/details/134480709