《python灰帽子》这本书感觉不错,所以分享下看书写下的源码
系统win10,python3.6(书里的都是python2),编码软件vscode
学习python灰帽子就是需要调用dll(动态链接库)这方面的知识就不说了,百度或去看书都很容易的,但是那些win32api还是推荐Google去搜索来看比较好,基本一搜第一个链接就是微软的。
用python3编写书里的代码最大的问题是编码问题,python2默认编码是ASCII,python3默认编码是unicode,所以书中的代码都需要改一下,很多win32api后面都有A或W,这分别表示ASCII和unicode,书上调用api都是带A的,不然也可以不用怕编码问题出现。例如
from ctypes import *
msvcrt = cdll.msvcrt
message_string = "hello world!\n"
msvcrt.printf("Testing: %s",message_string)
能在python2运行,但是python3只会出现一个T
两种办法解决。第一种:
msvcrt.wprintf("Testing: %s",message_string)
调用宽字符的wprintf()函数
第二种:
message_string = b"hello world!\n"
msvcrt.printf(b"Testing: %s",message_string)
在字符串(包括双引号单引号等)前面加b
学习这本书的代码还是要知道怎么用python创建结构体,联合体等知识,书上都有详细的讲或者浏览器搜索都有,我就不贴出来了,我就放出我能运行的代码给大家看。
接下来我们实现运行程序进入调试状态
首先我们创建my_debugger_defines.py,我们在这里创建符合win32的变量,常量,结构体等
from ctypes import *
WORD = c_ushort
DWORD = c_ulong
LPBYTE = POINTER(c_ubyte)
LPTSTR = POINTER(c_char)
HANDLE = c_void_p
DEBUG_PROCESS = 0x00000001
CREATE_NEW_CONSOLE = 0x00000010
class STARTUPINFO(Structure):
_fields_=[
("cb",DWORD),
("lpReserved",LPTSTR),
("lpDesktop",LPTSTR),
("lpTitle",LPTSTR),
("dwX",DWORD),
("dwY",DWORD),
("dwXSize",DWORD),
("dwYSize",DWORD),
("dwXCountChars",DWORD),
("dwYCountChars",DWORD),
("dwFillAttribute",DWORD),
("dwFlags", DWORD),
("wShowWindow", WORD),
("cbReserved2", WORD),
("lpReserved2", LPBYTE),
("hStdInput", HANDLE),
("hStdOutput", HANDLE),
("hStdError", HANDLE),
]
class PROCESS_INFORMATION(Structure):
_fields_=[
("hProcess", HANDLE),
("hThread", HANDLE),
("dwProcessId",DWORD),
("dwThreadId", DWORD),
]
然后创建my_debugger.py,里面我们调用各种win32api实现功能
from ctypes import *
from my_debugger_defines import *
kernel32 = windll.kernel32
class debugger():
def __init__(self):
self.h_process = None # 进程句柄
self.pid = None # 进程pid
self.debugger_active = False # 进程活跃状态
pass
def load(self,path_to_exe):
creation_flags=DEBUG_PROCESS
startupinfo = STARTUPINFO()
process_information=PROCESS_INFORMATION()
startupinfo.dwFlags =0x1
startupinfo.wShowWindow=0x0
startupinfo.cb=sizeof(startupinfo)
if kernel32.CreateProcessA(path_to_exe,
None,
None,
None,
None,
creation_flags,
None,
None,
byref(startupinfo),
byref(process_information)):
print("[*] 我们成功启动目标程序!")
print("[*] PID:%d"%process_information.dwProcessId)
else:
print("[*] Error:0x%08x."%kernel32.GetLastError())
最后创建my_test.py
from my_debugger import debugger
debugger = debugger()
debugger.load(b"C:\\Windows\\System32\\calc.exe")
输入的路径是我们win自带的计算器,运行my_test.py后(后面引入书中的话),你将看不到 计算器的图形界面出现。因为进程没有把界面绘画到屏幕上,它在等待调试器继续执行的命 令。
好了这章就到这里,虽然感觉还有点细节没有说出来,但是还是需要到正确的地方去了解,win32常量或者函数等可以用MSDN或者Google去查找(我下载MSDN不好找也很大,最好直接Google搜,这是个建议)。接下来会发如何附加一个进程进入调试状态。