-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathdebug.pas
174 lines (142 loc) · 3 KB
/
debug.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
unit debug;
{$IFDEF FPC}
{$MODE Delphi}
{$ENDIF}
interface
uses Windows, LCLIntf, LCLType, LMessages;
procedure Log(S : String);
type DebugEvent = procedure (S : String) of object;
procedure SetDebug(d : DebugEvent);
procedure UseWriteln;
procedure UseStdError;
procedure HexDump(P : PChar; Length : Integer);
type TWriteLine = class
public
procedure WriteLine(S : String);
end;
type TStdError = class
private
h : THandle;
public
constructor Create;
procedure Write(S : String);
procedure WriteLine(S : String);
end;
function IsDebuggerPresent : Boolean;
var
stderr : TStdError;
implementation
uses WinIOCTL, sysutils;
var
fOnDebug : DebugEvent;
type TIsDebuggerPresent = function : BOOL; stdcall;
procedure Log(S : String);
begin
if Assigned(fOnDebug) then
begin
fOnDebug(s);
end;
end;
procedure SetDebug(d : DebugEvent);
begin
fOnDebug := d;
end;
procedure TWriteLine.WriteLine(S : String);
begin
{$IFDEF FPC}
Writeln(S + #13);
{$ELSE}
Writeln(Output, S);
{$ENDIF}
end;
constructor TStdError.Create;
begin
h := GetStdHandle(STD_ERROR_HANDLE);
end;
procedure TStdError.Write(S : String);
var
Done : DWORD;
begin
WriteFile2(h, PChar(S), Length(S), done, nil);
end;
procedure TStdError.WriteLine(S : String);
var
Done : DWORD;
begin
S := S + #13 + #10;
WriteFile2(h, PChar(S), Length(S), done, nil);
end;
procedure UseWriteln;
var
wl : TWriteLine;
begin
wl := TWriteLine.Create;
SetDebug(wl.WriteLine);
end;
procedure UseStdError;
begin
stderr := TStdError.Create;
SetDebug(stderr.WriteLine);
end;
function IsDebuggerPresent : Boolean;
var
hModule : hInst;
// Error : DWORD;
JIsDebuggerPresent : TIsDebuggerPresent;
P : Pointer;
begin
Result := False;
// see if we can get IsDebuggerPresent from kernel32.dll
hModule := GetModuleHandle('kernel32.dll');
if hModule = 0 then
begin
// wininet is not yet loaded...
hModule := LoadLibrary('kernel32.dll');
{if hModule = 0 then
begin
Error := GetLastError;
//raise Exception.Create('Error loading Windows Internet Library. ' + SysErrorMessage(Error));
end;}
end;
if hModule <> 0 then
begin
P := GetProcAddress(hModule, 'IsDebuggerPresent');
if P = nil then
begin
//raise Exception.Create('Could not find procedure ' + ProcName);
end
else
begin
JIsDebuggerPresent := p;
Result := JIsDebuggerPresent;
end;
end;
end;
procedure HexDump(P : PChar; Length : Integer);
var
S : String;
S2 : String;
i : Integer;
begin
S := '0000 ';
for i := 0 to Length - 1 do
begin
S := S + IntToHex(Ord(P[i]), 2);
if not (ord(P[i]) in [0, 7, 8, 9, 10, 13]) then
begin
S2 := S2 + P[i];
end
else
begin
S2 := S2 + ' ';
end;
S := S + ' ';
if System.Length(S) >= 52 then
begin
Log(S + ' ' + S2);
S := IntToHex(i + 1, 4) + ' ';
s2 := '';
end;
end;
end;
end.