導航:首頁 > 凈水問答 > windbg怎麼過濾字元串

windbg怎麼過濾字元串

發布時間:2021-02-19 12:58:02

㈠ 如何使用windbg到hook的位置

那麼我們首先應該做的是怎麼樣來解除掉它們,替換我們的執行地址,當然在這里,我們必須要知道這個結構:
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
PVOID ServiceTableBase;
PULONG ServiceCounterTableBase;
ULONG NumberOfService;
ULONG ParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE; // 由於KeServiceDescriptorTable只有一項,這里就簡單點了
他就是SSDT 表了,這張表就類似於 PE 文件中的 IAT ,存儲著一系列的函數地址,我們都知道,現在的系統都是基於保護模式的,當我們要訪問內核的時候,MS 已經為我們定義好了介面,那麼當我們調用哪些介面的時候,哪些介面會在這張表中查找需要的服務的地址函數,
我們在這里可以截獲我們要過濾的函數請求,達到我們的目的。。。

這個結構有四個域:
反匯編得到:

HookApi!_SERVICE_DESCRIPTOR_TABLE
+0x000 ServiceTableBase : Ptr32 Void
+0x004 ServiceCounterTableBase : Ptr32 Uint4B
+0x008 NumberOfService : Uint4B
+0x00c ParamTableBase : Uint4B

//我們的替代的函數,是一個裸函數,編譯器不會像其他的函數一樣處理它。。。
__declspec(naked) NTSTATUS MyApiAddress(PHANDLE phandle,
ACCESS_MASK DesireAddress,
POBJECT_ATTRIBUTES pObjectAttributes,
PCLIENT_ID pClientID)
{
KdPrint(("NtPOpenProcess...Call"));
__asm
{
push 0C4h; //這兩個域,是通過我們要HOOK 的 API 定位得到的
push 804daaa8h;
jmp [g_JmpServerAddr];
}
}

kd> u 805c2296
nt!NtOpenProcess:
這里是我們要調用的函數的入口點:
兩個參數,遵循 C 的調用方式,手工清棧。。。就得到了
805c2296 68c4000000 push 0C4h //
805c229b 68a8aa4d80 push offset nt!ObWatchHandles+0x25c (804daaa8)
805c22a0 e86b6cf7ff call nt!_SEH_prolog (80538f10)

805c22a5 33f6 xor esi,esi
805c22a7 8975d4 mov dword ptr [ebp-2Ch],esi
805c22aa 33c0 xor eax,eax
805c22ac 8d7dd8 lea edi,[ebp-28h]
805c22af ab stos dword ptr es:[edi]
有兩種方法獲得我們要HOOK 的地址,可以通過函數,推薦PVOID
MmGetSystemRoutineAddress(
IN PUNICODE_STRING SystemRoutineName
);
比較方便,不用涉及其他的操作,返回的是要查的地址。。。。
不然的話,需要查MS 定義的服務描述表,而且個個平台還不一樣,難以做到跨平台。。。

上邊就完成了我們的導向工作,只要獲取到了需要跳轉的地址就 OK 了。。。
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable; // KeServiceDescriptorTable為導出函數

操作之前:
我們需要:
// 去掉內存保護
VOID ClearMemoryProtect()
{
__asm
{
cli;
mov eax, cr0;
and eax, not 10000h;
mov cr0, eax;
}
}

// 跳轉到NtOpenProcess函數頭+10的地方,這樣在其前面寫的JMP都失效了,完成替換
g_JmpServerAddr = (ULONG)NtOpenProcess + 10;

// 回復內存的保護
VOID RecoverMemoryProtect()
{
__asm
{
cli;
mov eax, cr0;
or eax, not 10000h;
mov cr0, eax;
sti;
}
}

*((ULONG*)uAddress) = (ULONG)MyApiAddress; // HOOK SSDT

去除內存的防寫,操作完成自後,回復之。。。。

㈡ 如何過濾windbg的列印信息

在logcat里點選綠色的+,然後在「by Application Name:」里填入com.my.app就OK了。 它還有「by Log Tag」、內「by Log Message」、「by PID」過濾容條件。

㈢ 如何過濾windbg的列印信息

在logcat里點選綠色的+,然後在「by Application Name:」里填入com.my.app就OK了。 它還有「by Log Tag」、「專by Log Message」、「by PID」過濾條屬件。

㈣ 如何過濾windbg的列印信息

在logcat里點選綠色的+,然後在「by Application Name:」里填入com.my.app就OK了。回 它還有「答by Log Tag」、「by Log Message」、「by PID」過濾條件。

㈤ Windows內核調試器的WinDBG

WinDBG和用戶調試器一點很大不同是內核調試器在一台機器上啟動,通過串口調試另一個相聯系的以Debug方式啟動的系統,這個系統可以是虛擬機上的系統,也可以是另一台機器上的系統(這只是微軟推薦和實現的方法,其實象SoftICE這類內核調試器可以實現單機調試)。很多人認為主要功能都是在WinDBG里實現,事實上並不是那麼一回事,windows已經把內核調試的機制集成進了內核,WinDBG、kd之類的內核調試器要做的僅僅是通過串列發送特定格式數據包來進行聯系,比如中斷系統、中斷點、顯示內存數據等等。然後把收到的數據包經過WinDBG處理顯示出來。
在進一步介紹WinDBG之前,先介紹兩個函數:KdpTrace、KdpStub,我在《windows異常處理流程》一文里簡單提過這兩個函數。現在再提一下,當異常發生於內核態下,會調用KiDebugRoutine兩次,異常發生於用戶態下,會調用KiDebugRoutine一次,而且第一次調用都是剛開始處理異常的時候。
當WinDBG未被載入時KiDebugRoutine為KdpStub,處理也很簡單,主要是對由int 0x2d引起的異常如DbgPrint、DbgPrompt、載入卸載SYMBOLS(關於int 0x2d引起的異常將在後面詳細介紹)等,把Context.Eip加1,跳過int 0x2d後面跟著的int 0x3指令。
真正實現了WinDBG功能的函數是KdpTrap,它負責處理所有STATUS_BREAKPOINT和STATUS_SINGLE_STEP(單步)異常。STATUS_BREAKPOINT的異常包括int 0x3、DbgPrint、DbgPrompt、載入卸載SYMBOLS。DbgPrint的處理最簡單,KdpTrap直接向調試器發含有字元串的包。DbgPrompt因為是要輸出並接收字元串,所以先將含有字元串的包發送出去,再陷入循環等待接收來自調試器的含有回復字元串的包。SYMBOLS的載入和卸載通過調用KdpReportSymbolsStateChange,int 0x3斷點異常和int 0x1單步異常(這兩個異常基本上是內核調試器處理得最多的異常)通過調用KdpReportExceptionStateChange,這兩個函數很相似,都是通過調用KdpSendWaitContinue函數。KdpSendWaitContinue可以說是內核調試器功能的大管家,負責各個功能的分派。這個函數向內核調試器發送要發送的信息,比如當前所有寄存器狀態,每次單步後我們都可以發現寄存器的信息被更新,就是內核調試器接受它發出的包含最新機器狀態的包;還有SYMBOLS的狀態,這樣載入和卸載了SYMBOLS我們都能在內核調試器里看到相應的反應。然後KdpSendWaitContinue等待從內核調試器發來的包含命令的包,決定下一步該干什麼。讓我們來看看KdpSendWaitContinue都能幹些什麼:
case DbgKdReadVirtualMemoryApi:
KdpReadVirtualMemory(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdReadVirtualMemory64Api:
KdpReadVirtualMemory64(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdWriteVirtualMemoryApi:
KdpWriteVirtualMemory(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdWriteVirtualMemory64Api:
KdpWriteVirtualMemory64(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdReadPhysicalMemoryApi:
KdpReadPhysicalMemory(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdWritePhysicalMemoryApi:
KdpWritePhysicalMemory(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdGetContextApi:
KdpGetContext(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdSetContextApi:
KdpSetContext(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdWriteBreakPointApi:
KdpWriteBreakpoint(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdRestoreBreakPointApi:
KdpRestoreBreakpoin(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdReadControlSpaceApi:
KdpReadControlSpace(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdWriteControlSpaceApi:
KdpWriteControlSpace(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdReadIoSpaceApi:
KdpReadIoSpace(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdWriteIoSpaceApi:
KdpWriteIoSpace(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdContinueApi:
if (NT_SUCCESS(ManipulateState.u.Continue.ContinueStatus) != FALSE) {
return ContinueSuccess;
} else {
return ContinueError;
}
break;
case DbgKdContinueApi2:
if (NT_SUCCESS(ManipulateState.u.Continue2.ContinueStatus) != FALSE) {
KdpGetStateChange(&ManipulateState,ContextRecord);
return ContinueSuccess;
} else {
return ContinueError;
}
break;
case DbgKdRebootApi:
KdpReboot();
break;
case :
(&ManipulateState,&MessageData,ContextRecord);
break;
case :
(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdSetSpecialCallApi:
KdSetSpecialCall(&ManipulateState,ContextRecord);
break;
case DbgKdClearSpecialCallsApi:
KdClearSpecialCalls();
break;
case DbgKdSetInternalBreakPointApi:
KdSetInternalBreakpoint(&ManipulateState);
break;
case DbgKdGetInternalBreakPointApi:
KdGetInternalBreakpoint(&ManipulateState);
break;
case DbgKdGetVersionApi:
KdpGetVersion(&ManipulateState);
break;
case DbgKdCauseBugCheckApi:
KdpCauseBugCheck(&ManipulateState);
break;
case DbgKdPageInApi:
KdpNotSupported(&ManipulateState);
break;
case DbgKdWriteBreakPointExApi:
Status = KdpWriteBreakPointEx(&ManipulateState,
&MessageData,
ContextRecord);
if (Status) {
ManipulateState.ApiNumber = DbgKdContinueApi;
ManipulateState.u.Continue.ContinueStatus = Status;
return ContinueError;
}
break;
case DbgKdRestoreBreakPointExApi:
KdpRestoreBreakPointEx(&ManipulateState,&MessageData,ContextRecord);
break;
case DbgKdSwitchProcessor:
KdPortRestore ();
ContinueStatus = KeSwitchFrozenProcessor(ManipulateState.Processor);
KdPortSave ();
return ContinueStatus;
case DbgKdSearchMemoryApi:
KdpSearchMemory(&ManipulateState,&MessageData,ContextRecord);
break;
讀寫內存、搜索內存、設置/恢復斷點、繼續執行、重啟等等,WinDBG里的功能是不是都能實現了?呵呵。
每次內核調試器接管系統是通過調用在KiDispatchException里調用KiDebugRoutine(KdpTrace),但我們知道要讓系統執行到KiDispatchException必須是系統發生了異常。而內核調試器與被調試系統之間只是通過串口聯系,串口只會發生中斷,並不會讓系統引發異常。那麼是怎麼讓系統產生一個異常呢?答案就在KeUpdateSystemTime里,每當發生時鍾中斷後在HalpClockInterrupt做了一些底層處理後就會跳轉到這個函數來更新系統時間(因為是跳轉而不是調用,所以在WinDBG斷下來後回溯堆棧是不會發現HalpClockInterrupt的地址的),是系統中調用最頻繁的幾個函數之一。在KeUpdateSystemTime里會判斷KdDebuggerEnable是否為TRUE,若為TRUE則調用KdPollBreakIn判斷是否有來自內核調試器的包含中斷信息的包,若有則調用DbgBreakPointWithStatus,執行一個int 0x3指令,在異常處理流程進入了KdpTrace後將根據處理不同向內核調試器發包並無限循環等待內核調試的回應。現在能理解為什麼在WinDBG里中斷系統後堆棧回溯可以依次發現KeUpdateSystemTime->,系統停在了int 0x3指令上(其實int 0x3已經執行過了,只不過Eip被減了1而已),實際已經進入KiDispatchException->KdpTrap,將控制權交給了內核調試器。
系統與調試器交互的方法除了int 0x3外,還有DbgPrint、DbgPrompt、載入和卸載symbols,它們共同通過調用DebugService獲得服務。
NTSTATUS DebugService(
ULONG ServiceClass,
PVOID Arg1,
PVOID Arg2

{
NTSTATUS Status;
__asm {
mov eax,ServiceClass
mov ecx,Arg1
mov edx,Arg2
int 0x2d
int 0x3
mov Status,eax
}
return Status;
}
ServiceClass可以是BEAKPOINT_PRINT(0x1)、BREAKPOINT_PROMPT(0x2)、BREAKPOINT_LOAD_SYMBOLS(0x3)、BREAKPOINT_UNLOAD_SYMBOLS(0x4)。為什麼後面要跟個int 0x3,M$的說法是為了和int 0x3共享代碼(我沒弄明白啥意思-_-),因為int 0x2d的陷阱處理程序是做些處理後跳到int 0x3的陷阱處理程序中繼續處理。但事實上對這個int 0x3指令並沒有任何處理,僅僅是把Eip加1跳過它。所以這個int 0x3可以換成任何位元組。
int 0x2d和int 0x3生成的異常記錄結(EXCEPTION_RECORD)ExceptionRecord.ExceptionCode都是STATUS_BREAKPOINT(0x80000003),不同是int 0x2d產生的異常的ExceptionRecord.NumberParameters>0且ExceptionRecord.ExceptionInformation對應相應的ServiceClass比如BREAKPOINT_PRINT等。事實上,在內核調試器被掛接後,處理DbgPrint等發送字元給內核調試器不再是通過int 0x2d陷阱服務,而是直接發包。用M$的話說,這樣更安全,因為不用調用KdEnterDebugger和KdExitDebugger。
最後說一下被調試系統和內核調試器之間的通信。被調試系統和內核調試器之間通過串口發數據包進行通信,Com1的IO埠地址為0x3f8,Com2的IO埠地址為0x2f8。在被調試系統准備要向內核調試器發包之前先會調用KdEnterDebugger暫停其它處理器的運行並獲取Com埠自旋鎖(當然,這都是對多處理器而言的),並設置埠標志為保存狀態。發包結束後調用KdExitDebugger恢復。每個包就象網路上的數據包一樣,包含包頭和具體內容。包頭的格式如下:
typedef struct _KD_PACKET {
ULONG PacketLeader;
USHORT PacketType;
USHORT ByteCount;
ULONG PacketId;
ULONG Checksum;
} KD_PACKET,*PKD_PACKET;
PacketLeader是四個相同位元組的標識符標識發來的包,一般的包是0x30303030,控制包是0x69696969,中斷被調試系統的包是0x62626262。每次讀一個位元組,連續讀4次來識別出包。中斷系統的包很特殊,包里數據只有0x62626262。包標識符後是包的大小、類型、包ID、檢測碼等,包頭後面就是跟具體的數據。這點和網路上傳輸的包很相似。還有一些相似的地方比如每發一個包給調試器都會收到一個ACK答復包,以確定調試器是否收到。若收到的是一個RESEND包或者很長時間沒收到回應,則會再發一次。對於向調試器發送輸出字元串、報告SYMBOL情況等的包都是一接收到ACK包就立刻返回,系統恢復執行,系統的表現就是會卡那麼短短一下。只有報告狀態的包才會等待內核調試器的每個控制包並完成對應功能,直到發來的包包含繼續執行的命令為止。無論發包還是收包,都會在包的末尾加一個0xaa,表示結束。
現在我們用幾個例子來看看調試流程。
記得我以前問過jiurl為什麼WinDBG的單步那麼慢(相對softICE),他居然說沒覺得慢?*$&$^$^(&(&;(我ft。現在可以理解為什麼WinDBG的單步和從操作系統正常執行中斷下來為什麼那麼慢了。單步慢是因為每單步一次除了必要的處理外,還得從串列收發包,怎麼能不慢。中斷系統慢是因為只有等到時鍾中斷發生執行到KeUpdateSystemTime後被調試系統才會接受來自WinDBG的中斷包。現在我們研究一下為什麼在KiDispatchException里不能下斷點卻可以用單步跟蹤KiDispatchException的原因。如果在KiDispatchException中某處下了斷點,執行到斷點時系統發生異常又重新回到KiDispatchException處,再執行到int 0x3,如此往復造成了死循環,無法不能恢復原來被斷點int 0x3所修改的代碼。但對於int 0x1,因為它的引起是因為EFLAG寄存中TF位被置位,並且每次都自動被復位,所以系統可以被繼續執行而不會死循環。現在我們知道了內部機制,我們就可以調用KdXXX函數實現一個類似WinDBG之類的內核調試器,甚至可以替換KiDebugRoutine(KdpTrap)為自己的函數來自己實現一個功能更強大的調試器,呵呵。

㈥ 如何給字元串下條件斷點

SCII字元集字元串設抄置方法:
代碼襲:
STRING
[eax]
==
"DDLX_CHAR"
STRING
[eax]
==
"DDLX_char"
//不區分大小寫
STRING
[eax]
==
"DDLX"
//不區分文本長度
UNICODE字元集字元串設置方法:
代碼:
UNICODE
[eax]
==
"DDLX_WCHAR"
UNICODE
[eax]
==
"DDLX_wchar"
//不區分大小寫
UNICODE
[eax]
==
"DDLX"
//不區分文本長度
WinDbg
ASCII字元集字元串斷點設置方法:
代碼:
//全字元串匹配,區分大小寫
bp
0041141d
"r
@$t1
=
eax;
as
/ma
${/v:pzString}
$t1;.if
($scmp(\"${pzString}\",\"DDLX_CHAR\")==0)
{}
.else
{gc}

㈦ WinDbg怎麼用

什麼是WinDBG? WinDbg是微軟開發的免費源碼級調試工具。Windbg可以用於Kernel模式調試和用戶模式調試,還可以調試Dump文件。由於大部分程序員不需要做Kernel模式調試, 我在這篇文章中不會介紹Kernel模式調試。Kernel模式調試對學習Windows核心極有幫助。如果你對此感興趣,可以閱讀Inside Windows 2000和Windbg所帶的幫助文件。這篇文章得主要目的是介紹WINDBG的主要功能以及相關的命令。關於這些命令的詳細語法,請參閱幫助文件。對文章中提到的許多命令,WINDBG有相應的菜單選項。如何得到幫助在命令(Command)窗口中輸入.hh 命會調出幫助文件令。.hh keyword會顯示關於keyword的詳細命令。啟動DebuggerWindbg可以用於如下三種調試:遠程調試:你可以從機器A上調試在機器B上執行的程序。具體步驟如下:
? 在機器B上啟動一個調試窗口(Debug Session)。你可以直接在Windbg下運行一個程序或者將Windbg附加(Attach)到一個進程。? 在機器B的Windbg命令窗口上啟動一個遠程調試介面(remote):.server npipe:pipe=PIPE_NAMEPIPE_NAME是該介面的名字。? 在機器A上運行:windbg –remote npipe:server=SERVER_NAME,pipe=PIPE_NAMESERVER_NAME是機器B的名字。Dump文件調試:如果在你的客戶的機器上出現問題,你可能不能使用遠程調試來解決問題。你可以要求你的用戶將Windbg附加到出現問題的進程上,然後在命令窗口中輸入:
.mp /ma File Name創建一個Dump文件。在得到Dump文件後,使用如下的命令來打開它:windbg –z DUMP_FILE_NAME本地進程調試:你可以在Windbg下直接運行一個程序:
Windbg 「path to executable」 arguments 也可以將Windbg附加到一個正在運行的程序: Windbg –p 「process id」 Windbg –pn 「process name」 注意有一種非侵入(Noninvasive)模式可以用來檢查一個進程的狀態並不進程的執行。當然在這種模式下無法控制被調試程序的執行。這種模式也可以用於查看一個已經在Debugger控制下運行的進程。具體命令如下: Windbg –pv –p 「process id」 Windbg –pv –pn 「process name」 調試多個進程和線程如果你想控制一個進程以及它的子進程的執行,在Windbg的命令行上加上-o選項。Windbg中還有一個新的命令.childdbg 可以用來控制子進程的調試。如果你同時調試幾個進程,可以使用 | 命令來顯示並切換到不同的進程。在同一個進程中可能有多個線程。~命令可以用來顯示和切換線程。調試前的必備工作在開始調試前首先要做的工作是設置好符號(Symbols)路徑。沒有符號,你看到的調用堆棧基本上毫無意義。Microsoft的操作系統符號文件(PDB)是對外公開的。另外請注意在編譯你自己的程序選擇生成PDB文件的選項。如果設置好符號路徑後,調用堆棧看起來還是不對。可以使用lm, !sym noisy, !reload 等命令來驗證符號路徑是否正確。Windbg也支持源碼級的調試。在開始源碼調試前,你需要用.srcpath設置源代碼路徑。如果你是在生成所執行代碼的機器上進行調試,符號文件中的源碼路徑會指向正確的位置,所以不需要設置源代碼路徑。如果所執行代碼是在另一台機器上生成的,你可以將所用的源碼拷貝(保持原有的目錄結構)的一個可以訪問的文件夾(可以是網路路徑)並將源代碼路徑設為該文件夾的路徑。注意如果是遠程調試,你需要使用.lsrcpath來設置源碼路徑。靜態命令:顯示調用堆棧:在連接到一個調試窗口後,首先要知道的就是程序當前的執行情況k* 命令顯示當前線程的堆棧。~*kb會顯示所有線程的調用堆棧。如果堆棧太長,Windbg只會顯示堆棧的一部分。.kframes可以用來設置預設顯示框架數。顯示局部變數:接下來要做通常是用dv顯示局部變數的信息。CTRL+ALT+V可以切換到更詳細的顯示模式。關於dv要注意的是在優化過的代碼中dv的輸出極有可能是不準確的。這時後你能做的就是閱讀匯編代碼來發現你感興趣的值是否存儲在寄存器中或堆棧上。有時後當前的框架(Frame)上可能找不到你想知道的數據。如果該數據是作為參數傳到當前的方法中的,可以讀一讀上一個或幾個框架的匯編代碼,有可能該數據還在堆棧的某個地址上。靜態變數是儲存在固定地址中的,所以找出靜態變數的值較為容易。.Frame(或者在調用堆棧窗口中雙擊)可以用來切換當前的框架。注意dv命令顯示的是當前框架的內容。你也可在watch窗口中觀察局部變數的值。顯示類和鏈表: dt可以顯示數據結構。比如dt PEB 會顯示操作系統進程結構。在後面跟上一個進程結構的地址會顯示該結構的詳細信息:dt PEB 7ffdf000。Dl命令可以顯示一些特定的鏈表結構。顯示當前線程的錯誤值:!gle會顯示當前線程的上一個錯誤值和狀態值。!error命令可以解碼HRESULT。搜索或修改內存:使用s 命令來搜索位元組,字或雙字,QWORD或字元串。使用e命令來修改內存。計算表達式:?命令可以用來進行計算。關於表達式的格式請參照幫助文檔。使用n命令來切換輸入數字的進制。顯示當前線程,進程和模塊信息:!teb顯示當前線程的環境信息。最常見的用途是查看當前線程堆棧的起始地址,然後在堆棧中搜索值。!peb顯示當前進程的環境信息,比如執行文件的路徑等等。lm顯示進程中載入的模塊信息。顯示寄存器的值:r命令可以顯示和修改寄存器的值。如果要在表達式中使用寄存器的值,在寄存器名前加@符號(比如@eax)。顯示最相近的符號:ln Address。如果你有一個C++對象的指針,可以用來ln來查看該對象類型。 查找符號:x命令可以用來查找全局變數的地址或過程的地址。x命令支持匹配符號。x kernel32!*顯示Kernel32.dll中的所有可見變數,數據結構和過程。查看lock:!locks顯示各線程的鎖資源使用情況。對調試死鎖很有用。查看handle:!handle顯示句柄信息。如果一段代碼導致句柄泄漏,你只需要在代碼執行前後使用!handle命令並比較兩次輸出的區別。有一個命令!htrace對調試與句柄有關的Bug非常有用。在開始調試前輸入:!htrace –enable 然後在調試過程中使用!htrace handle_value 來顯示所有與該句柄有關的調用堆棧。顯示匯編代碼:u。程序執行控制命令:設置代碼斷點:bp/bu/bm 可以用來設置代碼斷點。你可以指定斷點被跳過的次數。假設一段代碼KERNEL32!SetLastError在運行很多次後會出錯,你可以設置如下斷點: bp KERNEL32!SetLastError 0x100.在出錯後使用bl 來顯示斷點信息(注意粗體顯示的值):0 e 77e7a3b0 004f (0100) 0:*** KERNEL32!SetLastError重新啟動調試(.restart命令)並設置如下的斷點:bp Kernel32!SetLastError 0x100-0x4fDebugger會停在出錯前最後一次調用該過程的地方。你可以指定斷點被激活時Debugger應當執行的命令串。在該命令串中使用J命令可以用來設置條件斷點:bp `mysource.cpp:143` "j (poi(MyVar)」0n20) ''; 'g' "上面的斷點只在MyVar的值大於32時被激活(g命令條件斷點的用途極為廣泛。你可以指定一個斷點只在特殊的情況下被激活,比如傳入的參數滿足一定的條件,調用者是某個特殊的過程,某個全局變數被設為特殊的值等等。設置內存斷點:ba可以用來設置內存斷點。調試過程中一個常見的問題是跟蹤某些數據的變化。如下的斷點:ba w4 0x40000000 "kb; g"可以列印出所有修改0x40000000的調用堆棧。控製程序執行:p, pa,t, ta等命令可以用來控製程序的執行。控制異常和事件處理:Debugger的預設設置是跳過首次異常(first chance expcetion),在二次異常(second chance exception)時中斷程序的執行。sx命令顯示Debugger的設置。sxe和sxd可以改變Debugger的設置。 sxe clr可以控制Debugger在託管異常發生時中斷程序的執行。常用的Debugger事件有: av 訪問異常 eh C++異常 clr 託管異常 ld 模塊載入-c 選項可以用來指定在事件發生時執行的調試命令。

閱讀全文

與windbg怎麼過濾字元串相關的資料

熱點內容
什麼叫反滲透流程式控制制 瀏覽:179
進氣濾芯不好有什麼影響 瀏覽:173
用甲醛標樣代替蒸餾水 瀏覽:422
艾克羅司空氣負離子凈化器怎麼用 瀏覽:339
苗圃凈水廠建在哪裡 瀏覽:144
醫院化驗室重金屬廢水處理 瀏覽:480
污水處理廠污泥處置批復 瀏覽:176
杭州水處理中心 瀏覽:846
假冒南亞環氧樹脂 瀏覽:890
垃圾中轉站污水處理流程 瀏覽:285
超濾膜1004工作原理圖 瀏覽:239
反滲透凈水機不往桶走水怎麼辦 瀏覽:792
反滲透膜清理 瀏覽:159
污水廠工作單位狀況 瀏覽:714
無紡布的過濾效率 瀏覽:206
凈水器使用時要開廢水開關嗎 瀏覽:618
水壺燒水有水垢能不能喝 瀏覽:880
石家莊橋東污水處理廠還有嗎 瀏覽:213
為什麼要先定容後過濾 瀏覽:500
反滲透膜管清洗劑 瀏覽:64