< fdbg help >

fdbg for windows x64 (AMD64)
assembler level debugger for user mode 64-bit applications
supported platforms: windows XP x64, windows 2003 x64, Vista x64




Thanx to:
Tomasz Grysztar, the author of FASM,
alorent, valy for finding disassembler mistakes,
r22, alorent, Garthower for design ideas,
Garthower for finding mistake in displaying of floating point numbers

Please note that fdbg is compressed and an experimental modification (and nobody can know whether violation too) of PE32+ executable is made. If you have a problem with execution of compressed file (tested only on win2003 server x64 and Vista RC2 x64, but new releases of win64 are comming), just use original uncompressed file from the source directory. But current compression ratio looks great and producing of the smallest possible files is one of the reasons of using assembler!


00 command line parameters
01 debuggee menu
02 actions menu
03 breakpoints menu
04 explore menu
05 Rambo menu
06 face menu
07 help menu
08 left mouse doubleclick
09 right mouse menu
0A colors
0B scrolling in code, data, stack
0C strange code 1st, code 2nd on single-core CPU... what does it mean?
0D status window
0E varia

00 command line parameters
There is only 1 command line parameter to reset arrangement (positions and sizes) to the default
fdbg.exe -d

01 debuggee menu
01.00
open debuggee (Ctrl-E)
Hint: debuggee means process being debugged.
- arguments: you can put command line argument(s) for executable there
- debug only this process (exclude children): check this checkbox if you don't want to be notified about debug event(s) from child process(es) = DEBUG_ONLY_THIS_PROCESS, leave checkbox unchecked if you want to be notified about child process debug events
- run over ntdll.DbgBreakPoint and halt on exe entry point: leave this checkbox checked if you want to stop at exe entry point, uncheck this checkbox if you want to stop at ntdll.DbgBreakpoint
Breakpoint exception at ntdll.DbgBreakPoint is the first exception when you load debuggee under debugger. At that moment fdbg by default put breakpoint at exe entry point and executes run. Then load dll exceptions occur and at the end the exe entry point breakpoint is triggered. If you want to debug through routines for loading dlls, uncheck this checkbox. If you want to bypass stepping through initial dll loading, leave this checkbox checked.
01.01
terminate (Ctrl-T)
any explanation isn't necessary
01.02
program reset (Ctrl-R)
terminate debuggee and then resurrect it again (the same like: 1. terminate, 2. open debuggee with the same parameters)
01.03
attach to a process (Ctrl-A)
shows you a list of processes which you can doubleclick from. You can attach only 64-bit processes. If fdbg shows ??-bit for any process then it is usualy unable to attach to this process.
DebugSetProcessKillOnExit: If checked, the debug thread will kill the process being debugged on exit. Otherwise, the debug thread will detach from the process being debugged on exit. Uncheck it if you want to attach to a process, patch something there and exit debugger leaving the process to continue its run.
First note: You can't use program reset (Ctrl-R) for any attached process. This isn't due to any unability of fdbg to recreate the process again but according to unknown way of the run before the moment of attaching.
Second note for attaching under Vista: it is recommended to run fdbg with right mouse click -> Run as administrator
Third note: it seems like a bug in win, but just after attaching immediatelly asking for fdbg help lasts several seconds to complete
Forth note: After OS finishes attaching, OS calls ntdll.DbgBreakPoint so process is stopped at DbgBreakPoint: int3. You may modify process memory at that time. Then you can continue with F9 or with F8, F7, ...
01.04
detach (Ctrl-D)
You have 2 possibilities for the end of debugging of an attached process: 1. detach (Ctrl+D), 2. terminate (Ctrl+T)
Detaching from a process leaves it to continue it's execution.
Unfortunately detach doesn't work so well as I expected... It doesn't anything important yet.
01.05
exit fdbg
any explanation isn't necessary

02 actions menu
02.00
trace into (F7): single step, fdbg executes 1 instruction exactly. This is done by set TrapFlag of the flags register.
02.01
step over (F8): for instruction call, loop, rep string operations (repz, repnz) fdbg places temporary breakpoint after instruction and executes run. Call, loop, rep operation finish without any extra action (in contrast with single step, when e.g. for rcx=10 repz movsb you have to do single step 10 times to finish it, or for call you have to step procedure till ret (return).
02.02
run (F9): any explanation isn't necessary
fdbg does it in this way: if thread caused debug event = fdbg catched it in WaitForDebugEvent, then ContinueDebugEvent is necessary to rerun it. If thread was paused using Pause (F11) or calling SuspendThread, then ResumeThread is necessary to rerun it.
02.03
run unhandled (Ctrl-F12): This is done by telling the debug loop to continue with DBG_EXCEPTION_NOT_HANDLED and it is usefull only for debug your app's exception handler. Typical scenario is: 1. your app installs an exception handler, 2. you put a breakpoint into the procedure of exception handler, 3. run, 4. you are stopped at any exception and you are unable to continue with F7 F8 F9, 5. Ctrl-F12 tells to continue run and invoke app's exception handler, 6. you are stopped at breakpoint inside exception handler procedure. Note that when you do it for app without any exception handler installed, this made the application to terminate itself like in real life without debugger.
02.04
execute to (Alt-F9): This is done by putting temporary sw bp and execute run. You are asked to enter address to execute to.
02.05
run here (F4): This is done by putting temporary sw bp and executing run. Instead of Alt-F9 you aren't asked to enter address... Ooooo maybe you have feeling that there is something wrong, but the address is taken from selected address in code 1st or code 2nd. Thus one of them must be active (because fdbg uses WM_MDIGETACTIVE to retrieve it), and address is taken from selected iItem (the only one having rectangle of focus or selection).
Please note that it is really big helper when debugging, just go where you want in code (PGUP, PGDOWN, arrows) and press F4 on desired instruction.
02.06
pause (F11): This is done by suspending the currently runnig thread (kernel32.SuspendThread). SuspendThread allows to increment suspend count more than once, but only one incrementing is enough for us.
Note that a thread is in resumed state until someone uses PAUSE or something call SuspendThread or thread is created (CreateThread) with dwCreationFlags=CREATE_SUSPENDED and it is necessary to wait for its signaled state (WaitForSingleObject) after CreateThread... Debuggee = process(es) and thread(s) may be in resumed state and one of threads may be hung in debug loop (WaitForDebugEvent) after causing debug event = it is hung between WaitForDebugEvent and ContinueDebugEvent. You can safe modify thread's registers in hung state and you needn't to extra SuspendThread. Modifying process' memory is unsafe if your process has more threads: one of threads could change memory between picking memory content and writing modified content.

03 breakpoints menu
03.00
Toggle (F2) - puts temporary software breakpoint into a clean position in a code, removes any (permanent as well temporary) sw bp from a position in a code where SW BP is set. Conditions are the same as in run here (F4), so the position is determined from:
- active window (fdbg uses WM_MDIGETACTIVE to determine it) - thus activate code 1st or code 2nd
- selected iItem in SysListView32 - hence select one with up/down arrow using your keyboard or with single left mouse click
03.01
software breakpoint (Alt-F2): this is done by replacing 1 byte of the debuggee with int 3 instruction (byte 0CCh). After executing int 3, debuggee stops and debugger is notified by breakpoint exception.
- address: sincere condolence if you need to explain what it means
- permanent: check this checkbox if you want for breakpoint to stay in debuggee after it is triggered, otherwise leave this checkbox unchecked for breakpoint occurs only once
Note that SW BP is in memory, thus belongs to a process.
03.02
hardware breakpoint: this is done by set debug registers. It avoid to modify debuggee memory (in contrast of software breakpoint which overwrite 1 byte with 0CCh)
- No.: number, you can use up to 4 hardware breakpoints
- address:
- e/r/w: choose if you want to catch instruction Execution or memory Writing or memory Reading/Writing
- b/w/d/q: choose if you want to watch a byte, word, doubleword, quadword. HW BP for execution must have size of 1 byte exactly. Memory w, r/w may be up to qword large, and then the address is aligned to the size boundary (e.g. for qword at address 40203Eh the address is automatically 402038h). If you want to watch e.g. memory range 40327Fh-403286h exactly, you have to set 4 breakpoints: byte at 40327F, dword at 403280h, word at 403284h, byte at 403286h)
Note that hardware breakpoint uses debug registers, thus belongs to a thread. Fdbg manage HW BP in a different way than common debuggers. This way has some advantages (for common tasks) as well some disadvantages (for antidebug tasks). Fdbg sets identical content of debug registers to every thread as well to every newly created thread (immediately after receiving CREATE_THREAD_DEBUG_INFO or CREATE_PROCESS_DEBUG_INFO in fdbg debug loop). So the advantage is that after you once set HW BP then you won't worry whether any process is occupying the desired address or a process there is only going to create. The first disadvantage is that you can't use different debug registers in more threads (e.g. you can't set 12 HW BP for 3 threads). The second disadvantage is that some clever antidebug is able to modify the content of its own debug registers (yes, that's hard work, but is possible: 1. install exception handler, 2. cause exception, 3. exception handler modifies content of thread context, 4. exception handler gets thread handle by GetCurrentThread, 5. exception handler writes debug registers of the thread context to the thread itself by SetThreadContext with flag=CONTEXT_AMD64+CONTEXT_DEBUG_REGISTERS).
Second note isn't much important, it's only one small surprise for uninformed man - HWBP genereates exception single step, it doesn't generate exception breakpoint.
03.03
delete: shows you a lists of sw and hw breakpoints. To delete any, just double click on it. If you have a lot of SW BP, use button 'Wipe out all SW BP' to delete every SW BP. Fdbg supports 400h SW BP (if you need more, just modify MaxNumberOfBreakpoints in fdbg_constants.inc). For HW BP there isn't any button for lazy guys, everybody have to do at most 4 doubleclicks.

04 explore menu
04.00
processes and threads: shows you a list of processes and threads. Selected proc/thrd is the only one currently displayed (code, data, stack, registers). Double click on desired proc/thrd to display its code, data, stack, registers.
Note: 'hung' means thread execution is stopped in debug loop between WaitForDebugEvent and ContinueDebugEvent. FDBG must call ContinueDebugEvent to continue its execution. Suspended/Resumed means state after SuspendThread / ResumeThread.
04.01
imports: shows you imported APIs from DLLs. You can sort items by clicking on one of both column headers of the SysListView32 (API name, address). Only ascendent direction is supported, reverse order isn't. According to the rules for DLL's exports, API names are sorted alphabetically in DLLs by default. So the only one other choice for sort is by APIs' addresses. Double clicking with left rat's paw on SysListView32 copies the whole clicked "line" (both members: API_Name=iSubItem=0 and Address=iSubItem=1) into LogEdit so then you can pick addresses (1. select, 2. Ctrl-C) and e.g. put breakpoints there (Alt-F2)...
04.02
symbols (Ctrl-S): you can search symbol if you have compiled your application with debug support. Type address or symbol name into Edit Control. Uncheck checkbox if you want to scan only currently displayed process (you can switch process in Explore->Processes and Threads 04.00). Leave it checked to scan the whole process' tree (every PID=ProcessID). Entered address is hexadecimal number without h-terminator (e.g. 4012AD), entered symbol name isn't case sensitive. Result has hexadecimal numbers, only line number in source file is decimal.
1st example of output:
SetROP2 Address=000000001C0014FAh PID=00000D90h ModBase=000000001C000000h Flags=00000000h Value=0000000000000000h Register=00000000h
SetROP2 Address=000007FF7FCA5090h PID=00000D90h ModBase=0000000000000000h Flags=00000200h Value=0000000000000000h Register=00000000h
2nd example of output:
DemoInit+00000005h Address=0000000000401175h PID=00000D90h ModBase=0000000000400000h Flags=00000000h Value=0000000000000000h Register=00000000h
f:\asm\prog\fasm64\p006\fdbg000c_samples\debug_symbols\dll\demo.c LineNumber=101 FirstInstructionAddress=0000000000401170h
3rd example of output:
StartSelection Address=000000001C001020h PID=000009D4h ModBase=000000001C000000h Flags=00000000h Value=0000000000000000h Register=00000000h
d:\asm\prog\fasm64\p006\fdbg000c_samples\debug_symbols\dll\select.c LineNumber=66 FirstInstructionAddress=000000001C001020h
04.03
find: you can search for string (max 8 characters long) or sequence of hexa bytes (max 8 hexa bytes) in debuggee. Result is shown in Log EDIT. If such string/sequence is found, Data 3rd start position is updated to point to the result.
1st note - string is searched in currently displayed process, if you want to search it in another process, switch it in Explore->Processes and Threads.
2nd note - ascii string is case sensitive.
Hint - look into Log EDIT for to find module's begin and end before you try to search through it.
04.04
list of memory pages: shows you info about memory of the process using VirtualQueryEx
shortcuts are combinations of: NOACCESS Read Write Execute Copy Guard Nocache
double clicking with left rat's paw on SysListView32 copies the whole clicked "line" into LogEdit
04.05
memory save: you can save debuggee memory (=dump) as a binary file. You needn't to worry about software breakpoints, fdbg removes them immediately after reading memory from debuggee, thus memory dump is free of fdbg SW BP (1. read debuggee memory into a buffer, 2. restore bytes in the buffer at positions of SW BP, 3. write file from the buffer). Address and size are in hexa, but put them without h-terminator, e.g. 40012B
Note - memory is saved from the desired address of currently displayed process.
04.06
memory load: you can load binary file into debuggee memory. You needn't to worry about software breakpoints, fdbg itself sets them into the debuggee just in the time of writing memory (1. read file into a buffer, 2. overwrite bytes in the buffer with 0CCh at positions of SW BP, 3. write debuggee memory from the buffer). Address and size are hexa numbers as in 04.05
1st note - fdbg handles protect attributes (VirtualProtect access flag) for more memory pages. You needn't to worry for write more pages with different access flags in one action. E.g. loading end of code with read execute flag + begin of data with read write flag works fine. You can do it at once even for the whole image = header + code + data + ...
2nd note - memory is written into desired address of currently displayed process.

05 Rambo menu - the main core of anti-antidebugs (fight against antidebugs)
05.00
IsDebuggerPresent fight: it is done by CreateRemoteThread which sets one byte at certain position indicating presence of debugger. Yes, another way is possible, by WriteProcessMemory (ReadProcessMemory qword at (ThreadLocalBase + 60h), write byte at returned address + 2, but this doesn't work immediately after CREATE_PROCESS_DEBUG_EVENT (maybe OS refuses to send early debug events to the debugger when this byte is cleared so early exception causes EXIT_PROCESS), but should work with create thread with small delay.
challenge for experienced users: try to step through Vista's slc.dll with IsDebuggerPresent fight... e.g. slc.dll SLReArmWindows is dll procedure without input parameters which resets remaining activation time to the default. SLC.DLL has some antidebugs, the hardest is based on detecting debugger on IsDebuggerPresent method. Don't play with SLC.DLL if your Vista is activated, maybe you can damage your licence!
05.01
FindWindow weapon: hides fdbg against finding it by FindWindow with WindowName or ClassName
Note that it requires to restart fdbg. WindowName is changeable easy without restart, but change ClassName requires restart to create it with another class. Generating of random class name has a little probability, that routine generates class name which is already registered and then fdbg doesn't start correctly - just restart it again.
05.02
TrapFlag anti-terminator terminator: if you request single step (Trace into F7) on PUSHF instruction, fdbg puts temporary software breakpoint on the next instruction and executes run (=fdbg does step over F8). This prevents to push flags with TrapFlag=1 into the stack and thus detecting single stepping = debugging.
05.03
Executable header predator: todays CPUs have hardware NoExecute prevention and I haven't find any way how to made bytes from executable header to be executable immediatelly after execution (before exe entry point). It was common trick in 32-bit word. Maybe somebody uncovered, is uncovering, will uncover how to turn CPUs protections off and then this feature begins to be usable. But I'm afraid that its todays usability is close 0. It Supports headers of processes only, not headers of DLLs (if you want it for DLLs too, ask me for doing it, it's trivial to add support for DLLs). Once you set PE32+ header executable+writeable you can't reverse it (yeah, it is possible to do it easily, but fdbg doesn't support it yet - todays you have to uncheck this menu and restart debuggee).
05.04
Ignore exceptions: some antidebug can install exception handler and cause exception, then its exception handler does some decrypting or so... You can simple tell fdbg not to handle exception and to send the exception to application's exception handler by Run unhandled (Ctrl-F12). But when antidebug wants to trigger exception 1000 times, it's easier to tell fdbg to ContinueDebugEvent with dwContinueStatus=DBG_EXCEPTION_NOT_HANDLED automatically.
Note that fdbg doesn't save list of exceptions which you want to ignore. These setting are lost after fdbg exits.

06 face menu
06.00
font: choose font, its size and other parameters. Recommended fonts are: Terminal, Lucida Console. You can adjust font width in face->various settings (06.01)
06.01
various settings:
- font width: while font size (06.00) adjust LOGFONT.lfHeight, you can adjust LOGFONT.lfWidth here. Suitable especially for small fonts with bad visibility at high screen resolution. Don't hesitate to experimentate with several settings for you find the font size suitable for you. For font Terminal of size 6 try differences between width 0 and 5.
- edit border: if you double click on SysListView32 on allowed item and subitem, edit control (08.00) is created there for you be allowed to edit register/memory. You can choose whether you want to have edit control with WS_BORDER style.
- edit clientedge: choose if you like to have edit with WS_EX_CLIENTEDGE style.
- extra 1 pixel for item height: if you think that lines with text in SysListView32 jams too much, tell SysListView32 to make more space around the text (=to have 'rows' thicker). Suitable especially for small fonts, like Terminal, size 6, width 5.
- extra 2 pixels for item height: suitable for edit control with WS_BORDER style, you may want to have thicker items in SysListView32, else edited text don't fit into edit control.
- extra 4 pixels for item height: adds more space for text to fit into edit control with WS_EX_CLIENTEDGE style.
You may combine extra pixels together, so if you want to have item height thicker of 7 pixels, just check every 3 extras.
After doing some changes you may be asked for restart fdbg. This is due to chatching WM_MEASUREITEM when CreateWindowEx of SysListView32 with LVS_OWNERDRAWFIXED style.
- don't log exceptions/breakpoints/single_steps - checking corresponding checkbox disables logging it (less of output in Log window). Uncheck checkbox(es) for logging every step you made during debugging (usefull for keeping records about executed addresses, but fills Log window with recorded addresses so you can easier lose your orientation there). The default setting is to log exceptions (bugs in your application) but not to log single_steps neither steps_over.
- Code 1st disassemble back instructions: put here how much instructions to disassemble back. Don't put any number higher than how much items ("lines") your code 1st window has and don't resize this window to have less items than number in this setting. Default is 0 and it means that code 1st disassemble instructions exactly from rip at every step. Please note that you can turn on logging (in Log window) single steps (trace into F7) and steps over (F8) by unchecking above checkboxes Don't log breakpoints/single steps.

07 help menu
07.00
help: launch the help which you are reading now

08 left mouse doubleclick
08.00
Double click with left rat's paw on allowed item creates an edit control for you be able to change register/memory. Allowed changes are:
- code: address, raw opcode. Disassembled instruction can't be changed because fdbg hasn't any assembler engine to compile any entered instruction into the opcode. Clicking on disassembled instruction opens Edit Control for you be able to select and copy a part/whole text from it, but you aren't allowed to change anything there (every change disappears after destroying Edit Control).
- data: everything, ascii string is automatically selected to be automatically deleted after typying the first character, don't worry about deleted rest of the string, fdbg replaces just entered number of characters and keeps the rest.
- stack: everything
- general purpose registers: every
- instruction pointer: this one
- xmm registers: everything, note that you can't enter values in any mismatched format (value mustn't be any special, denormal, etc). Fdbg just counts the number of decimal dots and decides whether it means hexa value (0 dots), st 80-bit precision (1 decimal dot in st/mm), double precision (2 dots in xmm because 2 decimal numbers), single precision (4 dots in xmm because 4 decimal numbers, 2 dots in mm because 2 decimal numbers). If any of them doesn't match fdbg refuses to change the value. Then put it in appropriate column. Please note that you must separate numbers with only 1 space between two of them when editing them and maximal number of digits is 16 for fraction and 3 for exponent for double precision and 8 for fraction and 2 for exponent for single presicion. If there are any spaces after the last number, then don't forget to delete them.
- st/mm registers: everything, note that you can't enter values in any mismatched format (value mustn't be any special, denormal, etc). Fdbg just counts the number of decimal dots and decides whether it means hexa value (0 dots), st 80-bit precision (1 decimal dot in st/mm), double precision (2 dots in xmm because 2 decimal numbers), single precision (4 dots in xmm because 4 decimal numbers, 2 dots in mm because 2 decimal numbers). If any of them doesn't match fdbg refuses to change the value. Then put it in appropriate column. Please note that you must separate numbers with only 1 space between two of them when editing them and maximal number of digits is 18 for fraction and 4 for exponent for 80-bit st registers and 8 for fraction and 2 for exponent for single presicion. If there are any spaces after the last number, then don't forget to delete them.
- flags: everything (carry, parity, auxiliary carry, zero, sign, direction, overflow)
- segment regs: none (AMD64 uses flat memory model and you can't to do anything good here, you can only make damages by modifying them)
- debug registers: none (hint: use hardware breakpoint to set them)
- floating control: none
Note that everything showing memory belongs to a process, everything showing registers belongs to a thread. So code, data belong to a process. GPR, IP, xmm, mm/st, flags, seg regs, ebug regs, floating control registers belong to a thread. Stack is another living form, it belongs to a process (uses memory) as well to a thread (uses RSP register).
Second note: you are allowed to change memory/register of process/thread in the time when it is resumed and not hung even the result is unpredicable. Suggested steps are: 1. Explore->Processes and Threads (04.00), 2. notice the state of selected Proc/Thrd (or easier way instead of these 2 steps - look into status window in the bottom of fdbg), 3. use Pause F11 if the state is resumed... 4. the final question and maybe impossible task is how to restore the original resumed state (Run F9 shouldn't help enough because volatile registers could change...)
Third note: for address column in code data stack you may enter register name instead of long hexa values. Allowed register names are: rax rbx rcx rdx rsp rbp rsi rdi r8 r9 r10 r11 r12 r13 r14 r15 rip (entering rip / rsp is quick way to jump in current rip/rsp in code/stack if your pointer is faraway).
Forth note: don't forget to default windows hotkeys: selecting string / part of string and using Ctrl+C / then Ctrl+V

09 right mouse menu
09.00
right rat's paw clicking on SysListView32 opens menu where you have only 1 choice to select - copy the content of the whole SysListView32 into the clipboard. Window owning the SysListView32 needn't to be active, only small visible part of the SysListView32 is enough to click there. Clicking doesn't activate the window, just opens the huge menu.
Note, that you can't get memory/register of process/thread in the time when it is resumed and not hung in debug loop.

0A colors
0A.00
You can see various colors in code SysListView32. They indicate instruction pointer or breakpoint(s) on the instruction. When more events occur on the same position, colors are combined together. Coloring is a job for a routine catching WM_DRAWITEM notification for the SysListView32 created (CreateWindowsEx) with LVS_OWNERDRAWFIXED style.
- basic colors: RIP SWBP HWBP
- mixes: RIP+SWBP RIP+HWBP SW_BP+HWBP RIP+SWBP+HWBP
Please note that fdbg is unable to handle permanent swbp + permanent hwbp at the same instruction. At least one of them must be temporary to prevent the simulation routine for permanent breakpoints to generate neverending debug loop (in the case of both permanent, exception single step (for HWBP) and exception breakpoint (for SW BP) alternates at the same IP without progress of changing the IP, then just delete one of them to continue debugging).
Second note: fdbg colors only SW BP put into code by any fdbg action. Fdbg doesn't color breakpoint instruction incompiled in your code (int 03, db 0CCh in your apps source).

0B scrolling in code, data, stack
0B.00
For code/data/stack use PAGEUP/PAGEDOWN for move 1 page, UP/DOWN ARROW 1 line (it means 1 instruction in code, 16 bytes in data, 1 qword in stack), LEFT/RIGHT ARROW 1 byte. If you want to move further, double click on any address and type the desired address into the edit control.
Note that scrolling back in a code shouldn't be accurate, then adjust instructions finely by 1 byte with LEFT/RIGHT ARROW.
Second note: code 1st and stack starting displaying address is updated every step (exception after F9, single step F7, step over F8) and then every change of starting displaying address you made in these 2 windows is lost.

0C strange code 1st, code 2nd on single-core CPU... what does it mean?
0C.00 Yeah, perhaps your initial thought was: fdbg makes dual-core CPU from my single-core... but you aren't right. Both 2 windows look into the same code, you may use one for keeping wathing the current RIP (instruction pointer) and the other for looking faraway from RIP. Code 1st is updated every exception (exception, single_step, breakpoint), start address in Code 2nd stays untouched untill you change it. Code 2nd is usefull to watch several previous addresses, but it lost last instruction if there is a big jump in the code. If you want to watch more addresses executed before current one, then uncheck checkboxes Don't log exceptions, Don't log breakpoints, Don't log single steps in Face->Various settings + you can set there the number how much instructions to disassemble back in Code 1st every step.

0D status window
Status window (on the bottom of fdbg) shows you the state of the currently displayed thread. If the state is running, you can do only 4 things: wait for thread completes, kill thread (Debuggee->Terminate Ctrl-T, exit fdbg Alt+X), Pause thread (F11), switch to another thread (Explore->Processes and threads->double click on another thread). If the state is stopped, you can modify registers/memory, execute single_step / step_over, run, ... Stopped means that thread is hung in debug loop (after WaitForDebugEvent before ContinueDebugEvent) or stopped because SuspendThread, CreateThread/CREATE_SUSPENDED untill WaitForSingleObject. Running means that thread executes (read ResumeThread in microsoft API documentation).

0E varia
We will discuss some tricks here.
They are 2-3 possible choices how to find the position of a bug in the source without using debug symbols (how to transform address in fdbg into near label in source code):
0E.00
Try to watch some instructions near address of the bug (few instructions forward and backward in code 1st). If there is any exotic instruction there with rare appereance in your source then you may find it easily by search function of any text editor. Please keep in mind that walking backward in code may give same exotic instruction because fdbg can't know whether e.g. 5th instruction backward begins at address rip-20 or at address rip-21 or rip-22, ...
0E.01
Put:
db 0cch
into your source code, recompile it and run (F9) under fdbg again. Watch whether breakpoint or bug appears as the first. If breakpoint appears the first, then move it further and further from the entrypoint to go closer of buggy instruction untill bug causes the exception first (=before breakpoint). Then the bug is between current and previous position of db 0cch in the source code.
0E.02
Put instruction:
lea rax,[any_label_from_source] ; 7-bytes instruction
at entrypoint (the first instruction to execute) of the program. Recompile the program. Load under fdbg. Compare the address after lea instruction in code 1st with the address of bug obtained previously. The first instruction is transformed into an address so now you can compare whether the label address is below, above and how much close to the address of the bug. The increasing of code by 7 bytes by putting lea rax,[...] isn't much important, but may cause rare disappearing of the bug (especially may cause align 16 of accessing xmm registers with instructions: movdqa, movaps, movapd when they read from the code and not from aligned data - e.g. by calculating self-crc check of the code...). Then change lea rax,[any_label_from_source] to another label (or the name of a procedure), do the same and reload program under fdbg again. Watch whether hexa value in lea rax,[hexa_value] is closer to the address of the bug.
The trick with putting
db 0cch
into the source may be used as a way of quick and direct (without long stepping) jump into the code supposed not to do what you want for it to do. Put db 0CCh into your source just before the instructions you want to examine, then recompile it, load under fdbg and use run (F9). Execution stops after breakpoint trigger in your code at required position. Don't forget to remove db 0CCh and recompile the program before you release it to usage, else it crashes because there isn't any debugger as its parent to catch the exception generated by db 0CCh (int 03).


Please report bugs and disassembler mistakes to me, possible ways are:
- mail address at the bottom of the help
- ICQ 257740061
- flatassembler forum, PM to feryno

if you are looking for fdbg for Linux x64, try these links:
  • my home page
  • flat assembler Linux or Projects and Ideas section.
  • google - search

  • antishit protection:
    you must reconstruct my mail

    name@mailserver
    name db 'feryno'
    mailserver db 70h,6Fh,62h,6Fh,78h,2Eh,73h,6Bh