-
Notifications
You must be signed in to change notification settings - Fork 2
/
edb.doc
410 lines (333 loc) · 17.3 KB
/
edb.doc
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
#if 0 /* ;) */
File name: edb.doc, It can't be called the complete documentation,
but it is all I have...
x86 Emulating Debugger (EDB)
Copyright (C) 1991-1993 Serge Pachkovsky
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
If you need to contact me, feel free to write to [email protected]
or to Serge Pachkovsky, Erligatterweg 61, Zuerich CH 8038, Switzerland
#endif
Emulating debugger (EDB)
------------------------
Emulating debugger (EDB) was designed to debug 'undebuggable' programs.
EDB is able to browse thru programs what use trace and debug interrupts to
decrypt own code, executes from video RAM, temporarily overwrite BIOS and DOS
data areas, disables hardware interrupts, etc. All this with a small fraction
of efforts used to develop protected program (often with no efforts at all)
and without any hardware debugging capabilities necessary. EDB.COM supplied
with C.U.T. was compiled for 80286/80386 instruction set. Version for
8086/8088 is available on request.
* * * * * * * * * * * * NOTE * * * * * * * * * * * * * * * *
It is not recommended to compress EDB executable file image.
Although EDB will work correctly, it will be unable to
provide program being debugged with undocumented values in
CPU registers at start time. These values depend upon DOS
maker and version and are generally destroyed by
decompression stubs.
* * * * * * * * * * * END NOTE * * * * * * * * * * * * * * *
You can interrupt EDB by pressing Shift-Alt-Ctrl (all keys left)
simultaneously. After a small delay (EDB checks for break request each 5000
instructions) EDB prompt will appear.
EDB has only three command line switches:
/G - Grow EDB by one segment (see EXERECON.COM for explanation)
/I - Disable local IDT feature. EDB, when run on 80286 or later CPU,
makes undocumented use of protected mode LIDT instruction to provide
itself with local interrupt description table. When EDB detects
incompatible protected mode environment (QEMM/386, 386^MAX, Windows
3.0, etc.), it disables local IDT. Still, EDB can't detect programs,
which access extended memory via INT 15h/87h BIOS call, clearing IDT
register in CPU. /I permits to run EDB in such environment.
(Microsoft HIMEM.SYS and other software accessing extended memory
with LOADALL instruction (80286) or in huge real mode (80386) is
perfectly compatible with EDB's IDT moving). Another case then you
could be forced to use /I switch is running EDB under DesqView (or any
other multitasker on 286 machines), which can't keep track of IDT's in
user space.
/J:name - Start reading journal 'name.jou' (See 'JR' command).
All other options important for EDB operations are in file 'CONFIG.EDB',
which should be in current directory when EDB is started. CONFIG.EDB is
divided into sections, controlling different parts of EDB. At the very
beginning of each section it's name is placed in square brackets (a-la
Win.Ini). Then parameters of this section follow, specified in general
format ParameterName = Value. Order in which sections appear in configuration
file is perfectly indifferent to EDB, all sections with unknown tags are
ignored (and so is all lines beginning with ';').Currently, the following
sections should be present in CONFIG.EDB:
'[System bus]' section describes CPU's interactions with outside world.
It contains the following parameters:
WrapA20 = {Off|On}
Specifies state of A20 processor gate. Some programs rely on A20 to
be permanently closed, which is not the case with HIMEM.SYS present.
DisablePort = PortNumber
Obsolete. Ignore it.
DataVector = Number
DataVector = Begin-End
Vectors mentioned as data vectors will appear in program address space as
is, thus providing access to tables pointed by them. All other vectors
will appear as 0001:Vector_Number. Vectors not mentioned in DataVector
will potentially cause trouble with 'GF' command, while DataVector'ed
vectors will rely significantly on ProgramTop/ProgramBottom settings.
You should experiment to find settings which suit you best.
MonitorVector = Number
EDB will route hardware interrupts occurring on vector 'number' to program
being debugged. Meaningful values are from the following list (although up
to any 5 values from 00 to FF will be accepted):
02 - NMI - Coprocessor, parity
08 - IRQ 0 - System timer
[ 09 - IRQ 1 - Keyboard ]
0A - IRQ 2 - Cascade on AT, VGA, LPT3
0B - IRQ 3 - COM2
0C - IRQ 4 - COM1
0D - IRQ 5 - LPT2
0E - IRQ 6 - Floppy
0F - IRQ 7 - LPT1
Although 09 (Keyboard) can be used, EDB will not be able to accept
keyboard commands and should be controlled entirely from journal file.
InterruptDelay = Number
Instructs EDB to delay recognition of interrupt by Number instructions.
InterruptDelay should usually be set to zero, but some programs which
incorrectly rely upon instruction timing could require non-zero interrupt
delay. E.g., look at the following code:
interrupt:
mov interrupt_flag, 1
iret
start:
sti
nop
mov interrupt_flag, 0
...
wait_here:
cmp interrupt_flag, 0
je wait_here
...
On the extremly slow machines (and EDB IS extremly slow), interrupt can
occure before interrupt flag is cleared, and program will wait for flag
forever.
VirtualRAM = Start-End
Route program's memory references in region specified by 21-bits addresses
to a separate memory area. Note what word memory accesses falling on
boundary of virtual segment will NOT be split between memory blocks. Up to
five areas can be declared. Note what EDB always use implicit
VirtualRAM=0-3FF statement to provide program with own IDT.
VirtualRAM could cause trouble with 'GF' command and implicit
full-speed execution, expecially when VirtualRAM area overwrites DOS
areas.
MirrorPort = Port [Port ...]
Any value which was out'ed to port specified in this statement will be
later echoed back to the program with the execution of 'IN'. Hardware
ports with the same addresses with be unavailable to the program. It is
wise to insert 'MirrorPort=21 A1' statement in your config.edb, so that
program will not disable interrupts on entire machine...
'[DOS software]' sections have now three parameters:
ProgramBottom = Segment
All code in segments strictly below specified Segment will be executed on
a real CPU, assuming that far return address is on top of stack. Segment
0 represents PSP.
ProgramTop = Segment
All code in segments strictly above specified Segment will be executed on
a real CPU.
WatchExec = {On|Off}
Setting WatchExec to On causes EDB to intercept DOS EXEC function thus
leaving children processes inside virtual CPU. WatchExec is NOT able to track
actions of programs directly calling internal addresses of DOS (COMMAND.COM is
an example). Setting WatchExec to On with such program will cause system
failure.
If you are desperate to debug such application with EDB, you could act as
follows: 1. Boot with clean system (no XMS or EMS drivers, no 286/386-
specific software, etc.) 2. Set ProgramBottom = 1 and ProgramTop to whichever
you memory top is. 3. Be sure DOS vectors 20, 21, 22, 27 are not mentioned
it DataVector statements. 4. Try to debug program again.
'[CPU options]' section defines detail of CPU emulation
Processor = CPU type.
Currently recognised CPU types are: 8086 (Synonim: 8088), 80186 (Synonims:
80188, 186, 188), 80286 (Synonim: 286). 8086 and 80186 CPU's are emulated to
the best extent of my knowledge (which the exceptions stated below), while
80286 is crippled by lack of protected mode support (which requires a full AT
emulator, not only CPU) and limited support of 286 extended exceptions (which
requires a great deal of work on my part...). Loadall instruction is not
supported, too.
Prefetch = size
Valid values for processor prefetch queue size are 0 and 4 to 20. Prefetch
queue is used by most programs to determine CPU type (It is 4 bytes for 8088
and 80188 CPUs, and 6 bytes for 8086 and 80186) and by some protected programs
to prevent debugging. You should not set prefetch queue size to non-zero value
if it is not absolutely nesessary, because it slows down EDB by approximately
20 percent regardless of queue size.
'[Debug options]' section collect parameters which I failed to place
somewhere else.
TraceRecords = number
Specifies number of last instructions addresses of which should be kept in
trace buffer, so what execution history could be examined. Valid values are
from 1 to 16000. Note what setting number of trace records to some low value
will *decrease* performance.
WarnSysTrace = {On|Off}
If this option set to 'On', EDB will not permit implicit full-speed
execution when emulated CPU is in single-step mode, as the program will be
completely out of EDB's control while tracing.
EDB debugging session can be in two states: active and suspended. Active
session is indicated by ']' prompt and it is permitted to use all commands
except 'S'. Suspended session (which can be caused either by program
termination or by suspended memory write) has '>' prompt and does not
permit execution commands (T,P,G,X,GF). Suspended session causes by delayed
memory write can be resumed to active state by 'S' or 'SC'.
Let me now tell a little about each EDB command.
B or
BL
Lists all breakpoints
BP [seg[-seg]:]off[-off] [action]
Sets breakpoint on code range, '*' can be used instead of 0-FFFF. Up to 5
code breakpoints can be specified. Setting code breakpoint will decrease
emulator performance.
Examples:
'bp *:1234' will set breakpoint on execution of instruction in ANY
segment at offset 1234 hex.
'bp 12-24:56-111 jr bp1' is a more complex example. it will cause EDB to
execute command 'JR BP1' (i.e., read journal file BP1.JOU) each time
then program attempts to execute instruction beginning at offsets 56
thru 111 hex in segments 12 thru 24 hex.
BP -Number
Clear code breakpoint Number
BM[R,W] XXXXX[-XXXXX] [action]
Sets breakpoint on memory access in specified range (inclusive). EDB
checks STARTING address of any memory access to fall in this region, so
word memory access at address 1 less then starting still could overwrite
data in region. 'BMR' sets break on memory read, 'BMW' on memory write,
'BM' on both. Up to 5 breakpoints could be set. If program makes more
then one memory access during single instruction (as in call far or int
commands), EDB will remember only last stored word. Setting memory
breakpoint will decrease performance.
Examples:
'bmw 12345' sets breakpoint on access to a single memory location 12345
(I.e., any of: 1234:5, 1230:45, etc.)
'bmw 400-4FF SC' will inform you each time then program attempts to write
into BIOS data area and automatically cancel that access.
'bmr F0000-FFFFF' will trigger each time then program fetches data from
ROM BIOS
'bm 100000-1FFFF' will inform about each access depending on state of A20
gate (Note: WrapA20 should be Off)
BM[R,W] -Number
Clear memory breakpoint Number. Note that memory read and write
breakpoints are counted separately.
BI[R,W] nnn[-nnn] [action]
Sets breakpoint on I/O read, I/O write or both. EDB wraps I/O address
around 400h. Although any number of I/O breakpoints could be set,
only five (or so) of them could have associated action. Note what both
read and write breakpoint on the same port should have the same (or no)
action associated with them. I/O breakpoints have no impact on emulator
performance.
Examples:
'biw 21 X' Cancel any write access to port 21 (8259A IMR).
'bi 3F0-3F7' Trigger on any access to a FDC ports.
BI[R,W] -nnn[-nnn]
Clear I/O breakpoint.
BF {On|Off}
Set/clear breakpoin on implicit full-speed execution of program.
BQ {On|Off}
Set/clear breakpoint on prefetch queue mismatch code segment data.
Enabling this breakpoint will severely (by a factor of 2) damage
preformance.
D[B,W,D] [addr]
Dump memory as bytes, words, doublewords. Addr should be in ordinary
segment:offset form. (Names of segment registers are accepted).
E[B,W,D] [addr]
Examine memory as bytes, words, doublewords.
G [addr]
Go till addr is reached. All breakpoints are on.
GF addr
Go full speed. Run program on a real CPU until it arrives to location
addr. EDB could not check for any breakpoints in this mode and have no
control over actions of program. EDB executes 'GF' internally each time
it arrives at entry of system ISR (which it identified by dummy selector
'0001' (I.e., int 21 has EDB's entry point 0001:0021), or CS: below
ProgramBottom or above ProgramTop. Then EDB executes 'GF' internally, it
assumes return address to be on top of stack. If your application is not
pleased with such arrangement, you could do it manually with action
associated with code breakpoint.
GF command could be valuable with applications which relies on
perfect instruction timing.
I[B,W] port
O[B,W] port
Read or write I/O port (byte or word). Mirrow'ed ports will return values
last send to them.
J{S,C}
J{R,W} name
EDB journal functions. 'JS' displays current status, 'JC' closes
currently active journal. 'JR myfile' takes EDB input from file
myfile.JOU. 'JW myfile' sends all you have typed on keyboard to
myfile.JOU. When in 'JW' mode, EDB flushes DOS file buffer after each
five typed commands, thus ensuring that nothing is lost in case of system
crush. EDB interrupt command (Ctrl-Alt-Shift) will close journal file
if it was opened for read.
N number or
NI number
Simulate arrival of hardware interrupt 'number'. (PUSHF, PUSH CS, PUSH
IP, JMP FAR to interrupt entry point).
NT
Simulate IRET.
NN [number]
Simulate RETN number.
NF [number]
Simulate RETF number.
P
Pass single instruction. Executes program until it arrives to the
instruction, following current in memory.
Q
Quit EDB. 'Q' will work incorrectly if more then one process is currently
active (I.e., WatchExec is On, and current application spawned process,
which EDB is currently executing.)
R [name] [value]
Display or modify CPU registers. (Note: CPU flags register called 'FLAGS'
in EDB)
S[C]
Resume after memory write breakpoint. 'S' flushes delayed write buffer to
memory, 'SC' ignores it.
T [count]
Trace 'count' (or 1 if none specified) instructions.
U [addr]
Unassemble. Currently, only 8086/186/286 opcodes are supported depending
on current emulation mode.
V [count] - View trace buffer
View CPU trace buffer, starting with command which was executed 'count'
before last. No more then screenful of data will be displayed. By default,
EDB stores addresses of 800 most recently executed commands and will
show them on 'V' command.
W file [top]
Writes core image starting from PSP to 'top' (or to ProgramTop if none
specified) into 'file'. Used to create source images for EXERECON.COM.
X
Skips the following CPU instruction. (Will work incorrectly when prefetch
queue don't match memory data).
!
Clears screen.
EDB performs its functions by software emulating CPU instructions.
Because it is not possible (or at least too costly) to emulate all peculiars
of microprocessor, EDB will behave differently from 8088 in the following
aspects:
1. EDB will not execute out-of-the-blue fragments of microcode for
undefined instructions, as pre-286 CPU do (for example, try to
figure out the result of execution of 0feh,0e8h instruction on
8086 one day). It will generate 'invalid instruction' breakpoint
instead.
2. EDB will preserve all undefined flags during MUL and DIV instructions
(as NEC V20/V30 do, and will be therefore identified as V20/V30 by some
programs)
3. EDB will treat string instructions with multiply prefixes correctly
(again, as V20/V30 do).
4. EDB is a lot slower then 8086. Even on 33MHz 80486 it will perform as
about 30-40% of 8086
EXERECON.COM - .EXE file reconstruction utility
EXERECON.COM (ExeReconstruct) is a small and straightforward program,
analyzing two memory dumps in order to generate relocatable .EXE image of
program loaded into memory. In order for ExeReconstruct to correctly identify
relocatable references, memory dumps should be obtained for difference of 1
paragraph in starting load address. This is done by '/G' switch of EDB.