亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

win32調試API學習心得(三)

2019-11-18 18:30:28
字體:
來源:轉載
供稿:網友
 

要學習如何修改被調試進程,先讓我們來了解幾個與此有關的函數.
一.讀指定進程內存:ReadPRocessMemory
  此函數的定義為:function ReadProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer; lpBuffer: Pointer; nSize: DWord; var lpNumberOfBytesRead: DWORD): BOOL; stdcall;
  hProcess指向被讀取內存的進程的句柄,此句柄必須有PROCESS_VM_READ權限.
  lpBaseAddress:指向被讀取的內存在進程中基地址的指針.
  lpBuffer:指向用于保存讀出數據的緩沖區的指針.
  nSize:指定從指定進程中要讀取的字節數.
  lpNumberOfBytesRead:指向讀出數據的實際字節數.

二.寫指定進程內存:WriteProcessMemory
  此函數的定義為:function WriteProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer; lpBuffer: Pointer; nSize: DWORD; var lpNumberOfBytesWritten: DWORD): BOOL; stdcall;
參數含義同ReadProcessMemory,其中hProcess句柄要有對進程的PROCESS_VM_WRITE和PROCESS_VM_OperaTION權限.lpBuffer為要寫到指定進程的數據的指針.

  注意,如果要修改的內存所在的頁面的存取保護屬性為只讀,如代碼段,要修改頁面的存取保護才能夠正常修改.可使用VirtualProtectEx函數,請參考下面的代碼片段:
VirtualProtectEx(hPHandle, Address, SizeOf(BYTE), PAGE_READWRITE, OldFlg);
WriteProcessMemory(hPHandle, Address, @BreakCode, SizeOf(BYTE), Read);
VirtualProtectEx(hPhandle, Address, SizeOf(BYTE), OldFlg, OldFlg); // 恢復頁碼保護屬性
  hPHandle為目標進程句柄,Address為要修改的內存的基址,SizeOf(BYTE)表示要修改的區域長度,如果這個長度跨過一個或幾個頁面邊界時,將修改跨過的所有頁面的存取保護屬性,OldFlg用來存放原來的存取保護屬性,以便調用WriteProcessMemory后恢復頁面保護屬性.

三.得到指定線程的上下文結構:GetThreadContext
  此函數的定義為:function GetThreadContext(hThread: THandle; var lpContext: TContext): BOOL; stdcall;
  hThread:要取得上下文結構的線程的句柄,可以在發生CREATE_THEAD_DEBUG_EVENT調試事件時保存線程ID和線程句柄的關聯以便調用GetThreadContext時得到線程句柄.
  lpContext:用來保存指定線程上下文件信息的結構.
  在象Windows這樣的多任務操作系統中,同一時間里可能運行著幾個程序.Windows分配給每個線程一個時間片,當時間片結束后,Windows將凍結當前線程并切換到下一具有最高優先級的線程.在切換之前,Windows將保存當前進程的寄存器的內容,這樣當在該線程再次恢復運行時,Windows可以恢復最近一次線程運行的環境.保存的寄存器內容總稱為進程上下文.上下文件的結構取決于CPU的類型.
  在調用GetThreadContext之前,要先設置TContext的ContextFlags標志來指明要檢索的寄存器.例如只想得到CPU的段寄存器的值,可以設置ContextFlags標志為CONTEXT_SEGMENTS.其它可能的標志如下:
  CONTEXT_CONTROL:包含CPU的控制寄存器,比如指今指針,堆棧指針,標志和函數返回地址.
  CONTEXT_INTEGER:用于標識CPU的整數寄存器.
  CONTEXT_FLOATING_POINT:用于標識CPU的浮點寄存器.
  CONTEXT_SEGMENTS:用于標識CPU的段寄存器.
  CONTEXT_DEBUG_REGISTER:用于標識CPU的調試寄存器.
  CONTEXT_EXTENDED_REGISTERS:用于標識CPU的擴展寄存器.
  CONTEXT_FULL:相當于CONTEXT_CONTROL or CONTEXT_INTEGER or   CONTEXT_SEGMENTS,即這三個標志的組合.

四.設置指定線程的上下文結構:SetThreadContext
  此函數的定義為:function SetThreadContext(hThread: THandle; const lpContext: TContext): BOOL; stdcall;
  參數同GetThreadContext.
  有了這二個函數可以實現很多功能,比如用WriteProcessMemory在被調試進程的某個函數入口處寫一個調試中斷(int 3,即$cc),然后在運行到此調試中斷時會產生中斷,再用GetThreadContext得到當前線程的上下文,就可以根據Esp的值得到函數的參數等信息.你甚至可以修改Eip的值來讓被調試程序跳到任何地址來執行,或是修改標志寄存器的值來修改進程的執行方式.

  了解了以上函數后我們就可以用來修改被調試進程了,具體能實現怎樣的功能只局限于自己的想像力了,但運用不得當被調試程序通常會當得很慘。當然這幾個函數不止可以用于被調試進程,用于其它進程一樣適用(可用OpenProcess根據進程標識符得到進程句柄),例如用它們來做出你自己的游戲修改器等等.

下面的例子演示了如何其得線程的上下文并將CPU置為單步模式來運行程序,注意由于單步模式比較慢,運行一個大的被調試程序時可能會等很久時間.
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

 {調試信息處理過程}
procedure DebugPro;
var
  si: _STARTUPINFOA;         (進程啟動信息}
  pi: _PROCESS_INFORMATION;  {進程信息}
  Flage: DWORD;
  DebugD: DEBUG_EVENT;   {調試事件}
  Rc: Boolean;
  CodeCount: DWORD;       {運行的指令數}
  ThreadHandle: Thandle;  {主線程句柄}
  Context: TContext;
begin
    {建立調試進程}
  CodeCount := 0;
  ConText.ContextFlags := CONTEXT_CONTROL;
  Flage := DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS;
  GetStartupInfo(si);  {初始化si結構,不然無法正常建立進程}
  if not CreateProcess(nil, Pchar('C:/winnt/NOTEPAD.EXE C:/Boot.ini'), nil, nil,
    False, Flage, nil, nil, si, pi) then
  begin
    MessageBox(application.Handle, '建立被調試進程失敗', '!!!', MB_OK or MB_ICONERROR);
    exit;
  end;
  while WaitForDebugEvent(DebugD, INFINITE) do
  begin    {根據事件代碼進行相應處理}
    case DebugD.dwDebugEventCode of
      EXIT_PROCESS_DEBUG_EVENT:
      begin
        MessageBox(Application.Handle, '被調試進程中止', '!!!', MB_OK or MB_ICONERROR);
        Break;
      end;
      CREATE_PROCESS_DEBUG_EVENT:
      begin
        ThreadHandle := DebugD.CreateProcessInfo.hThread;
        MessageBox(Application.Handle, '被調試進程建立', '!!!', MB_OK or MB_ICONERROR);
      end;
      EXCEPTION_DEBUG_EVENT:
      begin
        if (DebugD.Exception.ExceptionRecord.ExceptionCode <> EXCEPTION_SINGLE_STEP) and
           (DebugD.Exception.ExceptionRecord.ExceptionCode <> EXCEPTION_BREAKPOINT) then
          Rc := False      {如果被調試程序產生了異常,讓它自己處理}
        else
        begin
          GetThreadContext(ThreadHandle, Context);
           {將標志寄存器的陷井標志設為TRUE,這樣CPU將會處于單步模式}
          Context.EFlags := Context.EFlags or $100;
          Inc(CodeCount);
          Form1.Label1.Caption := IntToStr(CodeCount);
          SetThreadContext(ThreadHandle, Context);
          Rc := True;
        end;
      end;
    end;
    if Rc then
      ContinueDebugEvent(DebugD.dwProcessId, DebugD.dwThreadId,
         DBG_CONTINUE)
    else
      ContinueDebugEvent(DebugD.dwProcessId, DebugD.dwThreadId,
         DBG_EXCEPTION_NOT_HANDLED);
  end;
  CloseHandle(pi.hProcess);
  Closehandle(pi.hThread);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  ThreadHandle, ThreadID: THandle;
begin
  ThreadHandle := CreateThread(nil, 0, @DebugPro, nil, 0, ThreadID);
end;

end.

最后附上其它的調試API.
一. procedure DebugBreak; stdcall;
  該函數在當前進程中產生斷點,以便調用的線程能夠向調試器發信號.
二. procedure FatalExit(ExitCode: Integer); stdcall;
  該函數把執行控制交給調試器,調試器的行為隨后被指定為所用調試器的類型.
三. function FlushInstructionCache(hProcess: THandle; const lpBaseAddress: Pointer; dwSize: DWORD): BOOL; stdcall;
  該函數為指定進程刷新指令高速緩存器,此函數僅在多進程計算機上是有效的.
  hProcess:要刷新的高速緩存器的進程句柄.
  lpBaseAddress:要刷新區域的基地址指針,可以為0
  dwSize:要刷新區域的長度.
四. function isDebuggerPresent; BOOL; stdcall;
  該函數表明調用的進程是否在調試器描述表下運行,此函數從KERNEL32.DLL輸出.
五. procedure OutputDebugString(lpOutputString: PChar); stdcall;
  該函數為當前的應用程序發送一個字符串到調試器中,lpOutputString為要發送的字符串.
  在DELPHI中可以通用View->Debug Windows->Event Log打開Event Log窗口查看被調試程序發送的字符串.
六. procedure SetDebugErrorLevel(dwLevel: DWORD); stdcall;
  該函數設置最小錯誤級別,在該錯誤級別中系統中將產生調試事件并把它傳遞給調試器.
  dwLevel:指定調試事件的最小錯誤調試程序,如果錯誤相等于或大于此程序,系統產生一個調試事件,此參數必須是下列值中的一個.
  0: 不記錄任何錯誤. SLE_ERROR:僅記錄ERROR級別的調試事件.
  SLE_MINORERROR:僅記錄MINORERROR級別和ERROR級別的調試事件.
  SLE_WARNING:記錄WARNING級別,MINORERROR和ERROR級別的調試事件.


上一篇:使用OLE拖放不同程序間的數據

下一篇:關于在VCL寫作過程中提示找不Proxies單元的解決方法

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲国产日韩欧美综合久久| 91精品视频观看| 最新国产成人av网站网址麻豆| 一区二区成人av| 91色精品视频在线| www.亚洲成人| 欧美激情乱人伦一区| 国产精品igao视频| 国产精品久久久久秋霞鲁丝| 欧美在线性爱视频| 中文字幕欧美日韩在线| 亚洲精品久久久久久久久久久久久| **欧美日韩vr在线| 97视频免费看| 亚洲自拍欧美另类| 欧美日本在线视频中文字字幕| 欧美壮男野外gaytube| 亚洲欧美国产日韩中文字幕| 插插插亚洲综合网| 欧美日韩免费在线| 91深夜福利视频| 国产成人亚洲综合青青| 亚洲成人精品久久| 欧美黑人极品猛少妇色xxxxx| 精品久久久久久中文字幕大豆网| 亚洲成人在线网| 乱亲女秽乱长久久久| 欧美亚洲激情在线| 欧美日韩国产成人高清视频| 欧美www在线| 日韩欧美在线观看视频| 欧美一区二区三区精品电影| 国产欧美在线看| 日韩av在线直播| 91精品国产高清久久久久久久久| 成人免费网视频| 三级精品视频久久久久| 久久成人精品一区二区三区| 欧美性猛交xxxx免费看久久久| 一二美女精品欧洲| 日本精品中文字幕| 啊v视频在线一区二区三区| 精品久久久一区二区| 麻豆国产va免费精品高清在线| 日本精品久久久| 国产精品第10页| 欧美超级乱淫片喷水| 欧美性xxxx极品hd欧美风情| 国内揄拍国内精品少妇国语| 国内外成人免费激情在线视频| 91在线免费视频| 欧美日韩国产一区二区| 亚洲视频第一页| 91精品国产成人www| 日韩精品在线观看一区二区| 欧美性xxxxxx| 精品久久久久久中文字幕大豆网| 国产日韩欧美自拍| 欧美激情精品久久久久久黑人| 日韩福利视频在线观看| 欧美中文在线字幕| 欧美中文在线观看| 性欧美xxxx视频在线观看| 国产精品视频色| www国产91| 亚洲偷欧美偷国内偷| 欧美视频一区二区三区…| 免费成人高清视频| 国产成人午夜视频网址| 欧美电影免费观看网站| 成人午夜一级二级三级| 国产成人精彩在线视频九色| 黄色成人av在线| 自拍偷拍亚洲精品| 国产精品高潮呻吟久久av黑人| 亚洲精品女av网站| 欧美电影在线观看高清| 国产一区二区三区直播精品电影| 国产成人精品一区二区三区| 成人综合国产精品| 性色av一区二区咪爱| 久久久久久伊人| 欧美综合国产精品久久丁香| 国产亚洲人成a一在线v站| 国外色69视频在线观看| 国产精品91久久久久久| 日韩免费av片在线观看| 久久久人成影片一区二区三区观看| 日韩亚洲成人av在线| 亚洲乱码一区av黑人高潮| 91av视频在线播放| 日韩欧美中文第一页| 国产精品美女久久久久av超清| 国产一区二区在线播放| 亚洲欧美变态国产另类| 激情懂色av一区av二区av| 欧美老少配视频| 日韩的一区二区| 草民午夜欧美限制a级福利片| 日本高清不卡在线| 91视频8mav| 久久久久999| 欧美日韩国产第一页| 92看片淫黄大片欧美看国产片| 在线日韩中文字幕| 亚洲高清av在线| 亚洲成人性视频| 欧美日韩中国免费专区在线看| 亚洲尤物视频网| 5252色成人免费视频| 国产婷婷成人久久av免费高清| zzijzzij亚洲日本成熟少妇| 欧美国产日本高清在线| 日韩成人在线视频观看| 国产精品羞羞答答| 国产精品免费电影| 欧美大学生性色视频| 国产成人综合亚洲| 91性高湖久久久久久久久_久久99| 国产精品久久久久久久久久东京| 国产精品69久久| 日韩在线视频国产| 久久精品一区中文字幕| 欧美性色19p| 91探花福利精品国产自产在线| 欧美国产日本在线| 中文精品99久久国产香蕉| 日韩国产精品一区| 91av视频在线免费观看| 久久这里有精品| 国产精彩精品视频| 成人在线中文字幕| 久久久久久久激情视频| 久久精品国产2020观看福利| 日韩精品免费综合视频在线播放| 欧美激情国产精品| 国产精品自产拍在线观看中文| 国产精品av在线| 久久综合免费视频| 久热精品视频在线观看一区| 伊人久久大香线蕉av一区二区| 日本精品免费一区二区三区| 国产成人精品一区二区在线| 国产69精品久久久久99| 91精品在线看| 一区二区亚洲精品国产| 国产精品入口日韩视频大尺度| 欧美在线xxx| 久久免费成人精品视频| 亚洲福利视频免费观看| 国产精品精品久久久久久| 亚洲夜晚福利在线观看| 啊v视频在线一区二区三区| 国模私拍视频一区| 国产精品久久久久久久久粉嫩av| 亚洲精品久久久久久久久久久久久| 国产日产亚洲精品| 96sao精品视频在线观看| 国产91精品网站| 最近更新的2019中文字幕| 97国产一区二区精品久久呦| 97色在线视频观看| 日本一区二区在线播放| 亚洲视频第一页|