1. 程式人生 > >在學習GraytHatPython構建Window偵錯程式過程中遇到的問題

在學習GraytHatPython構建Window偵錯程式過程中遇到的問題

程式設計環境:PyCharm 2017.1.3
Python 3.6.0

參考教程:《Python灰帽子》(Justin Seitz著)

暑期自學《Python灰帽子》的過程中在掌握基本理論知識後學習第三章的過程中一上手就遇到了下面的異常,稱之為異常是因為我編寫的程式碼與書中所寫無異,考慮到Python2.x與3.x版本之間的差異修改了部分函式,測試的時候卻出現了問題。一再檢查除錯問題沒有得到解決,故將其中資訊列舉在此,希望可以從網際網路上得到幫助,或者自己在未來解決問題後可以來填坑。
本頁的所有程式碼可以在我的[Github對應倉庫](https://github.com/LicheeGit/PythonProject/tree/master/GrayHatPython)找到
首先是兩個python指令碼檔案——my_debugger.py及my_debugger_defines.py。
# my_debugger.py
from ctypes import *
# from GrayHatPython.my_debugger_defines import *
from my_debugger_defines import *
# -*- coding: utf-8 -*-

kernel32 = windll.kernel32


class debugger():
    def __init__(self):
        pass

    def load(self, path_to_exe):
        # 引數 dwCreationFlags中的標誌位控制著程序的建立方式。
# 若希望新建立的程序獨佔一個新的控制檯視窗,而不是與父程序共用同一個控制檯 # 可以加上標誌位CREATE_NEW_CONSOLE creation_flags = DEBUG_PROCESS # 例項化之前定義的結構體 startupinfo = STARTUPINFO() process_information = PROCESS_INFORMATION() ''' 在以下兩個成員變數的共同作用下,新建程序將在一個單獨的窗體中被顯示, 可以通過改變結構體STARTUPINFO中的各成員變數的值來控制debugger程序的行為 '''
startupinfo.dwFlags = 0x1 startupinfo.wShowWindow = 0x0 # 設定結構體STARTUPINFO中的成員變數cb的值,用以表示結構體本身的大小 startupinfo.cb = sizeof(startupinfo) if kernel32.CreateProcessW(path_to_exe, None, None, None, None, creation_flags, None, None, byref(startupinfo), byref(process_information)): print("[*] We have successfully launched the process!") # 問題出在這句之前,processInformation獲取不到 # print(path_to_exe) # b'C:\\Windows\\System32\\calc.exe' print("[*] PID: %d" % process_information.dwProcessId) # 獲取PID的時候拋異常,其實是在啟動程序的時候出了問題 # Process finished with exit code -1073741819 (0xC0000005) else: print("[*] Error: 0x%08x." % kernel32.GetLastError())

其中建立了一個核心基類debugger(),後續會逐步新增各項除錯功能。
將所有的結構體,聯合體及常值定義放置於指令碼檔案my_debugger_defines.py之中。

# my_debugger_defines.py
# -*- coding: utf-8 -*-
from ctypes import *

# 為ctype變數建立符合匈牙利命名風格的匿名,這樣可以使程式碼更接近Win32的風格
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


# 定義函式CreateProcessA()所需的結構體
class STARTUPINFO(Structure):
    _fileds_ = [
        ("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", LPTSTR),
        ("hStdInput", HANDLE),
        ("hStdOutput", HANDLE),
        ("hStdError", HANDLE),
    ]


class PROCESS_INFORMATION(Structure):
    _fileds_ = [
        ("hProcess", HANDLE),
        ("hThread", HANDLE),
        ("dwProcessId", DWORD),
        ("dwThreadId", DWORD),
    ]

下面構建了一個測試用例my_test.py,與現有原始碼檔案置於相同目錄底下。

# my_test.py
import my_debugger
debugger = my_debugger.debugger()
debugger.load("C:\\Windows\\System32\\calc.exe")
測試指令碼選擇了Windows自帶的計算器calc.exe作為測試物件,按照書上的講解,通過命令列終端或者從IDE下執行這個指令碼檔案,會孵化一個新的計算器程序並輸出相應的PID後退出。我在運行了測試指令碼後情況如下——
![my_test.py執行結果](https://img-blog.csdn.net/20170914231811612?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbTBfMzc3ODY4NTk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
首先輸出了"[*] We have successfully launched the process!"然後在過了一段時間後輸出程序結束並返回一個0xC0000005。經查閱相關資訊,發現此錯誤通常出現在PyCharm上,在更換命令列終端執行後,仍能輸出"[*] We have successfully launched the process!",仍然要等很長時間之後程式彈出視窗提示Python停止執行。之後在PyCharm中加斷點除錯也沒看出個所以然,程式執行到需要從PID獲取資訊時就出現了停滯。我懷疑是在使用CreateProcessW()的時候出現了問題,因為在測試過程中檢視程序並沒有出現我們開啟的計算器程序,估計是程式不停地在嘗試開啟程序最終出現了程序數過多導致測試異常。
原書中作者使用了CreateProcessA()建立程序,考慮到Python3.x改用了[CreateProcessW()](https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx)(忘記當時為什麼要改成這個了,MSDN相關網頁不知道何由打不開了故無法查詢相關資訊),測試使用CreateProcessA()時得到的結果是

[*] Error: 0x00000002.
Process finished with exit code 0

我的解決思路是接下來將先充分理解Python指令碼開啟程序的程式碼。
剛剛發現了一篇講CreateProcess用法的blog,裡面涉及到了Unicode,我覺得我的偵錯程式可能有救了,明天再說。

相關推薦

學習GraytHatPython構建Window程式過程遇到的問題

程式設計環境:PyCharm 2017.1.3 Python 3.6.0 參考教程:《Python灰帽子》(Justin Seitz著) 暑期自學《Python灰帽子》的過程中在掌握基本理論知識後學習第三章的過程中一上手就

Window 7下QT5.9.2安裝、QTCreator程式配置

QT 5.9.2下載 QT在5.9版本及以上將不同的編譯器的版本放在同一個檔案qt-opensource-windows-x86-5.9.x.exe中,所以只需要此檔案即可,連結:qt-opensource-windows-x86-5.9.2.exe。首次下載

通過chrome程式測試瞭解瀏覽器解析和渲染HTML的過程

1.基礎知識:瞭解chrome的Timeline工具 僅僅是通過理論知識,很難記住和理解瀏覽器解析html的原則,因此我動手做了些小實驗。而做這個實驗,不得不用到一個工具:chrome的Timeline工具。 這個工具真的很強大,Timeline工具欄

linux下gdb程式使用學習-03

目錄 程序除錯命令 attach process-id/detach[附加/分離程序] attach process-id: 在GDB狀態下,開始除錯一個正在執行的程序,其程序ID為pro

linux下gdb程式使用學習-02

目錄 斷點(breakpoint)、監視點(watchpoint)和捕捉點(catchpoint) 雖然說這三類point的功能是不一樣的,但它們的用法卻極為相似。 因此,本文將以斷breakpoint為例,進行詳細的介紹,關於watchpoint和

linux下gdb程式使用學習-01

目錄 gdb入門-啟動與幫助命令檢視 gdb單獨啟動,檢視gdb的相關選項 直接通過shell命令視窗執行如下命令 進入gdb除錯介面【純文字介面】 2. gdb幫助說明 進入gdb後執行命令【help】即可看到gdb的相關命

巧用瀏覽器F12程式定位系統前後端bug

做測試的小夥伴可能用過httpwatch,firebug,fiddler,charles等抓包(資料包)工具,但實際上除了這些還有一個簡單實用並的抓包工具,那就是瀏覽器的F12偵錯程式。 httpwatch,firebug都是瀏覽器的外掛,需要額外下載,fiddler,charles也需要額外下載安裝包另行

2018/11/08-程式-《惡意程式碼分析實戰》

  偵錯程式是用來檢測或測試其他程式執行的以來軟體或硬體。由於剛完成的程式包含錯誤,因此偵錯程式在軟體開發過程中可以大顯身手。偵錯程式讓你能夠洞察程式在執行過程中做了什麼。偵錯程式的目的是允許開發者監控程式的內部狀態和執行。   從偵錯程式獲得程式的資訊可能比較困難,但並不意味著不可能,可以從反彙編器中獲得

[基礎]-Python3 程式入門

原文出處: Clément Verna   譯文出處:linux中國-Flowsnow    Python 生態系統包含豐富的工具和庫,可以讓開發人員更加舒適。 例如,我們之前已經介紹瞭如何使用互動式 shell 增強 Pyt

Linux程式——gdb

一、介紹      GDB是一個在UNIX/LINUX作業系統下基於命令列的且功能強大的程式除錯工具,由GNU開源組織釋出。 二、基本用法 1.如何進入除錯?      (1)要使用gdb除錯,我們必須首先在原始碼生

ros節點呼叫gdb程式和呼叫valgrind分析節點

    在很多情況下我們需要呼叫gdb偵錯程式去除錯自己的程式碼。有時候也需要使用valgrind來檢測程式的記憶體洩露情況。下面我們就來介紹如何啟動gdb或者valgrind分析ros節點。     我是使用的launch檔案去啟動r

嵌入式ARM處理器的7種整合開發環境和6種JTAG程式

      嵌入式ARM處理器的7種整合開發環境和6種JTAG偵錯程式 7種整合開發環境 1.ADS(ARM Developer Suite) ADS由以下幾部分組成: (1)命令列開發工具:armcc、armcpp、tcc、tcpp、armasm、

圖形化OpenGL程式 BuGLe

圖形化OpenGL偵錯程式 BuGLe [轉] BuGLe 結合圖形化的OpenGL除錯與選擇的過濾器上的OpenGL命令流。偵錯程式可以檢視狀態、紋理、framebuffers ,著色器,而過濾器允許日誌,錯誤檢查,自由相機控制,視訊捕捉等。   主頁:http://www.

C++/MFC程式專案

本次偵錯程式專案已實現的功能 附加,建立除錯程序 檢視,修改彙編,記憶體,棧,暫存器 檢視任意模組,匯入表,匯出表。 永久性的斷點(偵錯程式重新開啟斷點依然存在) 無限軟體(條件)斷點,硬體 (條件)斷點,執行,讀寫,訪問 記憶體斷點,執行,讀寫,訪問 反反除錯,外掛功能 解析符號,原始

Linux下程式GDB、makefile的使用

  前面的幾篇部落格中我們講解了Linux下的編輯器vim、編譯器gcc和g++,今天我們來介紹一下其他常用的三種工具,它們分別是程式偵錯程式:GDB、程式碼檢視器:ctags、還有一個輔助工程的工具:Makefile 程式偵錯程式:GDB 在windos下我們常用vs編輯器中自帶

Python 程式之pdb

https://www.cnblogs.com/xiaohai2003ly/p/8529472.html   Python 偵錯程式之pdb 使用PDB的方式有兩種: 1. 單步執行程式碼,通過命令 python -m pdb xxx.py 啟動指令碼,進入單步執行模式

那些在程式裡沒問題(在開發環境沒問題),但是獨立執行卻出問題的原因彙總

1.靜態編譯的動態庫依賴,在偵錯程式中會把程式的起始目錄放在當前專案目錄,因此如果依賴庫在當前專案目錄則不會出問題。 2.許可權問題,比如偵錯程式可能是administrator啟動,於是啟動的除錯程序也有了同樣的許可權。有些操作是需要降權的,比如注入後使用管道,在啟動目標程序的時候需要普通使用

Visual Studio圖形程式詳細使用教程(基於DirectX11)

前言 對於DirectX程式開發者來說,學會使用Visual Studio Graphics Debugger(圖形偵錯程式)可以幫助你全面瞭解渲染管線繫結的資源和執行狀態,從而確認問題所在。現在就以我所掌握的圖形除錯經驗來進行展開描述。 下面的教程基於Visual Studio 2017 Community

[轉]如何在程式啟動的時候將程式附加上去

有時,可能需要除錯由另一個程序啟動的應用程式的啟動程式碼。 這樣的示例包括服務和自定義設定操作。 在這些情況下,可以讓偵錯程式在應用程式啟動時啟動並自動附加。 設定應用程式以自動啟動偵錯程式 啟動登錄檔編輯器 (regedit)。 在“登錄檔編輯器”中開啟

Linux程式-gdb使用

如何用gdb執行一個程式 格式:gdb ./程式名 例: gdb ./main 程式名後邊不需要參加引數,因為引數的獲取在這裡無效,這裡僅僅載入可執行程式資訊 進入gdb除錯之後的命令操作: 退出:ctrl + d 或 quit 1.r/run:執行程式