1) general info GRDB is a real-mode debugger which supports up to the Pentium instruction set. GRDB is intended as a program development tool; certain features will make it hard to use for reverse-engineering. But you have the sources and can fix that if you want... GRDB is similar to debug in many ways. The major departure to the basic interface has been in making some of the commands less archaic. Also a variety of status commands have been added to help you see what is going on. for questions or complaints contact the author at: gclind01@starbase.spd.louisville.edu 2) Disclaimer GRDB is copyright (c) ladsoft and is FREEWARE- you may redistrubute it freely as long as the sources go along with it, however you may NOT charge a fee that is more than the costs of redistribution media. By running the program you assume all risks associated with using it. The author is not responsible for any damages resulting from use of this program, either direct or consequential, including but not limited to loss of life, profit, data, or other injuries. If you do not accept this, do not run the program. 3) Features GRDB is similar to debug in many ways. The syntax of the following commands departs from the DEBUG syntax: h,l,w and some of the l & w functionality has been split to new commands. In addition the 'n' command is now used for FPU status; the name is set in the l or w commands if necessary. In addition the following features have been added: a) software breakpoints b) interrupt status screen c) configuration options screen d) memory (arena) display screen e) program information screen f) session logging g) allows loading EXEs without the EXE parsing mechanism 4) command line interface the command line interface is similar to that of debug. However, some enhancements have been made: a) knows the names of ALL registers and allows you to use them anywhere a number is allowed. It knows 8, 16, and 32-bit register names... b) it knows how to parse string values and convert them to hex. so, a quoted string can be used anywhere a non-address value can be used. HOWEVER, in most cases strings longer than 4 characters will be truncated. Also, some commands (notably fill) will only use the least significant value of the number and will truncate it to one character c) commas are always treated like spaces. d) CTRL-BREAK is routed to the debugger, and will normally cause the program to halt at its present position as if there were an int 3 in the program stream. However: if interrupts get disabled you are out of luck. if there is a runaway condition that never returns control to memory belonging to your program you are out of luck if DOS is executing, the break will not happen until the end of the current DOS call. However it IS (remotely) possible that your break will come in between the int 21h and the time the indos flag gets set, in which case you will break early in the int 21h routine. DOS won't receive a break notification. 5) Commands Here is a brief list of commands: b [#] - Show breakpoint(s) b [-]#,addr - set or clear a breakpoint d [start [,end]] - dump memory e start [,list] - examine memory f start,end [,val] - fill memory g [=start] [,break] - run from start (or pos) to break h val1 [+-*/] val2 - hex arithmetic i port - read from port l [@] [-] [name[ command]] - read from file n [s] - show fp regs/status o port,val - write to port p [r][n] - step through q - quit r [reg[:val]] - show/modify regs s start,end [,list] - search for a byte pattern t [n] [count] - step into u [start [,end]] - unassemble w [@addr] [name] [,len] - write to file ? - this help ?? - extended commands xr drive: addr,start [,len] - read logical disk sector xw drive: addr,start [,len] - write logical disk sector @ [a] [logfile] - start/stop logging to a file ?i - view interrupt info ?m [x] - view arena tags ?o [+-option] - view/set options ?p - view program status Many of the commands are similar to what DEBUG does. Note that the ',' character is always optional. Following is a detailed description of each command: b show active breakpoints. this Does nothing if no breakpoints are active. b# where '#" is any number from 0-0F. this Shows the value of that breakpint. b # , address where '#' is a hex number from 0 to 0F and address is any valid address. Sets a breakpoint. At run time an 'int 3' will be inserted at the address. Note that breakpoint 0 is a special breakpoint used by the 'go' command; it will be automatically cleared at the end of the next go/trace/proceed. b-# clears a breakpoint d disply 80h bytes starting at the current location d addr display 80H bytes starting at addr d addr,addr display all the bytes between the two addresses. The second address may NOT be qualified with a segment. e addr start prompting for data. Note: you CAN quote a character here. e addr , list of data put the indicated data at the address. f addr , addr fills all the bytes between the two addresses with 0. the second address may NOT be qualified with a segment f addr , addr , value fills all the bytes between the two addresses with value g = addr start executing at address g addr start executing at current IP, set a temporary breakpoint at addr (overwrites breakpoint 0) g =addr , addr start executing at the first address, set a breakpoint at the second address h val [op] val do some math. Valid operators are : +-*/%. If no operator is given, + will be assumed i port show the value at the port l filename command load a file, setting its command line. The command is optional. l @ filename load an EXE file without using the normal EXE load mechanism (e.g. as a COM file). Note, you CANNOT run EXEs that are loaded this way. l - unload file l reload last file n show fp registers. The TOS register will have a star next to it. Note: if you have a 386 with no coprocessor you will get an error message. ns show fp status. Shows masked exceptions, active exceptions, rounding/precision selections, and status of the C? flags. Note: if you have a 386 with no coprocessor you will get an error message. o port, val output a value to a port p step over subroutines, string instructions, int calls. For loop instructions, it runs until the loop falls through. This is a DESTRUCTIVE instruction, it modifies the code stream temporarily if a simple trace won't do. pr exit debugger r show registers r reg prompt for a new value for reg r reg , value stuff a new value in reg s addr , addr , list search. List may be any combination of quoted strings and hex values. Note: you MAY use a segment value in the second argument. The segment of the result will be adjusted any time the offset of the first argument is greater than 8000h. t step into instruction t count single step for count instructions u disassemble from current location. Location gets set to CS:IP each time an R command or trace/go is executed. u addr dissassemble from address u addr, addr disassemble code between the two addresses. Second address may NOT be qualified with a segment w write file to disk. If no file is loaded or loaded file is an EXE file you will get an error. w name write the file, giving it a new name. This will allow you to resave an exe image, but bear in mind you don't get a header and patches have been performed. w name len write the file, giving it both a name and a length w ,len write the file, with a specific length. Resets the file length w @addr name len write a file of length len with name name. Note that if an address is given you MUST give a name and length xr drive: addr, sector read one (logical ) sector from the disk. Note that DRIVE is a letter from a to z. xr drive: addr, sector, len read multiple (logical) sector from the disk. xw drive: addr, sector write one (logical ) sector from the disk. Note that DRIVE is a letter from a to z. xw drive: addr, sector, len write multiple (logical) sector from the disk. @ filename start logging to a file. ONLY the debug session is logged; not the program output. @a filename start logging; append instead of truncating. there can be no space before the 'a' or it will be treated as the file name. @ end logging ? help ?i shows interrupt information. All interrupts hooked since the debugger has been invoked are shown, along with PIC information. If an interrupt has a '*' it is currently reserved by the debugger and the contents will be lost on the next go/trace/proceed. PIC information shows the PIC mask registers, and in parenthesis the original values of the PIC mask registers and the current value of the interrupt request register for example: 02 : CCE4:0000 03*: 0070:0400 PIC 0 mask: A8 (A8,00) PIC 1 mask: 89 (89,00) ?m shows the arena entry headers belonging to the program. also shows the address of the top of the program memory (normally 0a000h). Values are in paragraphs. For example: Top of memory: 9FFF Address: 262E Owner: Q(2659) Size: 0029 Address: 2658 Owner: Q(2659) Size: 79A6 the number in parenthesis is the PSP of the owner. The name will be expanded to stars if no file is loaded. ?mx shows all arena headers in the chain ?o show options. See the next section ?o +opt set an option ?o -opt clear an option ?p status about program size, PSP and environment location, some EXE characteristics, etc. For example: Dos version: 07.00 CPU type: Pentium Pro Program: grdb.exe Arguments: grdb.exe File length: 518A CS:IP = 266E:1AC0 SS:SP = 2B87:0800 minalloc: 0081 maxalloc: FFFF relocs: 0008 Psp at 265E with length 79A1 Environment at 2633 with 0289 bytes used of 02A0 6) Options Available options are as follows: WR - wide registers disabled FR - flat real commands disabled 32 - 32 bit disassembly enabled ZR - divide by zero trap enabled BK - ctrl-break trap enabled NV - native video disabled To set an option, type ?O followed by its two-character option name. For example: ?o WR turns on wide registers ?o +WR -32 turns on wide registers and turns off 32-bit instructions. Options are maintained in a file called 'grdb.opt'. Here are the meanings for the options: WR: normally the 'r' command will show the 16-bit registers. Setting this option will cause it to show the full 32-bit value for each register. FR: addresses are normally truncated at 0FFFFH to avoid protection faults. Setting this option allows commands to utilize the full 32-bit address range, which can be useful in debugging flat real mode programs. 32: the debugger normally interprets all instructions up through the Pentium whcn showing disassemblies. Resetting this option will force it to quit recognizing instructions for any processor above the 8086. ZR: This debugger traps divide by zero instead of exeiting you to DOS. If you want it to NOT trap divide by zero, for example you have your own handler... reset this option. BK: This debugger intercepts the ctrl-break trap and halts the program (assuming interrupts are enabled and it isn't totally runaway). Use this option to disable the handling, e.g. you want to use your own ctrl-break handler. NV: in the 'dump' display, the debugger will use native video translations for most characters in the ascii display ( characters that are translated by video function 0eh can not be displayed natively). If you want to see only characters in the ASCII character set, turn this option off. 7) guidelines a) the debugger uses ONLY 1 interrupt table. And it reloads all interrupts it hooks each time you trace or go. This means that if you go hooking interrupts the debugger uses they will get trampled. The following interrupts are ALWAYS off-limits: 01 - debug trap 03 - breakpoint trap 20 - DOS exit routine The following interrupts are off-limits unless you set the appropriate option off: 00 - divide by zero trap 1b - breakpoint trap In addition, hooking int 21h is problematic since the debugger needs to hook it for a variety of reasons. if you HAVE to hook it, do NOT write directly to the interrupt talbe but instead do a DOS call (function 25h,35h) to keep the debugger in sync with you. The debugger does not care what you do with other interrupt vectors b) Unless you have logging enabled, the program will not use DOS for I/O. However it DOES need to go resetting the PSP a lot; so I'm not sure how safe it is to step through DOS. c) The debugger maintains a proper program context even when no program is loaded. d) int 20h from the wrong CS WILL work, but you will get a warning message. Note this will cause a crash if the debugger isn't running! 8) changes The following changes will be made at a later date: 1) OPTIONS file renamed to fit the program being done, breakpoints will be logged in the options file 2) command line editing and history 3) assembler 4) public symbol support 5) support for hardware breakpoints. 6) command line math ? 7) I'm thinking about a screen-oriented interface :)