[翻译]Python2.5,windows XP,VC++2008 Express的环境下安装Pydasm和Pydbg以及请教

发布者:仙果
发布于:2011-05-15 11:14
作者:仙果
注:版权归原作者所有,虽然本人讨厌日本人,转载请注明出处,谢谢合作

题记:买了一本《Python 灰帽子》,书虽不足200页,但其中知识确是非常多,得益不少,又因最近在研究Fuzzing的相关问题,需要搭建Fuzzing进行测试,
        随按照书上的例子进行实验。网上搜集资料时搜索到了这篇文章,虽然买这本书的人挺多(今日在中关村图书大厦还看到某位安全爱好者买了这本书),
        但却是没有看到谁把Python环境搭建的文章发表出来,本着方便自己的想法把这篇文章翻译下,抱砖引玉,有些问题想请教一下。Go go Let's go!
        发现自己很罗嗦。

正文:
        昨天试着在自己的笔记本上安装Pydbg和Pydasm。Pydasm是常用且非常受欢迎的反汇编机器码(字节码)的库。Pydbg同样也是非常受欢迎windows 平台
下轻量级可扩展的Python 库。
        实际上,Pydbg是Windows平台下PaiMei(白眉)的调试框架。
        整个过程却是非常困难的,使用Python distutils充满了挣扎和陷阱。
        记录了如下的文档,把遇到的问题作为备忘录,方便其他人(包括我)安装这些使用C语言和Python编写非常好的反汇编引擎工具。
        我的笔记本配置如下:
	CPU : Intel Pentium M (Centrino) 1.2GHz
	RAM : 1GB
	OS : Windows XP Professional SP3 (Japanese)
	Python: Python 2.5 (install from MSI installer)
			Install Dir : C:\Python25
	Visual Studio : Visual C++ 2008 Express Edision (SP1)
	Subversion: TortoiseSVN 1.6.x

       
我们在后面会获取PaiMei(白眉)的更新版本。
        好吧,让我们开始!
        目录:
        ^一步步安装 Pydasm
                获取 libdasm
                尝试编译->错误
                避免distutils库的值校验
                重新尝试编译->创建成功
                安装Pydasm 并且测试...不是吧,没有找到"MSVCR90.dll"
                重新编辑 msvccompiler.py 修改编译选项 -> Pydasm工作正常
       
        一步步安装 Pydbg
                使用SVN更新和安装->提示找不到"Python26.dll!?"
                Pydbg中移除Pydasm包->成功!!
                白眉(PaiMei)其他模块的注意事项

一步步安装Pydasm

        Pydbg依赖于Pydasm。安装Pydbg之前必须要安装pydasm。但是Pydasm是使用C语言编写,并且
在Windows平台没有正式发行版的二进制文件。
使用的环境如下:
        Python 2.5
        Visual C++ 2008 Express Edition SP1
        Pydasm包含在"Libasm"中,这是一个轻量级的X86反汇编库。
        Pydasm的作者并不是libasm的作者。Libasm是jt(nologin.org)编写的,Pydasm的作者则是ero(dkbza.org).
        Pydasm被共享到Libasm中。
                dkbza - Pydasm (只是列出了libasm的下载链接,简述和一些示例代码)
                http://dkbza.org/pydasm.html
        现在我们来下载libasm,如下的链接包含Pydasm
                Libasm : nologin--代码
                http://www.nologin.org/main.pl?action=codeView&codeId=49&
        下载成功后,解压tar.gz到任意目录。
        昨天下载了Libasm-1.5.tar.gz。解压后,得到了如下的目录树:
		libdasm-1.5\
		libdasm.c
		README.txt
		...
		bin\
		pydasm\
		...

        下一步,打开命令行窗口,进入 VC++ 环境变量(如:vcvars32.bat)。确认"C:\Python25"被添加到环境变量的
的路径当中,或者".py"后缀名的文件已经与"C:\Python25\python.exe"进行关联。
        在命令行中执行"CD"命令进入到"libdasm-1.5\pydasm"目录, 输入如下:
	> setup.py build_ext
	running build_ext
	error: Python was built with Visual Studio 2003;
	extensions must be built with a compiler than can generate compatible binaries.
	Visual Studio 2003 was not found on this system. If you have Cygwin installed,
	you can try compiling with MingW32, by passing "-c mingw32" to setup.py.

       噢!!为什么? 我的命令行窗口环境在VC++ 工具下确认是可用的!!
	> cl
	Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
	Copyright (C) Microsoft Corporation.  All rights reserved.
	...
	> link
	Microsoft (R) Incremental Linker Version 9.00.30729.01
	Copyright (C) Microsoft Corporation.  All rights reserved.

        最终答案是 Python的distutils (没有找到这个单词的相关翻译,直接引用,译者注)工具(在steup.py中引用)检查
Visual Studio 的注册表值并且验证合适的版本来判断安装与否。
        不幸的是,我的本地环境VC++2008 Express Edision 的注册表键值并不是distutils 库支持的。
        绕过avoiding distutil 的注册表键值验证
        如何来绕过这些恼人的注册表键值验证呢?答案是编辑distutil 库源码。Python是开源的而且 distutils 是使用
Python语言编写的。
        (经过我对distutils以及它的源码进行研究分析后)
        结论是,修改如下的源码:
	C:\Python25\Lib\distutils\msvccompiler.py
	msvccompiler.py:
		...
	class MSVCCompiler (CCompiler) :
		...
		def __init__ (self, verbose=0, dry_run=0, force=0):
			...
			# comment out here!!
			self.__macros = MacroExpander(self.__version)

        在MacroExpander() 函数和它的构造函数中执行注册表键值校验,且"self.__macros"是可选的,不是必需的。因此删除掉
这行并不会影响到编译。因此删除掉不需要的这一行,删除先前的 ".pyc" 文件,msvccompiler.pyc ,可能存在".py"的相同
目录。
        尝试重新编译->成功了!!
        msvccompiler.py代码中,当"DISTUTILS_USE_SDK"和 "MSSdk" 的环境变量设置正确且"cl.exe"可以在环境变量目录中找到
时是不会进行注册表校验的。因此可以在命令行窗口中设置"DISTUTILS_USE_SDK"和 "MSSdk" :
	> set DISTUTILS_USE_SDK=1
	> set MSSdk=1

        环境变量内容都设置好以后,msvccompiler.py 只会校验注册表键是存在且忽略其值。
        OK,尝试编译:
	> setup.py build_ext
	running build_ext
	building 'pydasm' extension
	creating build
	creating build\temp.win32-2.5
	creating build\temp.win32-2.5\Release
	C:\Program Files\Microsoft Visual Studio 9.0\VC\BIN\cl.exe \
		/c /nologo /Ox /MD /W3 /GX /DNDEBUG \
		-IC:\Python25\include -IC:\Python25\include -IC:\Python25\PC \
		/Tc../libdasm.c /Fobuild\temp.win32-2.5\Release\../libdasm.obj
	C:\Program Files\Microsoft Visual Studio 9.0\VC\BIN\cl.exe \
		/c /nologo /Ox /MD /W3 /GX /DNDEBUG \
		-IC:\Python25\include -IC:\Python25\include -IC:\Python25\PC \
		/Tcpydasm.c /Fobuild\temp.win32-2.5\Release\pydasm.obj
	creating build\lib.win32-2.5
	C:\Program Files\Microsoft Visual Studio 9.0\VC\BIN\link.exe \
		/DLL /nologo /INCREMENTAL:NO \
		/LIBPATH:C:\Python25\libs /LIBPATH:C:\Python25\PCBuild /EXPORT:initpydasm \
		build\temp.win32-2.5\Release\../libdasm.obj build\temp.win32-2.5\Release\pydasm.obj \
		/OUT:build\lib.win32-2.5\pydasm.pyd \
		/IMPLIB:build\temp.win32-2.5\Release\..\pydasm.lib

        (删去了编译时的一些警告)
        当所有工作成功以后,就会得到
	libdasm-1.5\pydasm\build\lib.win32-2.5\pydasm.pyd


安装 Pydasm并且测试...OH-NO,没有找到"MSVCR90.dll"!?
       
        现在调用安装命令:
	> setup.py install
	running install
	running build
	running build_ext
	running install_lib
	copying build\lib.win32-2.5\pydasm.pyd -> C:\Python25\Lib\site-packages
	copying build\lib.win32-2.5\pydasm.pyd.manifest -> C:\Python25\Lib\site-packages
	running install_egg_info
	Removing C:\Python25\Lib\site-packages\pydasm-1.5-py2.5.egg-info
	Writing C:\Python25\Lib\site-packages\pydasm-1.5-py2.5.egg-info

        然后调用Python和尝试导入Pydasm
	> C:\Python25\python.exe
	Python 2.5.2 (r252:60911, Feb 21 2008, 13:11:45) [MSC v.1310 32 bit (Intel)] on win32
	Type "help", "copyright", "credits" or "license" for more information.
	>>> import pydasm
	Traceback (most recent call last):
	  File "<stdin>", line 1, in <module>
	ImportError: DLL load failed: 指定されたモジュールが見つかりません。(中文是“找不到指定的模块”,译者注)
	>>> quit()

O-No,最后的"ImportError"说明指定的模块没有找到。在我的环境中,窗口显示的是"MSVCR90.dll 没有找到"。
       
        检查模块的依赖关系:
	> dumpbin /dependents C:\Python25\python.exe
	...
	   python25.dll
	   MSVCR71.dll   <-- Python25 depends on MSVCR71.dll
	   KERNEL32.dll
	...
	> dumpbin /dependents build\lib.win32-2.5\pydasm.pyd
	...
	   MSVCR90.dll    <-- pydasm depends on MSVCR90.dll !!
	   python25.dll
	   KERNEL32.dll

        我的环境中,MSVCR90.dll 安装在 Visual Studio的安装目录中,并不是系统目录。如果你已经安装包含MSVCR90.dll
的VC运行库在系统目录中,那么导入错误就不会提示,一切工作正确。
        现在如何去做呢?有2中方法解决这个错误。
                1.在Windows上安装包含MSVCR90.dll的VC运行库。
                        1.这是最简单的,但是Python使用MSVCR71.dll (使用低版本的Visual Studio进行编译的),我担心在两个动态
                DLL会产生冲突。
                2.静态链接VC-DLL。
                        1.使用合适的模块,但是需要改变编译选项,模块文件大小会变大。
        我强烈担心两个动态DLL产生冲突(或者其他错误),因此选择了第二种方法。
        又一次编辑msvccompiler.py, 修改编译选项->Pydasm正常工作!!
        现在如何修改编译选项?选择什么选项呢?
        msvccompiler.py 在MSVCCompiler 类的初始化方法的安装编译选项。
	msvccompiler.py: 
	...
	class MSVCCompiler (CCompiler) :
	...
		def initialize(self):
			...
			self.preprocess_options = None
			if self.__arch == "Intel":
				self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' ,
										 '/DNDEBUG']
				self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
                                          '/Z7', '/D_DEBUG']

        "/MD" 和"/MDd"表示动态链接多线程库。若要了解关于动态库和编译选项的更详细信息,查看MSDN:
       
http://msdn.microsoft.com/en-us/library/abx4dbyh.aspx 
	"MSDN Library" > "Development Tools and Languages" > "Visual Studio 2010" > "Visual Studio" > "Visual Studio Languages" > "Visual C++" > "Visual C++ Reference" > "Visual C++ Libraries Reference" > "Run-Time Library" > "C Run-Time Libraries"

        这次我们需要链接静态多线程库,因此选择"/MT" 和 "/MTd"。
	...
	class MSVCCompiler (CCompiler) :
	...
		def initialize(self):
			...
			self.preprocess_options = None
			if self.__arch == "Intel":
				# change '/MD' => '/MT'
				self.compile_options = [ '/nologo', '/Ox', '/MT', '/W3', '/GX' ,
										 '/DNDEBUG']
				# change '/MDd' => '/MTd'
				self.compile_options_debug = ['/nologo', '/Od', '/MTd', '/W3', '/GX',
											  '/Z7', '/D_DEBUG']


        删除旧的msvccompiler.pyc和pydasm\build目录,重新尝试。
	> setup.py build_ext
	> dumpbin /dependents build\lib.win32-2.5\pydasm.pyd
	 Image has the following dependencies:

	   python25.dll
	   KERNEL32.dll
	...
	> setup.py install
	...
	> C:\Python25\python.exe
	Python 2.5.2 (r252:60911, Feb 21 2008, 13:11:45) [MSC v.1310 32 bit (Intel)] on win32
	Type "help", "copyright", "credits" or "license" for more information.
	>>> import pydasm
	>>> buffer = '\x90\x31\xc9\x31\xca\x31\xcb'
	>>> offset = 0
	>>> while offset < len(buffer):
	...     i = pydasm.get_instruction(buffer[offset:], pydasm.MODE_32)
	...     print pydasm.get_instruction_string(i, pydasm.FORMAT_INTEL, 0)
	...     if not i:
	...         break
	...     offset += i.length
	...
	nop
	xor ecx,ecx
	xor edx,ecx
	xor ebx,ecx
	>>> quit()

        好了。Pydasm开始工作正常。
        下一步,尝试安装(白眉)PaiMei,Pydbg。
        白眉官方文档
        http://pedram.redhive.com/PaiMei/docs/
        白眉google代码站
        http://code.google.com/p/paimei/
        其他资源
        http://thatsbroken.com/?p=26
        http://maliciousattacker.blogspot.com/2006/12/pydbg-in-vmware.html
        http://www.openrce.org/downloads/details/208/PaiMei
        http://maliciousattacker.blogspot.com/2007/01/setting-up-pydbg.html

从SVN上下载保存并安装->"找不到Python26.dll "

        首先,从SVN源上下载白眉的最新版(并不是导出)。使用你自己喜欢的SVN工具。昨天我更新了r248编号的源码。
        第二步,打开命令行窗口,CD到白眉的目录,执行setup.py
	> setup.py build
	(...)
	> setup.py install
	(...)

第三步,尝试导入 Pydbg:
	> C:\Python25\python.exe
	Python 2.5.2 (r252:60911, Feb 21 2008, 13:11:45) [MSC v.1310 32 bit (Intel)] on win32
	Type "help", "copyright", "credits" or "license" for more information.
	>>> import pydbg
	Traceback (most recent call last):
	  File "<stdin>", line 1, in <module>
	  File "pydbg\__init__.py", line 47, in <module>
		from pydbg                   import *
	  File "C:\in_vitro\SVNWORK\paimei\pydbg\pydbg.py", line 32, in <module>
		import pydasm
	ImportError: DLL load failed: 指定されたモジュールが見つかりません。

错误提示窗口表示“没有找到Python26.dll”。
               经过对Python的堆栈输出进行仔细的查看。非常奇怪的发生在"import pydasm"(导入 Python)上。
        上一节中,我们验证了"import pydasm"是可以正常工作的。那现在为什么?

在Pydbg包中移除pydasm.pyd->成功了!!
答案是: Pydbg的模块目录已经包含了"pydasm.pyd",而且是在 Python 2.6下编译的。
	> dumpbin /dependents C:\Python25\Lib\site-packages\pydbg\pydasm.pyd
														^^^^^^^^^^^^^^^^ pydasm.pyd was bundled!!
	...
	  Image has the following dependencies:

		MSVCR90.dll
		python26.dll
		KERNEL32.dll
	...

        然后我们简单的移除 "pydbg\pydasm.pyd"。关闭命令行窗口,一并关闭所有的Python程序,重新打开命令行窗口
(清除载入的DLL),再试一次:
	> C:\Python25\python.exe
	Python 2.5.2 (r252:60911, Feb 21 2008, 13:11:45) [MSC v.1310 32 bit (Intel)] on win32
	Type "help", "copyright", "credits" or "license" for more information.
	>>> import pydbg
	>>>

        好的,没有任何错误。
       
        最后,调用calc.exe ,得到它的PID,例子如下:
	from pydbg import *
	from pydbg.defines import *
	def handler_breakpoint (pydbg):
	  if pydbg.first_breakpoint:
		print "[*] Hit 1st breakpoint!"
		return DBG_CONTINUE
	  print "[*] Hit breakpoint!"
	  return DBG_CONTINUE
	dbg = pydbg()
	dbg.set_callback(EXCEPTION_BREAKPOINT, handler_breakpoint)
	dbg.attach(XXXXX) # pid of calc.exe
	recv = dbg.func_resolve("user32", "ShowWindow")
	dbg.bp_set(recv)
	dbg.debug_event_loop()

        例如:
	> C:\Python25\python.exe
	Python 2.5.2 (r252:60911, Feb 21 2008, 13:11:45) [MSC v.1310 32 bit (Intel)] on win32
	Type "help", "copyright", "credits" or "license" for more information.
	>>> from pydbg import *
	>>> from pydbg.defines import *
	>>> def handler_breakpoint (pydbg):
	...   if pydbg.first_breakpoint:
	...     print "[*] Hit 1st breakpoint!"
	...     return DBG_CONTINUE
	...   print "[*] Hit breakpoint!"
	...   return DBG_CONTINUE
	...
	>>> dbg = pydbg()
	>>> dbg.set_callback(EXCEPTION_BREAKPOINT, handler_breakpoint)
	>>> dbg.attach(5084)
	<pydbg.pydbg.pydbg instance at 0x00BF8198>
	>>> recv = dbg.func_resolve("user32", "ShowWindow")
	>>> dbg.bp_set(recv)
	<pydbg.pydbg.pydbg instance at 0x00BF8198>
	>>> dbg.debug_event_loop()
	[*] Hit 1st breakpoint!
	[*] Hit breakpoint!
	...
	(minimize, or restore calc window)
	...
	[*] Hit breakpoint!
	>>> quit()

        白眉其他模块的注意事项
        这篇文章中,我们只需要安装白眉的Pydbg。忽略了如何安装白眉的其他模块,如PIDA,GUI部件。如果你想安装这些模块
白眉都是可以设置的,通过阅读官方文档或者在SVN下载源码"docs/index.html" 。

        这是这篇文章的翻译,由于本人英语水平的问题,文中肯定有错误之处,欢迎指正。
下面我说下自己的环境
	OS:XP SP3_CN
	VC:Visual Studio 2008 Team SP1
	PY:Python 2.7

        按理说Python2.7是可以可以安装Pydbg的,我安装Pydasm是可以正常工作的,已经测试了,下载安装Pydbg的时候就报错了
请教其他安装Pydbg的朋友,你们遇到这个问题没,该如何解决?
        仙果感激不尽!
Python-Installing pydasm and pydbg with Python 2_5, WinXP, VC++2008 Express Edition及中文翻
上传的附件:

声明:该文观点仅代表作者本人,转载请注明来自看雪