V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
love
V2EX  ›  Python

写了个 Python 源码加密的工具,把源码混淆得它妈都不认识

  •  
  •   love · 2014-10-28 19:01:51 +08:00 · 34539 次点击
    这是一个创建于 3439 天前的主题,其中的信息可能已经有所发展或是发生改变。
    Python目前没有一个好用的混淆工具,所以我写了一个。
    另外要说的是编译成pyc是一点用处也没有的,用打包工具打成exe也是容易从exe里提取出来的。

    http://pyob.oxyry.com/

    新鲜出炉,欢迎提交BUG :)

    原理就是重命名程序中的变量名,除了
    模块公开名字 (__all__里面列出的名字,没有定义__all__的话就是所有下划线开头的名字)
    类公开名字 (除双下划线之外的名字)
    关键字参数
    之外的所有变量都可以被重命名。
    66 条回复    2019-05-26 07:23:06 +08:00
    mengzhuo
        1
    mengzhuo  
       2014-10-28 19:20:05 +08:00
    这也太容易逆向了吧……
    还是原版的结构
    差评
    love
        2
    love  
    OP
       2014-10-28 19:28:24 +08:00
    @mengzhuo
    结构是一样,可是里面的名字都变了,阅读理解这样子的代码还不如重写快呢,这就达到了不让别人在你的代码的基础再次开发的目的了。
    另外接下来会有穿插无用代码的功能。
    holyghost
        3
    holyghost  
       2014-10-28 19:42:29 +08:00
    加花来达到免杀。。。
    holmesabc
        4
    holmesabc  
       2014-10-28 20:21:21 +08:00
    混淆和加密还是两码事的。
    再怎么变量明替换,想看懂都不是什么难事。

    搞个ide或者编辑器,做一下变量名替换就好
    laotaitai
        5
    laotaitai  
       2014-10-28 20:36:19 +08:00
    @holmesabc
    就是啊, 借助王垠写的pysonar2, 一样把所谓"他妈都不认识"弄成"他奶奶"都认识的地步.
    jiongjionger
        6
    jiongjionger  
       2014-10-28 21:02:19 +08:00
    = =和我以前做的PHP混淆一样。0O0O0O000OOO。哈哈
    love
        7
    love  
    OP
       2014-10-28 21:25:02 +08:00
    @laotaitai 变量名替换不可逆,信息丢了就是丢了,你要找回原来变量所代表的意思非常难,这就象修改比最渣还渣十倍的代码,会让人崩溃的,因为你还要完全顺着原代码的想法来猜变量名,事实上还原这样子的代码比重写更难。
    yushiro
        8
    yushiro  
       2014-10-28 21:30:20 +08:00
    @love 你认为看代码就必须要有意思很简单直接的变量名吗?
    raincious
        9
    raincious  
       2014-10-28 21:33:09 +08:00
    © 2014 oxyry.com, all rights reversed.

    这是啥意思?我的代码粘贴进去转一圈出来就是你的了么……

    另外改变量名这种的……真的无效。
    love
        10
    love  
    OP
       2014-10-28 21:39:10 +08:00
    刚才随便从网上找了个8皇后算法的小脚本,

    这是加密前:
    https://gist.github.com/weijar/ded24f0b6949b8f502f8
    这是加密后:
    https://gist.github.com/weijar/377e463fbee60e243f02

    这二个都可以运行,但是不知道算法的情况下想搞明白后一个是要吐血的。
    love
        11
    love  
    OP
       2014-10-28 21:44:14 +08:00
    @raincious 写程序最难的就是命名了,把程序里的名字去掉了这个程序就没剩下什么了。。。

    另外这是网站的copyright,不是转换出来的程序的。
    evlos
        12
    evlos  
       2014-10-28 21:44:31 +08:00
    @love 看起来真带感,已收藏w//
    laotaitai
        13
    laotaitai  
       2014-10-28 21:45:13 +08:00
    呃,我想了想, 我觉得题主还是说的对, 就算用了IDE, 你改名怎么改? 不知道这代码是干嘛的, 变量名如何取?

    所以, 对不起题主, 我支持你继续写下去. 说不定将来我用得上.
    love
        14
    love  
    OP
       2014-10-28 21:45:52 +08:00
    @yushiro 不看名字看什么?你看看上面混淆后的代码,不告诉你是8皇后你会知道是什么吗?
    binux
        15
    binux  
       2014-10-28 21:46:13 +08:00
    你把 OOOOOOOOOOO00O000 换成 a1, a2, a3, int1, int2, int3, list1, list2, list3 试试
    laotaitai
        16
    laotaitai  
       2014-10-28 21:46:38 +08:00
    等哪天你公布到github时, 留下你的支付宝二维码, 我给你捐10元.
    izoabr
        17
    izoabr  
       2014-10-28 21:52:58 +08:00
    页面弄个中文版更好了就
    love
        18
    love  
    OP
       2014-10-28 22:00:52 +08:00
    @binux 用长名字和短名字的加密强度其实差不多,因为长名字可以用IDE方便地改成短名字,但这不是问题,加密的目的是去掉原先名字包含的信息。
    GtDzx
        19
    GtDzx  
       2014-10-28 22:08:31 +08:00
    感觉是防君子不防小人的功能
    xiaozhao992003
        20
    xiaozhao992003  
       2014-10-28 22:10:34 +08:00
    这代码加密的真够狠的啊
    binux
        21
    binux  
       2014-10-28 22:11:54 +08:00
    @love 汇编咱不谈,看个js混淆不要太简单。改个名字算什么。。
    wuxqing
        22
    wuxqing  
       2014-10-28 22:16:58 +08:00   ❤️ 1
    用cython把py编译成.so就没法看了,还能提供性能,是不是更好?
    love
        23
    love  
    OP
       2014-10-28 22:18:52 +08:00
    @GtDzx @binux
    这个工具的目的不是保护算法秘密,而且哪天你用python写了个软件卖钱时,不被别人直接在你的源码的基础上开发当作自已的软件,所以只要加密强度大于重写的难度就可以了。
    icedx
        24
    icedx  
       2014-10-28 22:21:10 +08:00
    楼主别骗自己了...
    就混淆 我遇到过比你这个丧心病狂的
    binux
        25
    binux  
       2014-10-28 22:21:54 +08:00
    @love 我可以不改你的代码,只调用你的方法啊。外观什么随便找个人再写一遍,把核心调用一下就完了。看不懂就看不懂咯
    raincious
        26
    raincious  
       2014-10-28 22:23:29 +08:00
    @love 我不知道你这代码基于什么理论,看样子是用两个“很难”分辨的字母扰乱视线达到“混淆”的目的。

    ……这根本就不是代码混淆啊

    代码混淆按原内容替换只是一个步骤,还需要分析与法树,优化部分代码,将整个代码格式更改成其他形式。

    而你这个跟字符串替换没区别吧?用正则表达式和一个字典表(做排斥)就能实现(猜测你连与法树都没分析,只是看到一个变量就去改了而已,而且估计还是正则)。

    并且,想要改回去也太容易了。

    试问你为什么非要用0和O?而不用A-Za-z0-9这段随机选取?因为如果你真的着么干了,这混淆就一点效果都没有了(因为已经可以分辨了)。
    love
        27
    love  
    OP
       2014-10-28 22:36:40 +08:00
    @raincious
    用a-z的效果其实差不多,用0O00这样只是看着更酷而已,事实是你还是不知道这个变量代表什么意思。
    另外你把这个程序想得太简单了,你用正则搞定试试?
    raincious
        28
    raincious  
       2014-10-28 22:46:00 +08:00
    @love 不知道你有没有写过正则表达式引擎,但是正则表达式引擎比你这个分析器要复杂和强大,所以用正则表达式来做没任何问题。

    是的,我知道Python的dir把这个问题变得更简单。

    但是这不是要讨论的,而是你这个方法本身就行不通,不能朝着错误的方向努力啊。

    http://coolshell.cn/articles/4758.html
    binux
        29
    binux  
       2014-10-28 22:59:21 +08:00
    @raincious 如果是python,其实用ast就好。。
    est
        31
    est  
       2014-10-28 23:12:53 +08:00
    不是eval()差评。
    imn1
        32
    imn1  
       2014-10-28 23:28:19 +08:00
    应该用 I l 1,这样屏幕不怎么占地,肉眼比o0更难认
    love
        33
    love  
    OP
       2014-10-28 23:29:58 +08:00
    @raincious 算了没法理解你要表达什么。另外你不知道python的变量有很多作用域规则吗?你能无视作用域规则来个无差别替换?这个必需要分析AST树。事实上这个程序用到了python的ast模块,就不需要自已分析了,只是用这些现成的工具还远远不够。这个加密算法目前就有4000行python代码了。


    @est 以前看到过eval版 :) http://pyobf.herokuapp.com/ 可惜无意义。
    br00k
        34
    br00k  
       2014-10-29 09:06:45 +08:00
    这个不叫加密吧。。。
    pythoner
        35
    pythoner  
       2014-10-29 09:30:24 +08:00
    已经有现成的工具了:pyobfuscate
    https://github.com/astrand/pyobfuscate
    love
        36
    love  
    OP
       2014-10-29 09:35:15 +08:00
    @pythoner 那个10年不更新了,且有大量BUG。而且不能支持最新的python。
    Shazoo
        37
    Shazoo  
       2014-10-29 10:14:34 +08:00
    这思路和很早前一个加密perl cgi的程序很像。

    功能足够了……

    赞一个。
    zkd8907
        38
    zkd8907  
       2014-10-29 10:24:24 +08:00
    替换变量的话,是不是意味着再替换回来就可以了呢 = =|||
    undeflife
        39
    undeflife  
       2014-10-29 11:04:06 +08:00
    网站做得挺漂亮的
    geew
        40
    geew  
       2014-10-29 11:27:49 +08:00
    @zkd8907 怎么替换回来? 你知道原来的变量名么qaq
    jsq2627
        41
    jsq2627  
       2014-10-29 12:32:13 +08:00
    @geew 先把这堆0O0O0O0OO0O这样的东西用同样的原理替换成 a1, a2, a3 这样能分辨、不眼花的变量名。然后开始读代码,尝试还原。用 IDE 的 refactor,认出一个变量就还原一个变量名,改一轮下来就八九不离十了。
    除非是复杂的算法模块,一般的变量都是很容易分辨功能的。
    josephok
        42
    josephok  
       2014-10-29 12:51:22 +08:00   ❤️ 7
    DiffView
        43
    DiffView  
       2014-10-29 13:01:19 +08:00
    替换所有变量名为肉眼容易分辨的,然后边猜边替换,读2轮下来也就八九不离十了=。=
    love
        44
    love  
    OP
       2014-10-29 13:17:04 +08:00
    @robinxiaobin @jsq2627 函数名和类名也被混淆了,在不知道函数是干什么的情况下很难知道变量是干什么的。

    另外同一个变量名,在不同的作用域里是被转成不同的名字的,比如在这个函数里的相同名字在另一个函数里会被转成不同的名字,你在这个函数里猜中的话也不能来个全文替换的。

    总之要还原比重写麻烦多了。
    zkd8907
        45
    zkd8907  
       2014-10-29 13:23:12 +08:00
    @geew 这个混淆只是把变量名称变成了会眼花的值,直接替换成简单的变量再去阅读就可以,不一定要变成原始的变量名。而且本身程序流程没有混淆,在这种情况下,想要读懂程序还是有可能的。
    wdlth
        46
    wdlth  
       2014-10-29 14:06:18 +08:00
    这和那些所谓的PHP加密不是差不多么……
    shunia
        47
    shunia  
       2014-10-29 15:58:12 +08:00
    @josephok
    42楼说的对
    shadowpsp
        48
    shadowpsp  
       2014-10-29 16:14:45 +08:00
    42楼真相了
    procen424
        49
    procen424  
       2014-10-29 17:21:47 +08:00
    只改名字是不行哒。
    找个合适的ide,以 "阅读-重命名" 的循环方式过一遍代码,然后纠正所有起得不合适的名字,这就还原出原貌了。
    sanddudu
        50
    sanddudu  
       2014-10-29 18:33:30 +08:00
    juicy
        51
    juicy  
       2014-10-29 19:41:28 +08:00
    42楼。。。。把程序写烂就是最好的加密方式。。。
    sohoer
        52
    sohoer  
       2014-10-29 20:02:23 +08:00
    支持楼主!
    混淆最终的目的是尽量避免二次开发,这是它为什么不叫加密。
    鸟巢采集器也是混淆,用的proguard比楼主的更酷
    yangff
        53
    yangff  
       2014-10-29 20:16:16 +08:00 via Android
    且不说真要复原也就那么回事(mcp人肉复原教你做人)
    本来做逆向就不需要变量名。。
    noanti
        54
    noanti  
       2014-10-29 20:29:51 +08:00
    同楼上,逆向根本不需要变量名。
    如果一段python很有价值,你这混淆挡得住为利益而逆向它的人?
    如果没有价值,混淆给谁看?
    dingyaguang117
        55
    dingyaguang117  
       2014-10-29 20:39:31 +08:00 via iPhone
    有用的,我试图理解过混淆后的代码,几乎不可读
    love
        56
    love  
    OP
       2014-10-29 20:40:36 +08:00
    @noanti
    你根本弄错了这个混淆器的目的是要让别人不能拿了你的代码再次开发售卖,你看到个软件觉得功能很好有前景,也想写一个来卖卖,你是试徒复原这个天书书一样的代码呢还是干脆重写一个?
    原有的代码写得乱了也可能需要推倒重来,这个还要乱上十倍的代码根本没有在上面开发的必要。
    另外代码的价值一大部分是在命名上,去掉了命名的代码价值就没有了。
    love
        57
    love  
    OP
       2014-10-29 21:11:01 +08:00
    @wdlth PHP加密几乎都是伪加密,把代码变换个形式而已,相当于用一个标准算法套了个壳,可惜它是完全可逆的,你只要分析下加密后的代码所用的算法(因为算法含在加密后的文件里),就能完全复原一个字节都不会少,而且对所有用这个算法的文件都通用。
    noanti
        58
    noanti  
       2014-10-29 21:24:26 +08:00
    @love
    “另外代码的价值一大部分是在命名上,去掉了命名的代码价值就没有了。”
    哦,代码价值原来如此。
    wdlth
        59
    wdlth  
       2014-10-29 22:33:15 +08:00
    @love 你这个无非就是Python版的PHP微盾嘛……
    tangzx
        60
    tangzx  
       2014-10-30 07:52:03 +08:00 via iPhone
    源码他妈……
    saber000
        61
    saber000  
       2014-10-31 18:15:56 +08:00
    使用Django的一段代码测试:https://github.com/django/django/blob/master/django/core/serializers/json.py

    感觉看混淆后的代码问题也不大嘛
    willy123
        62
    willy123  
       2014-12-09 01:06:21 +08:00
    不明白这样简单的变量替换的意义何在,我完全可以简单的用任何一个文本编辑软件,批量替换回来,比如把所有00000000000000换成a,变量多的话,完全可以写个脚本还原回来。建议从结构和其他角度入手,变量替换不是不可以,但绝对不能作为唯一混淆手段,不然也太弱了
    willy123
        63
    willy123  
       2014-12-09 01:09:26 +08:00
    恩。“另外代码的价值一大部分是在命名上,去掉了命名的代码价值就没有了。”这个的确也是,不过还是希望能多想一些 bt猥琐的方法综合起来,反正可读性越差越好,期待lz新版本~
    To5tE
        64
    To5tE  
       2018-03-11 15:24:55 +08:00
    你好 现在不能用了吗
    twoyuan
        65
    twoyuan  
       2018-07-30 14:53:08 +08:00
    二次混淆教做人
    GPU
        66
    GPU  
       2019-05-26 07:23:06 +08:00 via iPhone
    我更想知道生成 exe 之后怎么再提取源码
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3336 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 13:27 · PVG 21:27 · LAX 06:27 · JFK 09:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.