《python灰帽子》源码一,运行一个程序进入调试状态

《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搜,这是个建议)。接下来会发如何附加一个进程进入调试状态。

猜你喜欢

转载自blog.csdn.net/qq_41738613/article/details/83153392