Portable Python

admin 2021年4月10日00:00:50评论143 views字数 14238阅读47分27秒阅读模式

Portable Python

标题: Portable Python

创建: 2020-11-19 14:44
更新:
链接: http://scz.617.cn:8/python/202011191444.txt
☆ 简介
☆ 官方便携Python
☆ 便携版pip模块
    1) 给便携版Python安装便携版pip模块
    2) 用便携版pip模块安装其他模块
    3) 解析python39._pth
☆ PyCrypto
    1) Visual Studio 2019 社区版
    2) 给安装版Python安装pycrypto模块
    3) pycrypto-2.6.1.win-amd64-py3.9.exe
        3.1pycrypto-wininst.log
    4) RC4_Test.py
    5) 给便携版Python安装pycrypto模块
☆ PyCryptodome
    1) 给安装版Python安装pycryptodomex模块
    2) RC4_Test_1.py
    3) 给便携版Python安装pycryptodomex模块
    4) pycryptodome-3.9.9.win-amd64-py3.9.exe
    5) pycryptodomex-3.9.9.win-amd64-py3.9.exe
☆ Portable IDA+IDAPython
☆ 后记

☆ 简介

本文只考虑Win10中Python便携化。如果读者没有这种需求,或者无法理解这种需求,直接忽略本文。

Win10提供WSL,安装Win版Python的必要性降低,但不是所有环境都装有WSL。

原始需求是Python解释器及各种第三方库"All In One"式地出现在一个目录下,该目录可以随意复制、移动到其他目录、其他PC而不影响使用。此处所谓不影响使用,并不包括PATH环境变量之类的设置,那些属于小白式便捷,不在考虑范畴。

这事并不需要很多奇技淫巧,最简方式是在虚拟机中安装Python,安装相关模块,复制Python安装目录到别处,卸载虚拟机中的安装版Python;跟大多数绿色软件的搞法一样,没有技术含量。

本文展示Python便携化的更多细节,但未给出采用建议,随缘自取。

☆ 官方便携版Python

官方已经提供便携版Python:

https://www.python.org/ftp/python/3.9.0/python-3.9.0-embed-amd64.zip

把python-3.9.0-embed-amd64.zip展开到任意目录,比如"X:Python39",执行其中的python.exe即可。便携版没有include*.h、libs*.lib、Doc*.chm。

高阶用户可自行建立到.py的文件关联,不建也无所谓,每次用python.exe显式执行.py即可。按需修改PATH环境变量,我就不修改。

X:\Python39> python.exe -c "import sys;print(sys.path)"
['X:\Python39\python39.zip''X:\Python39']

缺省情况下sys.path中只有python39.zip和当前目录。

对比一下安装版Python:

https://www.python.org/ftp/python/3.9.0/python-3.9.0-amd64.exe

C:Python39> python.exe -c "import sys;print(sys.path)"
['''C:\Python39\python39.zip''C:\Python39\DLLs''C:\Python39\lib''C:\Python39''C:\Python39\lib\site-packages']

尽管安装Python的sys.path中出现python39.zip,但安装版没有显式提供它,它已经被解压展开了。如果需要"Portable IDAPython",只能从便携版Python中析取python39.zip。

尽管官方提供便携版Python,但事实上安装版Python一样可以随意复制、移动到其他目录、其他PC而不影响使用,对高阶用户尤其如此。本质上Python解释执行所需要的东西都在安装目录下了,安装版Python所做全局设置仅仅增加不必要的小白式便捷,比如修改PATH环境变量、提供pip.exe、增加.py文件关联、增加定位Python安装目录的注册表项等等,没有这些也不真正影响使用。官方便携版Python意义有限。

"pip install"的真正动作是"python -m pip install",后者要求pip模块就位,检查这个位置:

<Python>Libsite-packagespip

安装版Python提供pip模块,可以选装,其版本是20.2.3,用如下命令升级:

$ python.exe -m pip install --upgrade pip

$ python.exe -m pip --version
pip 20.2.4 from C:Python39libsite-packagespip (python 3.9)

☆ 便携版pip模块

1) 给便携版Python安装便携版pip模块

编辑python39._pth,原内容是:

python39.zip
.

Uncomment to run site.main() automatically
#import site

改成:

python39.zip
.
Lib/site-packages

# Uncomment to run site.main() automatically
import site

从如下链接下载get-pip.py放入Python解压目录:

https://pip.pypa.io/en/stable/installing/
https://bootstrap.pypa.io/get-pip.py

执行get-pip.py安装pip模块:

$ python.exe get-pip.py

几个告警忽悠你修改PATH环境变量,不用理。

确认pip模块就位:

$ dir Libsite-packagespip

$ python.exe -m pip --version
pip 20.2.4 from X:Python39Libsite-packagespip (python 3.9)

2) 用便携版Pip安装其他模块

没有修改PATH环境变量,不能"pip install …",只能"python -m pip install"。

$ python.exe -m pip install hexdump

$ dir Libsite-packageshexdump.py

查看已安装的模块:

$ python.exe -m pip list

Package    Version
---------- -------
hexdump    3.3
pip        20.2.4
setuptools 50.3.2
wheel      0.35.1

测试新安装的hexdump模块:

import hexdump
hexdump.hexdump(b'123456')

$ python.exe -c "import hexdump;hexdump.hexdump(b'123456')"

3) 解析python39._pth

python39.zip
.
Lib/site-packages

# Uncomment to run site.main() automatically
import site

python39._pth前部每一行都是一条路径,"import site"让这些路径进入sys.path:

['X:\Python39\python39.zip', 'X:\Python39', 'X:\Python39\Lib\site-packages']

这就是"import site"意义所在。如果不让"import site"生效,可以复制

X:Python39Libsite-packagespip

X:Python39

或将pip目录添加到python39.zip中,这样才能使用pip模块。显然hexdump模块也可照此办理,但吃撑了才用这种复制目录的方案,修改python39._pth更简捷优雅。

☆ PyCrypto

"pip install"有时需要编译源码,这事在Windows上不太理想,比如安装pycrypto模块就会遭遇。

1) Visual Studio 2019 社区版

https://visualstudio.microsoft.com/zh-hans/downloads/

社区版免费下载、使用,不需要序列号什么的。

为了编译pycrypto模块,并"不"需要这些组件:

How to install Python support in Visual Studio on Windows
https://docs.microsoft.com/en-us/visualstudio/python/installing-python-support-in-visual-studio

Python development
  Python native development tools

就正常的C/C++组件即可。

2) 给安装版Python安装pycrypto模块

先给安装版Python安装pycrypto模块,降低一下难度,别骚包地直接给便携版Python安装pycrypto模块。

有一个可选前置步骤,不做也无所谓:

$ python.exe -m pip install wheel

如果没有wheel模块,会用传统setup.py安装方式。

"C:Program Files (x86)Microsoft Visual Studio2019CommunityVCAuxiliaryBuildvcvarsall.bat" amd64

$ python.exe -m pip install pycrypto

报错

error C2061: syntax error: identifier 'intmax_t'

去找找哪个.h包含"intmax_t"。一般用UltraEdit搜,这次试试Win10的高级搜索

Advanced options
  File contents
Other properties
  Name

在搜索框输入"intmax_t name:*.h",命中:

C:Program Files (x86)Microsoft Visual Studio2019CommunityVCToolsMSVC14.28.29333includestdint.h

参看:

CL environment variables
https://docs.microsoft.com/en-us/cpp/build/reference/cl-environment-variables?view=msvc-160

cl.exe认CL、CL环境变量,%CL%被加在cl.exe参数的最前面,%CL%被加在cl.exe参数的最后面。

$ cl.exe /help

/FI<file> name forced include file

$
 echo %VCToolsInstallDir%
C:Program Files (x86)Microsoft Visual Studio2019CommunityVCToolsMSVC14.28.29333

$
 dir "%VCToolsInstallDir%includestdint.h"

$
 set CL=/FI"%VCToolsInstallDir%includestdint.h"

这相当于"#include <stdint.h>"。重新编译安装pycrypto模块:

$ python.exe -m pip install pycrypto

没有其他幺蛾子,顺利完成。

$ python.exe -m pip show pycrypto
Name: pycrypto
Version: 2.6.1
Summary: Cryptographic modules for Python.
Home-page: http://www.pycrypto.org/
Author: Dwayne C. Litzenberger
Author-email: [email protected]
...
Location: c:python39libsite-packages
...

$ dir Libsite-packagesCrypto
$ dir Libsite-packagespycrypto-2.6.1-py3.9.egg-info

小结一下步骤:

"C:Program Files (x86)Microsoft Visual Studio2019CommunityVCAuxiliaryBuildvcvarsall.bat" amd64
set CL=/FI"%VCToolsInstallDir%includestdint.h"
python.exe -m pip install pycrypto

注意,编译安装过程用到了:

C:Python39include*.h
C:Python39libs*.lib

3) pycrypto-2.6.1.win-amd64-py3.9.exe

https://ftp.dlitz.net/pub/dlitz/crypto/pycrypto/pycrypto-2.6.1.tar.gz

假设解压缩到

C:pycrypto-2.6.1

目录随意,只是示例。

cd /d C:pycrypto-2.6.1
set CL=/FI"C:Program Files (x86)Microsoft Visual Studio2019CommunityVCToolsMSVC14.28.29333includestdint.h"
C:Python39python.exe setup.py build
dir /s *.pyd

一切顺利的话,就得到一堆*.pyd,实际是64位的dll。有意思的是,这种编译方式并不需要事先执行"vcvarsall.bat amd64"设置编译环境,setup.py自己去找编译器,"pip install"时必须手动设置编译环境。

C:Python39python.exe setup.py bdist_wininst
dir distpycrypto-2.6.1.win-amd64-py3.9.exe

得到pycrypto的二进制安装包。不想搞编译环境的,用这个:

http://scz.617.cn:8/python/pycrypto-2.6.1.win-amd64-py3.9.exe

MD5     b585c59e1a9a5a92fc1eca8d63f0458d
SHA256  6ddc4fbc1090045e388b1282720cb141f52801089ec4964d1b89242e8725ef2e

3.1) pycrypto-wininst.log

pycrypto-2.6.1.win-amd64-py3.9.exe安装时会生成:

C:Python39pycrypto-wininst.log
C:Python39Removepycrypto.exe
C:Python39Libsite-packagespycrypto-2.6.1-py3.9.egg-info
C:Python39Libsite-packagesCrypto*

.log内容如下:

*** Installation started 2020/11/20 14:57 ***
Source: C:pycrypto-2.6.1.win-amd64-py3.9.exe
999 Root Key: HKEY_CURRENT_USER
020 Reg DB Key: [SoftwareMicrosoftWindowsCurrentVersionUninstall]pycrypto-py3.9
040 Reg DB Value: [SoftwareMicrosoftWindowsCurrentVersionUninstallpycrypto-py3.9]DisplayName=Python 3.9 pycrypto-2.6.1
040 Reg DB Value: [SoftwareMicrosoftWindowsCurrentVersionUninstallpycrypto-py3.9]UninstallString="C:Python39Removepycrypto.exe" -u "C:Python39pycrypto-wininst.log"
200 File Copy: C:Python39Libsite-packagespycrypto-2.6.1-py3.9.egg-info
100 Made Dir: C:Python39Libsite-packagesCrypto
200 File Copy: C:Python39Libsite-packagesCryptopct_warnings.py
...

在"程序和功能"里增加卸载项,实际操作是:

"C:Python39Removepycrypto.exe" -u "C:Python39pycrypto-wininst.log"

复制如下内容到相应位置即可完成安装:

C:Python39Libsite-packagespycrypto-2.6.1-py3.9.egg-info
C:Python39Libsite-packagesCrypto*

如果不是通过pycrypto-2.6.1.win-amd64-py3.9.exe安装,就没有.egg-info文件,而是:

C:Python39Libsite-packagespycrypto-2.6.1.dist-info*
C:Python39Libsite-packagesCrypto*

复制如上内容到相应位置同样完成安装。

4) RC4_Test.py

# -*- coding: cp936 -*-

import sys, os, binascii
from Crypto.Cipher import ARC4

def RC4 ( key, sth ) :
    return( ARC4.new( key ).encrypt( sth ) )
#
# end of RC4
#

if '__main__' == __name__ :
    if len( sys.argv ) < 3 :
        print( 'Usage: %s <key> <in>' % os.path.basename( sys.argv[0] ) )
    else:
        key     = binascii.unhexlify( sys.argv[1] )
        sth     = binascii.unhexlify( sys.argv[2] )
        outdata = RC4( key, sth )
        print( binascii.hexlify( outdata ).upper() )

"""
C:Python39python.exe RC4_Test.py 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B 0A0A0A0A0A0A0A0A
b'C05C2982D61530CA'

C:Python39python.exe RC4_Test.py 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B C05C2982D61530CA
b'0A0A0A0A0A0A0A0A'
"""

5) 给便携版Python安装pycrypto模块

这个没有实际意义,写下来仅仅出于完备性考虑。

便携版没有include*.h、libs*.lib,只能从安装版中复制这些目录到便携版目录;编译pycrypto模块时需要这些目录。假设已经安装Visual Studio 2019 社区版,安装步骤如下:

set PYTHONHOME=C:Python39
"C:Program Files (x86)Microsoft Visual Studio2019CommunityVCAuxiliaryBuildvcvarsall.bat" amd64
set CL=/FI"%VCToolsInstallDir%includestdint.h"
python.exe -m pip install pycrypto

相比前面的安装版,额外设置PYTHONHOME环境变量,否则编译时找不到include*.h。

pycrypto-2.6.1.win-amd64-py3.9.exe不能直接用于便携版Python,因为无法定位Python目录。需要如下注册表项:

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USERSOFTWAREPythonPythonCore3.9InstallPath]
@="C:\Python39\"
reg.exe add "HKCUSOFTWAREPythonPythonCore3.9InstallPath" /v "" /t REG_SZ /d "C:Python39\"
reg.exe query "HKCUSOFTWAREPythonPythonCore3.9InstallPath" /v ""
reg.exe delete "HKCUSOFTWAREPythonPythonCore3.9InstallPath" /v "" /f

手工添加上述注册表项后,pycrypto-2.6.1.win-amd64-py3.9.exe可以安装到便携版Python中,然后可以删除上述注册表项。没有实际意义,只是说可以这样干。

☆ PyCryptodome

参看:

https://www.pycryptodome.org/en/latest/src/introduction.html
https://github.com/Legrandin/pycryptodome

PyCryptodome用来代替不再维护的PyCrypto。按官方说法,如果完全替换:

pip uninstall pycrypto
pip install pycryptodome

此时继续使用"import Crypto"。如果想二者并存:

pip install pycryptodomex

此时后者使用"import Cryptodome"。还是二者并存吧,毕竟很多PoC用前者。

1) 给安装版Python安装pycryptodomex模块

假设已经安装Visual Studio 2019 社区版

$ python.exe -m pip install pycryptodomex --no-binary :all:

这个安装简单,完全没有幺蛾子,不需要手动设置编译环境。

产生目录:

C:Python39Libsite-packagespycryptodomex-3.9.9-py3.9.egg-info*
C:Python39Libsite-packagesCryptodome*

复制如上内容到相应位置即可完成安装。检验安装效果:

$ python.exe -m Cryptodome.SelfTest

2) RC4_Test_1.py

# -*- coding: cp936 -*-

import sys, os, binascii
from Cryptodome.Cipher import ARC4

def RC4 ( key, sth ) :
    return( ARC4.new( key ).encrypt( sth ) )
#
# end of RC4
#

if '__main__' == __name__ :
    if len( sys.argv ) < 3 :
        print( 'Usage: %s <key> <in>' % os.path.basename( sys.argv[0] ) )
    else:
        key     = binascii.unhexlify( sys.argv[1] )
        sth     = binascii.unhexlify( sys.argv[2] )
        outdata = RC4( key, sth )
        print( binascii.hexlify( outdata ).upper() )

"""
C:Python39python.exe RC4_Test_1.py 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B 0A0A0A0A0A0A0A0A
b'C05C2982D61530CA'

C:Python39python.exe RC4_Test_1.py 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B C05C2982D61530CA
b'0A0A0A0A0A0A0A0A'
"""

3) 给便携版Python安装pycryptodomex模块

这个没有实际意义,写下来仅仅出于完备性考虑。

单独下载这个文件到便携版Python目录:

https://github.com/Legrandin/pycryptodome/blob/master/compiler_opt.py

便携版Python的sys.path比较奇特,好像不包含点号(.)对应的当前目录,pip安装时setup.py找不到同一目录下的compiler_opt.py。

便携版没有include*.h、libs*.lib,只能从安装版中复制这些目录到便携版目录;编译pycryptodomex模块时需要这些目录。假设已经安装Visual Studio 2019 社区版,安装步骤如下:

python.exe -m pip install pycryptodomex --no-binary :all:

这次不需要设置PYTHONHOME环境变量,安装结束后可以删除compiler_opt.py。

4) pycryptodome-3.9.9.win-amd64-py3.9.exe

git clone https://github.com/Legrandin/pycryptodome

假设展开到

C:pycryptodome

目录随意,只是示例。

不需要事先执行"vcvarsall.bat amd64"设置编译环境,setup.py自己去找编译器。

cd /d C:pycryptodome
del .separate_namespace
C:Python39python.exe setup.py bdist_wininst
dir distpycryptodome-3.9.9.win-amd64-py3.9.exe

得到pycryptodome的二进制安装包。上面的"C:Python39python.exe"对应安装版Python,但可以是从安装版复制而得的绿色版,并不要求是原始安装版。这次不能用官方便携版Python,否则最后会失败:

(略)

不想搞编译环境的,用这个:

http://scz.617.cn:8/python/pycryptodome-3.9.9.win-amd64-py3.9.exe

MD5     8fd03655b46e208ece6b1b4899cc199c
SHA256  0016a53ec355d4f5480a18697218f3cab524f0195a8bbb8e55237418735258b9

这个版本用"import Crypto",不能与pycrypto-2.6.1.win-amd64-py3.9.exe共存,务必卸载其中一个再安装另一个。

我得吐槽,pycrypto才1MB,pycryptodome有13MB,而常用加密、散列算法在前者中都有实现,如非绝对必要,就用前者好了。

5) pycryptodomex-3.9.9.win-amd64-py3.9.exe

制做步骤:

cd /d C:pycryptodome
copy /y /b NUL .separate_namespace
C:Python39python.exe setup.py bdist_wininst
dir distpycryptodomex-3.9.9.win-amd64-py3.9.exe

不想搞编译环境的,用这个:

http://scz.617.cn:8/python/pycryptodomex-3.9.9.win-amd64-py3.9.exe

MD5     bb92ab13f406b0fbbc41fa27477cd89c
SHA256  2907f33b935b85f4b5e373e0482d9733812f03a752cc859354fd85bd7b3fc48e

这个版本用"import Cryptodome",可以与pycrypto-2.6.1.win-amd64-py3.9.exe共存。

我是怎么知道那条copy命令的呢?因为最开始没有创建.separate_namespace文件,得到的pycryptodome-3.9.9.win-amd64-py3.9.exe把pycrypto破坏了,然后去翻看setup.py源码,有这么一段:

use_separate_namespace = os.path.isfile(".separate_namespace")

project_name = "pycryptodome"
package_root = "Crypto"
other_project = "pycryptodomex"
other_root = "Cryptodome"

if use_separate_namespace:
    project_name, other_project = other_project, project_name
    package_root, other_root = other_root, package_root

如果setup.py所在目录有.separate_namespace文件,就会生成pycryptodomex,反之生成pycryptodome,copy命令就是确保出现.separate_namespace文件。

☆ Portable IDA+IDAPython

Q:

IDA已经绿色化,现在不想让IDA去找安装过的Python,事实上也没安装Python,但又需要用IDAPython。启动IDA时提示:

LoadLibrary(X:GreenIDApluginsidapython3.dll) error: 找不到指定的模块。
X:GreenIDApluginsidapython3.dll: can't load file

启动后底部没有Python命令栏。

A: zyh 2020-11-18

下载便携版Python

https://www.python.org/ftp/python/3.9.0/python-3.9.0-embed-amd64.zip

从python-3.9.0-embed-amd64.zip中析取如下文件:

python3.dll
python39.dll
python39.zip
python39._pth
_ctypes.pyd
libffi-7.dll

复制到IDA根目录,比如:

X:GreenIDA

一般情况下已经可以使用IDAPython。如果再有问题,用Process Monitor监控ida64.exe,补齐缺失的组件。从此随意移动IDA根目录到别处使用。

D: scz 2020-11-19

按前述办法简单处理后,在IDA的Python命令栏已经可以执行很多Python代码,但毕竟Python环境不完善,有可能在后续使用中碰上问题,见招拆招。

比如,在IDA的Python命令栏输入"import socket",提示:

Traceback (most recent call last):
  File "<string>", line 1in <module>
  File "<frozen zipimport>", line 259in load_module
  File "socket.py", line 51in <module>
ModuleNotFoundError: No module named '_socket'

此时需要复制如下文件到IDA根目录:

_socket.pyd
select.pyd

我是怎么知道的呢?愣试是一种办法,我则是用Process Monitor监控便携版python.exe,在后者中"import socket",看它加载了哪些文件。

偷懒的话,把python-3.9.0-embed-amd64.zip中所有文件复制到IDA根目录好了,一堆pyd、dll文件。不过IDAPython编程比较特殊,很可能不需要那些库。

D: scz 2020-11-20

IDAPython可能会去找这些注册表项:

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USERSOFTWAREPythonPythonCore3.9InstallPath]
@="C:\Python39\"
"ExecutablePath"="C:\Python39\python.exe"
"WindowedExecutablePath"="C:\Python39\pythonw.exe"

[HKEY_CURRENT_USERSOFTWAREPythonPythonCore3.9PythonPath]
@="C:\Python39\Lib\;C:\Python39\DLLs\"

找不着时有其他尝试。便携版Python肯定没有这些注册表项,安装版Python有。

☆ 后记

搞这些东西,还是Linux省心省力。

除了pycrypto,以前我还编译过Win版pycurl、pylibssh2、python-lzo等,各有各的坑,当时编译它们是为了制做一些绿色版exe。随着Win10+WSL的普及,这种需求不再那么强烈,但并不是绝对不再出现。

无论如何,我搞了两个绿色版Python 3.9,装了若干模块,到处复制着用。

本文写得很细,按照操作指导手册的性质来写的,为的是降低照猫画虎的门槛,能"All In One"式地完成从0到1的跨越,希望本文能帮到那些有此需求的人们。

Happy Hacking!

本文始发于微信公众号(青衣十三楼飞花堂):Portable Python

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年4月10日00:00:50
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Portable Pythonhttps://cn-sec.com/archives/188887.html

发表评论

匿名网友 填写信息