рдбрд┐рдмрдЧрд░ рд╕реАрдЦрдирд╛, рднрд╛рдЧ рджреЛ

рд▓реЗрдЦ рдХреЗ рдкрд╣рд▓реЗ рднрд╛рдЧ рдиреЗ рдПрдХреАрдХреГрдд рдбреЗрд▓реНрдлреА рдбрд┐рдмрдЧрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдХреБрдЫ рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рдХреА рдЬрд╛рдВрдЪ рдХреА - рд╕рднреА рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рдбреЗрд╡рд▓рдкрд░ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдЕрдм рдХрд╛рд░реНрдп рдереЛрдбрд╝рд╛ рдЕрд▓рдЧ рджрд┐рдЦрддрд╛ рд╣реИ: рдЕрдкрдиреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдВрджрд░ рд╕реЗ рдЗрд╕рдХреЗ рдХрд╛рдо рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рдПрдкреАрдЖрдИ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рд╕рд╛рде рдЖрдкрдХреЛ рдЕрдзрд┐рдХ рдмреЛрд░ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдФрд░ рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЗ рд╕рднреА рдЪрд░рдгреЛрдВ рдХреЛ рдЪрдмрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ, рдореИрдВ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ TFWDebugerCore рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕рдХреЗ рдХрд╛рдо рдХрд╛ рд╡рд░реНрдгрди рдХрд░реВрдВрдЧрд╛ред рдореИрдВ рдХреБрдЫ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдВрджреБрдУрдВ рдореЗрдВ рд╕реЗ рдХреБрдЫ рдХреЛ рдЫреЛрдбрд╝ рджреВрдВрдЧрд╛, рдпрджрд┐ рдЖрдк рдЪрд╛рд╣реЗрдВ, рддреЛ рдЖрдк рдЗрд╕ рд╡рд░реНрдЧ рдХреЗ рдХреЛрдб рдХреЛ рджреЗрдЦрдХрд░ рдЙрдиреНрд╣реЗрдВ рд╕реНрдкрд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдпрджрд┐ рдЖрдк рдбрд┐рдмрдЧрд░ рдХреЗ рдХрд╛рдо рд╕реЗ рдкрд╣рд▓реЗ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реИрдВ - рдпрд╣ рдареАрдХ рд╣реИ, рддреЛ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ рд▓реЗрдЦ рдореЗрдВ рдЙрд▓реНрд▓рд┐рдЦрд┐рдд рдЗрд╕рдХреЗ рдХрд╛рдо рдХреЗ рдХреБрдЫ рдкрд╣рд▓реВ рдЖрдкрдХреЗ рд▓рд┐рдП рд░реВрдЪрд┐ рдХреЗ рд╣реЛрдВрдЧреЗред

рдпрджрд┐ рдЖрдкрдиреЗ рдкрд╣рд▓реЗ рдбрд┐рдмрдЧрд░ рдХреЗ рдПрдХ рд╕реНрд╡рддрдВрддреНрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рд╕рд╛рдордирд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдХрдо рд╕реЗ рдХрдо рдЖрдкрдХреЛ рдЗрд╕ рд▓рд┐рдВрдХ рд╕реЗ рд╢реБрд░реВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП: рдбрд┐рдмрдЧрд┐рдВрдЧ рдФрд░ рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд┐рдВрдЧ
рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЖрдк рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЗ рдореБрдЦреНрдп рдкрд╣рд▓реБрдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рди рд╕рдХрддреЗ рд╣реИрдВ, рдЬреИрд╕реЗ рдЕрдкрд╡рд╛рджреЛрдВ рдХреА рд╕рдВрд░рдЪрдирд╛рддреНрдордХ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг, рдбрд┐рдмрдЧрд┐рдВрдЧ рдЬрд╛рдирдХрд╛рд░реА рдФрд░ рдорд┐рдиреАрдбрдВрдк рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ред рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдлрд╝рд╛рдЗрд▓, рд╣реЗрдбрд░, рдЕрдиреБрднрд╛рдЧ, рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдореЛрд░реА рдХрд╛рд░реНрдб рдХреА рдЫрд╡рд┐ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛, рдЖрд░рд╡реАрдП рдФрд░ рд╡реАрдП рдФрд░ рдЗрддрдиреЗ рдкрд░ рдХреНрдпрд╛ рд╣реИред
рд▓реЗрдХрд┐рди рдпрд╣ рдХреЗрд╡рд▓ рдЕрдЧрд░ рдЖрдк рдЗрд╕ рд░рд╕реЛрдИ рдХреЛ рд╕рдордЭрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

рдореИрдВ рдЗрд╕рдХрд╛ рдХреЗрд╡рд▓ рдПрдХ рд╕рд░рд▓ рднрд╛рд╖рд╛ рдореЗрдВ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛, рддрд╛рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдРрд╕рд╛ рдмрд┐рдВрджреБ рд╣реЛ рдЬрд┐рд╕рд╕реЗ рдЖрдк рдЕрдЪрд╛рдирдХ рд╕реЗ рджрд┐рд▓рдЪрд╕реНрдкреА рд▓реЗрдиреЗ рдкрд░ рдзрдХреНрдХрд╛ рджреЗ рд╕рдХреЗрдВ, рдФрд░ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдпрджрд┐ рдЖрдк рдЖрд╡реЗрджрди рд╕рдВрд░рдХреНрд╖рдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдХрдо рд╕реЗ рдХрдо рдбрд┐рдмрдЧрд░ рдХреА рдкреЗрдЪреАрджрдЧрд┐рдпреЛрдВ рдХреЛ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ (рдЕрдиреНрдпрдерд╛ рдХреИрд╕реЗ?)ред

рд▓реЗрдЦ рдХреЗ рдкрд╛рда рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдХреЛрдб рд╣реЛрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдореИрдВ рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреА рдШрдЯрдирд╛рдУрдВ рдХреЗ рд╣реЛрдиреЗ рдкрд░ рдкреНрд░рддреНрдпреЗрдХ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд╕рднреА рдорд╛рдкрджрдВрдбреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛, рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ MSDN рд╣реИред рдореИрдВ рдХреЗрд╡рд▓ рдХрд╛рдо рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдбрд┐рдмрдЧрд░ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реВрдВрдЧрд╛ рдФрд░ рдХреБрдЫ рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рдХреЛ рдкреНрд░рдХрдЯ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реВрдВрдЧрд╛ рдЬреЛ рдЖрдкрдХреЛ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реЛрдЧреА рдЬрдм рдЖрдк рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рдбрд┐рдмрдЧрд┐рдВрдЧ рдЗрдВрдЬрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд░рд╣реЗ рд╣реЛрдВрдЧреЗред

рдЖрдк рд╕реЗ, рдХреЛрдбрд╛рдВрддрд░рдХ рдХрд╛ рдХрдо рд╕реЗ рдХрдо рдиреНрдпреВрдирддрдо рдЬреНрдЮрд╛рди рд╣реЛрдирд╛ рд╡рд╛рдВрдЫрдиреАрдп рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЕрдлрд╕реЛрд╕, рдпрд╣ рд▓реЗрдЦ рдЗрд╕рдХреЗ рдмрд┐рдирд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ред



рдЪрд▓рд┐рдП рдбрд┐рдмрдЧрд░ рдХреЛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕реЗ рдЬреЛрдбрд╝рдХрд░ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:


рдПрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕реЗ рдЬреБрдбрд╝рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдбрд┐рдмрдЧрд┐рдВрдЧ рд╡рд┐рд╢реЗрд╖рд╛рдзрд┐рдХрд╛рд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓рд╛ рдХрджрдо рд╣реИред рдпрд╣ рдЗрд╕ рддрд░рд╣ рдХреЗ рд╕рд░рд▓ рдХреЛрдб рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

function SetDebugPriv: Boolean; var Token: THandle; tkp: TTokenPrivileges; begin Result := false; if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, Token) then begin if LookupPrivilegeValue(nil, PChar('SeDebugPrivilege'), tkp.Privileges[0].Luid) then begin tkp.PrivilegeCount := 1; tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; Result := AdjustTokenPrivileges(Token, False, tkp, 0, PTokenPrivileges(nil)^, PDWord(nil)^); end; end; end; 


рдЕрдЧрд▓рд╛ рдЪрд░рдг рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ: рдХреНрдпрд╛ рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рдЪрд▓ рд░рд╣реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛ рдЬрд╛рдПрдВрдЧреЗ, рдпрд╛ рд╣рдо рдЦрд░реЛрдВрдЪ рд╕реЗ рдПрдХ рдирдИ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╢реБрд░реВ рдХрд░реЗрдВрдЧреЗред

рдпрджрд┐ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкрд╣рд▓реЗ рд╕реЗ рдЪрд▓ рд░рд╣реА рд╣реИ рдФрд░ рд╣рдо рдЗрд╕рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдХреЗрд╡рд▓ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдкреАрдЖрдИрдбреА тАЛтАЛрдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛:

 function TFWDebugerCore.AttachToProcess(ProcessID: DWORD; SentEntryPointBreakPoint: Boolean): Boolean; begin Result := False; if FProcessInfo.ProcessID <> 0 then Exit; FSetEntryPointBreakPoint := SentEntryPointBreakPoint; FProcessInfo.ProcessID := ProcessID; Result := DebugActiveProcess(ProcessID); end; 


рд╕рдЪ рд╣реИ, рдпрд╣ рдХреЛрдб рд╣рдореЗрд╢рд╛ рдХрдо рд╕реЗ рдХрдо рджреЛ рдХрд╛рд░рдгреЛрдВ рд╕реЗ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред

рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рд╡рд┐рдВрдбреЛрдЬ рдореЗрдВ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рджреЛ рдбрд┐рдмрдЧрд░реНрд╕ рдХреЗ рд╕рд╛рде рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░рдирд╛ рдЕрд╕рдВрднрд╡ рд╣реИ, рдФрд░ рдпрджрд┐ рдХреЛрдИ рдбрд┐рдмрдЧрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╣рдорд╛рд░реА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ, рддреЛ рдбреАрдмрдЧрдПрдХреНрдЯрд┐рд╡рд╛рдЗрдкреНрд░реЛрд╕реЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рд╕рдлрд▓ рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдФрд░ GetLastError рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдПрдХ рддреНрд░реБрдЯрд┐ рдХреЛрдб рд▓реМрдЯрд╛рдПрдЧрд╛: ERROR_INVALID_PARAMETERред

рджреВрд╕рд░рд╛ рдХрд╛рд░рдг рдпрд╣ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╣рдореЗрдВ рдЬрд┐рд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рд╡рд╣ рдбрд┐рдмрдЧрд░ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЙрдЪреНрдЪ рд╡рд┐рд╢реЗрд╖рд╛рдзрд┐рдХрд╛рд░ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, DebugActiveProcess рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдХреЙрд▓ рднреА рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рдПрдЧрд╛, рдФрд░ GetLastError рдПрдХ рддреНрд░реБрдЯрд┐ рдХреЛрдб рд▓реМрдЯрд╛рдПрдЧрд╛: ERROR_ACCESS_DENIEDред

рджреВрд╕рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЖрдк рдЖрд╡рд╢реНрдпрдХ рд╡рд┐рд╢реЗрд╖рд╛рдзрд┐рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдбрд┐рдмрдЧрд░ рдЪрд▓рд╛рдХрд░ рдЗрд╕ рддреНрд░реБрдЯрд┐ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рджреВрд╕рд░рд╛ рд╡рд┐рдХрд▓реНрдк рдЗрд╕ рдХреЛрдб рдХреЗ рд╕рд╛рде рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╢реБрд░реВ рдХрд░рдХреЗ рдбрд┐рдмрдЧрд░ рдХреЛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд╕рдВрд▓рдЧреНрди рдХрд░рдирд╛ рд╣реИ:

 function TFWDebugerCore.DebugNewProcess(const FilePath: string; SentEntryPointBreakPoint: Boolean): Boolean; var PI: TProcessInformation; SI: TStartupInfo; begin Result := False; if FProcessInfo.ProcessID <> 0 then Exit; FSetEntryPointBreakPoint := SentEntryPointBreakPoint; ZeroMemory(@SI, SizeOf(TStartupInfo)); SI.cb := SizeOf(TStartupInfo); Result := CreateProcess(PChar(FilePath), nil, nil, nil, False, DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS, nil, nil, SI, PI); if Result then begin FProcessInfo.ProcessID := PI.dwProcessId; FProcessInfo.CreatedProcessHandle := PI.hProcess; FProcessInfo.CreatedThreadHandle := PI.hThread; end; end; 


рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИ, рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдореЗрдВ рд╣рдордиреЗ DEBUG_PROCESS рдзреНрд╡рдЬ рдХреЗ рд╕рд╛рде рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╢реБрд░реВ рдХреА рдФрд░ рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд DEBUG_ONLY_THIS_PROCESS рдзреНрд╡рдЬ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛, рдпрд╣ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдбреАрдмрдЧ рдХрд┐рдП рдЧрдП рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рдбреАрдмрдЧ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред
рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЗрд╕рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ (рдЙрдкрдпреЛрдЧреА) рдХреЛ рдпрд╛рдж рд░рдЦреЗрдВред

рдЬреИрд╕реЗ рд╣реА рд╣рдо рдПрдХ рдбрд┐рдмрдЧрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реБрдП, рдпрд╣ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЕрдкрдиреЗ рдЖрдк рд╣реА рдХрд╛рдо рдХрд░рдирд╛ рдмрдВрдж рдХрд░ рджреЗрддреА рд╣реИ рдФрд░ рдЕрдкрдиреА рдкреНрд░рддреНрдпреЗрдХ рдЧрддрд┐рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реА рдЯреАрдо рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдЧреА - рдЗрд╕реЗ рдЖрдЧреЗ рдХреНрдпрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╡рд╣ рдбрд┐рдмрдЧрд┐рдВрдЧ рдШрдЯрдирд╛рдУрдВ рдХреЛ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛ рдФрд░ рддрдм рддрдХ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдЧрд╛ рдЬрдм рддрдХ рд╣рдо рдЙрди рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдирд╣реАрдВ рдХрд░рддреЗред

рд╣рдо рдбреАрдмрдЧреНрдб рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕реЗ рдбреАрдмрдЧрд┐рдВрдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕реЗ WaitForDebugEvent рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рд╣рдо ContinueDebugEvent рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рдХрд┐рд╕реА рднреА рдЖрд╡рд╢реНрдпрдХ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдирд┐рдпрдВрддреНрд░рдг рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рд╣рдореЗрдВ рдлрд┐рд░ рд╕реЗ рдЕрдЧрд▓реЗ рдЗрд╡реЗрдВрдЯ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдПред
рдпрд╛рдиреА рдореЛрдЯреЗ рддреМрд░ рдкрд░, рд╣рдореЗрдВ рдПрдХ рдбреАрдмрдЧ рдЗрд╡реЗрдВрдЯ рд▓реВрдк рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рдПрдордПрд╕рдПрдирдбреА рдбрд┐рдмрдЧ рдЗрд╡реЗрдВрдЯ рд▓реВрдк рдХреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рд╕рд┐рдлрд╛рд░рд┐рд╢ рдХрд░рддрд╛ рд╣реИред

рдбрд┐рдмрдЧрд░ рдХрд╛ рдореБрдЦреНрдп рд▓реВрдк рд▓рд┐рдЦрдирд╛

рд╣рдо рдЕрдкрдиреЗ рдбрд┐рдмрдЧрд░ рдореЗрдВ рд▓рдЧрднрдЧ рд╕рдорд╛рди рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред

 procedure TFWDebugerCore.RunMainLoop; var DebugEvent: TDebugEvent; CallNextLoopIteration: Boolean; ThreadIndex: Integer; begin CallNextLoopIteration := False; repeat ContinueStatus := DBG_CONTINUE; if not WaitForDebugEvent(DebugEvent, MainLoopWaitPeriod) then begin if GetLastError = ERROR_SEM_TIMEOUT then begin DoIdle; if FProcessInfo.ProcessID = 0 then Exit; CallNextLoopIteration := True; Continue; end else begin DoMainLoopFailed; Break; end; end; case DebugEvent.dwDebugEventCode of CREATE_THREAD_DEBUG_EVENT: DoCreateThread(DebugEvent); CREATE_PROCESS_DEBUG_EVENT: DoCreateProcess(DebugEvent); EXIT_THREAD_DEBUG_EVENT: DoExitThread(DebugEvent); EXIT_PROCESS_DEBUG_EVENT: begin DoExitProcess(DebugEvent); Break; end; LOAD_DLL_DEBUG_EVENT: DoLoadDll(DebugEvent); UNLOAD_DLL_DEBUG_EVENT: DoUnLoadDll(DebugEvent); OUTPUT_DEBUG_STRING_EVENT: DoDebugString(DebugEvent); RIP_EVENT: DoRip(DebugEvent); EXCEPTION_DEBUG_EVENT: begin ThreadIndex := GetThreadIndex(DebugEvent.dwThreadId); case DebugEvent.Exception.ExceptionRecord.ExceptionCode of EXCEPTION_BREAKPOINT: ProcessExceptionBreakPoint(ThreadIndex, DebugEvent); EXCEPTION_SINGLE_STEP: ProcessExceptionSingleStep(ThreadIndex, DebugEvent); EXCEPTION_GUARD_PAGE: ProcessExceptionGuardPage(ThreadIndex, DebugEvent); else CallUnhandledExceptionEvents(ThreadIndex, CodeDataToExceptionCode( DebugEvent.Exception.ExceptionRecord.ExceptionCode), DebugEvent); end; end; end; CallNextLoopIteration := ContinueDebugEvent(DebugEvent.dwProcessId, DebugEvent.dwThreadId, ContinueStatus); until not CallNextLoopIteration; end; 


рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ, рд╣рдо рд▓рдЧрд╛рддрд╛рд░ рдЗрд╕ рдЪрдХреНрд░ рдХреЗ рдЕрдВрджрд░ рд░рд╣реЗрдВрдЧреЗ рдФрд░ рдЙрди рдШрдЯрдирд╛рдУрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░реЗрдВрдЧреЗ рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВред рдбреАрдмрдЧ рд▓реВрдк рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдкрд░ WaitForDebugEvent рдлрд╝рдВрдХреНрд╢рди DEBUG_EVENT рд╕рдВрд░рдЪрдирд╛ рджреЗрддрд╛ рд╣реИред рдЗрд╕ рд╕рдВрд░рдЪрдирд╛ рдХреЗ dwDebugEventCode рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рд╣рдо рдкреНрд░рд╛рдкреНрдд рдХрд┐рдП рдЧрдП рдИрд╡реЗрдВрдЯ рдХреЗ рдкреНрд░рдХрд╛рд░, рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЖрдИрдбреА рдФрд░ рдереНрд░реЗрдб рдХреА рдкрд╣рдЪрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдИрд╡реЗрдВрдЯ рдФрд░ рд╕рд╛рде рд╣реА рдкреНрд░рддреНрдпреЗрдХ рдИрд╡реЗрдВрдЯ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░, рдЗрд╕ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдЕрдВрддрд┐рдо рдХреНрд╖реЗрддреНрд░ рджреНрд╡рд╛рд░рд╛ рдпреВрдирд┐рдпрди рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ:

 PDebugEvent = ^TDebugEvent; _DEBUG_EVENT = record dwDebugEventCode: DWORD; dwProcessId: DWORD; dwThreadId: DWORD; case Integer of 0: (Exception: TExceptionDebugInfo); 1: (CreateThread: TCreateThreadDebugInfo); 2: (CreateProcessInfo: TCreateProcessDebugInfo); 3: (ExitThread: TExitThreadDebugInfo); 4: (ExitProcess: TExitProcessDebugInfo); 5: (LoadDll: TLoadDLLDebugInfo); 6: (UnloadDll: TUnloadDLLDebugInfo); 7: (DebugString: TOutputDebugStringInfo); 8: (RipInfo: TRIPInfo); end; {$EXTERNALSYM _DEBUG_EVENT} TDebugEvent = _DEBUG_EVENT; DEBUG_EVENT = _DEBUG_EVENT; {$EXTERNALSYM DEBUG_EVENT} 


рдкреНрд░рддреНрдпреЗрдХ рдШрдЯрдирд╛ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдЕрдкрдирд╛ рд╕реЗрдЯ рд╣реЛрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдо рдереЛрдбрд╝реА рджреЗрд░ рдмрд╛рдж рдЙрди рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реЗрдВрдЧреЗред

рдпрджрд┐ рдХрд┐рд╕реА рднреА рдШрдЯрдирд╛ рдХреЛ рд╣рдорд╛рд░реЗ рдХреЛрдб рджреНрд╡рд╛рд░рд╛ рд╕рдВрд╕рд╛рдзрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╣рдо рдмрд╕ рдЬрд╛рд░реА рд░рдЦрдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдбрд┐рдмрдЧрдбреНрдпреВрд╡реЗрдВрдЯ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ DBG_CONTINUE рдХреЛ ContinueStatus рдкреИрд░рд╛рдореАрдЯрд░ рд╕реЗрдЯ рдХрд░рдХреЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реИрдВред

Nuance: рдЕрдЧрд░ WaitForDebugEvent рдиреЗ рдПрдХ рддреНрд░реБрдЯрд┐ рд▓реМрдЯрд╛ рджреА (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЯрд╛рдЗрдордЖрдЙрдЯ рджреНрд╡рд╛рд░рд╛), рдЖрдкрдХреЛ ContinueDebugEvent рдХреЛ рдХреЙрд▓ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдпрд╣ рдПрдХ рддреНрд░реБрдЯрд┐ рднреА рд▓реМрдЯрд╛рдПрдЧрд╛ред рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░, рд╡реЗ рдЕрдХреНрд╕рд░ рдареЛрдХрд░ рдЦрд╛рддреЗ рд╣реИрдВ, рдбрд┐рдмрдЧрд░ рдХреЗ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдЗрд╕реЗ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрдирд╛ рди рднреВрд▓реЗрдВред

рдЕрдм рддрдХ, рд╕рдм рдХреБрдЫ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ, рдЕрдм рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдХреМрди рд╕реА рдШрдЯрдирд╛рдПрдВ рд╣рдореЗрдВ рджреЗрддреА рд╣реИрдВред

CREATE_PROCESS_DEBUG_EVENT:


рдбреАрдмрдЧрд┐рдВрдЧ рдкреНрд░рд╛рд░рдВрдн рд╣реЛрдиреЗ рдкрд░ рдбреАрдмрдЧрд░ рдХреЛ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдкрд╣рд▓реА рдкрд╣рд▓реА рдШрдЯрдирд╛ рд╣реЛрдЧреАред рдЗрд╕рд╕реЗ рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ рдХрд┐ рд╣рдордиреЗ рд╕реНрд╡рдпрдВ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╢реБрд░реВ рдХреА рд╣реИ, рдпрд╛ рдбреАрдмрдЧрдПрдХреНрдЯрд┐рд╡рдкреНрд░реЛрд╕реЗрд╕ рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рдЗрд╕рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛ рдЧрдП рд╣реИрдВ, рд╣рдо рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрдВрдЧреЗред рдЗрд╕ рдИрд╡реЗрдВрдЯ рдХреЗ рд▓рд┐рдП рдкреИрд░рд╛рдореАрдЯрд░ DebugEvent.CreateProcessInfo рд╕рдВрд░рдЪрдирд╛ (CREATE_PROCESS_DEBUG_INFO рд╕рдВрд░рдЪрдирд╛) рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИрдВ ред

рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдЗрд╕ рдИрд╡реЗрдВрдЯ рдХреЗ рд▓рд┐рдП рд╣реИрдВрдбрд▓рд░ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

 procedure TFWDebugerCore.DoCreateProcess(DebugEvent: TDebugEvent); begin //     FProcessInfo.AttachedFileHandle := DebugEvent.CreateProcessInfo.hFile; FProcessInfo.AttachedProcessHandle := DebugEvent.CreateProcessInfo.hProcess; FProcessInfo.AttachedThreadHandle := DebugEvent.CreateProcessInfo.hThread; FProcessInfo.EntryPoint := DWORD(DebugEvent.CreateProcessInfo.lpStartAddress); AddThread(DebugEvent.dwThreadId, FProcessInfo.AttachedThreadHandle); //  BreakPoint     if FSetEntryPointBreakPoint then SetBreakpoint(FProcessInfo.EntryPoint, 'Process Entry Point Breakpoint'); if Assigned(FCreateProcess) then begin FCreateProcess(Self, GetThreadIndex(DebugEvent.dwThreadId), DebugEvent.CreateProcessInfo); DoResumeAction(GetThreadIndex(DebugEvent.dwThreadId)); end; end; 


рдЗрд╕рдореЗрдВ, рд╣рдо рдмрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдпрд╛рдж рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЖрдВрддрд░рд┐рдХ рд╕реВрдЪреА рдореЗрдВ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдореБрдЦреНрдп рдзрд╛рдЧреЗ рдХреА рдЖрдИрдбреА рдФрд░ рд╣реИрдВрдбрд▓ рднреА рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред рдпреЗ рдбреЗрдЯрд╛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдмрд╛рдж рдореЗрдВ рдЙрдкрдпреЛрдЧреА рд╣реЛрдВрдЧреЗред

рдпрд╣рд╛рдВ рд╣рдо рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдмрд┐рдВрджреБ (рдПрдВрдЯреНрд░реА рдкреНрд╡рд╛рдЗрдВрдЯ) рднреА рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рдХрд╛ рдорд╛рди DebugEvent.CreateProcessInfo.lpStartAddres рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рджрд░реНрдЬ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░, рдпрджрд┐ рд╡рд╛рдВрдЫрд┐рдд рд╣реИ, рддреЛ рдЕрдкрдиреЗ рдкрддреЗ рдкрд░ рдПрдХ рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ (рдмрд╛рдж рдореЗрдВ рдмреАрдкреА рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрджрд░реНрднрд┐рдд) рд╕реЗрдЯ рдХрд░реЗрдВ рдФрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╢реБрд░реВ рдХрд░реЗрдВред рдпрджрд┐ рдЖрдк рдереЛрдбрд╝реЗ рдореЛрдЯреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдХреНрд░рд┐рдпрд╛ рдХрд░рдХреЗ рд╣рдо F7 рдмрдЯрди рджрдмрд╛рддреЗ рд╣реА рдбреЗрд▓реНрдлреА рдбреАрдмрдЧрд░ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░реЗрдВрдЧреЗред

рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рдХреНрдпрд╛ рд╣реИ: рдЬрдм рд▓реЛрдбрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдмрдирд╛рддрд╛ рд╣реИ, рдЬрдм рддрдХ рдХрд┐ рдЬрдм рдпрд╣ рд╢реБрд░реВ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рддрдм рддрдХ рдХрдИ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдХреНрд░рд┐рдпрд╛рдПрдВ рдХреА рдЬрд╛рддреА рд╣реИрдВред рдЖрд╡реЗрджрди рдХрд╛ рдореБрдЦреНрдп рдзрд╛рдЧрд╛ рдмрдирд╛рдирд╛, рд╕реНрдЯреИрдХ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛, рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкрд░реНрдпрд╛рд╡рд░рдг / рдереНрд░реЗрдб рдмреНрд▓реЙрдХ, рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЛ рд▓реЛрдб рдХрд░рдирд╛, рдЙрдирдХреЗ рдЯреАрдПрд▓рдПрд╕ рдХреЙрд▓рдЧрд░реНрд▓реНрд╕ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛, рдЖрджрд┐ред рдпрд╣ рд╕рдм рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рд╣реА, рд▓реЛрдбрд░ рд╣рд╕реНрддрд╛рдВрддрд░рдг рд╕реАрдзреЗ рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рдХрд░рддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рд╕реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рджреНрд╡рд╛рд░рд╛ рд▓рд╛рдЧреВ рдХреЛрдб рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╢реБрд░реВ рд╣реЛ рд░рд╣рд╛ рд╣реИред рдЗрд╕ рдмрд┐рдВрджреБ рдХрд╛ рдкрддрд╛ рдкреАрдИ рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╣реЗрдбрд░ рдореЗрдВ рд╕реАрдзреЗ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рд╕реЗ рдЗрд╕реЗ рдкреАрдИ рдлрд╝рд╛рдЗрд▓ рдХреА рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХрд┐рд╕реА рднреА рдПрдкреНрд▓рд┐рдХреЗрд╢рди рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП PEiD рдпрд╛ PeExplorer, рдпрд╛ рдЖрдк рдЗрд╕ рдорд╛рди рдХреЛ рд╕реНрд╡рдпрдВ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдлрд╝рд╛рдЗрд▓ рдХреЗ рдмрд╣реБрдд рд╢реБрд░реБрдЖрдд рдореЗрдВ рд╕реНрдерд┐рдд TIIAGEDosHeader рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдкрдврд╝рдХрд░, рдЗрд╕рдХреЗ _lfanew рдлрд╝реАрд▓реНрдб рдХреЛ рдСрдлрд╕реЗрдЯ рдХрд░реЗрдЧрд╛ред TImageNtHeaders рд╢реБрд░реВ рдХрд░реЗрдВ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж TImageNtHeaders рд╕рдВрд░рдЪрдирд╛ рдХреЛ рд╕реНрд╡рдпрдВ рдкрдврд╝реЗрдВ рдФрд░ рдЗрд╕рдХреЗ TImageNtHeaders.OptionalHeader.AddressOfEntryPoint рдлрд╝реАрд▓реНрдб рдХрд╛ рдорд╛рди рджреЗрдЦреЗрдВред

рдПрдХ рдЦрд╛рд▓реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ, рдФрд░ рдЗрд╕рдореЗрдВ F7 рджрдмрд╛рдПрдВ, рдФрд░ рдлрд┐рд░ рд╕реАрдкреАрдпреВ-рд╡реНрдпреВ рдЯреИрдм рдкрд░ рдЬрд╛рдПрдВ, рдпрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП:

рдЫрд╡рд┐

рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рдкрддрд╛ рдирд┐рдХрд▓рд╛: 0x0043E2D4ред рдЕрдм рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ PEiD рд╣рдореЗрдВ рдкрд░рд┐рдгрд╛рдореА рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛ рдмрддрд╛рддрд╛ рд╣реИ:

рдЫрд╡рд┐

рд╡рд╣ рдХрд╣рддреЗ рд╣реИрдВ рдХрд┐ рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рдорд╛рди 0x0003E2D4 рд╣реИред

рд╣рд╛рд▓рд╛рдБрдХрд┐ рдпрд╣ рдЙрд╕ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде рдореЗрд▓ рдирд╣реАрдВ рдЦрд╛рддрд╛, рдЬрд┐рд╕реЗ рд╣рдордиреЗ рдбрд┐рдмрдЧрд░ рдореЗрдВ рджреЗрдЦрд╛ рдерд╛, рдлрд┐рд░ рднреА, рд╕рдм рдХреБрдЫ рдпрд╣рд╛рдБ рдареАрдХ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ AddressOfEntryPoint рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдорд╛рди RVA (рд╕рд╛рдкреЗрдХреНрд╖ рд╡рд░реНрдЪреБрдЕрд▓ рдкрддрд╛) рдХреЗ рд░реВрдк рдореЗрдВ рджрд░реНрд╢рд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕ рдкрддреЗ рдХреА рдЦрд╝рд╛рд╕рд┐рдпрдд рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рд╣рдорд╛рд░реЗ рдореЙрдбреНрдпреВрд▓ (hInstance) рдХреЗ рд▓реЛрдб рдкрддреЗ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рдирд╣реАрдВ рд░рдЦрддрд╛ рд╣реИред RVA рдкрддреЗ рд╕реЗ VA (рд╡рд░реНрдЪреБрдЕрд▓ рдПрдбреНрд░реЗрд╕) рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЗрд╕рдореЗрдВ hInstance рдореЙрдбреНрдпреВрд▓ рдХреЛ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ред

рдПрдХ рдЕрддрд┐ рд╕реВрдХреНрд╖реНрдо рдЕрдВрддрд░ рд╣реИ: рдпрд╣ рдХреЗрд╡рд▓ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдЪ рд╣реИ, рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдпрд╣ рдереЛрдбрд╝рд╛ рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдЙрдирдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЕрдиреБрднрд╛рдЧреЛрдВ рдХреЗ рдкрддреЗ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕ рдбреЗрдореЛ рдореЗрдВ рдЕрдзрд┐рдХ рд╡рд┐рд╡рд░рдг рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ: "рдлрд╝рд╛рдЗрд▓ рдЧреБрдгреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдмреБрдХрдорд╛рд░реНрдХ" ред
рдЗрд╕рдореЗрдВ, DebugHlp.pas рдореЙрдбреНрдпреВрд▓ рдореЗрдВ, ImageRvaToVa () рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдПрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ рдЖрдк рдХрд╛рд╕реНрдЯрд┐рдВрдЧ рдкрддреЗ рдХреЗ рдирд┐рдпрдореЛрдВ рдХрд╛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЕрдзреНрдпрдпрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЦреИрд░, рдЖрд╡реЗрджрди рдХреЗ рд▓рд┐рдП, рдЖрдзрд╛рд░ рдбрд╛рдЙрдирд▓реЛрдб рдкрддрд╛ рд╣рдореЗрд╢рд╛ рдЗрдореЗрдЬ рдмреЗрд╕ рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рд▓рд┐рдВрдХрд░ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдореЗрдВ рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдореВрд▓реНрдп рдХреЗ рдмрд░рд╛рдмрд░ рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рдХрд┐ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ 0x00400000 рд╣реИред рдЗрди рджреЛ рдирдВрдмрд░реЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдкрд░, рд╣рдореЗрдВ рдХреЗрд╡рд▓ рдЖрд╡рд╢реНрдпрдХ 0x0043E2D4 рдорд┐рд▓рддрд╛ рд╣реИред

LOAD_DLL_DEBUG_EVENT:


CREATE_PROCESS_DEBUG_EVENT рдХреЗ рддреБрд░рдВрдд рдмрд╛рдж, рд╣рдо DebugEvent.LoadDll рд╕рдВрд░рдЪрдирд╛ (LOAD_DLL_DEBUG_INFIN рд╕рдВрд░рдЪрдирд╛) рдореЗрдВ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде, рдкреБрд╕реНрддрдХрд╛рд▓рдп рд▓реЛрдбрд┐рдВрдЧ рдШрдЯрдирд╛рдУрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрдВрдЧреЗ ред

рд╕рд╛рдорд╛рдиреНрдп рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рд╣рдо рдбреЗрд▓реНрдлреА рдбрд┐рдмрдЧрд░ рдореЗрдВ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реАрдХреНрд╖рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдЗрд╡реЗрдВрдЯ рдореЗрдВ рд▓реЛрдб рд╣реЛрдиреЗ рдХреА рд╕реВрдЪрдирд╛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ:

рдЫрд╡рд┐

рдЗрд╕ рдШрдЯрдирд╛ рдХреЗ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдиреЗ рдкрд░, рдбреЗрд▓реНрдлреА рдбреАрдмрдЧрд░, рдпрджрд┐ рдмреАрдкреА рдореЙрдбреНрдпреВрд▓ рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдЗрд╕реЗ рд▓реЛрдб рд╣реЛрдиреЗ рдХреЗ рддреБрд░рдВрдд рдмрд╛рдж рдмрд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЫрд╡рд┐

рд╣рдо рдЗрд╕ рдХреЛрдб рдХреЗ рд╕рд╛рде рдПрдХ рдореЙрдбреНрдпреВрд▓ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рднреА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 procedure TFWDebugerCore.DoLoadDll(DebugEvent: TDebugEvent); begin if Assigned(FLoadDll) then begin FLoadDll(Self, GetThreadIndex(DebugEvent.dwThreadId), DebugEvent.LoadDll); DoResumeAction; end; CloseHandle(DebugEvent.LoadDll.hFile); end; 


рдЬрд┐рд╕рдореЗрдВ, рдШрдЯрдирд╛ рдХреЛ рдмрдврд╝рд╛рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рддреБрд░рдВрдд рд▓реЛрдб рдХрд┐рдП рдЧрдП рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рд╣реИрдВрдбрд▓ рдХреЛ рдмрдВрдж рдХрд░ рджреЗрддреЗ рд╣реИрдВ, рд╣рдореЗрдВ рдЕрдм рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрдЧреА (рдбрд┐рдмрдЧрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдЗрд╕ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ)ред

рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рдпрд╣ рд╣реИ: рдбрд┐рдмрдЧEvent.LoadDll.lpImageName рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд▓реЛрдб рдХрд┐рдП рдЧрдП рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд▓рд┐рдП рдкрде рдХреЗ рд╕рд╛рде рдкрддрд╛, рд╣рдорд╛рд░реЗ рдкрддрд╛ рд╕реНрдерд╛рди рдореЗрдВ рд╕реНрдерд┐рдд рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдЗрд╕реЗ ReadcesscessMemory рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрдврд╝рдирд╛ рд╣реЛрдЧрд╛ред
рджреВрд╕рд░реА рдмрд╛рд░реАрдХрд┐рдпреЛрдВ: рдпрд╣ рдорд╛рди рдПрдХ рдмрдлрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХреЗрддрдХ рднреА рд╣реИ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдкрде рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдбреЗрдЯрд╛ рд╕реНрдерд┐рдд рд╣реИрдВ, рдЕрд░реНрдерд╛рддред рдХрдо рд╕реЗ рдХрдо рджреЛ рдмрд╛рд░ рдкрдврд╝рдирд╛ рд╣реИред
рддреАрд╕рд░рд╛ рдХреИрд╡рд┐рдПрдЯ: рдкрде рджреЛрдиреЛрдВ Ansii рдФрд░ рдпреВрдирд┐рдХреЛрдб рдПрдиреНрдХреЛрдбрд┐рдВрдЧ рдореЗрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред
рдареАрдХ рд╣реИ, рдПрдХ рдирд╛рд╢реНрддреЗ рдХреЗ рд▓рд┐рдП, рдЪреМрдерд╛ рдХреИрд╡реЗрдЯ: рд╣рдо рдбреЗрдЯрд╛ рдирд╣реАрдВ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ :)

рд▓реЛрдб рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рд▓рд┐рдП рдПрдХ рд╡реИрдз рдорд╛рд░реНрдЧ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, TFWDebugerCore рд╡рд░реНрдЧ GetDllName рд╡рд┐рдзрд┐ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдЗрди рд╕рднреА рдмрд┐рдВрджреБрдУрдВ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддрд╛ рд╣реИред

рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред
TFWDebugerCore рд╡рд░реНрдЧ рдмрд╛рд╣рд░реА OnLoadDll рдШрдЯрдирд╛ рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рд╣рдореЗрдВ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд▓реЛрдб рдХрд░рдиреЗ рдХреА рд╕реВрдЪрдирд╛ рджреЗрдЧрд╛, рдЬрд╣рд╛рдВ рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рд▓рд┐рдЦреЗрдВрдЧреЗ:

 procedure TdlgDebuger.OnLoadDll(Sender: TObject; ThreadIndex: Integer; Data: TLoadDLLDebugInfo); const FormatStrKnownDLL = 'Load Dll at instance %p handle %d "%s"'; FormatStrUnknownDLL = 'Load unknown Dll at instance %p handle %d'; var DllName: AnsiString; IsUnicodeData: Boolean; begin FCore.ContinueStatus := DBG_EXCEPTION_NOT_HANDLED; IsUnicodeData := Data.fUnicode = 1; DllName := FCore.GetDllName(Data.lpImageName, Data.lpBaseOfDll, IsUnicodeData); if DllName <> '' then begin if IsUnicodeData then Writeln(Format(FormatStrKnownDLL, [Data.lpBaseOfDll, Data.hFile, PWideChar(@DllName[1])])) else Writeln(Format(FormatStrKnownDLL, [Data.lpBaseOfDll, Data.hFile, PAnsiChar(@DllName[1])])); end else Writeln(Format(FormatStrUnknownDLL, [Data.lpBaseOfDll, Data.hFile])); end; 


рдпрд╣рд╛рдВ, рд╣рдо TFWDebugerCore.GetDllName () рд╡рд┐рдзрд┐ рдХреЛ рдХрд╣рддреЗ рд╣реИрдВ рдФрд░ (рдлрд╝реНрдпреВрдирд┐рдХреЛрдб рдкреИрд░рд╛рдореАрдЯрд░ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рддреЗ рд╣реБрдП) рдбреЗрдЯрд╛ рдХреЛ рдХрдВрд╕реЛрд▓ рдкрд░ рдкреНрд░рд┐рдВрдЯ рдХрд░рддреЗ рд╣реИрдВред

GetDllName рд╡рд┐рдзрд┐ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:

 function TFWDebugerCore.ReadData(AddrPrt, ResultPtr: Pointer; DataSize: Integer): Boolean; var Dummy: DWORD; begin Result := ReadProcessMemory(FProcessInfo.AttachedProcessHandle, AddrPrt, ResultPtr, DataSize, Dummy) and (Integer(Dummy) = DataSize); end; function TFWDebugerCore.ReadStringA(AddrPrt: Pointer; DataSize: Integer): AnsiString; begin SetLength(Result, DataSize); if not ReadData(AddrPrt, @Result[1], DataSize) then Result := ''; end; function GetMappedFileNameA(hProcess: THandle; lpv: Pointer; lpFilename: LPSTR; nSize: DWORD): DWORD; stdcall; external 'psapi.dll'; function TFWDebugerCore.GetDllName(lpImageName, lpBaseOfDll: Pointer; var Unicode: Boolean): AnsiString; var DllNameAddr: Pointer; MappedName: array [0..MAX_PATH - 1] of AnsiChar; begin if ReadData(lpImageName, @DllNameAddr, 4) then Result := ReadStringA(DllNameAddr, MAX_PATH); if Result = '' then begin if GetMappedFileNameA(FProcessInfo.AttachedProcessHandle, lpBaseOfDll, @MappedName[0], MAX_PATH) > 0 then begin Result := PAnsiChar(@MappedName[0]); Unicode := False; end; end; end; 


рдпрд╣реА рд╣реИ, рдкрд╣рд▓реЗ рд╣рдо рдбрд┐рдмрдЧ рдХреА рдЧрдИ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдкрддрд╛ рд╕реНрдерд╛рди (ReadData + ReadStringA) рд╕реЗ рдбреЗрдЯрд╛ рдкрдврд╝рдХрд░ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рд░рд╛рд╕реНрддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдпрджрд┐ рдпрд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рддреЛ рд╣рдо GetMappedFameNameA рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рдЗрд╕ рдбреЗрдЯрд╛ рдХреЛ рд▓реЗрддреЗ рд╣реИрдВред рдпрд╣ рдкреНрд░рддреАрдХрд╛рддреНрдордХ рд▓рд┐рдВрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбреЗрдЯрд╛ рджреЗрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЕрдЪреНрдЫреЗ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдЕрднреА рднреА рд╕рд╛рдорд╛рдиреНрдп рдкрде рдкрд░ рд▓рд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдореИрдВрдиреЗ рдРрд╕рд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛, рддрд╛рдХрд┐ рдХреЛрдб рдХреЛ рдЬрдЯрд┐рд▓ рди рдХрд░реЗрдВред

CREATE_THREAD_DEBUG_EVENT


рд╣рдо рдЗрд╕ рдШрдЯрдирд╛ рдХреЛ рдЙрд╕ рд╕рдордп рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗ рдЬрдм рдбрд┐рдмрдЧ рдХрд┐рдП рдЧрдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдПрдХ рдирдпрд╛ рдзрд╛рдЧрд╛ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рдИрд╡реЗрдВрдЯ рдХреЗ рд▓рд┐рдП рдкреИрд░рд╛рдореАрдЯрд░ DebugEvent.CreateThread рд╕рдВрд░рдЪрдирд╛ (CREATE_THREAD_DEBUG_INFO рд╕рдВрд░рдЪрдирд╛) рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИрдВ ред

рд╕рднреА рдорд╛рдкрджрдВрдбреЛрдВ рдореЗрдВ рд╕реЗ, рд╣рдо DebugEvent.CreateThread.hThread рдореЗрдВ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ рдЖрдВрддрд░рд┐рдХ рд╕реВрдЪреА рдореЗрдВ рд╕рд╣реЗрдЬрдирд╛ рд╡рд╛рдВрдЫрдиреАрдп рд╣реИред

рд╕реВрдХреНрд╖реНрдорддрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЕрдзрд┐рдХрд╛рдВрд╢ рдШрдЯрдирд╛рдУрдВ рдореЗрдВ рдХреЗрд╡рд▓ рдереНрд░реЗрдб рдХреА рдЖрдИрдбреА рдкрд░ рдбреЗрдЯрд╛ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдЬрдм рд╣рдо рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рд╛рд░реНрдбрд╡реЗрдпрд░ рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ), рддреЛ рд╣рдореЗрдВ рдкреНрд░реЗрд╖рд┐рдд рдЖрдИрдбреА рдкрд░ рдПрдХ рдУрдкрдирдереНрд░реЗрдб рдХреЙрд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЗрди рдХрд╛рд░реНрдпреЛрдВ рд╕реЗ рдкрд░реЗрд╢рд╛рди рди рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдереНрд░реЗрдбрд┐рдб = рдереНрд░реЗрдбрд╣реИрдВрдбрд▓ рдЬреЛрдбрд╝реЗ рдХреЛ рдЕрдкрдиреЗ рдХреИрд╢ рдореЗрдВ рд░рдЦреЗрдВрдЧреЗред

рдЗрд╕ рдШрдЯрдирд╛ рдХреЗ рд▓рд┐рдП рд╣реИрдВрдбрд▓рд░ рдХреЛрдб рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:

 procedure TFWDebugerCore.DoCreateThread(DebugEvent: TDebugEvent); begin AddThread(DebugEvent.dwThreadId, DebugEvent.CreateThread.hThread); if Assigned(FCreateThread) then begin FCreateThread(Self, GetThreadIndex(DebugEvent.dwThreadId), DebugEvent.CreateThread); DoResumeAction; end; end; 


рдзрд╛рдЧреЗ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдмрдЪрд╛рдиреЗ рдФрд░ рдмрд╛рд╣рд░реА рд╣реИрдВрдбрд▓рд░ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЗрд╕рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИред

OUTPUT_DEBUG_STRING_EVENT:


рдпрд╣ рдШрдЯрдирд╛ рдЙрд╕ рд╕рдордп рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИ рдЬрдм рдбреАрдмрдЧ рдХрд┐рдП рдЧрдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЖрдЙрдЯрдкреБрдЯрдбрдмрдЧрд╕реНрдЯреНрд░рд┐рдВрдЧ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╕рдВрд╡рд╛рдж рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реИред рдЗрд╕ рдИрд╡реЗрдВрдЯ рдХреЗ рд▓рд┐рдП рдкреИрд░рд╛рдореАрдЯрд░ DebugEvent.DebugString рд╕рдВрд░рдЪрдирд╛ (OUTPUT_DEBUG_STRING_INFO рд╕рдВрд░рдЪрдирд╛) рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИрдВ ред

рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рд╕рд░рд▓ рд╣реИ:

 procedure TFWDebugerCore.DoDebugString(DebugEvent: TDebugEvent); begin if Assigned(FDebugString) then begin FDebugString(Self, GetThreadIndex(DebugEvent.dwThreadId), DebugEvent.DebugString); DoResumeAction; end; end; 


рдпрд╛рдиреА рд╣рдо рд╕рд┐рд░реНрдл рдмрд╛рд╣рд░реА рд╣реИрдВрдбрд▓рд░ рдХреЛ рдХрд╣рддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рд╣рдореЗрдВ рдЙрд╕реА рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдкреНрд░реЗрд╖рд┐рдд рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдкрдврд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рд▓реЛрдб рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд▓рд┐рдП рдкрде рдкрдврд╝рддреЗ рд╣реИрдВред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ рддрд░рд╣:

 procedure TdlgDebuger.OnDebugString(Sender: TObject; ThreadIndex: Integer; Data: TOutputDebugStringInfo); begin if Data.fUnicode = 1 then Writeln('DebugString: ' + PWideChar(FCore.ReadStringW(Data.lpDebugStringData, Data.nDebugStringLength))) else Writeln('DebugString: ' + PAnsiChar(FCore.ReadStringA(Data.lpDebugStringData, Data.nDebugStringLength))); end; 


рд╣реИрдВрдбрд▓рд░ рдореЗрдВ, рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдбреЗрдЯрд╛ рдХреЛ рдлрд╝реЛрдХрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдлрд╝рд░ рдХреЛ рдХреНрдпрд╛ рд░рдЦрд╛ рдЧрдпрд╛ рд╣реИред Data.fUnicode рдкреИрд░рд╛рдореАрдЯрд░ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рддреЗ рд╣реБрдП рдФрд░ рдбреАрдмрдЧрд░ рдХреЛрд░ ReadStringX () рдХреЗ рд╕рдВрдЧрдд рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВред

UNLOAD_DLL_DEBUG_EVENT, EXIT_THREAD_DEBUG_EVENT, EXIT_PROCESS_DEBUG_EVENT, RIP_EVENT:


рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рд▓реЛрдб рдХрд░рдирд╛, рдереНрд░реЗрдб рдХреЛ рдмрдВрдж рдХрд░рдирд╛, рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рдирд╛, рдФрд░ рдбреАрдмрдЧрд░ рдХреА рдХрд░реНрдиреЗрд▓ рдореЗрдВ рддреНрд░реБрдЯрд┐ред
рдЗрди рдЪрд╛рд░ рдШрдЯрдирд╛рдУрдВ рдХреЛ рдореИрдВ рдЫреЛрдбрд╝ рджреВрдВрдЧрд╛ред рдЙрдирдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рдЕрд╕рд╛рдзрд╛рд░рдг рдирд╣реАрдВ рд╣реИред рдЙрдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдиреЗ рдкрд░, рдмрд╛рд╣рд░реА рд╣реИрдВрдбрд▓рд░ рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдбреАрдмрдЧрд░ рджреНрд╡рд╛рд░рд╛ рд╕рдВрдЧреНрд░рд╣реАрдд рдЖрдВрддрд░рд┐рдХ рд╕реВрдЪрд┐рдпреЛрдВ рдХреЛ рд╕рд╛рдл рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЙрдирдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рдХреЛрдИ рдмрд╛рд░реАрдХрд┐рдпрд╛рдВ рдирд╣реАрдВ рд╣реИрдВред

EXCEPTION_DEBUG_EVENT:


рдЙрдкрд░реЛрдХреНрдд рд╕рднреА рдЖрда рдШрдЯрдирд╛рдПрдБ, рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рджреНрд╡рд┐рддреАрдпрдХ рд╣реИрдВред EXCEPTION_DEBUG_EVENT рдИрд╡реЗрдВрдЯ рдХреЗ рдЖрдиреЗ рдХреЗ рдмрд╛рдж рд╣реА рдореБрдЦреНрдп рдХрд╛рд░реНрдп рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред
рдЗрд╕рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ DebugEvent.Exception рд╕рдВрд░рдЪрдирд╛ (EXCEPTION_DEBUG_INFO рд╕рдВрд░рдЪрдирд╛) рдкрд░ рдЬрд╛рддреЗ рд╣реИрдВ ред

рдЗрд╕ рдШрдЯрдирд╛ рдХреА рдкреАрдврд╝реА рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдбрд┐рдмрдЧ рдХрд┐рдП рдЧрдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдЕрдкрд╡рд╛рдж рдЙрддреНрдкрдиреНрди рд╣реБрдЖ, рдЬрд┐рд╕рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ DebugEvent.Exception.ExceptionRecord.ExceptionCode рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╛рдж рд░рдЦреЗрдВ, рд▓реЗрдЦ рдХреЗ рдкрд╣рд▓реЗ рднрд╛рдЧ рдореЗрдВ рдореИрдВрдиреЗ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рд╣реИ рдХрд┐ рд╕рдВрд░рдЪрд┐рдд рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд┐рдВрдЧ (рдПрд╕рдИрдПрдЪ) рддрдВрддреНрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдбрд┐рдмрдЧрд┐рдВрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ? рдЕрдм рд╣рдо рдЗрд╕ рдкрд░ рдФрд░ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗред

рдбрд┐рдмрдЧрд┐рдВрдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдЕрдзрд┐рдХрд╛рдВрд╢ рдЕрдкрд╡рд╛рдж рдЗрдВрдЧрд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рдпрд╣реА рд╣реИ, рдЕрдкрд╡рд╛рдж рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдорддрд▓рдм рдпрд╣ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ рдПрдХ рддреНрд░реБрдЯрд┐ рд╣реБрдИ рд╣реИред рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ рдЖрд╡реЗрджрди рдореЗрдВ рдбрд┐рдмрдЧрд░ рдХреЗ рд╣рд╕реНрддрдХреНрд╖реЗрдк рдХреЗ рдХрд╛рд░рдг рдЕрдкрд╡рд╛рдж рд╣реБрдЖ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдмреАрдкреА рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдХреЗред

Nuance: рдпрджрд┐ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рд╣реЛрддреА рд╣реИ, рддреЛ рд╣рдо рдЗрд╕реЗ рдбрд┐рдмрдЧрд┐рдВрдЧ рдЕрдкрд╡рд╛рдж рдХреЗ рд░реВрдк рдореЗрдВ рднреА рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗ рдФрд░ рд╣рдореЗрдВ рдбрд┐рдмрдЧрд░ рдХреЛрдб рдХреЛ рдЗрд╕ рддрд░рд╣ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рдХрд┐ рд╣рдо рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рддреНрд░реБрдЯрд┐рдпреЛрдВ рд╕реЗ рдЕрдкрдиреА рдкреНрд░реЗрд░рд┐рдд рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЕрд▓рдЧ рдХрд░ рд╕рдХреЗрдВред

рдЖрдорддреМрд░ рдкрд░, рдбреАрдмрдЧрд░ рдмреАрдкреА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреАрди рддрдВрддреНрд░ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ (рдареАрдХ рд╣реИ, рдпрджрд┐ рдЖрдк рдореЙрдбреНрдпреВрд▓ рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмреАрдкреА рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рдирд╣реАрдВ рд░рдЦрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рд╕реБрд╡рд┐рдзрд╛ рдХреНрд▓рд╛рд╕рд┐рдХ рдмреАрдкреА рдирд╣реАрдВ рд╣реИ)ред

  1. рдХреЛрдб рдХреА рдкреНрд░рддрд┐ рд▓рд╛рдЗрди рдорд╛рдирдХ рдмреА.рдкреА.
  2. рдмреАрдкреА рдХреЛ рдореЗрдореЛрд░реА рдПрдбреНрд░реЗрд╕ (рдореЗрдореЛрд░реА рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рдпрд╛ рдбреЗрд▓реНрдлреА рдореЗрдВ рдбреЗрдЯрд╛ рдХреНрд░рд┐рдкреНрдЯрдкреЙрдЗрдВрдЯ рдХрд╛рдЯ рджрд┐рдпрд╛ рдЧрдпрд╛)ред
  3. рд╣рд╛рд░реНрдбрд╡реЗрдпрд░ рдмреАрдкреА (рдбреЗрд▓реНрдлреА рдореЗрдВ рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ)ред


рдЙрдирдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рддреАрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ:

 EXCEPTION_DEBUG_EVENT: begin ThreadIndex := GetThreadIndex(DebugEvent.dwThreadId); case DebugEvent.Exception.ExceptionRecord.ExceptionCode of EXCEPTION_BREAKPOINT: ProcessExceptionBreakPoint(ThreadIndex, DebugEvent); EXCEPTION_SINGLE_STEP: ProcessExceptionSingleStep(ThreadIndex, DebugEvent); EXCEPTION_GUARD_PAGE: ProcessExceptionGuardPage(ThreadIndex, DebugEvent); else CallUnhandledExceptionEvents(ThreadIndex, CodeDataToExceptionCode( DebugEvent.Exception.ExceptionRecord.ExceptionCode), DebugEvent); end; end; 


рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХреЗрд╡рд▓ рдпреЗ рддреАрди рдЕрдкрд╡рд╛рдж рдкрд░реНрдпрд╛рдкреНрдд рдХреНрдпреЛрдВ рд╣реИрдВ, рдЖрдкрдХреЛ EXCEPTION_DEBUG_EVENT рдШрдЯрдирд╛ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддрд░реНрдХ рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд╕рд╛рде рдЖрдЧреЗ рдмрдврд╝рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдмреАрдкреА рдХреЛ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддрдВрддреНрд░ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рдХреЛрдб рдХреА рдПрдХ рдкрдВрдХреНрддрд┐ рдкрд░ рдПрдХ рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рд▓рд╛рдЧреВ рдХрд░рдирд╛:

рдХреЛрдб рдХреА рдПрдХ рдкрдВрдХреНрддрд┐ рдкрд░ рдмреАрдкреА рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛ рдбрд┐рдмрдЧ рдХрд┐рдП рдЧрдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдХреЛрдб рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╢рд╛рд╕реНрддреНрд░реАрдп рд░реВрдк рд╕реЗ, рдпрд╣ рдмреАрдкреА рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдкрддреЗ рдкрд░ 0xCC рдУрдкрдХреЛрдб рд▓рд┐рдЦрдХрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдирд┐рд░реНрджреЗрд╢ "INT3"ред

рдЕрдиреНрдп рд╡рд┐рдХрд▓реНрдк рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, 0xCD03 рдУрдкрдХреЛрдб, рдЬреЛ рдПрдХ "INT3" рдирд┐рд░реНрджреЗрд╢ рднреА рд╣реИред рджреВрд╕рд░рд╛ рд╡рд┐рдХрд▓реНрдк рдПрдВрдЯреА-рдбрд┐рдмрдЧрд┐рдВрдЧ рдореЗрдВ рдЕрдзрд┐рдХ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЕрдзрд┐рдХрд╛рдВрд╢ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рджреНрд╡рд╛рд░рд╛ рд╣реА рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕ рддрдереНрдп рдкрд░ рдбрд┐рдмрдЧрд░ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реИ рдХрд┐ рдкрд░рдорд╛рдгреБ _KiTrap03 () рдХреЗрд╡рд▓ рдПрдХрд▓-рдмрд╛рдЗрдЯ рдХреЛрдб рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдереЛрдбрд╝рд╛ рдЧрд▓рдд рддрд░реАрдХреЗ рд╕реЗ рдбрдмрд▓-рдмрд╛рдЗрдЯ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд░рддрд╛ рд╣реИред

рд▓реЗрдХрд┐рди, рдпрд╣ рд╕рдм рдЧреАрдд рд╣реИ, рд╣рдо рдкрд╣рд▓реЗ opcode рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВред

рд╕реНрдерд╛рдкрд┐рдд BPs рдХреА рд╕реВрдЪреА рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, TFWDebugerCore рд╡рд░реНрдЧ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ:

 //      ( ) TBreakpointType = ( btBreakpoint, // WriteProcessMemoryEx + 0xCC btMemoryBreakpoint // VirtualProtectEx + PAGE_GUARD ); //         TInt3Breakpoint = record Address: Pointer; ByteCode: Byte; end; TMemotyBreakPoint = record Address: Pointer; Size: DWORD; BreakOnWrite: Boolean; RegionStart: Pointer; RegionSize: DWORD; PreviosRegionProtect: DWORD; end; TBreakpoint = packed record bpType: TBreakpointType; Description: ShortString; Active: Boolean; case Integer of 0: (Int3: TInt3Breakpoint;); 1: (Memory: TMemotyBreakPoint); end; TBreakpointList = array of TBreakpoint; 


рдПрдХ рдирдпрд╛ рдмреАрдкреА рдЬреЛрдбрд╝рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╡рд╣ рдЯреАрдмреАрдЯреНрд░реИрдХрдкреЙрдЗрдВрдЯ рд░рд┐рдХреЙрд░реНрдб рдХреЛ рдЖрд░рдВрдн рдХрд░рддрд╛ рд╣реИ, рдЗрд╕реЗ рдЖрд╡рд╢реНрдпрдХ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рднрд░рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рдХреА рд╕рд╛рдорд╛рдиреНрдп рд╕реВрдЪреА рдореЗрдВ рдЬреЛрдбрд╝рддрд╛ рд╣реИред

рдХреЛрдб рдХреА рдПрдХ рдкрдВрдХреНрддрд┐ рдкрд░ рдмреАрдкреА рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдХреЗрд╡рд▓ рджреЛ рдорд╛рди рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдмреАрдкреА рдХрд╛ рдкрддрд╛ рдФрд░ рдЗрд╕ рдкрддреЗ рдкрд░ рд╕рдВрдЧреНрд░рд╣реАрдд рдмрд╛рдЗрдЯ рдХрд╛ рдореВрд▓реНрдп 0xCC opcode рдХреЗ рд╕рд╛рде рдорд┐рдЯрд╛ рджреЗрддрд╛ рд╣реИред

рдбреАрдмрдЧ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдореЗрдВ BP рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

 function TFWDebugerCore.SetBreakpoint(Address: DWORD; const Description: string): Boolean; var Breakpoint: TBreakpoint; OldProtect: DWORD; Dummy: DWORD; begin ZeroMemory(@Breakpoint, SizeOf(TBreakpoint)); Breakpoint.bpType := btBreakpoint; Breakpoint.Int3.Address := Pointer(Address); Breakpoint.Description := Description; Check(VirtualProtectEx(FProcessInfo.AttachedProcessHandle, Pointer(Address), 1, PAGE_READWRITE, OldProtect)); try Check(ReadProcessMemory(FProcessInfo.AttachedProcessHandle, Pointer(Address), @Breakpoint.Int3.ByteCode, 1, Dummy)); Check(WriteProcessMemory(FProcessInfo.AttachedProcessHandle, Pointer(Address), @BPOpcode, 1, Dummy)); finally Check(VirtualProtectEx(FProcessInfo.AttachedProcessHandle, Pointer(Address), 1, OldProtect, OldProtect)); end; Result := AddNewBreakPoint(Breakpoint); end; 


рдкреНрд░рд╛рд░рдВрдн рдореЗрдВ, рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдкреНрд░рд╛рд░рдВрдн рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдмреАрдкреА рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рдХрд╛ рд╡рд┐рд╡рд░рдг рдФрд░ рдкреИрд░рд╛рдореАрдЯрд░ред рдХреЛрдб рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд▓рд┐рдЦрдиреЗ рдХреЗ рдмрд╛рдж, рдЬрд┐рд╕рдореЗрдВ рдЖрдорддреМрд░ рдкрд░ рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рд╕рдВрдмрдВрдзрд┐рдд рдЕрдзрд┐рдХрд╛рд░ рд╕реЗрдЯ рд╣реЛрддреЗ рд╣реИрдВ, рдкрддрд╛ BP рдкрд░ рд╕реНрдерд┐рдд рдореВрд▓ рдорд╛рди рдкрдврд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ, BPOpcode рдирд┐рд░рдВрддрд░ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╕реНрддреБрдд 0xCC рдирд┐рд░реНрджреЗрд╢ рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдореВрд▓ рдкреГрд╖реНрда рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдБ VirtualProtectEx () рдХреЛ рдмрд╛рд░-рдмрд╛рд░ рдХреЙрд▓ рдХрд░рдХреЗ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рддреА рд╣реИрдВред рд╕рдм рдХреБрдЫ рдХреЗ рдЕрдВрдд рдореЗрдВ, рдпрджрд┐ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рд╣реБрдИ рд╣реИ, рддреЛ рд╕реНрдерд╛рдкрд┐рдд рдмреАрдкреА рдХрд╛ рд░рд┐рдХреЙрд░реНрдб рдХрдХреНрд╖рд╛ рдХреА рд╕рд╛рдорд╛рдиреНрдп рд╕реВрдЪреА рдореЗрдВ рд░рдЦрд╛ рдЧрдпрд╛ рд╣реИред

рдЦреИрд░, рдЕрдм рдордЬрд╝рд╛ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ:

рдмреАрдкреА рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдбрд┐рдмрдЧ рдХрд┐рдП рдЧрдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЕрдкрдиреЗ рд╕рд╛рдорд╛рдиреНрдп рдСрдкрд░реЗрд╢рди рдХреЛ рдЬрд╛рд░реА рд░рдЦреЗрдВрдЧреЗ, рдЬрдм рддрдХ рдХрд┐ рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рджрд░реНрдЬ рдХрд┐рдП рдЧрдП INT3 рдирд┐рд░реНрджреЗрд╢ рдореЗрдВ рд╕рдВрдХреНрд░рдордг рди рд╣реЛ рдЬрд╛рдПред рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░, EXCEPTION_DEBUG_EVENT рдИрд╡реЗрдВрдЯ рдЕрдкрд╡рд╛рдж рдХреЛрдб EXCEPTION_BREAKPOINT рдХреЗ рд╕рд╛рде рдЙрдард╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдЕрдкрд╡рд╛рдж рдкреИрд░рд╛рдореАрдЯрд░ рд╣рдореЗрдВ рдбрд┐рдмрдЧ-рдИрд╡реЗрдВрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЕрдкрд╡рд╛рдж.ExceptionRecord (EXCEPTION_DEBUG_INFO рд╕рдВрд░рдЪрдирд╛)ред

рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рдмрддрд╛рдпрд╛, рдмреАрдкреА рдХреЛ рдбреАрдмрдЧ рдХрд┐рдП рдЧрдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рджреНрд╡рд╛рд░рд╛ рд╣реА рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП, рдЗрди рдорд╛рдкрджрдВрдбреЛрдВ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рддреЗ рд╣реБрдП, рдЖрдкрдХреЛ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдмреАрдкреА рдХрд┐рд╕ рддрд░рд╣ рдХрд╛ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ?

рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╕рд╣реЗрдЬреЗ рдЧрдП рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯреНрд╕ рдХреА рдПрдХ рд╕реВрдЪреА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдЗрд╕рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓рдиреЗ рдФрд░ DebugEvent.Exception.Exception.ecception.ExceptionRecord.ExceptionAddress рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдкрддреЗ рдХреА рддреБрд▓рдирд╛ рдкреНрд░рдХрд╛рд░ btBreakpoint рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рдкрддрд╛ рдлрд╝реАрд▓реНрдб рдХреЗ рд╕рд╛рде, рд╣рдо рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рд╣рдо рдЗрд╕ рдкрддреЗ рдкрд░ рдмреАрдкреА рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдпрд╛ рдпрд╣ рдХреБрдЫ рд╣рдорд╛рд░рд╛ рдирд╣реАрдВ рд╣реИред

рдпрджрд┐ рд╣рдордиреЗ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рд╣реИ рдХрд┐ рдмреАрдкреА рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╣рдорд╛рд░рд╛ рд╣реИ, рддреЛ рд╣рдо рдПрдХ рдмрд╛рд╣рд░реА рдШрдЯрдирд╛ рдХреЛ рдмрдврд╝рд╛рддреЗ рд╣реИрдВ (рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рд╣рдо рд╕рд┐рд░реНрдл рдпрд╣рд╛рдВ рдирд╣реАрдВ рд╣реИрдВ, рдмрд▓реНрдХрд┐ рдХрд╛рдо рднреА рдХрд░ рд░рд╣реЗ рд╣реИрдВ) рдФрд░ рдЗрд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдбрд┐рдмрдЧ рдХрд┐рдП рдЧрдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВред

рдмреАрдкреА рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкрд░рд┐рдгрд╛рдо: рдмреАрдкреА рд╕реНрдерд╛рдкрд┐рдд

рдХрд░рдХреЗ, рд╣рдордиреЗ рдХреБрдЫ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдХреЛрдб рдЦреЛ рджрд┐рдП рд╣реИрдВред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдХреЛрдб рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдерд╛:

рдЫрд╡рд┐

рд╣рдорд╛рд░реЗ рдЬреЛрдбрд╝рддреЛрдбрд╝ рдХреЗ рдмрд╛рдж, рдпрд╣ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдореЗрдВ рдмрджрд▓ рдЧрдпрд╛:

рдЫрд╡рд┐

рдкрд╣рд▓рд╛ рдХрджрдо рдореВрд▓ рдирд┐рд░реНрджреЗрд╢ рдХреЗ рдЕрд░реНрде рдХреЛ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛ рд╣реИред

рдЗрд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, TBreakpoint рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдПрдХ рд╕рдХреНрд░рд┐рдп рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИ рдЬреЛ рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдкреИрд░рд╛рдореАрдЯрд░ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рддреЗ рд╣реБрдП, TFWDebugerCore рд╡рд░реНрдЧ рдЙрдирдХреА рдЧрддрд┐рд╡рд┐рдзрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирддрд╛ рд╣реИ, рдФрд░ рд░рд╛рдЬреНрдп рдХреЛ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ ToggleInt3Breakpoint рд╡рд┐рдзрд┐ рдХреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдзреНрд╡рдЬ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдмреАрдкреА рдХреЛ рдЪрд╛рд▓реВ рдФрд░ рдмрдВрдж рдХрд░ рджреЗрддрд╛ рд╣реИ, рдорд┐рдЯрд╛рдП рдЧрдП рдмрд╛рдЗрдЯ рдХреЛ рдЕрдкрдиреА рдЬрдЧрд╣ рдкрд░ рд▓реМрдЯрд╛рддрд╛ рд╣реИред

 procedure TFWDebugerCore.ToggleInt3Breakpoint(Index: Integer; Active: Boolean); var OldProtect: DWORD; Dummy: DWORD; begin CheckBreakpointIndex(Index); if FBreakpointList[Index].bpType <> btBreakpoint then Exit; if FBreakpointList[Index].Active = Active then Exit; Check(VirtualProtectEx(FProcessInfo.AttachedProcessHandle, FBreakpointList[Index].Int3.Address, 1, PAGE_READWRITE, OldProtect)); try if Active then Check(WriteProcessMemory(FProcessInfo.AttachedProcessHandle, FBreakpointList[Index].Int3.Address, @BPOpcode, 1, Dummy)) else Check(WriteProcessMemory(FProcessInfo.AttachedProcessHandle, FBreakpointList[Index].Int3.Address, @FBreakpointList[Index].Int3.ByteCode, 1, Dummy)); finally Check(VirtualProtectEx(FProcessInfo.AttachedProcessHandle, FBreakpointList[Index].Int3.Address, 1, OldProtect, OldProtect)); end; FBreakpointList[Index].Active := Active; end; 


рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд▓рдЧрднрдЧ рдмреАрдкреА рд╕реЗрдЯ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреЛрдб рдХреЗ рд╕рдорд╛рди рд╣реИ, рдЗрд╕ рддрдереНрдп рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдХрд┐ рдЬрдм рдЖрдк рдмреАрдкреА рдХреЛ рдлрд┐рд░ рд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдмрд╛рдЗрдЯ рдорд╛рди рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрдврд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ (рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЬрд╛рдирддреЗ рд╣реИрдВ)ред

рдЕрдм рдЪреЗрддрд╛рд╡рдиреА: рдпрджрд┐ рд╣рдо рдбрд┐рдмрдЧ рдХрд┐рдП рдЧрдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдЕрднреА рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдПрдХ рддреНрд░реБрдЯрд┐ рдорд┐рд▓рддреА рд╣реИред рдФрд░ рд╕рднреА рдХреНрдпреЛрдВрдХрд┐ "INT3" рдирд┐рд░реНрджреЗрд╢ рдХреЛ рдкрд╣рд▓реЗ рд╣реА рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рдЪреБрдХрд╛ рд╣реИ, рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЕрдЧрд░ рд╣рдордиреЗ рдЙрд╕ рдмрд╛рдЗрдЯ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рджрд┐рдпрд╛ рдЬрд┐рд╕реЗ рд╣рдордиреЗ 0x452220 рдкрд░ рдЬрдЧрд╣ рдкрд░ рдкрд╣рдирд╛ рдерд╛, рддреЛ рдбрд┐рдмрдЧ рдХрд┐рдП рдЧрдП рдкреНрд░реЛрдЧреНрд░рд╛рдо 0x452221 рдкрддреЗ рд╕реЗ рдирд┐рд╖реНрдкрд╛рджрди рдЬрд╛рд░реА рд░рдЦреЗрдВрдЧреЗ, рдЬрд╣рд╛рдВ "рдореВрд╡ рдПрдм, рдПрд╕реНрдк" рдирд┐рд░реНрджреЗрд╢ рд╕реНрдерд┐рдд рд╣реИ, рдФрд░ рдЬрд╣рд╛рдВ рд╕реЗ рдпрд╣ рдирд╣реАрдВ рдерд╛ред рдбрд┐рдмрдЧ рдЕрдкрд╡рд╛рдж рдХреЛ рдлреЗрдВрдХ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

рджреВрд╕рд░реА рдмрд╛рд░реАрдХрд┐рдпреЛрдВ: рдЖрдк рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЗрд╕ рджрд┐рд╢рд╛ рдореЗрдВ рд╕рдкрдирд╛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ: "рдареАрдХ рд╣реИ, рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪреЛ -" рдкреБрд╢ рдПрдмрдк "рд╡рд┐рдлрд▓ рд░рд╣рд╛, рдареАрдХ рд╣реИ, рдвреЗрд░ рджреВрд░ рдЪрд▓рд╛ рдЧрдпрд╛, рд▓реЗрдХрд┐рди рд╣рдо рдПрдХ рдбрд┐рдмрдЧрд░ рд╣реИрдВ рдФрд░ рдЕрдЧрд░ рдХреБрдЫ рдЖ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рд╕рдм рдХреБрдЫ рдареАрдХ рдХрд░ рд╕рдХрддрд╛ рд╣реИ ..."ред рддреЛ рдпрд╣ рдореВрд▓ рд░реВрдк рд╕реЗ рд╕рд╣реА рд╣реИ, рдПрдХ рдмрд┐рдВрджреБ рдХреЛ рдЫреЛрдбрд╝рдХрд░ред

рд╣рд╛рдВ, рдпрд╣ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рд╣реИ рдХрд┐ рд╣рдо рдПрдХ рдбрд┐рдмрдЧрд░ рдХреЗ рд░реВрдк рдореЗрдВ, рд╕реНрдЯреИрдХ рд╣реЗрдбрд░ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЕрдзреВрд░реЗ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдкрд░ рдзреНрдпрд╛рди рдирд╣реАрдВ рджреЗ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕ рддрд░рд╣ рдХреА рдПрдХ рдЪрд╛рд▓ рд╣реИ, рдЬрд┐рд╕реЗ рдЕрдХреНрд╕рд░ рдПрдВрдЯреА-рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ рдбрд┐рд╕реНрд╕реИрдореНрдмрд▓рд░ рдХреЛ рдирд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рдЙрджреНрджреЗрд╢реНрдп рд╕реЗ, рдбрд┐рдмрдЧрд░ рдЗрд╕реЗ рдиреЛрдЯрд┐рд╕ рднреА рдирд╣реАрдВ рдХрд░реЗрдЧрд╛) рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рдмреАрдЪ рдореЗрдВред

рдпрд╣ рдХреНрдпрд╛ рд╣реИ:

рдпрд╣ рддрдХрдиреАрдХ рдЗрд╕ рддрдереНрдп рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ рдХрд┐ рдбрд┐рд╕реНрд╕реЗрдореНрдмрд▓рд░ рд╣рдореЗрд╢рд╛ рдорд╢реАрди рдХреЛрдб рдХреА рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЦрд╛рд╕рдХрд░ рдЕрдЧрд░ рдпрд╣ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдбрд┐рд╕реНрдХ рдХреЛ рднреНрд░рдорд┐рдд рдХрд░рдиреЗ рдХреЗ рдЙрджреНрджреЗрд╢реНрдп рд╕реЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИред

рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ, рдХрд╛рдлреА рдХрдо рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдРрд╕реА рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреЛ "рд▓рдВрдмреЗ рдПрдирдУрдкреА" рдХреЗ рд░реВрдк рдореЗрдВ рдЬрд╛рдирддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрдХ рдпрд╛ рдбреЗрдврд╝ рдпрд╛ рджреЛ рд╕рд╛рд▓ рдкрд╣рд▓реЗ рдпрд╣ рдЗрдВрдЯреЗрд▓ рдХреЗ рдореИрдиреБрдЕрд▓ рдореЗрдВ рдирд╣реАрдВ рдерд╛, рдЬрд╣рд╛рдВ рдпрд╣ рдХрд╣рд╛ рдЧрдпрд╛ рдерд╛ рдХрд┐ рдПрдирдУрдкреА (рдХреЛрдб рдХреЛ рд╕рдВрд░реЗрдЦрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдиреЗ рд╡рд╛рд▓рд╛ рдПрдХ рдЦрд╛рд▓реА рдирд┐рд░реНрджреЗрд╢) рдХреЗрд╡рд▓ 0x90 рдУрдкрдХреЛрдб рдХреЗ рд░реВрдк рдореЗрдВ рджрд┐рдЦрддрд╛ рд╣реИред рддрджрдиреБрд╕рд╛рд░, рдЕрдзрд┐рдХрд╛рдВрд╢ рдЕрд╕рдВрддреБрд╖реНрдЯ рдХреЗрд╡рд▓ рдЗрд╕ рдУрдкрдХреЛрдб рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рд╛рдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдмрд╣реБрдордд рдХреНрдпреЛрдВ - рдореИрдВ рдЕрднреА рддрдХ рдПрдХ рдбрд┐рд╕реНрд╕реЗрдореНрдмрд▓рд░ рд╕реЗ рдирд╣реАрдВ рдорд┐рд▓рд╛ рд╣реВрдВ рдЬреЛ рд▓рдВрдмреЗ рдкреИрд░реЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкрд╣рдЪрд╛рдирддрд╛ рд╣реИред

рдЪреВрдВрдХрд┐ рдбрд┐рд╕реНрд╕реЗрдореНрдмрд▓рд░ рдЗрд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдирд╣реАрдВ рдкрд╣рдЪрд╛рди рд╕рдХрддрд╛ рд╣реИ, рд╣рдо рдирд┐рдореНрди рдЪрд╛рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рддреАрди-рдмрд╛рдЗрдЯ рдПрдирдУрдкреА (рдУрдкрдХреЛрдб $ 0F, $ 1F, $ 00) рд▓реЗрдВ рдФрд░ рдЗрд╕ рдХреЛрдб рдХреЛ рд▓рд┐рдЦреЗрдВ:

 asm db $0F, $1F, $00 xor eax, eax inc eax neg eax end; 


рдФрд░ рдпрд╣рд╛рдВ рд╡рд╣ рд╣реИ рдЬреЛ

рдЫрд╡рд┐

рдбрд┐рд╕реНрд╕реЗрдореНрдмрд▓рд░ рд╣рдореЗрдВ рджрд┐рдЦрд╛рдПрдЧрд╛: рд╕рднреА рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рдСрдкреНрд╕реЛрдб рд╕рд╣реА рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдбрд┐рд╕реНрд╕реЗрдореНрдмрд▓рд░ рд╣рдореЗрдВ рд╡рд╣ рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдЬреЛ рд╣рдордиреЗ рд╢реБрд░реВ рдореЗрдВ рдирд╣реАрдВ рд▓рд┐рдЦрд╛ рдерд╛ред

рдЦреИрд░, рдпрд╛ рджреВрд╕рд░рд╛ рдЙрджрд╛рд╣рд░рдг, рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕реАрдзреЗ рдХреВрдж рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реИред рдпрд╣рд╛рдВ рдпрд╣ рд╡рд┐рдЪрд╛рд░ рдЗрд╕ рддрдереНрдп рдореЗрдВ рдирд┐рд╣рд┐рдд рд╣реИ рдХрд┐ рдЕрдЧрд▓реЗ рдирд┐рд░реНрджреЗрд╢ рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ рдкрд╣рд▓реЗ, рдмрд┐рд▓реНрдХреБрд▓ рдмрд╛рдПрдВ рдмрд╛рдЗрдЯ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдкрд╣рд▓реЗ рдирд┐рд░реНрджреЗрд╢ рдХреЛрдб "jmp +1" рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рдЗрд╕ рдХрдЪрд░рд╛ рдмрд╛рдЗрдЯ рдХреЛ рдЫреЛрдбрд╝ рдХрд░ рд╕реАрдзреЗ рд╡рд╛рдВрдЫрд┐рдд рдХреЛрдб рдкрд░ рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдпрд╣ рдПрдХ рднрдпрд╛рд╡рд╣ рдмрд╛рдд рдкреНрд░рддреАрдд рд╣реЛрддреА рд╣реИ - рд▓реЗрдХрд┐рди рдЕрд╕рдВрддреБрд╖реНрдЯ рдХрд╛рдлреА рднреНрд░рд╛рдордХ рд╣реИред

рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ, рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рд▓рд┐рдЦреЗрдВрдЧреЗ:

 asm db $EB, $01 // jmp +1 (  xor  " ") db $B8 //   ""  xor eax, eax //   inc eax neg eax not eax sub edx, eax imul eax, edx nop nop end; 


рдЕрдм рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ disassembler рд╣рдореЗрдВ рдХреНрдпрд╛ рджрд┐рдЦрд╛рддрд╛ рд╣реИ:

рдЫрд╡рд┐

рдкреВрд░реНрдг рдХрдЪрд░рд╛, рдЬреИрд╕рд╛ рдХрд┐ рдЕрдкреЗрдХреНрд╖рд┐рдд рдерд╛ред

рддреЛ, рдореИрдВрдиреЗ рдпрд╣ рд╕рдм рдХреНрдпрд╛ рдмрддрд╛рдпрд╛: рдЖрдЗрдП рдЕрдкрдиреЗ рдмреАрдкреА рдкрд░ рд╡рд╛рдкрд╕ рдЬрд╛рдПрдВ рдФрд░ рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рдЗрд╕реЗ 0x452220 рдкрд░ рдирд╣реАрдВ рдмрд▓реНрдХрд┐ рдиреМ рдмрд╛рдЗрдЯреНрд╕ рдореЗрдВ рдЖрдЧреЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдмрд╕ рдкреБрд╢ $ 00452245 рдирд┐рд░реНрджреЗрд╢ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВред

рдпрд╣ рдирд┐рд░реНрджреЗрд╢, рд╕рд┐рдВрдЧрд▓-рдмрд╛рдЗрдЯ "рдкреБрд╢ рдПрдкрдм" рдХреЗ рд╡рд┐рдкрд░реАрдд, рдкрд╛рдВрдЪ рдмрд╛рдЗрдЯреНрд╕ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдорд┐рдЯрд╛рдП рдЧрдП рдмрд╛рдЗрдЯ рдХреЗ рдореВрд▓реНрдп рдХреА рд╡рд╕реВрд▓реА рдХреЗ рдмрд╛рдж рднреА, рдЕрдЧрд░ рд╣рдо рдХреЛрдб рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдирд┐рд░реНрджреЗрд╢ рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдЗрд╕рдХреЗ рдмреАрдЪ рд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдВрдЧреЗ, рдФрд░ рдпрд╣рд╛рдВ рдпрд╣ рдЕрд╕рд╣рдорддрд┐ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдбреАрдмрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдЦреБрдж рд╣реА рдЧрд▓рдд рд╣реЛрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдХреЗ рд▓рд┐рдП рдпрд╣ рдХреЛрдб рдЕрдм рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреА рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛ред рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ:

рдЫрд╡рд┐

рдпрд╛рдиреАрдореВрд▓ "рдкреБрд╢ $ 00452245" рдХреЗ рдмрдЬрд╛рдп, рдирд┐рд░реНрджреЗрд╢ "inc epb" рдФрд░ "рдФрд░ al, [ebp + $ 00]" рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЬреЛ рдпрд╣рд╛рдВ рдирд╣реАрдВ рдереЗред рдФрд░ рдХреБрдЫ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рдмрд╛рдж, рд╣рдореЗрдВ рд╡рд╣ рдорд┐рд▓рддрд╛ рд╣реИ рдЬреЛ рдЕрдкреЗрдХреНрд╖рд┐рдд рдерд╛ - рдПрдХ рддреНрд░реБрдЯрд┐ред

рдЗрд╕рд▓рд┐рдП, рдорд┐рдЯрд╛рдП рдЧрдП рдмрд╛рдЗрдЯ рдХреЛ рдЙрд╕рдХреЗ рд╕реНрдерд╛рди рдкрд░ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИ, рдЖрдкрдХреЛ рдбрд┐рдмрдЧ рдХрд┐рдП рдЧрдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд╕рд╣реА рдкрддреЗ рд╕реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЬрд╛рд░реА рд░рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЕрдЧрд▓реЗ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдЕрдиреБрджреЗрд╢ рдХрд╛ рдкрддрд╛ рдИрдЖрдИрдкреА (рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдирд┐рд░реНрджреЗрд╢ рд╕реВрдЪрдХ) рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рд░рдЬрд┐рд╕реНрдЯрд░ рддрдХ рдкрд╣реБрдВрдЪ рдбреАрдмрдЧ рдХреА рдЧрдИ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдереНрд░реЗрдб рд╕рдВрджрд░реНрдн рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╡реНрдпрд╡рдзрд╛рди рдЙрддреНрдкрдиреНрди рд╣реБрдЖред EIP рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗ рдореВрд▓реНрдп рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ GetThreadContext рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рд╕рдВрджрд░реНрдн рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, Context.Eip рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╡рд░реНрддрдорд╛рди рдореВрд▓реНрдп рдХреЛ рдХрдо рдХрд░реЗрдВ, рдФрд░ рдлрд┐рд░ SetThreadContext рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рдирдпрд╛ рдорд╛рди рд▓рд┐рдЦреЗрдВред

рдПрдХ рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рд╣реИ: рдЬрдм EXCEPTION_DEBUG_EVENT рдШрдЯрдирд╛ рд╣реЛрддреА рд╣реИ, рддреЛ рд╣рдореЗрдВ рдХреЗрд╡рд▓ рдбрд┐рдмрдЧEvent.dwTreadId рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рдереНрд░реЗрдб рдЖрдИрдбреА, рдФрд░ GetThreadContext () рдФрд░ SetThreadContext () рдлрд╝рдВрдХреНрд╢рди рдЙрдирдХреЗ рдХрд╛рдо рдХреЗ рд▓рд┐рдП рдПрдХ рдереНрд░реЗрдб рд╣реИрдВрдбрд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЖрдИрдбреА рдЙрдирдХреЗ рд▓рд┐рдП рджрд┐рд▓рдЪрд╕реНрдк рдирд╣реАрдВ рд╣реИред рдмреЗрд╢рдХ, рдЖрдк OpenThread рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рдЖрд╡рд╢реНрдпрдХ рдорд╛рди рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рд╣рдореЗрдВ рдРрд╕рд╛ рдирд╣реАрдВ рдХрд░рдирд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдереНрд░реЗрдбрдЖрдИрдбреА = рдереНрд░реЗрдбрд╣реИрдВрдбрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдереНрд░реЗрдб рд╣реИрдВрдбрд▓ рдХреА рдПрдХ рд╕рд╣реЗрдЬреА рдЧрдИ рд╕реВрдЪреА рд╣реИред

рдЕрдм рд╣рдореЗрдВ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рдорд┐рдЯрд╛рдП рдЧрдП рдмрд╛рдЗрдЯ рдХреЛ рдмрд╣рд╛рд▓ рдХрд░ рджрд┐рдпрд╛ рд╣реИ, рдирд┐рд░реНрджреЗрд╢ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рдкрддрд╛ рд╕реЗрдЯ рдХрд┐рдпрд╛ рд╣реИ, рдФрд░ рд╣рдо рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрдХреНрд░рдо рднреА рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдПрдХ рдФрд░ рд╣реИред рдФрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдмреАрдкреА рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдордиреЗ 0xCC рдУрдкреЛрдб рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреЗ рдмрд╛рдж, рдмреАрдкреА рд░рд┐рдХреЙрд░реНрдб рдХреЗрд╡рд▓ рдбреАрдмрдЧрд░ рд╕реВрдЪрд┐рдпреЛрдВ рдореЗрдВ рдмрдирд╛ рд░рд╣рд╛, рд▓реЗрдХрд┐рди рдбреАрдмрдЧ рдХрд┐рдП рдЧрдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдирд╣реАрдВ рд╣реИ? рдпрджрд┐ рд╣рдо рдЕрднреА рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рд╡рд░реНрддрдорд╛рди рдирд┐рд░реНрджреЗрд╢ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдЧрд╛ рдФрд░ рдмрд┐рдирд╛ рд░реБрдХреЗ рдЕрдЧрд▓реЗ рдПрдХ рдкрд░ рдЪрд▓реЗрдЧрд╛, рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛрдб рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦреЗрдЧрд╛ рдЬрдм рддрдХ рдХрд┐ рдпрд╣ рдХрд┐рд╕реА рдЕрдиреНрдп рдмреАрдкреА рдпрд╛ рддреНрд░реБрдЯрд┐ рдореЗрдВ рдирд╣реАрдВ рдЪрд▓рддрд╛ред

рдЗрд╕рд▓рд┐рдП рдпрд╣ рдХрд╛рд░реНрдп рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛, рд╣рдореЗрдВ рдХрд┐рд╕реА рддрд░рд╣ рдирд┐рд░реНрджреЗрд╢ рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рддреБрд░рдВрдд рдмрд╛рдж рдбрд┐рдмрдЧрд░ рдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЯреНрд░рд╛рдВрд╕рдлрд░ рдХрдВрдЯреНрд░реЛрд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рд╣рдордиреЗ рдмреАрдкреА рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдерд╛ред рдпрджрд┐ рд╣рдо рд╕рдлрд▓ рд╣реЛрддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдмреАрдкреА рдХреЛ рдЙрд╕рдХреЗ рд╕рд╣реА рд╕реНрдерд╛рди рдкрд░ рд▓реМрдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдХрдИ рд╕рдорд╛рдзрд╛рди рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рд╡рд░реНрддрдорд╛рди рдирд┐рд░реНрджреЗрд╢ рдХреЗ рдЖрдХрд╛рд░ рдХреА рдЧрдгрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЕрдЧрд▓реЗ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдПрдХ рдирдпрд╛ рдЕрд╕реНрдерд╛рдпреА рдмреАрдкреА рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рд▓рдВрдмрд╛рдИ рдбрд┐рд╕реНрд╕реЗрдореНрдмрд▓рд░ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛, рдЙрд╕ рдХреНрд╖рдг рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦреЗрдВ рдХрд┐ рдмреАрдкреА рдХреЛ рдЕрдЧрд▓реЗ рдирд┐рд░реНрджреЗрд╢ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЖрджрд┐ред рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рд╕рд╣реА рдирд┐рд░реНрдгрдп рдирд╣реАрдВ рд╣реИред

рдФрд░ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рд╕рд╣реА рд╕рдорд╛рдзрд╛рди рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЛ рдЯреНрд░реЗрд╕ рдореЛрдб рдореЗрдВ рд░рдЦрдирд╛ рд╣реИред
рдкреНрд░реЛрд╕реЗрд╕рд░ рдзреНрд╡рдЬ рдЗрд╕ рдореЛрдб рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рдпрджрд┐ рдпрд╣ рдзреНрд╡рдЬ рд╕рдХреНрд╖рдо рд╣реИ, рддреЛ рдкреНрд░рддреНрдпреЗрдХ рдирд┐рд░реНрджреЗрд╢ рдПрдХ "INT1" рд╡реНрдпрд╡рдзрд╛рди рдХреЛ рдЯреНрд░рд┐рдЧрд░ рдХрд░реЗрдЧрд╛, рдЬреЛ рдбреАрдмрдЧ рдХреА рдЧрдИ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдЕрдкрд╡рд╛рдж рдХреЛ рдлреЗрдВрдХ рджреЗрдЧрд╛ рдФрд░ рдбрд┐рдмрдЧрд░ рдХреЛ рдЕрдкрд╡рд╛рдж рдХреЛрдб EXTEPTION_SINGLE_STEP рдХреЗ рд╕рд╛рде EXCEPTION_DEBUG_EVENT рдЗрд╡реЗрдВрдЯ рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рдорд┐рд▓ рдЬрд╛рдПрдЧрд╛ред

рдЖрдк рдЗрд╕ рдзреНрд╡рдЬ рдХреЛ рдереНрд░реЗрдб рд╕рдВрджрд░реНрдн рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рдХреНрд╖рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╣рдордиреЗ рдИрдЖрдИрдкреА рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗ рдореВрд▓реНрдп рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛ рд╣реИред рдЭрдВрдбреЗ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ Context.EFlags рдкреИрд░рд╛рдореАрдЯрд░ рджреНрд╡рд╛рд░рд╛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред TF рдзреНрд╡рдЬ рдЗрд╕ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдЖрдард╡реЗрдВ рдмрд┐рдЯ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╛рдиреА рдЗрд╕реЗ рд╕рдХреНрд╖рдо рдХрд░рдирд╛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП:

 const EFLAGS_TF = $100; // 8-  ... Context.EFlags := Context.EFlags or EFLAGS_TF; 


рдЯреНрд░реЗрд╕рд┐рдВрдЧ Nuance: "INT1" рд░реБрдХрд╛рд╡рдЯ рдХреА рдЦрд╝рд╛рд╕рд┐рдпрдд рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ TF рдзреНрд╡рдЬ рдХреЛ рд░реАрд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИред рдпрд╛рдиреАрдЕрдЧрд░ рд╣рдореЗрдВ рдмреАрдкреА рдХреЛ рдмрд╣рд╛рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рдПрдХ рдирд┐рд░реНрджреЗрд╢ рдкрд░ рдЕрдорд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдпрд╣ рд╡реНрдпрд╡рд╣рд╛рд░ рд╣рдореЗрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реВрдЯ рдХрд░рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдореЗрдВ рдЯреАрдПрдл рдзреНрд╡рдЬ рдХреЛ рдЙрд╕рдХреЗ рдореВрд▓ рд░рд╛рдЬреНрдп рдореЗрдВ рдмрд╣рд╛рд▓ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рд▓реЗрдХрд┐рди рдпрджрд┐ рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдирд┐рд░реНрджреЗрд╢ рдХреЗ рдЕрдиреБрдХреНрд░рдорд┐рдХ рдЕрдиреБрд░реЗрдЦрдг рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ EXCEPTION_SINGLE_STEP рд╣реИрдВрдбрд▓рд░ рдореЗрдВ TF рдзреНрд╡рдЬ рдХреЛ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рдлрд┐рд░ рд╕реЗ рдЙрдард╛рдирд╛ рд╣реЛрдЧрд╛ред рд╣рдо рдЗрд╕ рдореЛрдб рдкрд░ рдмрд╛рдж рдореЗрдВ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗред

рд╕рд╛рд░рд╛рдВрд╢ рдореЗрдВ, рдХреЛрдб рдкрддреЗ рдкрд░ рдмреАрдкреА рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдФрд░ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ:



рдЕрдм рдЖрдкрдХреЛ рдЗрд╕ рдмрд╛рдд рдХрд╛ рдХрдо рд╕реЗ рдХрдо рдЕрдВрджрд╛рдЬрд╛ рд╣реИ рдХрд┐ рдбреЗрд▓реНрдлреА рдбреАрдмрдЧрд░ рдореЗрдВ F7 рдмрдЯрди рджрдмрд╛рдиреЗ рдкрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрд┐рддрдиреЗ рдХрд╛рд░реНрдп рд╣реЛрддреЗ рд╣реИрдВ :)

рдЦреИрд░, рдпрд╣ рдХреИрд╕реЗ TFWDebugerCore рд╡рд░реНрдЧ рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

EXCEPTION_BREAKPOINT рд╣реИрдВрдбрд▓рд░ рдЕрдкрд╡рд╛рдж:

 procedure TFWDebugerCore.ProcessExceptionBreakPoint(ThreadIndex: Integer; DebugEvent: TDebugEvent); var ReleaseBP: Boolean; BreakPointIndex: Integer; begin ReleaseBP := False; BreakPointIndex := GetBPIndex( DWORD(DebugEvent.Exception.ExceptionRecord.ExceptionAddress)); if BreakPointIndex >= 0 then begin if Assigned(FBreakPoint) then FBreakPoint(Self, ThreadIndex, DebugEvent.Exception.ExceptionRecord, BreakPointIndex, ReleaseBP) else CallUnhandledExceptionEvents(ThreadIndex, ecBreakpoint, DebugEvent); ToggleInt3Breakpoint(BreakPointIndex, False); SetSingleStepMode(ThreadIndex, True); if ReleaseBP then RemoveBreakpoint(BreakPointIndex) else FRestoreBPIndex := BreakPointIndex; end else CallUnhandledExceptionEvents(ThreadIndex, ecBreakpoint, DebugEvent); end; 


рдЗрд╕рдореЗрдВ, рд╣рдо рдкрд╣рд▓реА рдмрд╛рд░ ExceptionAddress рдкреИрд░рд╛рдореАрдЯрд░ рджреНрд╡рд╛рд░рд╛ рдЖрдВрддрд░рд┐рдХ рд╕реВрдЪреА рдореЗрдВ BP рдЗрдВрдбреЗрдХреНрд╕ рдХреА рддрд▓рд╛рд╢ рдХрд░рддреЗ рд╣реИрдВред
рдмрд╛рд╣рд░реА рдШрдЯрдирд╛ рдХреЛ рдЙрдард╛рдПрдВред
ToggleInt3Breakpoint рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ BP рдмрдВрдж рдХрд░реЗрдВред
EIP рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ рдФрд░ SetSingleStepMode рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рдЯреНрд░реЗрд╕рд┐рдВрдЧ рд╕рдХреНрд╖рдо рдХрд░реЗрдВред
рдпрджрд┐ рдмрд╛рд╣рд░реА рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдореЗрдВ рдореМрдЬреВрдж рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдиреЗ рдХрд╣рд╛ рдХрд┐ рд╡рд╣ рдЗрд╕ рдмреАрдкреА рдХреЛ рд╣рдЯрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ, рддреЛ рд╣рдо рдЗрд╕реЗ рд░рд┐рдореВрд╡ рдкреНрд╡рд╛рдЗрдВрдЯ рд░рд┐рдореВрд╡ рдХрд░рдХреЗ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВред
рдареАрдХ рд╣реИ, рдЕрдЧрд░ рдЖрдкрдХреЛ рдмрд╕ рдирд┐рд╖реНрдкрд╛рджрди рдЬрд╛рд░реА рд░рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рд╣рдореЗрдВ EXCEPTION_SINGLE_STEP рд╣реИрдВрдбрд▓рд░ рдХреЗ рд▓рд┐рдП рд╡рд░реНрддрдорд╛рди рдмреАрдкреА рдХреЗ рд╕реВрдЪрдХрд╛рдВрдХ рдХреЛ рдпрд╛рдж рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬрд╣рд╛рдВ, рдЗрд╕ рдЪрд░ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рддреЗ рд╣реБрдП, рдпрд╣ рдбреАрдмрдЧ рдХреА рдЧрдИ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдмреАрдкреА рдХреЛ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдЧрд╛ред

SetSingleStepMode рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ:

 procedure TFWDebugerCore.SetSingleStepMode(ThreadIndex: Integer; RestoreEIPAfterBP: Boolean); var Context: TContext; begin ZeroMemory(@Context, SizeOf(TContext)); Context.ContextFlags := CONTEXT_FULL; Check(GetThreadContext(FThreadList[ThreadIndex].ThreadHandle, Context)); if RestoreEIPAfterBP then Dec(Context.Eip); Context.EFlags := Context.EFlags or EFLAGS_TF; Check(SetThreadContext(FThreadList[ThreadIndex].ThreadHandle, Context)); end; 


рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ, рд╣рдореЗрдВ CONTEXT_FULL рдзреНрд╡рдЬ рд╕реЗрдЯ рдХрд░рдХреЗ рдкреВрд░реНрдг рдереНрд░реЗрдб рд╕рдВрджрд░реНрдн рдорд┐рд▓рддрд╛ рд╣реИред
рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рддреЛ рдИрдЖрдИрдкреА рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВред
рдЯреАрдПрдл рдзреНрд╡рдЬ рдХреЛ рдЪрд╛рд▓реВ рдХрд░реЗрдВред
рдФрд░ рд╣рдо рдПрдХ рдирдпрд╛ рд╕рдВрджрд░реНрдн рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВред

RemoveBreakpoint рд╡рд┐рдзрд┐ рдФрд░ рднреА рд╕рд░рд▓ рд╣реИ:

 procedure TFWDebugerCore.RemoveBreakpoint(Index: Integer); var Len: Integer; begin ToggleBreakpoint(Index, False); Len := BreakpointCount; if Len = 1 then SetLength(FBreakpointList, 0) else begin FBreakpointList[Index] := FBreakpointList[Len - 1]; SetLength(FBreakpointList, Len - 1); end; end; 


рдпрд╣рд╛рдВ, рдмреАрдкреА рдмрдВрдж рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдлрд┐рд░ рдбреАрдмрдЧрд░ рд╕реВрдЪреА рд╕реЗ рдмреАрдкреА рдбреЗрдЯрд╛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдореИрдВ рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд░ EXCEPTION_SINGLE_STEP рдХрд╛ рдХреЛрдб рдЕрдм рддрдХ рдирд╣реАрдВ рджреВрдВрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рди рдХреЗрд╡рд▓ рдмреАрдкреА рдХреЛ рдмрд╣рд╛рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдореИрдВ рдЗрд╕реЗ рд▓реЗрдЦ рдХреЗ рдмрд╣реБрдд рдЕрдВрдд рдореЗрдВ рджрд┐рдЦрд╛рдКрдВрдЧрд╛, рдЬрдм рд╕рднреА рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рд╕реНрдореГрддрд┐ рдкрддреЗ рдкрд░ рдмреАрдкреА рд▓рд╛рдЧреВ рдХрд░рдирд╛:


рдбреАрдмрдЧ рдХрд┐рдП рдЧрдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреА рдореЗрдореЛрд░реА рдореЗрдВ рдбреЗрдЯрд╛ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдЧрд▓реЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдмреАрдкреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдореЗрдореЛрд░реА рдмреНрд░реЗрдХрдкреНрд╡рд╛рдЗрдВрдЯ (рдЗрд╕рдХреЗ рдмрд╛рдж рдПрдордмреАрдкреА) рдХреЗ рд░реВрдк рдореЗрдВ рдмреЗрд╣рддрд░ рдЬрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЗрд╕реЗ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: рд╕рдВрдкреВрд░реНрдг рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдореЛрд░реА рдХреЛ рдЙрди рдкреГрд╖реНрдареЛрдВ рдХреЗ рдПрдХ рд╕реЗрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рдиреНрд╣реЗрдВ рд╕реВрдЪреАрдмрджреНрдз рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЙрдирдХреА рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред (рдбреЗрдореЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рджреЗрдЦреЗрдВ: рдореЗрдореЛрд░реА рдХрд╛рд░реНрдб рдкреНрд░реЛрд╕реЗрд╕ рдХрд░реЗрдВ )ред рдЬрдм рд╣рдо MBP рдХреЛ рдХрд┐рд╕реА рдкрддреЗ рдкрд░ рд░рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдЙрд╕ рдкреГрд╖реНрда рдХреА рд╕реАрдорд╛рдУрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдпрд╣ рдкрддрд╛ рд╣реИ рдФрд░ VirtualProtectEx рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ PAGE_GUARD рдзреНрд╡рдЬ рдХреЛ рдЗрд╕рдХреЗ рд▓рд┐рдП рд╕реЗрдЯ рдХрд░реЗрдВред

Nuance: рдЖрдк рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдкреГрд╖реНрда рдХреЗ рдкрддреЗ рдХреА рдЧрдгрдирд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЖрд╡рд╢реНрдпрдХ рдкрддреЗ рдкрд░ рдмрд╕ VirtualProtectEx рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВ, рд▓реЗрдХрд┐рди рдкреЗрдЬ рдПрдбреНрд░реЗрд╕рд┐рдВрдЧ рдХреА рдЦрд╝рд╛рд╕рд┐рдпрдд рдпрд╣ рд╣реИ рдХрд┐ рдЖрдк рдкреЗрдЬ рдХреЗ рдПрдХ рдЫреЛрдЯреЗ рд╕реЗ рд╣рд┐рд╕реНрд╕реЗ рдХреА рд╕реБрд░рдХреНрд╖рд╛ рдХреЛ рдмрджрд▓ рдирд╣реАрдВ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рд╕реЗ рд╕рднреА рдкрддреЗ рдЕрдкрд░рд┐рд╡рд░реНрддрд┐рдд рд░рд╣рддреЗ рд╣реИрдВред рд╕реБрд░рдХреНрд╖рд╛ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рд╣рдореЗрд╢рд╛ рдПрдХ рдкреГрд╖реНрда рдкрд░ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реМрдВрдкрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдпрджрд┐ рд╣рдо рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рдЗрдЯ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рдЗрд╕рдХреЗ рдмрдЧрд▓ рдореЗрдВ рдмрд╛рдЗрдЯреНрд╕ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдкрд░, рдбрд┐рдмрдЧрд░ рдХреЛ рднреА рд╕реВрдЪрдирд╛рдПрдВ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдВрдЧреАред

рджреВрд╕рд░рд╛ рдЪреЗрддрд╛рд╡рдиреА: рдЕрдзрд┐рдХрд╛рдВрд╢ рдбрд┐рдмрдЧрд░ рдЖрдкрдХреЛ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдПрдХ рд╣реА рдкреГрд╖реНрда рдкрд░ рд╕реНрдерд┐рдд рджреЛ рдпрд╛ рдЕрдзрд┐рдХ рдПрдордмреАрдкреА рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддреЗ рд╣реИрдВред рдпрд╣ рд╡реНрдпрд╡рд╣рд╛рд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдмрд┐рдВрджреБ рдХреЗ рдХрд╛рд░рдг рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ: рдПрдордмреАрдкреА рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╕рдордп, рдЖрдкрдХреЛ рдПрдордмреАрдкреА рдХреЛ рд╣рдЯрд╛рдиреЗ рдХрд╛ рд╕рдордп рдЖрдиреЗ рдкрд░ рдЗрд╕реЗ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреГрд╖реНрда рдХреЗ рд╕реБрд░рдХреНрд╖рд╛ рдХреНрд╖реЗрддреНрд░ рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЛ рдпрд╛рдж рд░рдЦрдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕ рдШрдЯрдирд╛ рдореЗрдВ рдХрд┐ рдПрдордмреАрдкреА рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреГрд╖реНрда рдкрд░ рд╕реЗрдЯ рд╣реИ, рдЗрд╕рдХреА рд╕реБрд░рдХреНрд╖рд╛ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рдмрд┐рдВрджреБ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрди рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ TFWDebugerCore рд╡рд░реНрдЧ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдПрдХ рдирдпрд╛ MBP рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╕рдордп, рдпрд╣ рдкрд╣рд▓реЗ рдЬрд╛рдВрдЪрд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЗрд╕ рдкреГрд╖реНрда рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдХреЛрдИ рдЕрдиреНрдп MBP рд╣реИред рдпрджрд┐ рдХреЛрдИ рдкрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ PreviosRegionProtect рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдорд╛рди рд▓реЗрддрд╛ рд╣реИ, рдпрджрд┐ рдХреЛрдИ MDR рдирд╣реАрдВ рд╣реИ, рддреЛ VirtualProtectEx рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рдпрд╣ рдорд╛рди рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

MVR рд╕реНрдерд╛рдкрдирд╛ рдХреЛрдб рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

 function TFWDebugerCore.SetMemoryBreakpoint(Address: Pointer; Size: DWORD; BreakOnWrite: Boolean; const Description: string): Boolean; var Breakpoint: TBreakpoint; MBI: TMemoryBasicInformation; Index: Integer; begin Index := GetMBPIndex(DWORD(Address)); if (Index >= 0) and (FBreakpointList[Index].bpType = btMemoryBreakpoint) then begin MBI.BaseAddress := FBreakpointList[Index].Memory.RegionStart; MBI.RegionSize := FBreakpointList[Index].Memory.RegionSize; MBI.Protect := FBreakpointList[Index].Memory.PreviosRegionProtect; end else Check(VirtualQueryEx(DebugProcessData.AttachedProcessHandle, Address, MBI, SizeOf(TMemoryBasicInformation)) > 0); ZeroMemory(@Breakpoint, SizeOf(TBreakpoint)); Breakpoint.bpType := btMemoryBreakpoint; Breakpoint.Description := ShortString(Description); Breakpoint.Memory.Address := Address; Breakpoint.Memory.Size := Size; Breakpoint.Memory.BreakOnWrite := BreakOnWrite; Breakpoint.Memory.RegionStart := MBI.BaseAddress; Breakpoint.Memory.RegionSize := MBI.RegionSize; Check(VirtualProtectEx(FProcessInfo.AttachedProcessHandle, Address, Size, MBI.Protect or PAGE_GUARD, Breakpoint.Memory.PreviosRegionProtect)); if Index >= 0 then Breakpoint.Memory.PreviosRegionProtect := MBI.Protect; Result := AddNewBreakPoint(Breakpoint); end; 


рдПрдордмреАрдкреА рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдмреАрдкреА рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЕрдзрд┐рдХ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдирд┐рдпрдВрддреНрд░рд┐рдд рдХреНрд╖реЗрддреНрд░ рдФрд░ рдЙрд╕рдХреЗ рдЖрдХрд╛рд░ рдХреЗ рдкрддреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрдордмреАрдкреА рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдкреИрд░рд╛рдореАрдЯрд░ рд╕реНрд╡рдпрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИ - рдмреНрд░реЗрдХрдСрдирд░рд╛рдЗрдЯ, рдЬреЛ рдПрдХ рдмрд╛рд╣рд░реА рдШрдЯрдирд╛ рдХреЛ рдЯреНрд░рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИ (рдЬрдм рдирд┐рдпрдВрддреНрд░рд┐рдд рдХреНрд╖реЗрддреНрд░ рд╕реЗ рдбреЗрдЯрд╛ рдкрдврд╝ рд░рд╣рд╛ рд╣реИ рдпрд╛ рдЬрдм рдЗрд╕реЗ рд▓рд┐рдЦрдирд╛ рд╣реИ)ред рдкреГрд╖реНрда рдХреА рд╢реБрд░реБрдЖрдд рдХрд╛ рдкрддрд╛ рдФрд░ рдЙрд╕рдХрд╛ рдЖрдХрд╛рд░ рднреА рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИред

рдПрдорд╡реАрдЖрд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдк рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрдХреНрд░рдо рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВред рдЬреИрд╕реЗ рд╣реА рдореЙрдирд┐рдЯрд░ рдХрд┐рдП рдЧрдП рдкреГрд╖реНрда рддрдХ рдкрд╣реБрдВрдЪ рд╣реЛрддреА рд╣реИ, EXCEPTION_DEBUG_EVENT рдШрдЯрдирд╛ EXCEPTION_GUARD_PAGE рдЕрдкрд╡рд╛рдж рдХреЛрдб рдХреЗ рд╕рд╛рде рдЙрддреНрдкрдиреНрди рд╣реЛрдЧреАред

рдпрд╣рд╛рдВ рдПрдХ рдмрд╛рд░реАрдХрд┐рдпрд╛рдВ рднреА рд╣реИрдВред рдЬрдм рд╣рдо рдкреГрд╖реНрда рдкрд░ PAGE_GUARD рдзреНрд╡рдЬ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдкрд╣рд▓реА рдмрд╛рд░ рдЗрд╕реЗ рдПрдХреНрд╕реЗрд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдПрдХ рдЕрдкрд╡рд╛рдж рдЙрдард╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕ рдзреНрд╡рдЬ рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣реА рд╣реИ, рдмреАрдкреА рдХреЗ рд╡рд┐рдкрд░реАрдд, рд╣рдореЗрдВ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рдПрдорд╡реАрдЖрд░ рдХреЛ рдбрд┐рд╕реНрдХрдиреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрдЧреАред рд▓реЗрдХрд┐рди рдПрдХ рдЫреЛрдЯреА рд╕реА рд╕рдорд╕реНрдпрд╛ рд╣реИредрдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рдХрд╣рд╛, рдЬрдм рднреА рдкреГрд╖реНрда рдПрдХреНрд╕реЗрд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддрдм рди рдХреЗрд╡рд▓ EXCEPTION_GUARD_PAGE рдЕрдкрд╡рд╛рдж рддрдм рд╣реЛрдЧрд╛, рдЬрд┐рд╕ рдкрд░ MDR рд╕реЗрдЯ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдбреАрдмрдЧрд░ PAGE_GUARD рдзреНрд╡рдЬ рдХреЛ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рддрд╛рдХрд┐ рд╕реНрдерд╛рдкрд┐рдд MVR рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦреЗред

рд╣реИрдВрдбрд▓рд░ рдХреЛрдб рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

 procedure TFWDebugerCore.ProcessExceptionGuardPage(ThreadIndex: Integer; DebugEvent: TDebugEvent); var CurrentMBPIndex: Integer; function CheckWriteMode: Boolean; begin Result := not FBreakpointList[CurrentMBPIndex].Memory.BreakOnWrite; if not Result then Result := DebugEvent.Exception.ExceptionRecord.ExceptionInformation[0] = 1; end; var MBPIndex: Integer; ReleaseMBP: Boolean; dwGuardedAddr: DWORD; begin ReleaseMBP := False; dwGuardedAddr := DebugEvent.Exception.ExceptionRecord.ExceptionInformation[1]; MBPIndex := GetMBPIndex(dwGuardedAddr); if MBPIndex >= 0 then begin CurrentMBPIndex := MBPIndex; while not CheckIsAddrInRealMemoryBPRegion(CurrentMBPIndex, dwGuardedAddr) do begin CurrentMBPIndex := GetMBPIndex(dwGuardedAddr, CurrentMBPIndex + 1); if CurrentMBPIndex < 0 then Break; end; if CurrentMBPIndex >= 0 then begin MBPIndex := CurrentMBPIndex; if Assigned(FBreakPoint) and CheckWriteMode then FBreakPoint(Self, ThreadIndex, DebugEvent.Exception.ExceptionRecord, MBPIndex, ReleaseMBP) else CallUnhandledExceptionEvents(ThreadIndex, ecGuard, DebugEvent); end else CallUnhandledExceptionEvents(ThreadIndex, ecGuard, DebugEvent); FBreakpointList[MBPIndex].Active := False; SetSingleStepMode(ThreadIndex, False); if ReleaseMBP then RemoveBreakpoint(MBPIndex) else FRestoreMBPIndex := MBPIndex; end else CallUnhandledExceptionEvents(ThreadIndex, ecGuard, DebugEvent); end; 


рдкреНрд░рд╛рд░рдВрдн рдореЗрдВ, рдбрд┐рдмрдЧрд░ рдХреЛ рд╡рд╣ рдкрддрд╛ рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рд╣реБрдЖ рдерд╛ рдЬрд┐рд╕рдХреЗ рдХрд╛рд░рдг рдЕрдкрд╡рд╛рдж рд╣реБрдЖред рдпрд╣ рдкрддрд╛ ExceptionRecord.ExceptionInformation рд╕рд░рдгреА рдореЗрдВ рджреВрд╕рд░реЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИ, рдСрдкрд░реЗрд╢рди рдзреНрд╡рдЬ рдЗрд╕ рд╕рд░рдгреА рдореЗрдВ рдкрд╣рд▓рд╛ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИред рд╢реВрдиреНрдп рдХрд╛ рдорддрд▓рдм рдПрдХ рдкрддреЗ рдкрд░ рдкрдврд╝рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рд╣реИ, рдПрдХ рдХрд╛ рдорддрд▓рдм рдПрдХ рдкрддреЗ рдкрд░ рдкрдврд╝рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рд╣реИред
рдЕрдЧрд▓рд╛, рд╣рдо CheckIsAddrInRealMemoryBPRegion рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рдПрдХ рдЙрдкрдпреБрдХреНрдд рдПрдордбреАрдЖрд░ рдХреА рдЦреЛрдЬ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдпрд╣ рдЬрд╛рдВрдЪрддрд╛ рд╣реИ рдХрд┐ рдкрддрд╛ рдПрдордбреАрдЖрд░ рджреНрд╡рд╛рд░рд╛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╣реИ рдпрд╛ рдирд╣реАрдВред

рдпрджрд┐ рдПрдХ рдЙрдкрдпреБрдХреНрдд рдкрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдмреНрд░реЗрдХрдСрдирд░рд╛рдЗрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХреА рдЬрд╛рдБрдЪ рдХреА рдЬрд╛рддреА рд╣реИред
рдЗрд╕ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдореВрд▓реНрдп рдХреА рддреБрд▓рдирд╛ рдкрд╣рд▓реЗ рдкреИрд░рд╛рдореАрдЯрд░ ExceptionInformation рдХреЗ рдорд╛рди рд╕реЗ рдХреА рдЬрд╛рддреА рд╣реИред рдпрджрд┐ рдмреНрд░реЗрдХрдСрдирд░рд╛рдЗрдЯ рдХреЛ рд╕рдХреНрд╖рдо рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдПрдХ рдмрд╛рд╣рд░реА рдШрдЯрдирд╛ рдХреЛ рдХреЗрд╡рд▓ рддрднреА рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рдЗрдХрд╛рдИ рдПрдХреНрд╕рд╕реЗрдкреНрд╢рди рдЗрдВрдлреЙрд░реНрдореЗрд╢рди рдореЗрдВ рд╣реЛрддреА рд╣реИ; рдЕрдиреНрдпрдерд╛, рдпрджрд┐ рдмреНрд░реЗрдХрдСрдирд░рд╛рдЗрдЯ рдХреЛ рдЕрдХреНрд╖рдо рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдИрд╡реЗрдВрдЯ рдХреЛ рд╣рдореЗрд╢рд╛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред

рд╕рднреА рдЬрд╛рдВрдЪреЛрдВ рдХреЗ рдмрд╛рдж, рдХреЛрдб рдХреЛ рдмреАрдкреА рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рд╛рде рд╕рд╛рджреГрд╢реНрдп рджреНрд╡рд╛рд░рд╛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдмреАрдкреА рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд╕реЗ рдПрдХрдорд╛рддреНрд░ рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рд╣рдореЗрдВ рдИрдЖрдИрдкреА рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗ рдореВрд▓реНрдп рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЧрд▓рдд рджреВрд╕рд░реЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ SetSingleStepMode рд╡рд┐рдзрд┐ рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рд╕рд╛рджреГрд╢реНрдп рд╕реЗ, рдХреИрдкреНрдЪрд░ рдХрд┐рдП рдЧрдП MVP рдХреА рд╡рд╕реВрд▓реА FRCEoreMBPIndex рдЗрдВрдбреЗрдХреНрд╕ рдкрд░ рдЖрдзрд╛рд░рд┐рдд EXCEPTION_SINGLE_STEP рд╣реИрдВрдбрд▓рд░ рдореЗрдВ рд╣реЛрддреА рд╣реИред

MBP рдХреА рдЧрддрд┐рд╡рд┐рдзрд┐ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрди рдХреЛрдб рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИ:

 procedure TFWDebugerCore.ToggleMemoryBreakpoint(Index: Integer; Active: Boolean); var Dummy: DWORD; begin CheckBreakpointIndex(Index); if FBreakpointList[Index].bpType <> btMemoryBreakpoint then Exit; if FBreakpointList[Index].Active = Active then Exit; if Active then Check(VirtualProtectEx(FProcessInfo.AttachedProcessHandle, FBreakpointList[Index].Memory.Address, FBreakpointList[Index].Memory.Size, FBreakpointList[Index].Memory.PreviosRegionProtect or PAGE_GUARD, Dummy)) else Check(VirtualProtectEx(FProcessInfo.AttachedProcessHandle, FBreakpointList[Index].Memory.Address, FBreakpointList[Index].Memory.Size, FBreakpointList[Index].Memory.PreviosRegionProtect, Dummy)); FBreakpointList[Index].Active := Active; end; 


MVR рдХреЛ рдирд┐рдХрд╛рд▓рдирд╛ рдмреАрдкреА рдХреЗ рд╕рдорд╛рди рд╡рд┐рдзрд┐ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдмреАрдкреА рдФрд░ рдПрдорд╡реАрдЖрд░ рдореЗрдВ рдХреБрдЫ рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде рдХреЛрдИ рдкреНрд░рдореБрдЦ рдХрд╛рд░реНрдбрд┐рдирд▓ рдЕрдВрддрд░ рдирд╣реАрдВ рд╣реИрдВред рд╡реЗ рд╕рд┐рд░реНрдл рдЕрдкрдиреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреНрдпреЗрдХ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрднреА-рдХрднреА рдПрдордмреАрдкреА рдХреЛ рдПрдХ рдЯреНрд░реЗрд╕рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, ICBM рдХреЛ рдХреЛрдб рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдбрд┐рдмрдЧрд░ рдЪрд╛рд▓реВ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдореЗрдВ рджреВрд░рд╕реНрде рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдореЗрдВ рд╡рд░реНрддрдорд╛рди EIP рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рд╕реВрдЪрдирд╛ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдиреЗ рд▓рдЧрддреА рд╣реИред рдПрдХ рдЙрдЪрд┐рдд рд░реВрдк рд╕реЗ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдЪреАрдЬ, рдбреЗрд▓реНрдлреА рдбрд┐рдмрдЧрд░ рдореЗрдВ рдПрдХ рджрдпрд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИред

рдореИрдВ рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХреЗ рдЙрдкрдпреЛрдЧ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджрд┐рдЦрд╛рдКрдВрдЧрд╛ред рдЕрдм рдЪрд▓реЛ рддреАрд╕рд░реЗ рдФрд░ рдЕрдВрддрд┐рдо рдкреНрд░рдХрд╛рд░ рдХреЗ рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рдкрд░ рдЪрд▓рддреЗ рд╣реИрдВред

рд╣рд╛рд░реНрдбрд╡реЗрдпрд░ рдмреНрд░реЗрдХрдкреНрд╡рд╛рдЗрдВрдЯ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди:


рддрдерд╛рдХрдерд┐рдд рд╣рд╛рд░реНрдбрд╡реЗрдпрд░ рдмреНрд░реЗрдХрдкреНрд╡рд╛рдЗрдВрдЯ (рдЗрд╕рдХреЗ рдмрд╛рдж HBP)ред рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдкрд░реНрдпрд╛рдкреНрдд рдбрд┐рдмрдЧрд┐рдВрдЧ рдЙрдкрдХрд░рдгред рдмреАрдкреА рдФрд░ рдПрдорд╡реАрдЖрд░ рдХреЗ рд╡рд┐рдкрд░реАрдд, рдпреЗ рдмреНрд░реЗрдХрдкреНрд╡рд╛рдЗрдВрдЯ рдбрд┐рдмрдЧ рдХрд┐рдП рдЧрдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреА рдореЗрдореЛрд░реА рдореЗрдВ рд╕рдВрд╢реЛрдзрди рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рдХреЗрд╡рд▓ рдмреБрд░реА рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдЙрдирдореЗрдВ рд╕реЗ рдмрд╣реБрдд рдХрдо рд╣реИрдВ, рдкреНрд░рддреНрдпреЗрдХ рдзрд╛рдЧреЗ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рдЪрд╛рд░ рдЯреБрдХрдбрд╝реЗ рд╣реИрдВред

рд▓реЗрдХрд┐рди рдЕрдиреНрдп HBPs рдХреЗ рд╡рд┐рдкрд░реАрдд, рдпрд╣ рдбреАрдмрдЧ рдХрд┐рдП рдЧрдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рд▓рдЪреАрд▓реА рд╕реНрдерд┐рддрд┐ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред

рдХреЗ рддреБрд▓рдирд╛ рдХрд░рддреЗ рд╣реИрдВ:
рдмреАрдкреА - рдХреЗрд╡рд▓ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдХреЛрдб рддрдХ рдкрд╣реБрдВрдЪ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рддрд╛ рд╣реИ (рдПрдХреНрдЬрд╝реАрдХреНрдпреВрд╢рди рдореЛрдб рдХрд╣реЗрдВ),
рдПрдорд╡реАрдЖрд░ - рдЖрдкрдХреЛ рд░реАрдб рдпрд╛ рд░реАрдб / рд░рд╛рдЗрдЯ рдореЛрдб рдореЗрдВ рдПрдХреНрд╕реЗрд╕ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
- рдЖрдкрдХреЛ рд╕реНрдерд┐рддрд┐ рдХреЛ рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдпрд╣ рд▓рд┐рдЦреЗрдВ, рдкрдврд╝реЗрдВ / рд▓рд┐рдЦреЗрдВ, IO рдореЛрдб (рдЗрдирдкреБрдЯ / рдЖрдЙрдЯрдкреБрдЯ рдкреЛрд░реНрдЯ рддрдХ рдкрд╣реБрдВрдЪ) рдФрд░ рдирд┐рд╖реНрдкрд╛рджрди рдореЛрдб рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдХрд░рддрд╛ рд╣реИред

рдпрд╛рдиреАHBP BP (рдирд┐рд╖реНрдкрд╛рджрди рдореЛрдб рдореЗрдВ) рдФрд░ MBP (рд░рд┐рдХреЙрд░реНрдб рдореЗрдВ - рдкрдврд╝реЗрдВ / рд▓рд┐рдЦреЗрдВ рдореЛрдб) рджреЛрдиреЛрдВ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░ рд╕рдХрддрд╛ рд╣реИред рд╕рдЪ рд╣реИ, рдПрдорд╡реАрдЖрд░ рдХреЗ рд╡рд┐рдкрд░реАрдд, рдпрд╣ рдореЗрдореЛрд░реА рдХреНрд╖реЗрддреНрд░ рдХреА рдПрдХ рдмрдбрд╝реА рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХреЗрд╡рд▓ рдирд┐рд╢реНрдЪрд┐рдд рдЖрдХрд╛рд░ 1, 2 рдпрд╛ 4 рдмрд╛рдЗрдЯ рдХреЗ рдмреНрд▓реЙрдХ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

HBP рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЛ рдкреНрд░рддреНрдпреЗрдХ рдереНрд░реЗрдб рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рдХреЗ рд▓рд┐рдП DR рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рддрдм рдПрдХреНрд╕реЗрд╕ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ рдЬрдм CONTEXT_DEBUG_REGISTERS рдзреНрд╡рдЬ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЙрдирдореЗрдВ рд╕реЗ рдЫрд╣ рд╣реИрдВред Dr0..Dr3, Dr6, Dr7ред (Dr4 рдФрд░ Dr5 рдЖрд░рдХреНрд╖рд┐рдд рд╣реИрдВ)ред
рдкрд╣рд▓реЗ 4 рд░рдЬрд┐рд╕реНрдЯрд░ HBP рдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЗ рдкрддреЗ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддреЗ рд╣реИрдВред рд░рдЬрд┐рд╕реНрдЯрд░ рдбреНрд░рдм рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдЪрдмреАрдкреА рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд░рдЬрд┐рд╕реНрдЯрд░ Dr6 рдЪрд╛рд░ HBP рдореЗрдВ рд╕реЗ рдХрд┐рд╕реА рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рдмрд╛рдж рдкрд░рд┐рдгрд╛рдо рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИред

TFWDebugerCore рд╡рд░реНрдЧ рдирд┐рдореНрди рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд░реВрдк рдореЗрдВ HBP рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ:

 THWBPIndex = 0..3; THWBPSize = (hsByte, hdWord, hsDWord); THWBPMode = (hmExecute, hmWrite, hmIO, hmReadWrite); THardwareBreakpoint = packed record Address: array [THWBPIndex] of Pointer; Size: array [THWBPIndex] of THWBPSize; Mode: array [THWBPIndex] of THWBPMode; Description: array [THWBPIndex] of ShortString; Active: array [THWBPIndex] of Boolean; end; 


рдЪреВрдВрдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рд╢реЗрд╖ рдзрд╛рдЧреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА 4 рдПрдЪрдмреАрдкреА рдХрд╛ рдЕрдкрдирд╛ рд╣реИ, рд╡реЗ рдмреАрдкреА рдХрдХреНрд╖рд╛рдУрдВ рдХреА рд╕рд╛рдорд╛рдиреНрдп рд╕реВрдЪреА рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдирд╣реАрдВ рд╣реИрдВред
рдпрд╛рдж рд░рдЦреЗрдВ рдХрд┐ рд╢реБрд░реБрдЖрдд рдореЗрдВ рдореИрдВрдиреЗ рдХрд╣рд╛ рдерд╛ рдХрд┐ рд╣рдо рдереНрд░реЗрдбреНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдбреЗрдЯрд╛ рдХреЛ рдПрдХ рдЬреЛрдбрд╝реА ID = hThreadHolle рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдЕрд▓рдЧ рд╕реВрдЪреА рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдВрдЧреЗред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рд╕реВрдЪреА рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:

 TThreadData = record ThreadID: DWORD; ThreadHandle: THandle; Breakpoint: THardwareBreakpoint; end; TThreadList = array of TThreadData; 


рдпрд╛рдиреАрдЗрди рджреЛ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкреНрд░рддреНрдпреЗрдХ рдереНрд░реЗрдб рдХреА рдЕрдкрдиреА рд╕рдВрд░рдЪрдирд╛ рд╣реЛрддреА рд╣реИ рдЬреЛ рдЗрд╕рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдПрдЪрдмреАрдкреА рдХреА рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреА рд╣реИред

рдПрдЪрдмреАрдкреА рдХреА рд╕реНрдерд╛рдкрдирд╛, рд░рд╛рдЬреНрдп рдХреЗ рдкрд░рд┐рд╡рд░реНрддрди рдФрд░ рд╣рдЯрд╛рдиреЗ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдмреЗрд╣рдж рд╕рд░рд▓ рд╣реИред

рд╕реНрдерд╛рдкрдирд╛ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддреА рд╣реИ:

 procedure TFWDebugerCore.SetHardwareBreakpoint(ThreadIndex: Integer; Address: Pointer; Size: THWBPSize; Mode: THWBPMode; HWIndex: THWBPIndex; const Description: string); begin if ThreadIndex < 0 then Exit; FThreadList[ThreadIndex].Breakpoint.Address[HWIndex] := Address; FThreadList[ThreadIndex].Breakpoint.Size[HWIndex] := Size; FThreadList[ThreadIndex].Breakpoint.Mode[HWIndex] := Mode; FThreadList[ThreadIndex].Breakpoint.Description[HWIndex] := ShortString(Description); FThreadList[ThreadIndex].Breakpoint.Active[HWIndex] := True; UpdateHardwareBreakpoints(ThreadIndex); end; 


рд╣рдо рдХреЗрд╡рд▓ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ UpdateHardwareBreakpoint рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВред

рд░рд╛рдЬреНрдп рд╕рдВрд╢реЛрдзрди рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рджреНрд╡рд╛рд░рд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

 procedure TFWDebugerCore.ToggleHardwareBreakpoint(ThreadIndex: Integer; Index: THWBPIndex; Active: Boolean); begin if ThreadIndex < 0 then Exit; if FThreadList[ThreadIndex].Breakpoint.Active[Index] = Active then Exit; FThreadList[ThreadIndex].Breakpoint.Active[Index] := Active; UpdateHardwareBreakpoints(ThreadIndex); end; 


рдмрд╕ рд╕рдХреНрд░рд┐рдп рдзреНрд╡рдЬ рдХреЛ рдмрджрд▓реЗрдВ рдФрд░ рдлрд┐рд░ рд╕реЗ рдЕрдкрдбреЗрдЯрд╣рд╛рд░реНрдбрд╡реЗрдпрд░ рдХреНрд░рд┐рдкреНрдЯрдкреЙрдЗрдВрдЯреНрд╕ рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВред

рдЦреИрд░, рд╣рдЯрд╛рдиреЗ:

 procedure TFWDebugerCore.DropHardwareBreakpoint(ThreadIndex: Integer; Index: THWBPIndex); begin if ThreadIndex < 0 then Exit; if FThreadList[ThreadIndex].Breakpoint.Address[Index] = nil then Exit; FThreadList[ThreadIndex].Breakpoint.Address[Index] := nil; UpdateHardwareBreakpoints(ThreadIndex); end; 


рд╣рдо рдПрдЪрдмреАрдкреА рдкрддреЗ рдХреЛ рд░реАрд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдлрд┐рд░ рд╕реЗ рдЕрдкрдбреЗрдЯрд╣рд╛рд░реНрдбрд╡реЗрдпрд░ рдХреНрд░рд┐рдкреНрдЯрдкреЙрдЗрдВрдЯреНрд╕ рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВред

рдкреВрд░реА рдмрд╛рд░реАрдХрд┐рдпрд╛рдБ UpdateHardwareBreakpoint рд╡рд┐рдзрд┐ рдореЗрдВ рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ рдирд┐рд╣рд┐рдд рд╣реИред
рдЗрд╕рдХрд╛ рдореБрдЦреНрдп рдХрд╛рд░реНрдп рд╕рдХреНрд░рд┐рдп рдПрдЪрдмреАрдкреА рдХреЗ рдкрддреЗ рдХреЗ рд╕рд╛рде Dr0-Dr3 рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЛ рднрд░рдирд╛ рд╣реИ рдФрд░ Dr7 рд░рдЬрд┐рд╕реНрдЯрд░ рдХрд╛ рд╕рд╣реА рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬреЗрд╢рди рдХрд░рдирд╛ рд╣реИред

рдпрд╣рд╛рдВ рдЗрд╕рдХреЗ рд╕рд╛рде рдЫреЗрдбрд╝рдЫрд╛рдбрд╝ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред

рдпрд╣ рд░рдЬрд┐рд╕реНрдЯрд░ рдмрд┐рдЯ рдлрд╝реНрд▓реИрдЧ рдХрд╛ рдПрдХ рд╕реЗрдЯ

рд╣реИ рдЬреЛ рдПрдЪрдмреАрдкреА рдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЗ рд▓рд┐рдП рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдФрдкрдЪрд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рд╕рдм рдХреБрдЫ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рджрд┐рдЦрддрд╛ рд╣реИ: рд╕рдмрд╕реЗ рдкреБрд░рд╛рдиреЗ 4 рдмрд┐рдЯреНрд╕ (31-28) Dr3 рд░рдЬрд┐рд╕реНрдЯрд░ рдХреА рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддреЗ рд╣реИрдВред
рдпрд╣ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

рдореЙрдирд┐рдЯрд░ рдХрд┐рдП рдЧрдП HBP рдореЗрдореЛрд░реА рдХреЗ рдЖрдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдЪрд╛рд░ рдХреЗ рдКрдкрд░реА 2 рдмрд┐рдЯреНрд╕ (LENi) рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИрдВред
00 - 1 рдмрд╛рдЗрдЯ
01 - 2 рдмрд╛рдЗрдЯреНрд╕
10 - рдмрд┐рдЯреНрд╕ рдХреЗ рдЗрд╕ рд╕рдВрдпреЛрдЬрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
11 - 4 рдмрд╛рдЗрдЯреНрд╕ 4 рдХреЗ

рдирд┐рдЪрд▓реЗ 2 рдмрд┐рдЯреНрд╕ (рдЖрд░рдбрдмреНрд▓реНрдпреВрдЖрдИ) рдПрдЪрдмреАрдкреА
00 рдХреЗ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рдореЛрдб рдХреЛ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИрдВ - рдирд┐рд╖реНрдкрд╛рджрд┐рдд
01 -
10 рд▓рд┐рдЦреЗрдВ - рдЖрдИрдУ рдкрдврд╝реЗрдВ / рд▓рд┐рдЦреЗрдВ
11 - рдкрдврд╝реЗрдВ / рд▓рд┐рдЦреЗрдВ

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЕрдЧрд░ рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдбреНрд░рдм рд░рдЬрд┐рд╕реНрдЯрд░ рд╕реЗ рдПрдЪрдмреАрдкреА рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрдВред Dr3 рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдорд╛рди рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдХрд┐рд╕реА рднреА 4 рдмрд╛рдЗрдЯреНрд╕, Dr7 рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗ рдКрдкрд░реА 4 рдмрд┐рдЯреНрд╕ 1101

рдХреА рддрд░рд╣ рджрд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП ред рдЕрдЧрд▓реЗ 4 рдмрд┐рдЯреНрд╕ (27-24) Dr2
рдмрд┐рдЯреНрд╕ рдХреЗ HBP рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ 23-20 Dr1 рдФрд░ рдЕрдВрдд рдореЗрдВ, рдмрд┐рдЯреНрд╕ 19- рдХреЛ рджреЗрдЦреЗрдВред 16 рд╕реЗ рд░рдЬрд┐рд╕реНрдЯрд░ Dr0ред

Dr7 рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗ рдмрд┐рдЯ 13 (рдЬреАрдбреА - рдЧреНрд▓реЛрдмрд▓ рдбрд┐рдмрдЧ рд░рдЬрд┐рд╕реНрдЯрд░ рдПрдХреНрд╕реЗрд╕ рдбрд┐рдЯреЗрдХреНрдЯ) - рдбрд┐рдмрдЧ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдореЗрдВ рдбреЗрдЯрд╛ рдХреА рдЕрдЦрдВрдбрддрд╛ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдбрд┐рдмрдЧ рдХрд┐рдП рдЬрд╛ рд░рд╣реЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдиреЗ рдЕрдЪрд╛рдирдХ рдЗрди рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдореЗрдВ рдЕрдкрдиреЗ рдореВрд▓реНрдпреЛрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛, рддреЛ рдбрд┐рдмрдЧрд░ рдХреЛ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рд╕реВрдЪрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

Dr7 рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗ рдмрд┐рдЯ 9 (GE - рдЧреНрд▓реЛрдмрд▓ рд╕рдЯреАрдХ рдбреЗрдЯрд╛ рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рдореИрдЪ) - рдЗрд╕рдореЗрдВ рд╡реИрд╢реНрд╡рд┐рдХ HBP рдХреЗ рд╕рд╛рде рдХрд╛рдо рд╢рд╛рдорд┐рд▓ рд╣реИред
Dr7 рд░рдЬрд┐рд╕реНрдЯрд░ (LE - рд╕реНрдерд╛рдиреАрдп рд╕рдЯреАрдХ рдбреЗрдЯрд╛ рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рдореИрдЪ) рдХреЗ рдмрд┐рдЯ 8 - рд╕реНрдерд╛рдиреАрдп HBP рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдмрдирд╛рддрд╛ рд╣реИред

рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╕реНрд╡рд┐рдЪ рдХрд░рддреЗ рд╕рдордп LE рдмрд┐рдЯ рдХреЛ рд░реАрд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╡рд░рдг рдЗрдВрдЯреЗрд▓ рдореИрдиреБрдЕрд▓ рдореЗрдВ рдкрд╛рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред

рд╡реИрд╢реНрд╡рд┐рдХ рдпрд╛ рд╕реНрдерд╛рдиреАрдп рдореЛрдб рдореЗрдВ HBP рд╕рд╣рд┐рдд рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЗ рд▓рд┐рдП 8 рдмрд┐рдЯреНрд╕ (7-0) рдмрдЪреЗ рд╣реИрдВ рдЬреЛ Gi рдФрд░ Li рдЭрдВрдбреЗ рдХреА рдПрдХ рдЬреЛрдбрд╝реА рдХреЗ рд░реВрдк рдореЗрдВ рджрд░реНрд╢рд╛рдП рдЧрдП рд╣реИрдВред

рдмрд┐рдЯ 7 (Gi - рд╡реИрд╢реНрд╡рд┐рдХ рдмреНрд░реЗрдХрдкреНрд╡рд╛рдЗрдВрдЯ рд╕рдХреНрд╖рдо) - Dr3 рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗ рд▓рд┐рдП рд╡реИрд╢реНрд╡рд┐рдХ рдореЛрдб рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рддрд╛ рд╣реИ
рдмрд┐рдЯ 6 (рд▓реА - рд╕реНрдерд╛рдиреАрдп рдмреНрд░реЗрдХрдкреНрд╡рд╛рдЗрдВрдЯ рд╕рдХреНрд╖рдо) - Dr3 5-4 рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗ рд▓рд┐рдП рд╕реНрдерд╛рдиреАрдп рдореЛрдб рдХреЛ рдЪрд╛рд▓реВ рдХрд░рддрд╛ рд╣реИ
, рд╡рд╣реА Dr1 рдХреЗ рд▓рд┐рдП Dr2
3-2 рдФрд░ Dr0

рдХрдиреНрдлреНрдпреВрдЬ рдХреЗ рд▓рд┐рдП 1-0 рд╕реЗ ?

рдареАрдХ рд╣реИ, рдлрд┐рд░ рдпрд╣рд╛рдВ рдЪрд┐рддреНрд░ рд╣реИ:

рдЫрд╡рд┐

рд╕реНрд░реЛрдд рдХреЛрдб рдХреЗ рд░реВрдк рдореЗрдВ, рд╕рдм рдХреБрдЫ рдХрд╛рдлреА рд╕рд░рд▓ рджрд┐рдЦрддрд╛ рд╣реИред

 procedure TFWDebugerCore.UpdateHardwareBreakpoints(ThreadIndex: Integer); const DR7_SET_LOC_DR0 = $01; DR7_SET_GLB_DR0 = $02; DR7_SET_LOC_DR1 = $04; DR7_SET_GLB_DR1 = $08; DR7_SET_LOC_DR2 = $10; DR7_SET_GLB_DR2 = $20; DR7_SET_LOC_DR3 = $40; DR7_SET_GLB_DR3 = $80; DR7_SET_LOC_ON = $100; DR7_SET_GLB_ON = $200; DR7_PROTECT = $2000; DR_SIZE_BYTE = 0; DR_SIZE_WORD = 1; DR_SIZE_DWORD = 3; DR_MODE_E = 0; DR_MODE_W = 1; DR_MODE_I = 2; DR_MODE_R = 3; DR7_MODE_DR0_E = DR_MODE_E shl 16; DR7_MODE_DR0_W = DR_MODE_W shl 16; DR7_MODE_DR0_I = DR_MODE_I shl 16; DR7_MODE_DR0_R = DR_MODE_R shl 16; DR7_SIZE_DR0_B = DR_SIZE_BYTE shl 18; DR7_SIZE_DR0_W = DR_SIZE_WORD shl 18; DR7_SIZE_DR0_D = DR_SIZE_DWORD shl 18; DR7_MODE_DR1_E = DR_MODE_E shl 20; DR7_MODE_DR1_W = DR_MODE_W shl 20; DR7_MODE_DR1_I = DR_MODE_I shl 20; DR7_MODE_DR1_R = DR_MODE_R shl 20; DR7_SIZE_DR1_B = DR_SIZE_BYTE shl 22; DR7_SIZE_DR1_W = DR_SIZE_WORD shl 22; DR7_SIZE_DR1_D = DR_SIZE_DWORD shl 22; DR7_MODE_DR2_E = DR_MODE_E shl 24; DR7_MODE_DR2_W = DR_MODE_W shl 24; DR7_MODE_DR2_I = DR_MODE_I shl 24; DR7_MODE_DR2_R = DR_MODE_R shl 24; DR7_SIZE_DR2_B = DR_SIZE_BYTE shl 26; DR7_SIZE_DR2_W = DR_SIZE_WORD shl 26; DR7_SIZE_DR2_D = DR_SIZE_DWORD shl 26; DR7_MODE_DR3_E = DR_MODE_E shl 28; DR7_MODE_DR3_W = DR_MODE_W shl 28; DR7_MODE_DR3_I = DR_MODE_I shl 28; DR7_MODE_DR3_R = DR_MODE_R shl 28; DR7_SIZE_DR3_B = DR_SIZE_BYTE shl 30; DR7_SIZE_DR3_W = DR_SIZE_WORD shl 30; DR7_SIZE_DR3_D = $C0000000; //DR_SIZE_DWORD shl 30; DR_On: array [THWBPIndex] of DWORD = ( DR7_SET_LOC_DR0, DR7_SET_LOC_DR1, DR7_SET_LOC_DR2, DR7_SET_LOC_DR3 ); DR_Mode: array [THWBPIndex] of array [THWBPMode] of DWORD = ( (DR7_MODE_DR0_E, DR7_MODE_DR0_W, DR7_MODE_DR0_I, DR7_MODE_DR0_R), (DR7_MODE_DR1_E, DR7_MODE_DR1_W, DR7_MODE_DR1_I, DR7_MODE_DR1_R), (DR7_MODE_DR2_E, DR7_MODE_DR2_W, DR7_MODE_DR2_I, DR7_MODE_DR2_R), (DR7_MODE_DR3_E, DR7_MODE_DR3_W, DR7_MODE_DR3_I, DR7_MODE_DR3_R) ); DR_Size: array [THWBPIndex] of array [THWBPSize] of DWORD = ( (DR7_SIZE_DR0_B, DR7_SIZE_DR0_W, DR7_SIZE_DR0_D), (DR7_SIZE_DR1_B, DR7_SIZE_DR1_W, DR7_SIZE_DR1_D), (DR7_SIZE_DR2_B, DR7_SIZE_DR2_W, DR7_SIZE_DR2_D), (DR7_SIZE_DR3_B, DR7_SIZE_DR3_W, DR7_SIZE_DR3_D) ); var Context: TContext; I: THWBPIndex; begin if ThreadIndex < 0 then Exit; ZeroMemory(@Context, SizeOf(TContext)); Context.ContextFlags := CONTEXT_DEBUG_REGISTERS; for I := 0 to 3 do begin if not FThreadList[ThreadIndex].Breakpoint.Active[I] then Continue; if FThreadList[ThreadIndex].Breakpoint.Address[I] <> nil then begin Context.Dr7 := Context.Dr7 or DR7_SET_LOC_ON; case I of 0: Context.Dr0 := DWORD(FThreadList[ThreadIndex].Breakpoint.Address[I]); 1: Context.Dr1 := DWORD(FThreadList[ThreadIndex].Breakpoint.Address[I]); 2: Context.Dr2 := DWORD(FThreadList[ThreadIndex].Breakpoint.Address[I]); 3: Context.Dr3 := DWORD(FThreadList[ThreadIndex].Breakpoint.Address[I]); end; Context.Dr7 := Context.Dr7 or DR_On[I]; Context.Dr7 := Context.Dr7 or DR_Mode[I, FThreadList[ThreadIndex].Breakpoint.Mode[I]]; Context.Dr7 := Context.Dr7 or DR_Size[I, FThreadList[ThreadIndex].Breakpoint.Size[I]]; end; end; Check(SetThreadContext(FThreadList[ThreadIndex].ThreadHandle, Context)); end; 


рдпрджрд┐ рдЖрдк рдХреЛрдб рд╕реЗ рдкрд╣рд▓реЗ рд╕реНрдерд┐рд░рд╛рдВрдХ рдХреЗ рдмреНрд▓реЙрдХ рдкрд░ рдзреНрдпрд╛рди рдирд╣реАрдВ рджреЗрддреЗ рд╣реИрдВ, рддреЛ Dr7 рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗ рдЖрд░рдВрдн рдХреЛ рддреАрди рд▓рд╛рдЗрдиреЛрдВ рдХреЗ рд╕рд╛рде рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

 Context.Dr7 := Context.Dr7 or DR_On[I]; Context.Dr7 := Context.Dr7 or DR_Mode[I, FThreadList[ThreadIndex].Breakpoint.Mode[I]]; Context.Dr7 := Context.Dr7 or DR_Size[I, FThreadList[ThreadIndex].Breakpoint.Size[I]]; 


рдЦреИрд░, DR7_SET_LOC_ON рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реВрдкрд┐рдд LE рдмрд┐рдЯ рдХреЗ рд╕рдорд╛рд╡реЗрд╢ рдХреЗ рдЕрд▓рд╛рд╡рд╛ред

рдЕрдм рд╣рдо HBP рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреА рдУрд░ рдореБрдбрд╝рддреЗ рд╣реИрдВред

рдЬрдм BP рдЯреНрд░рд┐рдЧрд░ рд╣реБрдЖ, рддреЛ рд╣рдореЗрдВ EXCEPTION_BREAKPOINT рдХреЛрдб рдкреНрд░рд╛рдкреНрдд рд╣реБрдЖред
рдЬрдм MVR рдЯреНрд░рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рддреЛ рдХреЛрдб EXCEPTION_GUARD_PAGE рдерд╛ред
рдФрд░ HBP рдкрд░ рд░реБрдХрд╛рд╡рдЯ рд╣реЛрдиреЗ рдкрд░, рд╣рдо EXCEPTION_SBLE_STEP рдХреЛрдб рдХреЗ рд╕рд╛рде рдПрдХ EXCEPTION_DEBUG_EVENT рдШрдЯрдирд╛ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рдЕрдиреНрдп рдмрд╛рддреЛрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдмреАрдкреА рдФрд░ рдПрдордмреАрдкреА рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрд╣рд╛рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЗрд╕рд▓рд┐рдП, рдореИрдВрдиреЗ рд▓реЗрдЦ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдЗрд╕рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рд╣рд╡рд╛рд▓рд╛ рдирд╣реАрдВ рджрд┐рдпрд╛)ред

рдЬрдм EXCEPTION_SINGLE_STEP рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ, рддреЛ HBP рд╣реИрдВрдбрд▓рд░ рдХреЛ рдкрд╣рд▓реЗ рд╡рд╛рд▓реЗ рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

 function TFWDebugerCore.ProcessHardwareBreakpoint(ThreadIndex: Integer; DebugEvent: TDebugEvent): Boolean; var Index: Integer; Context: TContext; ReleaseBP: Boolean; begin ZeroMemory(@Context, SizeOf(TContext)); Context.ContextFlags := CONTEXT_DEBUG_REGISTERS; Check(GetThreadContext(FThreadList[ThreadIndex].ThreadHandle, Context)); Result := Context.Dr6 and $F <> 0; if not Result then Exit; Index := -1; if Context.Dr6 and 1 <> 0 then Index := 0; if Context.Dr6 and 2 <> 0 then Index := 1; if Context.Dr6 and 4 <> 0 then Index := 2; if Context.Dr6 and 8 <> 0 then Index := 3; if Index < 0 then begin Result := False; Exit; end; ReleaseBP := False; if Assigned(FHardwareBreakpoint) then FHardwareBreakpoint(Self, ThreadIndex, DebugEvent.Exception.ExceptionRecord, Index, ReleaseBP); ToggleHardwareBreakpoint(ThreadIndex, Index, False); SetSingleStepMode(ThreadIndex, False); if ReleaseBP then DropHardwareBreakpoint(ThreadIndex, Index) else begin //   HWBP    , //  ..     //  ProcessExceptionSingleStep,   HWBP   //        HWBP if (FRestoredThread >= 0) and (FRestoredHWBPIndex >= 0) then ToggleHardwareBreakpoint(FRestoredThread, FRestoredHWBPIndex, True); FRestoredHWBPIndex := Index; FRestoredThread := ThreadIndex; end; end; 


рдЗрд╕рдХрд╛ рдХрд╛рд░реНрдп рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдирд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕ рд╡рд┐рд╢реЗрд╖ HBP рдиреЗ рд░реБрдХрд╛рд╡рдЯ рдХрд╛ рдХрд╛рд░рдг рдмрдирд╛, рдПрдХ рдмрд╛рд╣рд░реА рдШрдЯрдирд╛ рдХреЛ рдЯреНрд░рд┐рдЧрд░ рдХрд┐рдпрд╛ рдФрд░ рдЕрдВрддрд┐рдо рд░реВрдк рд╕реЗ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЛ рдЕрдВрдЬрд╛рдо рджрд┐рдпрд╛, рдЬреЛ рдмреАрдкреА рдФрд░ рдПрдорд╡реАрдЖрд░ рд╣реИрдВрдбрд▓рд░ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ред

HBP рд╕рдВрдЦреНрдпрд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдереНрд░реЗрдб рд╕рдВрджрд░реНрдн рд╕реЗ Dr6 рд░рдЬрд┐рд╕реНрдЯрд░ рдХрд╛ рдореВрд▓реНрдп рдкрдврд╝рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред
рдЗрд╕ рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗ рдирд┐рдЪрд▓реЗ 4 рдмрд┐рдЯреНрд╕ рдЭрдВрдбреЗ рд╣реИрдВ рдЬреЛ рдорд╛рди 1 рд▓реЗрддреЗ рд╣реИрдВ рдпрджрд┐ рд╕рдВрдмрдВрдзрд┐рдд DrX рд░рдЬрд┐рд╕реНрдЯрд░ рдиреЗ рдХрд╛рдо рдХрд┐рдпрд╛ рд╣реИред

рд╕рдм рдХреБрдЫ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ, рдЖрд╡рд╢реНрдпрдХ рдПрдирд╡реАрдЖрд░ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдПрдХ рдмрд╛рд╣рд░реА рдШрдЯрдирд╛ рдХрд╣рддреЗ рд╣реИрдВ, рдПрдирд╡реАрдЖрд░ рдХреЛ рдмрдВрдж рдХрд░ рджреЗрддреЗ рд╣реИрдВ, рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЛ рдЯреНрд░реЗрд╕ рдореЛрдб рдореЗрдВ рдбрд╛рд▓рддреЗ рд╣реИрдВ (рдИрдЖрдИрдкреА рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдХрд┐рдП рдмрд┐рдирд╛), рдлрд┐рд░ рдпрд╛ рддреЛ рдПрдирд╡реАрдЖрд░ рдХреЛ рд╣рдЯрд╛ рджреЗрдВ рдпрд╛ рджреЛ рдЪрд░ рдореЗрдВ рдЕрдкрдиреЗ рдЗрдВрдбреЗрдХреНрд╕ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░реЗрдВ, рдЬрд┐рд╕ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рддреЗ рд╣реБрдП EXCEPTION_SINGLE_STEP рд╣реИрдВрдбрд▓рд░ NVR рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдЧрд╛ред

рдЦреИрд░, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдПрдХ рддрд╛рд░реНрдХрд┐рдХ рдирд┐рд╖реНрдХрд░реНрд╖ рдкрд░ рдЖрдП рд╣реИрдВред
рдпрд╣ рдХреЗрд╡рд▓ EXCEPTION_SINGLE_STEP рд╣реИрдВрдбрд▓рд░ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИред

рдпрд╣ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

 procedure TFWDebugerCore.ProcessExceptionSingleStep(ThreadIndex: Integer; DebugEvent: TDebugEvent); var Handled: Boolean; begin //  HWBP Handled := ProcessHardwareBreakpoint(ThreadIndex, DebugEvent); //    - HWPB   HWBP if not Handled and (FRestoredThread >= 0) and (FRestoredHWBPIndex >= 0) then begin ToggleHardwareBreakpoint(FRestoredThread, FRestoredHWBPIndex, True); FRestoredThread := -1; FRestoredHWBPIndex := -1; end; //   if FRestoreBPIndex >= 0 then begin CheckBreakpointIndex(FRestoreBPIndex); if FBreakpointList[FRestoreBPIndex].bpType = btBreakpoint then ToggleInt3Breakpoint(FRestoreBPIndex, True); FRestoreBPIndex := -1; end; //  M if FRestoreMBPIndex >= 0 then begin CheckBreakpointIndex(FRestoreMBPIndex); if FBreakpointList[FRestoreMBPIndex].bpType = btMemoryBreakpoint then ToggleMemoryBreakpoint(FRestoreMBPIndex, True); FRestoreMBPIndex := -1; end; //         //     if ResumeAction <> raRun then begin CallUnhandledExceptionEvents(ThreadIndex, ecSingleStep, DebugEvent); //          DoResumeAction(ThreadIndex); end; end; 


рдЙрдирдХрд╛ рдХрд╛рд░реНрдп рд╢реБрд░реВ рдореЗрдВ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдирд╛ рд╣реИ рдХрд┐ HBP рдкрд░ рд░реЛрдХ рдХреЗ рдХрд╛рд░рдг рдХреЛрдИ рдЕрдкрд╡рд╛рдж рдЙрддреНрдкрдиреНрди рд╣реБрдЖ рд╣реИ рдпрд╛ рдирд╣реАрдВред рдпрджрд┐ рдпрд╣ рд╕рдЪ рд╣реИ, рддреЛ ToggleHardwareBreakpoint рдкрд░ рдХреЙрд▓ рдХрд░рдХреЗ HBP рдЕрдкрдиреА рдЬрдЧрд╣ рдкрд░ рд▓реМрдЯ рдЖрддрд╛ рд╣реИред
рдпрджрд┐ рдЕрдкрд╡рд╛рдж рдХреЛ рдЙрдард╛рдпрд╛ рдЧрдпрд╛ рдерд╛ рдХреНрдпреЛрдВрдХрд┐ рдмреАрдкреА рдпрд╛ рдПрдорд╡реАрдкреА рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рдмрд╛рдж рдЯреНрд░реЗрд╕ рдзреНрд╡рдЬ рдХреЛ рдЪрд╛рд▓реВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рддреЛ рд╡реИрд░рд┐рдПрдмрд▓ FRestoreBPIndex рдФрд░ FRestoreMBPIndex рдЙрд╕ рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рдХреЗ рд╕реВрдЪрдХрд╛рдВрдХ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░реЗрдЧрд╛, рдЬрд┐рд╕реЗ рдЕрдкрдиреА рдЬрдЧрд╣ рдкрд░ рд▓реМрдЯрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдЗрд╕рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдХреЙрд▓ ToggleInt3Breakpoint рдпрд╛ ToggleMemoryBreakpoint рддрд░реАрдХреЛрдВ рд╕реЗ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред

рдЕрднреНрдпрд╛рд╕:


рдореИрдВ рдбрд┐рдмрдЧрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╡рд░реНрдгрди рдХреЗ рд╕рд╛рде рдЗрд╕реЗ рд╕рдорд╛рдкреНрдд рдХрд░реВрдВрдЧрд╛, рд▓реЗрдХрд┐рди рдЕрдкрдирд╛ рд╕рдордп рд▓реЗ рд▓реЛ - рдХреБрдЫ рдФрд░ рдмрд┐рдВрджреБ рд╣реИрдВ рдЬреЛ рдореИрдВ рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рджрд┐рдЦрд╛рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред
рдЦреИрд░, рдЬреИрд╕рд╛ рдХрд┐ рдЙрд╕ рд╡рд┐рдорд╛рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдордЬрд╝рд╛рдХ рд╣реИ: "рдЕрдм рд╣рдо рдЗрд╕ рдкреВрд░реЗ рдбреЛрдВрдЧреА рдХреЛ рд╣рд╡рд╛ рдореЗрдВ рдЙрдард╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВрдЧреЗ" :)

рдЗрд╕рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рджреЛ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдЗрд╕реЗ рдбреАрдмрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВрдЧреЗред рдПрдХ рдирдпрд╛ VCL рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирд╛рдПрдВ, рдЗрд╕реЗ "test_app" рдирд╛рдо рд╕реЗ рд╕рд╣реЗрдЬреЗрдВ рдФрд░ рдлрд┐рд░ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВред

рдЕрдм рд╣рдо рдбрд┐рдмрдЧрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓рд┐рдЦреЗрдВрдЧреЗред рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд░реНрдпрд╛рдкреНрдд рдлреЙрд░реНрдо, рджреЛ рдмрдЯрди (рдбрд┐рдмрдЧрд┐рдВрдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╢реБрд░реВ рдХрд░рдиреЗ рдФрд░ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП) рдФрд░ TMemo рдпрд╛ TRichEdit рд╣реЛрдЧрд╛, рдЬрд╣рд╛рдВ рд╕рднреА рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХреА рдЬрд╛рдПрдЧреАред

рд╣рдо рд▓рд┐рдЦрддреЗ рд╣реИрдВ:

 type TdlgDebuger = class(TForm) Panel1: TPanel; btnStart: TButton; btnStop: TButton; edLog: TRichEdit; procedure btnStartClick(Sender: TObject); procedure btnStopClick(Sender: TObject); private FCore: TFWDebugerCore; FNeedStop: Boolean; procedure Writeln(const Value: string = ''); end; ... procedure TdlgDebuger.btnStartClick(Sender: TObject); var Path: string; begin FNeedStop := False; //        Path := ExtractFilePath(ParamStr(0)) + '..\test_app\test_app.exe'; FCore := TFWDebugerCore.Create(50); try btnStart.Enabled := False; btnStop.Enabled := True; if not FCore.DebugNewProcess(Path, True) then RaiseLastOSError; FCore.RunMainLoop; finally FCore.Free; btnStart.Enabled := True; btnStop.Enabled := False; end; Writeln; Writeln('Debug stop'); end; procedure TdlgDebuger.Writeln(const Value: string); begin edLog.Lines.Add(Value); end; procedure TdlgDebuger.btnStopClick(Sender: TObject); begin FNeedStop := True; end; 

рдЖрдкрдХреЛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рдорд┐рд▓рдирд╛ рдЪрд╛рд╣рд┐рдП:

рдЫрд╡рд┐

"рдкреНрд░рд╛рд░рдВрдн" рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВ, рдЕрдЧрд░ рд╕рдм рдХреБрдЫ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдкрд░реАрдХреНрд╖рдг рдЖрд╡реЗрджрди рд╢реБрд░реВ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред

рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдореБрдЦреНрдп рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдорд╛рдЙрд╕ рдФрд░ рдХреАрдмреЛрд░реНрдб рдХрдорд╛рдВрдб рдХрд╛ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рдЬрд╡рд╛рдм рджреЗрдирд╛ рдмрдВрдж рдХрд░ рджреЗрдЧрд╛ред

рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдпрд╣ TFWDebugerCore.RunMainLoop рдбрд┐рдмрдЧрд┐рдВрдЧ рдЪрдХреНрд░ рдХреЗ рдЕрдВрджрд░ рд╕реНрдерд┐рдд рд╣реИ, рдЬреЛ рд╕рдВрджреЗрд╢ рдХрддрд╛рд░ рднреНрд░реВрдг рдЪрдХреНрд░ рдХреЛ рдХреНрд░рд┐рдпрд╛рдиреНрд╡рд┐рдд рдХрд░рдиреЗ рд╕реЗ рд░реЛрдХрддрд╛ рд╣реИред

рдкрд░реАрдХреНрд╖рдг рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдмрдВрдж рдХрд░реЗрдВ, рдпрд╣ рдбрд┐рдмрдЧрд░ рдХреЛ рдбрд┐рдмрдЧрд┐рдВрдЧ рдЪрдХреНрд░ рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ рдФрд░ рдЦрд┐рдбрд╝рдХреА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рджреЗрдЧрд╛ред

рдЕрдЪреНрдЫреЗ рддрд░реАрдХреЗ рд╕реЗ, рдбрд┐рдмрдЧрд░ рдХреЛ рдПрдХ рдЕрд▓рдЧ рдереНрд░реЗрдб рдореЗрдВ рдЪрд▓рд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ (рдпрд╛ рдмрд▓реНрдХрд┐, рдПрдХ рдЕрдЪреНрдЫреЗ рддрд░реАрдХреЗ рд╕реЗ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдпрд╣ рд╕рд╣реА рддрд░реАрдХрд╛ рд╣реИ), рд▓реЗрдХрд┐рди рдЗрд╕реЗ рд▓реЙрдиреНрдЪ рдХрд┐рдП рдмрд┐рдирд╛ рднреА, рд╣рдо TFWDebugerCore рдХреНрд▓рд╛рд╕ рдХреЗ рдСрдирдЗрдпрд░ рдЗрд╡реЗрдВрдЯ рдХреЛ рдмрдВрдж рдХрд░рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рддрд░реАрдХреЗ рд╕реЗ рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рд▓рд┐рдЦрддреЗ рд╣реИрдВ:

 procedure TdlgDebuger.OnIdle(Sender: TObject); begin if FNeedStop then FCore.StopDebug else Application.ProcessMessages; end; 


Application.ProcessMessages рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рд╣рдорд╛рд░реЗ рдЖрд╡реЗрджрди рдХреЛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдзреАрдорд╛ рдирд╣реАрдВ рд╣реЛрдиреЗ рджреЗрдЧрд╛ред

рдЕрдм рдбреЗрд▓реНрдлреА рдбрд┐рдмрдЧрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдбрд┐рдмрдЧрд┐рдВрдЧ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, OnCreateProcess рдФрд░ OnLoadDll рд╕рдВрдЪрд╛рд▓рдХреЛрдВ рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВред

рдкрд╣рд▓реЗ рдореЗрдВ рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд▓рд┐рдЦрддреЗ рд╣реИрдВ:

 procedure TdlgDebuger.OnCreateProcess(Sender: TObject; ThreadIndex: Integer; Data: TCreateProcessDebugInfo); var T: TThreadData; begin T := FCore.GetThreadData(ThreadIndex); Writeln(Format('CreateThread ID: %d', [T.ThreadID])); Writeln(Format('ProcessStart ID: %d', [FCore.DebugProcessData.ProcessID])); end; 


рджреВрд╕рд░реЗ рдореЗрдВ, рдпрд╣ рдХреЛрдб:

 procedure TdlgDebuger.OnLoadDll(Sender: TObject; ThreadIndex: Integer; Data: TLoadDLLDebugInfo); const FormatStrKnownDLL = 'Load Dll at instance %p handle %d "%s"'; FormatStrUnknownDLL = 'Load unknown Dll at instance %p handle %d'; var DllName: AnsiString; IsUnicodeData: Boolean; begin FCore.ContinueStatus := DBG_EXCEPTION_NOT_HANDLED; IsUnicodeData := Data.fUnicode = 1; DllName := FCore.GetDllName(Data.lpImageName, Data.lpBaseOfDll, IsUnicodeData); if DllName <> '' then begin if IsUnicodeData then Writeln(Format(FormatStrKnownDLL, [Data.lpBaseOfDll, Data.hFile, PWideChar(@DllName[1])])) else Writeln(Format(FormatStrKnownDLL, [Data.lpBaseOfDll, Data.hFile, PAnsiChar(@DllName[1])])); end else Writeln(Format(FormatStrUnknownDLL, [Data.lpBaseOfDll, Data.hFile])); end; 


рдЙрд╕рдХреЗ рдмрд╛рдж, рд╣рдо рдбрд┐рдмрдЧрд┐рдВрдЧ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдВрдЧреЗ рдФрд░ "рд╕реНрдЯрд╛рд░реНрдЯ" рдмрдЯрди рджрдмрд╛рдПрдВрдЧреЗред

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП:

рдЫрд╡рд┐

рдареАрдХ рд╣реИ, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ - рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИред

рдЯреНрд░реЗрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди:


рдЕрдм рдбрд┐рдмрдЧрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВред рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЯреНрд░реЗрд╕рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рджреЛ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ, рдкрд╣рд▓рд╛ рдЯреАрдПрдл рдзреНрд╡рдЬ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рджреВрд╕рд░рд╛ рдПрдордмреАрдкреА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗред рд╣рдо рдкреНрд░реЛрдЧреНрд░рд╛рдо рдПрдВрдЯреНрд░реА рдкреЙрдЗрдВрдЯ рд╕реЗ рдкрд╣рд▓реЗ 40 рдмрд╛рдЗрдЯреНрд╕ рдЯреНрд░реЗрд╕ рдХрд░реЗрдВрдЧреЗред рдЖрдЗрдП рддреБрд░рдВрдд рджреЗрдЦреЗрдВ рдХрд┐ рд╡реЗ рдХреИрд╕реЗ рджрд┐рдЦрддреЗ рд╣реИрдВ:

рдЫрд╡рд┐

рдЕрдЪреНрдЫреЗ рдХреЗ рд▓рд┐рдП рдЯреНрд░реЗрд╕рд┐рдВрдЧ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрдВрддрдЬрд╛рд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рдЖрдк рдмреАрдкреА / рдПрдорд╡реАрдЖрд░ рдФрд░ рдЗрддрдиреЗ рдкрд░ рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдмрд┐рдВрджреБ рдкрд░ рдмреАрдкреА рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдмрдЧрд░ рдХреЛ рдмрддрд╛рдирд╛ рд╣реЛрдЧрд╛ред рдбреАрдмрдЧрдПрдирдкреНрд░реЛрд╕реЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рджреВрд╕рд░рд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА True рдкрд░ рд╕реЗрдЯ рд╣реИ, рдФрд░ рдпрд╣ рдХреЗрд╡рд▓ рдЗрд╕ BP рдХреЛ рдкреНрд░реЛрд╕реЗрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдСрдирдмреНрд░реИрдХрдкреЙрдЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ рдЬрд┐рд╕рдореЗрдВ рд╣рдордиреЗ рдЯреНрд░реЗрд╕ рдореЛрдб рд╕реЗрдЯ рдХрд┐рдпрд╛ рд╣реИред

 procedure TdlgDebuger.OnBreakPoint(Sender: TObject; ThreadIndex: Integer; ExceptionRecord: Windows.TExceptionRecord; BreakPointIndex: Integer; var ReleaseBreakpoint: Boolean); begin //      Writeln(Format('!!! --> Breakpoint "%s"', [FCore.BreakpointItem(BreakPointIndex).Description])); //   (    ) ReleaseBreakpoint := True; //    FCore.ResumeAction := raTraceInto; //     FStepCount := 0; end; 


рдЪреВрдВрдХрд┐ рдЕрдиреБрд░реЗрдЦрдг OnSingleStep рдИрд╡реЗрдВрдЯ рдХреА рдкреАрдврд╝реА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╣реЛрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЗрд╕реЗ рд▓рд╛рдЧреВ рднреА рдХрд░рддреЗ рд╣реИрдВ:

 procedure TdlgDebuger.OnSingleStep(Sender: TObject; ThreadIndex: Integer; ExceptionRecord: Windows.TExceptionRecord); begin //      Inc(FStepCount); Writeln(Format('!!! --> trace step тДЦ%d at addr 0x%p', [FStepCount, ExceptionRecord.ExceptionAddress])); //        if FStepCount > 10 then FCore.ResumeAction := raRun else FCore.ResumeAction := raTraceInto; end; 


рдкрд░рд┐рдгрд╛рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдирд┐рд╖реНрдХрд░реНрд╖ рд╣реЛрдЧрд╛:

рдЫрд╡рд┐

рд╣рдордиреЗ StepIn рдЯреНрд░реЗрд╕ рдХрд┐рдпрд╛, рдЯреНрд░реЗрд╕ рдХрд╛ рдкрд╛рдВрдЪрд╡рд╛рдВ рдЪрд░рдг рдЬреЛ 0x00409FF4 рдкрд░ рд╣реБрдЖ рдерд╛, рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╣рдореЗрдВ рджрд┐рдЦрд╛рддрд╛ рд╣реИ, рдпрд╣ _InitExe () рдлрд╝рдВрдХреНрд╢рди рдХреА рд╢реБрд░реБрдЖрдд рд╣реИ, рдЬрд┐рд╕реЗ 0x00409C53 рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдЕрдиреБрд░реЗрдЦрдг рдПрдХ рдзреАрдореА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╣реИ рдФрд░ рдореИрдВрдиреЗ _InitExe () рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рд╡рд╛рдкрд╕ рд▓реМрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдпрдВрддреНрд░рдг рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдирд╛ рд╢реБрд░реВ рдирд╣реАрдВ рдХрд┐рдпрд╛, рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд▓рд┐рдП рдореИрдВрдиреЗ рдЦреБрдж рдХреЛ рдПрдХ рджрд░реНрдЬрди рдЪрд░рдгреЛрдВ рддрдХ рд╕реАрдорд┐рдд рдХрд░ рд▓рд┐рдпрд╛ред

рджреВрд╕рд░рд╛ рдЯреНрд░реЗрд╕ рдореЛрдб MVR рдХреА рд╕реНрдерд╛рдкрдирд╛ рд╣реИред
рдЗрд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, OnPageGuard рдЗрд╡реЗрдВрдЯ рдХреЛ рдмреНрд▓реЙрдХ рдХрд░рдирд╛ рдФрд░ рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рдкрд░ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рд╢реВрдиреНрдп рдХреА рдПрдХ рдирд┐рдпрдВрддреНрд░рд┐рдд рдореЗрдореЛрд░реА рд░реЗрдВрдЬ рдХреЗ рд╕рд╛рде SetMemoryBreakpoint рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдбрд┐рдмрдЧрд░ рдХреЛ MBP рджреНрд╡рд╛рд░рд╛ рдореЙрдирд┐рдЯрд░ рдХрд┐рдП рдЬрд╛ рд░рд╣реЗ рдкреГрд╖реНрда рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрддрд╛ рдЪрд▓ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдЗрд╕ MBP рдХреЗ рд▓рд┐рдП рдСрдирдмреНрд░реЗрдХ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдирд╣реАрдВ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕ рдЕрдиреБрд░реЗрдЦрдг рд╡рд┐рдХрд▓реНрдк рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдЖрдкрдХреЗ рд╡рд┐рд╡реЗрдХ рдкрд░ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдореИрдВ рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рдПрдХ рд╕рдВрдХреЗрдд рджреЗрддрд╛ рд╣реВрдВ, рдпрд╣ рдЕрддреНрдпрдзрд┐рдХ рдЕрдиреБрд╢рдВрд╕рд╛ рдХреА рдЬрд╛рддреА рд╣реИ рдХрд┐ рдбреАрдмрдЧ рдЗрд╡реЗрдВрдЯ рд╕рдВрдЪрд╛рд▓рдХреЛрдВ (рдЗрдВрдбреЗрдХреНрд╕ рдЧрд╛рдпрдм рд╣реЛ рдЬрд╛рдП) рд╕реЗ RemoveBreakpoint рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рди рдХрд░реЗрдВ, рдмреАрдкреА / рдПрдордмреАрдкреА / рдПрдЪрдмреАрдкреА рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рджреЛ рддрд░реАрдХреЗ рд╣реИрдВ, рдЬрдм рдмреАрдкреА рд╣реИрдВрдбрд▓рд░ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред , рдпрд╛ рдХрд┐рд╕реА рднреА рд╣реИрдВрдбрд▓рд░ рдореЗрдВ рдЙрдкрд▓рдмреНрдз RemoveCurrentBreakpoint рдкреНрд░рдХреНрд░рд┐рдпрд╛ред рд╕рдВрднрд╡рддрдГ TFWDebugerCore рд╡рд░реНрдЧ рдХреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдЗрд╕ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛,рд▓реЗрдХрд┐рди рдХреБрдЫ рд╕рдордп рдХреЗ рд▓рд┐рдП, рдРрд╕рд╛ рд╡рд┐рдХрд▓реНрдк рдЬрд╛рдПрдЧрд╛ред

рдЯреНрд░реЗрд╕рд┐рдВрдЧ, рдЬрд╝рд╛рд╣рд┐рд░ рд╣реИ, рдЕрдЪреНрдЫрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рд▓реЗрдЦ рдХреЗ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рднрд╛рдЧ рдореЗрдВ рдмрд╛рдд рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛, рдЗрд╕рд▓рд┐рдП рд▓реЗрдЦ рдХреЗ рд╕рд╛рде рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдбреЗрдореЛ рдореЗрдВ рдХреЛрдИ рдЕрдиреБрд░реЗрдЦрдг рдЙрджрд╛рд╣рд░рдг рдирд╣реАрдВ рд╣реИрдВред

рдбрд┐рдмрдЧ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛:

рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреА рд░рд╕реАрдж рджрд┐рдЦрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдХрд┐ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдбреАрдмрдЧрд░ рдХреЛ OutputDebugString рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рднреЗрдЬрддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкрд░реАрдХреНрд╖рдг рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдмрдЯрди рд░рдЦреЗрдВ рдФрд░, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕рдХреЗ рд╣реИрдВрдбрд▓рд░ рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рд▓рд┐рдЦреЗрдВ:

 // //    // ============================================================================= procedure TForm1.btnDebugStringClick(Sender: TObject); begin OutputDebugString('Test debug string'); end; 


рдлрд┐рд░, рдбрд┐рдмрдЧрд░ рдореЗрдВ, рдирд┐рдореНрди рдХреЛрдб рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдХреЗ OnDebugString рдИрд╡реЗрдВрдЯ рдХреЛ рдмрдВрдж рдХрд░реЗрдВ:

 procedure TdlgDebuger.OnDebugString(Sender: TObject; ThreadIndex: Integer; Data: TOutputDebugStringInfo); begin if Data.fUnicode = 1 then Writeln('DebugString: ' + PWideChar(FCore.ReadStringW(Data.lpDebugStringData, Data.nDebugStringLength))) else Writeln('DebugString: ' + PAnsiChar(FCore.ReadStringA(Data.lpDebugStringData, Data.nDebugStringLength))); end; 


рдбреАрдмрдЧрд░ рдЪрд▓рд╛рдПрдБ, рдЗрд╕рдореЗрдВ рдбреАрдмрдЧ рдХрд┐рдП рдЧрдП рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдФрд░ рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВред рд╕рдВрджреЗрд╢ "рдЯреЗрд╕реНрдЯ рдбрд┐рдмрдЧ рд╕реНрдЯреНрд░рд┐рдВрдЧ" рд▓реЙрдЧ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ? рдпрджрд┐ рд╣рд╛рдБ, рддреЛ рд╕рдм рдХреБрдЫ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ :)

рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд┐рдВрдЧ:

рдпрд╛рдж рд░рдЦреЗрдВ, рдореИрдВрдиреЗ рдмреАрдкреА рдХреЛ рдПрдХ рдбрд┐рдмрдЧрд┐рдВрдЧ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХреА рдереА? рдЕрдм рдЙрд╕реА рд╡рд┐рдХрд▓реНрдк рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред рдкрд░реАрдХреНрд╖рдг рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ, рдПрдХ рдФрд░ рдмрдЯрди рдЬреЛрдбрд╝реЗрдВ рдФрд░ рдЙрд╕рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рд▓рд┐рдЦреЗрдВ:

 // //       // ============================================================================= procedure TForm1.btnExceptClick(Sender: TObject); begin try asm int 3 end; ShowMessage('Debugger detected.'); except ShowMessage('Debugger not found.'); end; end; 


рдпрд╣, рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рд╡рд┐рд░реЛрдзреА рдбрд┐рдмрдЧрд┐рдВрдЧ рднреА рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдЬреАрдм рддрд░рд╣ рд╕реЗ рдХрднреА-рдХрднреА рдХреБрдЫ рдЙрд▓рдЯрдлреЗрд░ рдРрд╕реА рдкреНрд░рд╛рдЗрдорд░реА рд╕реНрдХреАрдо рдкрд░ рднреА рдЭреБрд▓рд╕ рд░рд╣реЗ рд╣реИрдВред

рдЗрд╕ рдкрджреНрдзрддрд┐ рдХрд╛ рд╕рд╛рд░ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ: рд▓реЗрдЦ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдореИрдВрдиреЗ рдбрд┐рдмрдЧрд┐рдВрдЧ рдЪрдХреНрд░ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛, рдЗрд╕рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдкрд░, ContinueStatus рдкреИрд░рд╛рдореАрдЯрд░, рдЬрд┐рд╕рдХреЗ рд╕рд╛рде ContinueDebugEvent рдлрд╝рдВрдХреНрд╢рди рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, DBG_CONTINUE рдирд┐рд░рдВрддрд░ рдХреЗ рд╕рд╛рде рдкреНрд░рд╛рд░рдВрдн рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдЗрд╕рдХрд╛ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИ?рдпрд╣ рдПрдХ рд╕рдВрдХреЗрдд рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдбрд┐рдмрдЧрд░ рдиреЗ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдЙрд╕ рдЕрдкрд╡рд╛рдж рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рд╣реИ рдЬреЛ рдЖрдЧреЗ рдЙрддреНрдкрдиреНрди рд╣реБрдЖ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рд╕рд╛рде рдЖрдЧреЗ рдмрдврд╝рдиреЗ рд▓рд╛рдпрдХ рдирд╣реАрдВ рд╣реИред

рдЦреИрд░, рдЕрдм рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдЗрд╕рдХрд╛ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИ: "INT3" рдирд┐рд░реНрджреЗрд╢ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдХреЗ, рд╣рдо рдПрдХ рдЕрдкрд╡рд╛рдж рдмрдврд╝рд╛рддреЗ рд╣реИрдВред рдЖрд╡реЗрджрди рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рд╕рдВрдЪрд╛рд▓рди рдХреЗ рджреМрд░рд╛рди, рдЗрд╕ рдЕрдкрд╡рд╛рдж рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЬрдм рдРрд╕рд╛ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдЕрдкрд╡рд╛рдж рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХреНрд░рдордг..рд╣реИрдВрдбрд▓рд░ рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдХрд╣рддреЗ рд╣реИрдВ рдХрд┐ рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реИред рдпрджрд┐ рд╣рдо рдбрд┐рдмрдЧрд░ рдХреЗ рдЕрдзреАрди рд╣реИрдВ, рддреЛ рд╡рд╣ рдЗрд╕ рдЕрдкрд╡рд╛рдж рдХреЛ рдкрдХрдбрд╝ рд▓реЗрдЧрд╛ рдФрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реИрдВрдбрд▓рд░ рдХреЛ рдирд╣реАрдВ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдЖрдк рдЖрд╡реЗрджрди рдХреА рдЬрд╛рдВрдЪ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕ рдХреЛрдб рдХреЗ рд╕рд╛рде рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣ рдЖрдкрдХреЛ рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ рдмрддрд╛рдПрдЧрд╛ - рд╣рдо рдбрд┐рдмрдЧрд░ рдХреЗ рдЕрдзреАрди рд╣реИрдВред

рдпрд╣ рдЗрд╕ рдХреЛрдб рдХреЛ рдкрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╕ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рд░рд▓ рд╣реИ, рдпрд╣ OnUnognBreakPoint рдИрд╡реЗрдВрдЯ рдХреЛ рдмреНрд▓реЙрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ (int3 рдПрдХ рдмреНрд░реЗрдХрдкреЙрдЗрдВрдЯ рд╣реИ, рдФрд░ рдпрд╣ рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рд╕реЗрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЗрд╕рд▓рд┐рдП, рдпрд╣ рдЗрд╕ рдИрд╡реЗрдВрдЯ рдореЗрдВ рдкрдХрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛)ред рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдореЗрдВ, рдирд┐рдореНрди рдХреЛрдб рд▓рд┐рдЦреЗрдВ:

 procedure TdlgDebuger.OnUnknownBreakPoint(Sender: TObject; ThreadIndex: Integer; ExceptionRecord: Windows.TExceptionRecord); var ApplicationBP: Boolean; begin ApplicationBP := (DWORD(ExceptionRecord.ExceptionAddress) > FCore.DebugProcessData.EntryPoint) and (DWORD(ExceptionRecord.ExceptionAddress) < $500000); Writeln; if ApplicationBP then begin Writeln(Format('!!! --> Unknown application breakpoint at addr 0X%p', [ExceptionRecord.ExceptionAddress])); Writeln('!!! --> Exception not handled.'); FCore.ContinueStatus := DBG_EXCEPTION_NOT_HANDLED; end else begin Writeln(Format('!!! --> Unknown breakpoint at addr 0X%p', [ExceptionRecord.ExceptionAddress])); Writeln('!!! --> Exception handled.'); FCore.ContinueStatus := DBG_CONTINUE; end; Writeln; end; 


рдЗрд╕рдореЗрдВ рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИ, рдЬрд┐рд╕ рдкрддреЗ рдкрд░ рдмреАрдкреА рд╕реНрдерд╛рдкрд┐рдд рд╣реИ, рдЙрд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╣рдо рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмреЙрдбреА рдореЗрдВ рдЙрд╕рдХрд╛ рд╕реНрдерд╛рди рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдпрд╛ рдирд╣реАрдВ (рдореЛрдЯреЗ рддреМрд░ рдкрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдбрд╛рдЙрдирд▓реЛрдб рдкрддреЗ рд╕реЗ $ 500,000 рддрдХ рдХреА рд╕реАрдорд╛ рд▓реЗрддреЗ рд╣реИрдВ)ред рдпрджрд┐ рдЖрд╡реЗрджрди рдХреЗ рд╢рд░реАрд░ рдореЗрдВ рдмреАрдкреА рд╕реНрдерд╛рдкрд┐рдд рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдПрдВрдЯреА-рдбрд┐рдмрдЧрд┐рдВрдЧ рд╣реИред рд╣рдо рдбрд┐рдмрдЧрд░ рд╕реЗ рдХрд╣рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдореЗрдВ рдкрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ DBG_EXCEPTION_NOT_HANDLED рдзреНрд╡рдЬ рд╕реЗрдЯ рдХрд░рдХреЗ рдЗрд╕рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ, рдЕрдиреНрдпрдерд╛ рд╣рдо рдмрд╕ рдЙрд╕ рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рд▓реЙрдЧ рдЗрди рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдХреЛрдИ рдФрд░ рд╡реНрдпрдХреНрддрд┐ рдмреНрд░реЗрдХрдкреНрд╡рд╛рдЗрдВрдЯ рдХреЗ рд╕рд╛рде рдЦреЗрд▓ рд░рд╣рд╛ рд╣реИред

рдЗрд╕ рддрд░рд╣ рдХреЗ рдЗрд╢рд╛рд░реЛрдВ рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдЖрд╡реЗрджрди рджреНрд╡рд╛рд░рд╛ рдХреГрддреНрд░рд┐рдо рд░реВрдк рд╕реЗ рдЙрдард╛рдП рдЧрдП рдЕрдкрд╡рд╛рдж рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдпрд╣ рд╣рдореЗрдВ рдЦреБрд╢реА рд╕реЗ рд╕реВрдЪрд┐рдд рдХрд░реЗрдЧрд╛ рдХрд┐ рдпрд╣ рдбрд┐рдмрдЧрд░ рдХрд╛ рдкрддрд╛ рдирд╣реАрдВ рд▓рдЧрд╛рддрд╛ рд╣реИ :)

рд╕реНрдЯреИрдХ рдУрд╡рд░рдлреНрд▓реЛ рд╣реЛрдиреЗ рдкрд░ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ:

рдЦреИрд░, рдЖрдЦрд┐рд░реА рдмрд╛рдд рдореИрдВ рдЖрдкрдХреЛ рджрд┐рдЦрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдХрд┐ рдбрд┐рдмрдЧрд░ рдХреЗ рдХрд┐рдирд╛рд░реЗ рд╕реЗ рд╕реНрдЯреИрдХ рдУрд╡рд░рдлреНрд▓реЛ рдХреИрд╕реЗ рджрд┐рдЦрддрд╛ рд╣реИред рдореИрдВ рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╕реЗ рдЕрддрд┐рдкреНрд░рд╡рд╛рд╣ рдХрд╛ рдЙрджрд╛рд╣рд░рдг рд▓реВрдВрдЧрд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ рддрд░рд╣:

 // //      // ============================================================================= procedure TForm1.btnKillStackClick(Sender: TObject); procedure T; var HugeBuff: array [0..10000] of DWORD; begin if HugeBuff[0] <> HugeBuff[10000] then Inc(HugeBuff[0]); T; end; begin try T; except T; end; end; 


рдкрд░реАрдХреНрд╖рдг рдХреЛрдб рдореЗрдВ рдЗрд╕ рдХреЛрдб рдХреЛ рдЬреЛрдбрд╝реЗрдВ рдФрд░ рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВред рдбрд┐рдмрдЧрд░ рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рднрд┐рдиреНрди рд╣реЛ рд╕рдХрддреА рд╣реИ, рд▓реЗрдХрд┐рди рдкрд░рд┐рдгрд╛рдо рд╣рдореЗрд╢рд╛ рдПрдХ рд╣реА рд╣реЛрдЧрд╛ - рдбреАрдмрдЧрд░ рдмрд╣реБрдд рдЦрд░рд╛рдм рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ? рд╕реНрдЯреИрдХ рдУрд╡рд░рдлреНрд▓реЛ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рддрдВрддреНрд░ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ, рдЬрд┐рд╕ рд╕реАрдорд╛ рдХреЛ рдкрд╛рд░ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЙрд╕реЗ PAGE_GUARD рдзреНрд╡рдЬ рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рдПрдХ рдЕрд▓рдЧ рдкреГрд╖реНрда рджреНрд╡рд╛рд░рд╛ рджрд░реНрд╢рд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдареАрдХ рд╣реИ, рд╣рд╛рдБ, рдпрд╣ рд╡рд╣реА рддрдВрддреНрд░ рд╣реИ рдЬрд┐рд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ рд╣рдо рдЕрдкрдирд╛ рдПрдорд╡реАрдЖрд░ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрдиреНрдп рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдУрд╡рд░рдлреНрд▓реЛ рдХрд░рддреЗ рд╕рдордп, EXCEPTION_STACK_OVERFLOW рдбреАрдмрдЧрд░ рдХреЛ рдПрдХ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕реВрдЪрдирд╛ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдЧреАред рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдпрд╣реАрдВ рдЖрдк "рд╕реВрдЕрд░ рдХреЛ рд╕реБрдЦрд╛ рд╕рдХрддреЗ рд╣реИрдВ" рдФрд░ рдбрд┐рдмрдЧрд░ рдХреЛ рдмрдВрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╣рдо рд▓рдЧрд╛рддрд╛рд░ рд╣реИрдВ рдФрд░ рдЖрдЧреЗ рдкрд░реАрдХреНрд╖рдг рдЖрд╡реЗрджрди рд╢реБрд░реВ рдХрд░реЗрдВрдЧреЗред рдпрджрд┐ рдЖрдкрдХреЛ рдпрд╛рдж рд╣реИ, PAGE_GUARD рдзреНрд╡рдЬ рдХреА рдмрд╛рд░реАрдХрд┐рдпрд╛рдБ рдпрд╣ рд╣реИ рдХрд┐ рдкрд╣рд▓реА рдХреЙрд▓ рдХреЗ рдмрд╛рдж рдЗрд╕реЗ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрд╣рд╛рдБ рднреА рдРрд╕рд╛ рд╣реА рдорд╛рдорд▓рд╛ рд╣реИредрдЗрд╕ рдкреГрд╖реНрда рдкрд░ рдлрд┐рд░ рд╕реЗ рдкрд╣реБрдВрдЪрдиреЗ рдкрд░, рд╣рдо EXCEPTION_ACCESS_VIOLATION рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдФрд░ рдХреБрдЫ рдирд╣реАрдВ рдкрдХрдбрд╝реЗрдВрдЧреЗ рдФрд░ рдпрд╣рд╛рдБ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ "рд╕рдм рдХреБрдЫ" рд╣реИ, рдЗрд╕рд╕реЗ рдЕрдм рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИ, рдпрд╣ рдХреЗрд╡рд▓ DBG_CONTROL_C рд╕реЗрдЯ рдХрд░рдиреЗ рдФрд░ рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдмрдиреА рд╣реБрдИ рд╣реИ (рдареАрдХ рд╣реИ, рдЬрдм рддрдХ рдХрд┐ рдЖрдк рд╕рддрдд рдЪрдХреНрд░ рдХрд╛ рдирд┐рд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдПрд╡реА рдЬрд╛рд░реА рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде)ред

рд╣рдо OnUnognException рдЗрд╡реЗрдВрдЯ рдореЗрдВ рдУрд╡рд░рдлрд╝реНрд▓реЛ рд╣реИрдВрдбрд▓рд░ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ TFWDebugerCore рдЗрди рджреЛ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдШрдЯрдирд╛рдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдирд╣реАрдВ рдлреЗрдВрдХрддрд╛ рд╣реИред рд╣рдо рдЗрд╕рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд▓рд┐рдЦреЗрдВрдЧреЗ:

 procedure TdlgDebuger.OnUnknownException(Sender: TObject; ThreadIndex: Integer; ExceptionRecord: Windows.TExceptionRecord); var Cause: string; begin Writeln; case ExceptionRecord.ExceptionCode of EXCEPTION_STACK_OVERFLOW: begin Writeln('!!! --> Stack overflow detected. Probe to continue.'); FCore.ContinueStatus := DBG_CONTINUE; end; EXCEPTION_ACCESS_VIOLATION: begin { The first element of the array contains a read-write flag that indicates the type of operation that caused the access violation. If this value is zero, the thread attempted to read the inaccessible data. If this value is 1, the thread attempted to write to an inaccessible address. If this value is 8, the thread causes a user-mode data execution prevention (DEP) violation. The second array element specifies the virtual address of the inaccessible data. } case ExceptionRecord.ExceptionInformation[0] of 0: Cause := 'read'; 1: Cause := 'write'; 8: Cause := 'DEP violation'; else Cause := 'unknown cause'; end; Writeln(Format('!!! --> Access violation at addr 0x%p %s of address 0x%p', [ ExceptionRecord.ExceptionAddress, Cause, Pointer(PDWORD(@ExceptionRecord.ExceptionInformation[1])^) ])); Writeln('!!! --> Process Stopped.'); FCore.ContinueStatus := DBG_CONTROL_C; end; else Writeln(Format('!!! --> Unknown exception code %p at addr 0x%p', [ Pointer(ExceptionRecord.ExceptionCode), ExceptionRecord.ExceptionAddress ])); end; Writeln; end; 


рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдмрджрд▓рдирд╛ рдЪрд╛рд╣рд┐рдП:

рдЫрд╡рд┐

рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ:


рдореВрд▓ рд░реВрдк рд╕реЗ, рдпрд╣ рд╕рдм рдореИрдВ рдбрд┐рдмрдЧрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред рдХреБрдЫ рдЕрдкреНрд░рдХрд╛рд╢рд┐рдд рд╡рд┐рд╖рдп рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╡реЗ рддреАрд╕рд░реЗ рднрд╛рдЧ рдореЗрдВ рд╣реЛрдВрдЧреЗред
рдореБрдЭреЗ рдЦреЗрдж рд╣реИ рдХрд┐ рдпрд╣ рд▓реЗрдЦ рдмрд╣реБрдд рдмрдбрд╝рд╛ рдирд┐рдХрд▓рд╛, рд▓реЗрдХрд┐рди рдЕрдлрд╕реЛрд╕, рдЗрд╕реЗ рдЫреЛрдЯреЗ рднрд╛рдЧреЛрдВ рдореЗрдВ рддреЛрдбрд╝рдиреЗ рдХрд╛ рдХрд╛рдо рдирд╣реАрдВ рдХрд┐рдпрд╛ред рдХрдо рд╕реЗ рдХрдо рдореИрдВрдиреЗ рд╕реВрдЦреЗ рддрдереНрдпреЛрдВ рдХреЛ рдирд╣реАрдВ рджреЗрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА, рд▓реЗрдХрд┐рди рдЖрдорддреМрд░ рдкрд░ рддрдХрдиреАрдХреА рд▓реЗрдЦреЛрдВ рдореЗрдВ рдЫреЛрдбрд╝реА рдЧрдИ рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рдкрд░ рдЕрдзрд┐рдХрддрдо рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреАред
рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдРрд╕реЗ рд▓реЛрдЧ рд╣реЛрдВрдЧреЗ рдЬреЛ рдЗрд╕ рд╕рд╛рдордЧреНрд░реА рдХреЛ рдЙрдкрдпреЛрдЧреА рдкрд╛рддреЗ рд╣реИрдВ :)

рд▓реЗрдЦ рдХреЗ рд▓рд┐рдП рд╕реНрд░реЛрдд рдХреЛрдб рдЗрд╕ рд▓рд┐рдВрдХ рдкрд░ рдбрд╛рдЙрдирд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ: http://rouse.drkb.ru/blog/dbg_part2.zip

рдЦреИрд░, рд▓реЗрдЦ рдХреЗ рддреАрд╕рд░реЗ рднрд╛рдЧ рдореЗрдВ рд╣рдо рдбрд┐рдмрдЧрд░ рдХреЗ рдЖрд╡реЗрджрди рдкрд░ рд╡рд┐рд░реЛрдз рдХреЛ рджреЗрдЦреЗрдВрдЧреЗ, рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рдбрд┐рдмрдЧ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ :)

рдФрд░ рдЗрд╕ рдкрд░ рдореЗрд░реЗ рдкрд╛рд╕ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рдм рдХреБрдЫ рд╣реИред

┬й рдЕрд▓реЗрдХреНрдЬреЗрдВрдбрд░ (Rouse_) Bagel
рдореЙрд╕реНрдХреЛ, рдирд╡рдВрдмрд░ 2012

Source: https://habr.com/ru/post/In178159/


All Articles