精华内容
下载资源
问答
  • 什么是pyc文件 pyc是一种二进制文件,是由py文件经过编译后,生成的文件,是一种byte code,py文件变成pyc文件后,加载的速度有所提高,而且pyc是一种跨平台的字节码,是由python的虚拟机来执行的,这个是类似于JAVA...
  • 搭建python环境 1.百度搜索python3.7下载,找到官网下载安装包,运行安装包并...2.使用archive_viewer.py工具,提取出CM.pyc文件,接着open PYZ-00.pyz压缩包,提取出压缩包中的两个.pyc文件。 3.编辑三个.py
  • pyc文件

    2021-05-04 16:26:10
    pyc文件是Python文件(后缀是.py)编译出来的二进制文件,能够提高加载速度,以及隐藏源代码 编译的方法: python -m py_compile file.py 比如: python -m py_compile /root/src/{file1,file2}.py 也可以写份脚本...

    pyc文件是Python文件(后缀是.py)编译出来的二进制文件,能够提高加载速度,以及隐藏源代码

    编译的方法:

    python -m py_compile file.py

    比如: python -m py_compile /root/src/{file1,file2}.py

    也可以写份脚本来做这事:

    import py_compile 
    py_compile.compile('path') //path是包括.py文件名的路径

     

     

    如果没有产生pyc文件,用sudo命令试试

    展开全文
  • 1 什么是pyc文件 1.1 什么是pyc文件 1、pyc文件:是由Python文件经过编译后所生成的文件,它是一种字节码 byte code,因此我们直接查看就是乱码的,也对源码起到一定的保护作用,但是这种字节码byte code是可以反...

    1 什么是pyc文件

    1.1 什么是pyc文件

    1、pyc文件:是由Python文件经过编译后所生成的文件,它是一种字节码 byte code,因此我们直接查看就是乱码的,也对源码起到一定的保护作用,但是这种字节码byte code是可以反编译的,后面会介绍!

    我们都知道计算机是不认识你在代码里写的那一行行字母的,计算机只认二进制,也只执行二进制文件,我们写的代码是需要编译器编译成二进制的。(参考

    对于Python来说你写的Python代码在执行python xxx.py时会由Python解析器翻译成PyCodeObject对象,俗称字节码(byte code),然后交由Python虚拟机来执行字节码(PS:字节码才是可执行的)。

    在这个过程中这些字节码都是在内存中的,众所周知Python的运行性能不如编译性语言(比如C语言,JAVA …),所以Python在程序执行结束后会把字节码写入到硬盘中,保存为.pyc文件,目的是下一次再执行python xxx.py程序时,Python会先在目录下找xxx.pyc文件来执行,因为.pyc文件里保存的是字节码,所以就节省了Python解析器把xxx.py翻译成字节码的时间,所以就提高了性能。

    总结就是.pyc文件是一个可执行的字节码文件,目的是节省Python解析器翻译时间,提高运行效率。其实性能只会提高那么一丢丢,大型项目.py文件很多的话,猿人学Python测试过节省的时间就多一点。

    2、我们同样可以像执行py文件一样来执行pyc文件,例如:

    • python test.py
    • python test.pyc

    注意:

    必须保证编译成pyc文件的python解释器版本和现在执行的python解释器版本保持一致,否则会报错,如下我导入deepsocial.pyc文件中的模块是报错:ImportError: bad magic number in 'deepsocial': b'B\r\r\n'

        from deepsocial import *
    ImportError: bad magic number in 'deepsocial': b'B\r\r\n'
    

    1.2 pyc文件是怎么生成的,有什么好处

    从上面的介绍我们已经知道pyc的好处主要是:

    • 由于pyc源码不可见,因此可以起到保护代码安全性的作用,但也不是绝对的,因为pyc文件是可以被反编译
    • pyc文件可以提高代码的执行效率

    pyc的内容python的版本相关,不同版本编译的pyc文件不一样

    2 把python的py文件编译成pyc文件

    下面我测试的文件目录结构:

    (yolov4) shl@zhihui-mint:~/shl_res/5_new_project$ tree test/
    test/
    ├── deepsocial.py
    └── scripts
        └── run.py
    
    1 directory, 2 files
    (yolov4) shl@zhihui-mint:~/shl_res/5_new_project$ 
    

    2.1 使用python内置库py_compile把单个py文件编译成pyc文件

    1、使用py_compile把单个py文件编译成pyc文件

    (yolov4) shl@zhihui-mint:~/shl_res/5_new_project/test$ ls
    deepsocial.py  scripts
    (yolov4) shl@zhihui-mint:~/shl_res/5_new_project/test$ python
    Python 3.6.12 |Anaconda, Inc.| (default, Sep  8 2020, 23:10:56) 
    [GCC 7.3.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import py_compile
    >>> py_compile.compile("./deepsocial.py")
    './__pycache__/deepsocial.cpython-36.pyc'
    >>> 
    

    生成文件如下:

    (yolov4) shl@zhihui-mint:~/shl_res/5_new_project/test$ tree
    .
    ├── deepsocial.py
    ├── __pycache__
    │   └── deepsocial.cpython-36.pyc
    └── scripts
        └── run.py
    
    2 directories, 3 files
    (yolov4) shl@zhihui-mint:~/shl_res/5_new_project/test$ 
    

    2.2 使用python内置库compileall把多个py文件编译成pyc文件

    2.2.1 使用python -m compileall命令把多个py文件编译成pyc文件

    1、首先来查看python -m compileall有哪些参数

    (yolov4) shl@zhihui-mint:~/shl_res/5_new_project/test$ python -m compileall -h
    usage: compileall.py [-h] [-l] [-r RECURSION] [-f] [-q] [-b] [-d DESTDIR]
                         [-x REGEXP] [-i FILE] [-j WORKERS]
                         [FILE|DIR [FILE|DIR ...]]
    
    Utilities to support installing Python libraries.
    
    positional arguments:
      FILE|DIR              zero or more file and directory names to compile; if
                            no arguments given, defaults to the equivalent of -l
                            sys.path
    
    optional arguments:
      -h, --help            show this help message and exit
      -l                    don't recurse into subdirectories
      -r RECURSION          control the maximum recursion level. if `-l` and `-r`
                            options are specified, then `-r` takes precedence.
      -f                    force rebuild even if timestamps are up to date
      -q                    output only error messages; -qq will suppress the
                            error messages as well.
      -b                    use legacy (pre-PEP3147) compiled file locations
      -d DESTDIR            directory to prepend to file paths for use in compile-
                            time tracebacks and in runtime tracebacks in cases
                            where the source file is unavailable
      -x REGEXP             skip files matching the regular expression; the regexp
                            is searched for in the full path of each file
                            considered for compilation
      -i FILE               add all the files and directories listed in FILE to
                            the list considered for compilation; if "-", names are
                            read from stdin
      -j WORKERS, --workers WORKERS
                            Run compileall concurrently
    (yolov4) shl@zhihui-mint:~/shl_res/5_new_project/test$ 
    

    2、把单个py文件生成pyc文件,例如

    python -m compileall deepsocial.py

    在这里插入图片描述

    3、递归的把当前目录下所有的py文件都生成对应的pyc文件

    python -m compileall .

    注意:

    后面有一个点., 表示当前目录!
    在这里插入图片描述

    2.2.2 使用compileall的API把多个py文件编译成pyc文件

    如下,是通过调用compileall的API接口,递归的指定目录下所有的py文件都生成对应的pyc文件

    >>> import compileall
    >>> compileall.compile_dir("/home/shl/shl_res/5_new_project/test")
    Listing '/home/shl/shl_res/5_new_project/test'...
    Compiling '/home/shl/shl_res/5_new_project/test/deepsocial.py'...
    Listing '/home/shl/shl_res/5_new_project/test/scripts'...
    Compiling '/home/shl/shl_res/5_new_project/test/scripts/run.py'...
    True
    >>> 
    
    

    在这里插入图片描述

    3 使用uncomplye6工具把pyc文件反编译成py文件

    只有pyc文件可以运行程序,但是是不能获取程序源码的。同时如果python的版本pyc版本使用的不同,那么程序会闪退。对pyc文件进行反编译需要用到python第三方库包uncompyle

    3.1 使用uncomplye6工具安装

    3.1.1 uncomplye6介绍

    1、uncomplye6介绍

    uncomplye6继承了decompyleuncompyleuncompyle2。uncompyle6可将python字节码转换回等效的python源代码,它接受python 1.3版到3.8版的字节码

    2、uncomplye6的github地址

    3.1.2 uncomplye6安装

    1、pip安装

    pip install uncomplye6

    2、从源码安装

    git clone https://github.com.cnpmjs.org/rocky/python-uncompyle6.git

    编译:

    $cd python-uncompyle6
    $pip install -e .  # set up to run from source tree
                        # Or if you want to install instead
    $python setup.py install # may need sudo
    

    3.2 使用uncomplye6工具把pyc反编译为py文件的具体使用

    3.2.1 查看uncomplye6的参数

    1、安装好uncomplye6后,可以使用uncomplye6 -h

    (yolov4) shl@zhihui-mint:~/shl_res/5_new_project/DeepSOCIAL$ python -V
    Python 3.6.12 :: Anaconda, Inc.
    (yolov4) shl@zhihui-mint:~/shl_res/5_new_project/DeepSOCIAL$ uncompyle6 -V
    uncompyle6 3.7.4
    (yolov4) shl@zhihui-mint:~/shl_res/5_new_project/DeepSOCIAL$ uncompyle6 -h
    
    Usage:
      uncompyle6 [OPTIONS]... [ FILE | DIR]...
      uncompyle6 [--help | -h | --V | --version]
    
    Examples:
      uncompyle6      foo.pyc bar.pyc       # decompile foo.pyc, bar.pyc to stdout
      uncompyle6 -o . foo.pyc bar.pyc       # decompile to ./foo.pyc_dis and ./bar.pyc_dis
      uncompyle6 -o /tmp /usr/lib/python1.5 # decompile whole library
    
    Options:
      -o <path>     output decompiled files to this path:
                    if multiple input files are decompiled, the common prefix
                    is stripped from these names and the remainder appended to
                    <path>
                      uncompyle6 -o /tmp bla/fasel.pyc bla/foo.pyc
                        -> /tmp/fasel.pyc_dis, /tmp/foo.pyc_dis
                      uncompyle6 -o /tmp bla/fasel.pyc bar/foo.pyc
                        -> /tmp/bla/fasel.pyc_dis, /tmp/bar/foo.pyc_dis
                      uncompyle6 -o /tmp /usr/lib/python1.5
                        -> /tmp/smtplib.pyc_dis ... /tmp/lib-tk/FixTk.pyc_dis
      --compile | -c <python-file>
                    attempts a decompilation after compiling <python-file>
      -d            print timestamps
      -p <integer>  use <integer> number of processes
      -r            recurse directories looking for .pyc and .pyo files
      --fragments   use fragments deparser
      --verify      compare generated source with input byte-code
      --verify-run  compile generated source, run it and check exit code
      --syntax-verify compile generated source
      --linemaps    generated line number correspondencies between byte-code
                    and generated source output
      --encoding  <encoding>
                    use <encoding> in generated source according to pep-0263
      --help        show this message
    
    Debugging Options:
      --asm     | -a        include byte-code       (disables --verify)
      --grammar | -g        show matching grammar
      --tree={before|after}
      -t {before|after}     include syntax before (or after) tree transformation
                            (disables --verify)
      --tree++ | -T         add template rules to --tree=before when possible
    
    Extensions of generated files:
      '.pyc_dis' '.pyo_dis'   successfully decompiled (and verified if --verify)
        + '_unverified'       successfully decompile but --verify failed
        + '_failed'           decompile failed (contact author for enhancement)
    
    (yolov4) shl@zhihui-mint:~/shl_res/5_new_project/DeepSOCIAL$ 
    

    3.2.2 使用uncompyle6命令把pyc反编译成py文件

    1、首先我们可以去下载一个pyc文件(我正式因为看不到它的源码,才去搞的这个)

    wget https://github.com.cnpmjs.org/DrMahdiRezaei/DeepSOCIAL/blob/master/deepsocial.pyc

    2、使用uncompyle6命令把pyc反编译成py文件

    uncompyle6 deepsocial.pyc > deepsocial.py

    uncompyle6 -o deepsocial.py deepsocial.pyc

    输出的deepsocial.py文件开头会多一段这样的注释:

    # uncompyle6 version 3.7.4
    # Python bytecode 3.7 (3394)
    # Decompiled from: Python 3.6.12 |Anaconda, Inc.| (default, Sep  8 2020, 23:10:56) 
    # [GCC 7.3.0]
    # Embedded file name: deepsocial.py
    # Compiled at: 2021-03-06 05:54:51
    # Size of source mod 2**32: 14036 bytes
    

    说明:

    • uncompyle6 version 3.7.4uncompyle6工具的版本是3.7.4
    • Python bytecode 3.7deepsocial.pyc字节码byte code文件是使用python3.7生成的,因此要执行pyc文件,必须要python的版本也是3.7版本才可以!
    • Decompiled from: Python 3.6.12:我解码pyc使用的是python版本是3.6.12

    3、将当前文件夹中所有的 pyc 文件反编译成后缀名为.pyc_dis 的源文件

    uncompile -o . *.pyc

    4 python编译的如何设置不生成pyc文件

    pyc文件一般是在使用import导入另一个模块的时候会生成python3会把生成的pyc文件存储在__pycache__目录下。

    那如何让python编译的时候不生成pyc文件呢,有如下几种方法:

    方法一:使用-B参数

    python -B test.py

    可以使用python -h查看参数的含义

    (base) shl@zhihui-mint:~$ python -h
    usage: python [option] ... [-c cmd | -m mod | file | -] [arg] ...
    Options and arguments (and corresponding environment variables):
    -b     : issue warnings about str(bytes_instance), str(bytearray_instance)
             and comparing bytes/bytearray with str. (-bb: issue errors)
    -B     : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x
    -c cmd : program passed in as string (terminates option list)
    -d     : debug output from parser; also PYTHONDEBUG=x
    -E     : ignore PYTHON* environment variables (such as PYTHONPATH)
    -h     : print this help message and exit (also --help)
    -i     : inspect interactively after running script; forces a prompt even
             if stdin does not appear to be a terminal; also PYTHONINSPECT=x
    -I     : isolate Python from the user's environment (implies -E and -s)
    -m mod : run library module as a script (terminates option list)
    -O     : remove assert and __debug__-dependent statements; add .opt-1 before
             .pyc extension; also PYTHONOPTIMIZE=x
    -OO    : do -O changes and also discard docstrings; add .opt-2 before
             .pyc extension
    -q     : don't print version and copyright messages on interactive startup
    -s     : don't add user site directory to sys.path; also PYTHONNOUSERSITE
    -S     : don't imply 'import site' on initialization
    -u     : force the stdout and stderr streams to be unbuffered;
             this option has no effect on stdin; also PYTHONUNBUFFERED=x
    -v     : verbose (trace import statements); also PYTHONVERBOSE=x
             can be supplied multiple times to increase verbosity
    -V     : print the Python version number and exit (also --version)
             when given twice, print more information about the build
    -W arg : warning control; arg is action:message:category:module:lineno
             also PYTHONWARNINGS=arg
    -x     : skip first line of source, allowing use of non-Unix forms of #!cmd
    

    方法二:设置环境变量

    export PYTHONDONTWRITEBYTECODE=1

    方法三:在导入的地方设置如下

    import sys
    sys.dont_write_bytecode = True
    

    参考:https://www.yuanrenxue.com/tricks/what-is-pyc-file.html # 对pyc文件解释比较清楚
    参考:https://www.php.cn/python-tutorials-416352.html # 把py文件生成pyc文件

    展开全文
  • python反编译成.py获得源码所需要的文件
  • PYC文件阅读器是一款非常专业实用的pyc文件查看工具。用户可以通过它更改pyc文件原作者设定的打开次数和阅读时效的阅读权限,对文件内容进行更改、复制和另存为操作,从此再也不用担心pyc文件无法正常使用,欢迎有...
  • pyc文件删除工具

    2013-09-19 14:26:21
    写个小工具专门清理pyc文件 顺便给一段bat脚本 我自己用的 这个文件我放在 project tool文件夹内 清除的是 project文件夹内所有的pyc文件 所以请注意目录哦 @ECHO OFF :: locate to proj root dir CD % dp0 CD ...
  • py转pyc文件 pyc文件转py文件

    千次阅读 热门讨论 2020-07-02 16:20:03
    生产环境中 有的时候 不想让自己写的代码泄露 可以讲py文件编译成pyc文件 两种文件使用Python执行的时候 结果一样 pyc的存在 客观上起到了保护代码 防止泄露的作用 下边说一下如何进行两种文件的转换 pyc —> py ...

    生产环境中 有的时候 不想让自己写的代码泄露 可以讲py文件编译成pyc文件 两种文件使用Python执行的时候 结果一样 pyc的存在 客观上起到了保护代码 防止泄露的作用 下边说一下如何进行两种文件的转换

    pyc —> py

    wget https://bootstrap.pypa.io/get-pip.py
    python get-pip.py 
    
    如果本机有pip 上边的这两步可以省略
    pip install uncompyle6
    

    将m.pyc转换为m.py

    uncompyle6 -o m.py m.pyc
    

    使用场景:
    遇到如下报错 说明pyc文件损坏 可以使用上述方法还原出py文件

    RuntimeError: Bad magic number in .pyc file
    

    py —> pyc

    安装compileall

    pip install compileall2
    
    $ cat com.py
    
    #!/usr/bin/env python
    # encoding=utf-8
    import compileall
     
    def compile_run():
        compileall.compile_dir(r'./')
     
    if __name__ == '__main__':
        compile_run()
    
    [root@tsbdata1 tmp]# cat hello.py 
    #!/usr/bin/env python
    # encoding: utf-8
    print ("hello world")
    [root@tsbdata1 tmp]# ls
    com.py hello.py 
    
    
    [root@tsbdata1 tmp]# python com.py 
    Listing ./ ...
    Compiling ./com.py ...
    Compiling ./hello.py ...
    [root@tsbdata1 tmp]# ls
    com.py  com.pyc  hello.py  hello.pyc
    
    展开全文
  • .pyc文件的结构

    千次阅读 2020-04-23 21:39:20
    .pyc文件的结构

    0x01.pyc文件

    Python的原始代码在运行前都会被先编译成字节码(二进制),并把编译的结果保存到一个四字节magic number,一个四字节的时间戳和一个PyCodeObject中,把这三部分在内存中以marshal格式保存为文件,即pyc文件。python 内置库dis,可以把二进制反编译CPython bytecode(也称opcode)。二进制对应的opcode可以参考: 二进制与opcode对应 ,其中opcode所代表的意义:opcode代表含义
    pyc格式解析
    首先4个字节是magic number,03f30d0a 其中0d0a就是\r\n了,接下来4个字节是时间,这里是d2e73855,注意到是小端模式,所以实际是0x5538e7d2,可以发现是我开始编译的时间。然后就是PyCodeObject对象了。

    0x02.PyCodeObject

    Python代码中的Code.h中定义的PyCodeObject

    /* Bytecode object */  
    typedef struct {  
        PyObject_HEAD  
        int co_argcount;        /* #arguments, except *args */  
        int co_nlocals;     /* #local variables */  
        int co_stacksize;       /* #entries needed for evaluation stack */  
        int co_flags;       /* CO_..., see below */  
        PyObject *co_code;      /* instruction opcodes */  
        PyObject *co_consts;    /* list (constants used) */  
        PyObject *co_names;     /* list of strings (names used) */  
        PyObject *co_varnames;  /* tuple of strings (local variable names) */  
        PyObject *co_freevars;  /* tuple of strings (free variable names) */  
        PyObject *co_cellvars;      /* tuple of strings (cell variable names) */  
        /* The rest doesn't count for hash/cmp */  
        PyObject *co_filename;  /* string (where it was loaded from) */  
        PyObject *co_name;      /* string (name, for reference) */  
        int co_firstlineno;     /* first source line number */  
        PyObject *co_lnotab;    /* string (encoding addr<->lineno mapping) See
                       Objects/lnotab_notes.txt for details. */  
        void *co_zombieframe;     /* for optimization only (see frameobject.c) */  
        PyObject *co_weakreflist;   /* to support weakrefs to code objects */  
    } PyCodeObject;
    

    各字段的意义:

    • argcount:参数的个数
    • nlocals:局部变量的个数(包括参数在内)
    • stacksize:堆栈的大小
    • flags:用来表示参数中是否有*args或者**kwargs
    • code:字节码
    • names:全局变量,函数,类,类的方法的名称
    • varnames:局部变量的名称(包含参数)
    • consts:一个常量表,在marshal.c中有定义所有的类型
    #define TYPE_NULL               '0'  
    #define TYPE_NONE               'N'  
    #define TYPE_FALSE              'F'  
    #define TYPE_TRUE               'T'  
    #define TYPE_STOPITER           'S'  
    #define TYPE_ELLIPSIS           '.'  
    #define TYPE_INT                'i'  
    #define TYPE_INT64              'I'  
    #define TYPE_FLOAT              'f'  
    #define TYPE_BINARY_FLOAT       'g'  
    #define TYPE_COMPLEX            'x'  
    #define TYPE_BINARY_COMPLEX     'y'  
    #define TYPE_LONG               'l'  
    #define TYPE_STRING             's'  
    #define TYPE_INTERNED           't'  
    #define TYPE_STRINGREF          'R'  
    #define TYPE_TUPLE              '('  
    #define TYPE_LIST               '['  
    #define TYPE_DICT               '{'  
    #define TYPE_CODE               'c'  
    #define TYPE_UNICODE            'u'  
    #define TYPE_UNKNOWN            '?'  
    #define TYPE_SET                '<'  
    #define TYPE_FROZENSET          '>'
    

    所有的PyCodeObject都是通过调用以下的函数得以运行:PyObject * PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)这个函数是Python的一个重量级的函数,他的作用即是执行中间码,Python的代码都是通过调用这个函数来运行的

    PyFrameObject这个数据结构:

    typedef struct _frame {  
        PyObject_VAR_HEAD  
        struct _frame *f_back;  /* previous frame, or NULL */  
        PyCodeObject *f_code;   /* code segment */  
        PyObject *f_builtins;   /* builtin symbol table (PyDictObject) */  
        PyObject *f_globals;    /* global symbol table (PyDictObject) */  
        PyObject *f_locals;     /* local symbol table (any mapping) */  
        PyObject **f_valuestack;    /* points after the last local */  
        /* Next free slot in f_valuestack.  Frame creation sets to f_valuestack.
           Frame evaluation usually NULLs it, but a frame that yields sets it
           to the current stack top. */  
        PyObject **f_stacktop;  
        PyObject *f_trace;      /* Trace function */  
    
    
        /* If an exception is raised in this frame, the next three are used to
         * record the exception info (if any) originally in the thread state.  See
         * comments before set_exc_info() -- it's not obvious.
         * Invariant:  if _type is NULL, then so are _value and _traceback.
         * Desired invariant:  all three are NULL, or all three are non-NULL.  That
         * one isn't currently true, but "should be".
         */  
        PyObject *f_exc_type, *f_exc_value, *f_exc_traceback;  
    
    
        PyThreadState *f_tstate;  
        int f_lasti;        /* Last instruction if called */  
        /* Call PyFrame_GetLineNumber() instead of reading this field
           directly.  As of 2.3 f_lineno is only valid when tracing is
           active (i.e. when f_trace is set).  At other times we use
           PyCode_Addr2Line to calculate the line from the current
           bytecode index. */  
        int f_lineno;       /* Current line number */  
        int f_iblock;       /* index in f_blockstack */  
        PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */  
        PyObject *f_localsplus[1];  /* locals+stack, dynamically sized */  
    } PyFrameObject;
    

    重点关注下以下的成员:

    PyObject **f_stacktop;  
    
    PyCodeObject *f_code;   /* code segment */  
    PyObject *f_globals;    /* global symbol table (PyDictObject) */  
    PyObject *f_locals;     /* local symbol table (any mapping) */
    

    可见PyFrameObject中包含一个PyCodeObject的结构体指针f_code,PyFrameObject中的f_globals和f_locals这两个dict对象分别用于保存全局对象和局部对象,可以说,PyFrameObject结构就是PyCodeObject的运行环境,PyCodeObject结构是静态的,创建以后就一般不会再变,而PyFrameObject则是动态的,在创建以后,f_globals和f_locals这两个dict都经常会发生变化,并且一个PyCodeObject可能对应好几个的PyFrameObject中。

    0x03实例演示

    • 新建test.py
    import dis  
    myglobal = True   //全局作用域
    
    def add(a):  
        b = 1  
        a += b  
        return a  
    
    class world:  
        def __init__(self): 
            pass              //不做任何事情,一般用做占位语句
        def sayHello(self):  //类中定义的函数第一个参数是self
            print 'hello,world'  
    
    w = world()  
    w.sayHello()
    

    _init_使用规则
    1.把一些我们认为必须绑定的属性强制填写进去。
    2.__init__方法的第一个参数永远是实例变量self。
    3.调用__init__方法,传入除self外其他参数。

    • 编译成pyc
    python -m compileall test.py
    
    • 分析test.pyc

    showfile.py

    import dis, marshal, struct, sys, time, types, binascii
    
    def show_file(fname):
        f = open(fname, "rb")
        magic = f.read(4)
        moddate = f.read(4)
        filesz = f.read(4)
        modtime = time.asctime(time.localtime(struct.unpack('=L', moddate)[0]))
        filesz = struct.unpack('=L', filesz)
        print ("magic %s" % (binascii.hexlify(magic)))
        print ("moddate %s (%s)" % (binascii.hexlify(moddate), modtime))
        print ("files sz %d" % filesz)
        code = marshal.load(f)
        show_code(code)
    
    def show_code(code, indent=''):
        print ("%scode" % indent)
        indent += '   '
        print ("%sargcount %d" % (indent, code.co_argcount))
        print ("%snlocals %d" % (indent, code.co_nlocals))
        print ("%sstacksize %d" % (indent, code.co_stacksize))
        print ("%sflags %04x" % (indent, code.co_flags))
        show_hex("code", code.co_code, indent=indent)
        dis.disassemble(code)
        print ("%sconsts" % indent)
        for const in code.co_consts:
            if type(const) == types.CodeType:
                show_code(const, indent+'   ')
            else:
                print ("   %s%r" % (indent, const))
        print ("%snames %r" % (indent, code.co_names))
        print ("%svarnames %r" % (indent, code.co_varnames))
        print ("%sfreevars %r" % (indent, code.co_freevars))
        print ("%scellvars %r" % (indent, code.co_cellvars))
        print ("%sfilename %r" % (indent, code.co_filename))
        print ("%sname %r" % (indent, code.co_name))
        print ("%sfirstlineno %d" % (indent, code.co_firstlineno))
        show_hex("lnotab", code.co_lnotab, indent=indent)
    
    def show_hex(label, h, indent):
        h = binascii.hexlify(h)
        if len(h) < 60:
            print ("%s%s %s" % (indent, label, h))
        else:
            print ("%s%s" % (indent, label))
            for i in range(0, len(h), 60):
                print ("%s   %s" % (indent, h[i:i+60]))
    
    show_file(sys.argv[1])
    
    showfile.py test.pyc > test.xml
    

    (没复现成功,linux和windows平台都报错,拿大佬内容研究(他这个是python2.7版本))

    • test.xml
    magic 03f30d0a
    moddate 9c4cdf58 (Sat Apr  1 14:45:48 2017)
    <code>
       <argcount> 0 </argcount>
       <nlocals> 0</nlocals>
       <stacksize> 3</stacksize>
       <flags> 0040</flags>
       <code>
          6400006401006c00005a00006501005a02006402008400005a0300640300
          640500640400840000830000595a04006504008300005a05006505006a06
          008300000164010053
       </code>
       <dis>
      1           0 LOAD_CONST               0 (-1)
                  3 LOAD_CONST               1 (None)
                  6 IMPORT_NAME              0 (dis)
                  9 STORE_NAME               0 (dis)
    
      2          12 LOAD_NAME                1 (True)
                 15 STORE_NAME               2 (myglobal)
    
      4          18 LOAD_CONST               2 (<code object add at 0x10e0b7ab0, file "test.py", line 4>)
                 21 MAKE_FUNCTION            0
                 24 STORE_NAME               3 (add)
    
      9          27 LOAD_CONST               3 ('world')
                 30 LOAD_CONST               5 (())
                 33 LOAD_CONST               4 (<code object world at 0x10e0b7db0, file "test.py", line 9>)
                 36 MAKE_FUNCTION            0
                 39 CALL_FUNCTION            0
                 42 BUILD_CLASS         
                 43 STORE_NAME               4 (world)
    
     15          46 LOAD_NAME                4 (world)
                 49 CALL_FUNCTION            0
                 52 STORE_NAME               5 (w)
    
     16          55 LOAD_NAME                5 (w)
                 58 LOAD_ATTR                6 (sayHello)
                 61 CALL_FUNCTION            0
                 64 POP_TOP             
                 65 LOAD_CONST               1 (None)
                 68 RETURN_VALUE        
       </dis>
       <names> ('dis', 'True', 'myglobal', 'add', 'world', 'w', 'sayHello')</names>
       <varnames> ()</varnames>
       <freevars> ()</freevars>
       <cellvars> ()</cellvars>
       <filename> 'test.py'</filename>
       <name> '<module>'</name>
       <firstlineno> 1</firstlineno>
       <consts>
          -1
          None
          <code>
             <argcount> 1 </argcount>
             <nlocals> 2</nlocals>
             <stacksize> 2</stacksize>
             <flags> 0043</flags>
             <code> 6401007d01007c00007c0100377d00007c000053</code>
             <dis>
      5           0 LOAD_CONST               1 (1)
                  3 STORE_FAST               1 (b)
    
      6           6 LOAD_FAST                0 (a)
                  9 LOAD_FAST                1 (b)
                 12 INPLACE_ADD         
                 13 STORE_FAST               0 (a)
    
      7          16 LOAD_FAST                0 (a)
                 19 RETURN_VALUE        
             </dis>
             <names> ()</names>
             <varnames> ('a', 'b')</varnames>
             <freevars> ()</freevars>
             <cellvars> ()</cellvars>
             <filename> 'test.py'</filename>
             <name> 'add'</name>
             <firstlineno> 4</firstlineno>
             <consts>
                None
                1
             </consts>
             <lnotab> 000106010a01</lnotab>
          </code>
          'world'
          <code>
             <argcount> 0 </argcount>
             <nlocals> 0</nlocals>
             <stacksize> 1</stacksize>
             <flags> 0042</flags>
             <code> 6500005a01006400008400005a02006401008400005a03005253</code>
             <dis>
      9           0 LOAD_NAME                0 (__name__)
                  3 STORE_NAME               1 (__module__)
    
     10           6 LOAD_CONST               0 (<code object __init__ at 0x10e0b7c30, file "test.py", line 10>)
                  9 MAKE_FUNCTION            0
                 12 STORE_NAME               2 (__init__)
    
     12          15 LOAD_CONST               1 (<code object sayHello at 0x10e0b7d30, file "test.py", line 12>)
                 18 MAKE_FUNCTION            0
                 21 STORE_NAME               3 (sayHello)
                 24 LOAD_LOCALS         
                 25 RETURN_VALUE        
             </dis>
             <names> ('__name__', '__module__', '__init__', 'sayHello')</names>
             <varnames> ()</varnames>
             <freevars> ()</freevars>
             <cellvars> ()</cellvars>
             <filename> 'test.py'</filename>
             <name> 'world'</name>
             <firstlineno> 9</firstlineno>
             <consts>
                <code>
                   <argcount> 1 </argcount>
                   <nlocals> 1</nlocals>
                   <stacksize> 1</stacksize>
                   <flags> 0043</flags>
                   <code> 64000053</code>
                   <dis>
     11           0 LOAD_CONST               0 (None)
                  3 RETURN_VALUE        
                   </dis>
                   <names> ()</names>
                   <varnames> ('self',)</varnames>
                   <freevars> ()</freevars>
                   <cellvars> ()</cellvars>
                   <filename> 'test.py'</filename>
                   <name> '__init__'</name>
                   <firstlineno> 10</firstlineno>
                   <consts>
                      None
                   </consts>
                   <lnotab> 0001</lnotab>
                </code>
                <code>
                   <argcount> 1 </argcount>
                   <nlocals> 1</nlocals>
                   <stacksize> 1</stacksize>
                   <flags> 0043</flags>
                   <code> 640100474864000053</code>
                   <dis>
     13           0 LOAD_CONST               1 ('hello,world')
                  3 PRINT_ITEM          
                  4 PRINT_NEWLINE       
                  5 LOAD_CONST               0 (None)
                  8 RETURN_VALUE        
                   </dis>
                   <names> ()</names>
                   <varnames> ('self',)</varnames>
                   <freevars> ()</freevars>
                   <cellvars> ()</cellvars>
                   <filename> 'test.py'</filename>
                   <name> 'sayHello'</name>
                   <firstlineno> 12</firstlineno>
                   <consts>
                      None
                      'hello,world'
                   </consts>
                   <lnotab> 0001</lnotab>
                </code>
             </consts>
             <lnotab> 06010902</lnotab>
          </code>
          ()
       </consts>
       <lnotab> 0c010602090513060901</lnotab>
    </code>
    

    可以看到,整个test.pyc就是一个嵌套的PyCodeObject结构的组合,对于每个函数,或者类的方法,都会生成一个对应的PyCodeObject结构,并且模块还会生成额外的一个PyCodeObject结构,pyc文件中一共保存了5个PyCodeObject结构:

    • 最外层的为模块test的PyCodeObject,其中的代码在import或者直接运行时会得到执行。
    • 在module的PyCodeObject中嵌套了add函数的PyCodeObject结构以及world类的PyCodeObject结构。
    • 在world类的PyCodeObject结构中,又嵌套了init方法和sayHello方法的PyCodeObject结构。

    0x04.解析部分产生的opcode

    1           0 LOAD_CONST               0 (-1) #加载consts数组中索引为0处的值,这里为数值-1  
                 3 LOAD_CONST               1 (None) #加载consts数组中索引为1处的值,这里为None  
    
    
                 6 IMPORT_NAME              0 (dis) #加载dis模块:names[0]即为"dis"  
                 9 STORE_NAME               0 (dis) #将模块保存到一个dict中,这个dict专门用来保存局部变量的值,key为names[0],即"dis"  
    
    
     2          12 LOAD_NAME                1 (True) #将names[1],即True压栈。  
                15 STORE_NAME               2 (myglobal) #将栈顶的元素,即True保存到locals['myglobal']中,names[2]即为字符串'myglobal'  
    
    
     4          18 LOAD_CONST               2 (<code object add at 024E3B60, file "test.py", line 4>) #将consts[2],即add函数的PyCodeObject压栈。  
                21 MAKE_FUNCTION            0 #通过add函数的PyCodeObject创建一个函数,并压入栈顶。  
                24 STORE_NAME               3 (add) #将创建的函数出栈并保存到locals['add']中  
    
    
     9          27 LOAD_CONST               3 ('world') #consts[3],即"world"入栈  
                30 LOAD_CONST               5 (()) #consts[5],即空数组入栈  
                33 LOAD_CONST               4 (<code object world at 024E3650, file "test.py", line 9>) #将consts[4],即world的PyCodeObject入栈。  
                36 MAKE_FUNCTION            0 #创建函数  
                39 CALL_FUNCTION            0 #调用刚创建的函数,用于初始化类,会返回一个dict到栈顶,这个dict中保存了类的方法以及一些全局变量,  
                                            #具体的实现要看world类的PyCodeObject中的opcode  
                42 BUILD_CLASS               #创建类,注意BUILD_CLASS会用到栈中的三个对象,这里分别为:保存在dict中的类的信息,基类数组,这里为空数组(),类的名称:"world"  
                43 STORE_NAME               4 (world) #将类保存到locals['world']中  
    
    
    15          46 LOAD_NAME                4 (world)  
                49 CALL_FUNCTION            0  
                52 STORE_NAME               5 (w)  
    #以上三行代码创建一个world对象  
    16          55 LOAD_NAME                5 (w)  
                58 LOAD_ATTR                6 (sayHello)  
                61 CALL_FUNCTION            0  
    #以上三行代码调用w.sayHello()  
                64 POP_TOP               
                65 LOAD_CONST               1 (None)  
                68 RETURN_VALUE
    
    展开全文
  • py文件编译成pyc文件

    千次阅读 2020-11-28 00:11:16
    pyc是一种二进制文件,是由py文件经过编译后,生成的文件,是一种byte code,py文件变成pyc文件后,加载的速度有所提高。 而且pyc是一种跨平台的字节码,是由python的虚拟机来执行的,这个是类似于JAVA或者.NET的...
  • pyc文件反编译成py文件

    千次阅读 2020-12-13 16:15:31
    从git上拉下来的程序,运行的时候发现import少一个py文件,相应文件夹下只有对应的pyc文件,且程序运行报import不了这个文件模块。 基础知识 pyc是一种二进制文件,是由py文件经过编译后,生成的文件,是一种byte ...
  • pyc文件转为py文件

    2021-03-14 19:24:10
    今天在github下载的代码竟然是pyc文件格式,来看一下如何转为py文件 首先安装uncompyle6 打开cmd pip install uncompyle6 然后进入pyc文件的文件夹下,比如我的pyc文件在D盘\BCI Code 首先进入D盘 D: 进入BCI ...
  • py文件转换成pyc文件

    2021-09-15 15:27:19
    py文件转换成pyc文件 pyc介绍 pyc是一种二进制文件,是由py文件经过编译后,生成的文件,是一种byte code,py文件变成pyc文件后,加载的速度有所提高。 而且pyc是一种跨平台的字节码,是由python的虚拟机来执行的,...
  • 什么是pyc文件 pyc是一种二进制文件,是由py文件经过编译后,生成的文件,是一种byte code,py文件变成pyc文件后,加载的速度有所提高,而且pyc是一种跨平台的字节码,是由python的虚拟机来执行的,这个是类似于JAVA...
  • 当我们运行python文件程序的时候,Python解释器将源码转换为字节码,然后再由解释器来执行这些字节码。 因此总的来说,它具有以下三条特性 源码距离底层更远(根据官方文档的解释。不说,你...
  • python py生成及调用pyc文件

    万次阅读 2021-01-27 14:16:29
    python py文件中调用pyc文件 1.生成pyc文件 # 目录下所有py文件生成pyc import compileall compileall.compile_dir('D:\python项目\ceshi') # py生成pyc文件 import py_compile py_compile.compile('proxy.py') ...
  • pyc文件反编译

    千次阅读 2020-10-09 21:03:40
    找一个pyc文件(不是源代码文件),然后搜索相关反编译工具把pyc反编译成Python源代码,最好能多找几种工具或者途径达到反编译的目的。 我找的是另一位同学的pyc文件 1、在线反编译 2、Easy Python Decompiler反...
  • python编译pyc文件

    2021-09-01 22:23:16
    什么是pyc文件 pyc是一种二进制文件,是由py文件经过编译后,生成的文件,是一种byte code,py文件变成pyc文件后,加载的速度有所提高,而且pyc是一种跨平台的字节码,是由python的虚拟机来执行的,这个是类似于JAVA...
  •   将Python工程目录下的所有py文件(递归所有子目录)编译成pyc文件,可选择生成新的工程目录,也可以选择删除源文件,仅保留pyc文件用于部署 pyc部署优点   省去了Python动态编译的过程,直接加载pyc字节码文件...
  • .pyc文件反编译

    2021-10-14 22:20:48
    1.pyc文件产生的原因 首先我们要知道python是解释型语言,即P在执行程序(.py)时代码会由Python解析器翻译成 PyCodeObject对象,俗称字节码(byte code),然后交由Python虚拟机来执行字节码(PS字节码才是可执行的)....
  • 我在将项目打包成exe文件之后,执行后出现出现了该错误 我在打包的.spec文件中已经导入了hiddenimport torch_utils和pathlib pyc文件不是打包的时候自动生成的吗?打包后的文件并没有\utils这个文件夹
  • pyc文件编码还原

    千次阅读 2019-01-04 21:36:00
    今天本来是要将.py文件转换成.pyc文件,使用py_complie进行的转换,以防止有人误改了原代码,但不巧的是在操作过程中,致使一个主.py文件出现了乱码。如下图: 当时就傻了,这要重写一遍很麻烦。看了一下论坛,可...
  • Python之pyc文件作用及生成方法

    千次阅读 2019-02-15 10:03:14
    首先了解下python的运行机制及特性:当我们运行python文件程序的时候,Python解释器将源码转换为字节码,然后再由解释器来执行这些字节码,整体执行流程如下: 完成模块的加载和链接; 将源代码翻译为PyCodeObject...
  • Python生成pyc文件

    2019-05-31 18:25:00
    Python生成pyc文件pyc文件是py文件编译后生成的字节码文件(byte code)。pyc文件经过python解释器最终会生成机器码运行。所以pyc文件是可以跨平台部署的,类似Java的.class文件。一般py文件改变后,都会重新生成pyc...
  • [CTF]pyc文件的逆向

    2021-05-07 18:36:59
    下载附件之后得到pyc文件,使用在线pyc反编译得到源码 分析 从翻遍后得到的源码进行分析,他是对输入的字符进行encode编码后,如果等于correct,则此输入字符为正确的flag.对encode函数进行分析,遍历输入的字符,...
  • 什么是pyc文件

    万次阅读 2018-09-03 10:26:38
    其实很简单, 用 python -m py_compile file.py ...编译成pyc文件。 也可以写份脚本来做这事: Code: import py_compile  py_compile.compile('path') //path是包括.py文件名的路径 用 python...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 20,854
精华内容 8,341
关键字:

pyc文件