fdbg help

fdbg for windows x64 (AMD64)
assembler level debugger for user mode 64-bit applications
supported platforms: XP/win2003 x64, vista/win2008 x64, windows7/win2008 R2 x64, windows8/windows_server_2012 x64


hint: to improve performance, minimize all unnecessary fdbg MDI children windows, especially when displaying all info lasts longer than keystroke repeat delay

credits go to


format of numbers

Numbers are in hexadecimal format by default (if not defined differently in the help file - as e.g. floating point numbers which are not in hexadecimal form of course).

contact, bug reports

Please report bugs and disassembler mistakes to me, possible ways are:

fdbg for Linux x64

if you are looking for fdbg for Linux x64, try these links:


command line parameters

the syntax is:
fdbg.exe -d -n -t debuggee.exe params_for_debuggee

-d reset arrangement (positions, sizes, saved settings) to the default

-n stop the debuggee in initial int3 (earlier than at the debuggee entry point - OEP - entry point is shown in the Log window as 'ThreadStartAddress=' in the line beginnig with 'Process created.'), this is the same as unchecking the checkbox 'run over initial int3 and halt on exe entry point' in the open debuggee menu and is usually unwanted unless you do some advanced debugging

-t forces to debug only this process (prevents its children from being debugged), this is the same as checking the checkbox 'debug only this process (exclude children)' in the open debuggee menu

debuggee.exe the name of program being debugged

params_for_debuggee parameters passed to program being debugged, may be more strings separated by space including other switches

imagine this sample:
fdbg.exe -d -t notepad.exe -n project1.asm text2.txt
note that in the above sample, the -n param is passed into debuggee (notepad.exe), not for fdbg, there are only -d -t params passed for fdbg, the notepad.exe program (debuggee) is run with 3 parameters:
-n
project1.asm
text2.txt

debuggee menu

open debuggee (Ctrl-E)

Hint: debuggee means process being debugged.

terminate (Ctrl-T)

any explanation isn't necessary.

program reset (Ctrl-R)

terminate debuggee and then resurrect it again (the same like: 1. terminate, 2. open debuggee with the same parameters).

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.

notes:

  1. You can't use program reset (Ctrl-R) for any attached process. This isn't because of fdbg unability to recreate the process again but according to unknown way of the run before the moment of attaching.
  2. for attaching under Vista: it is recommended to run fdbg with right mouse click -> Run as administrator
  3. it seems like a bug in win, but just after attaching immediatelly asking for fdbg help lasts several seconds to complete
  4. After OS finishes attaching, OS calls ntdll.dll int3 so process is stopped at int3 inside of ntdll.dll. You may modify process memory at that time. Then you can continue with F9 or with F8, F7, ...

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.

exit fdbg

any explanation isn't necessary.

actions menu

trace into (F7)

single step, fdbg executes 1 instruction exactly. This is done by set TrapFlag of the flags register. You can also change steps from "fine" steps to "larger" steps (only on branches) by Control -> Toggle DebugCtlMSR.BTF

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=8 repz movsb you have to do single step 8 times to finish it, or for call you have to step procedure till ret (return).

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.

run unhandled (Ctrl-F12)

This is done by telling the debug loop to continue with DBG_EXCEPTION_NOT_HANDLED and it is useful only for special antidebugs based on exceptions by cooperation with Rambo -> Ignore_exceptions or for debugging your app's exception handler. Typical scenario for the second task 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.

for more, see fdbg0023_samples\IgnoreExceptions\*.*

return from procedure (Alt-F8)

fdbg tries to scan memory of debuggee from thread RSP to the top of stack and find an address which may be return address from procedure (there should be a call instruction which saves the return address into the stack), if such address found, temporary breakpoint is put there and debuggee is run. software breakpoint type is used by default. if you want to defeat some antidebug trick you may force fdbg to use hardware breakpoint type instead of software breakpoint by setting on the menu Rambo -> CC collateral damage. note that this may not be ever ultimately accurate as some procedure with antidebug tricks may put some false addresses into the stack at lower RSP than is the qword holding real return address from procedure so fdbg finds the false address instead of correct return address - in such case debuggee runs and misses correct return address from procedure

execute to (Alt-F9)

This is done by putting temporary breakpoint and executing run. You are asked to enter address to execute to. You can also pick up the address directly from a symbol based on exports, see fdbg0023_samples\symbols_easy\*.* (you can also add extra hexa value into address of symbol).

run here (F4)

This is done by putting temporary breakpoint and executing run. Instead of Alt-F9 you aren't asked to enter address... Ooooo maybe you have a 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.

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 safely modify thread's registers in hung state and you needn't to do 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.

breakpoints menu

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:

software breakpoint (Alt-F2)

this is done by replacing 1 byte of the debuggee memory with int3 instruction (byte 0CCh). After executing int3, debuggee stops and debugger is notified about breakpoint exception.

You can also pick up the address directly from a symbol based on exports, see fdbg0023_samples\symbols_easy\*.* (you can also add extra hexa value into address of symbol).

Note that SW BP is in memory, thus belongs to a process.

hardware breakpoint

this is done by setting debug registers. It avoids to modify debuggee memory (in contrast of software breakpoint which overwrites 1 byte of memory with 0CCh)

Note that hardware breakpoint uses debug registers, thus belongs to a thread. Fdbg manages 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 generates debug exception (int01, the same as single step), it doesn't generate exception breakpoint (int3).

breakpoint at symbol

you may put a symbol or a name of an export from DLL for setting breakpoint there. the breakpoint is always set temporary (one-shot bp). the type of breakpoint is SW BP by default, if you want HW BP, you must enable Rambo -> CC collateral damage

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.

explore menu

goto (Alt-G)

creates an edit control for address in code/data/stack SysListView (as left mouse dobleclick) so you can manually edit the begining address
note that Code/Data/Stack window must be active = "on the top"
without any mouse assistence, pressing Ctrl-Tab / Shift-Ctrl-Tab rotates among windows, or you can select the window from the face menu

Hint0: you can change the cursor position (begin/end) or the whole text selecting in the menu Face -> Various setting -> goto command edit style cursor

Hint1: if you are doubleclicking on the address too often to select the content, then you may set it automatically in the menu Face -> Various setting -> double clicking on item selects the content of the item also

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.

stack

shows you info from the stack of currently displayed process/thread. The most valuable is 'call stack'. Every call procedure leaves a trace in stack - return address from the procedure. Fdbg just checks values in the stack whether they points to an instruction following instruction of call. Thanks to this feature you can watch how much and which subprocedures were called and how much deeply you are in subprocedures tree. When an exception (bug) occures, you know the tree of called procedures and subprocedures which lead into exception. Search for 'called from' from current RSP and every parent procedure has its own record in the stack where subprocedure returns by RET instruction. Values under address of current RSP are usually useless, but may help in rare ocassions (they may or mayn't record return addresses of earlier and finished procedures, they don't belong to current procedures tree, they may be overwritten with fake values).

Stack call values are obtained in this way: fdbg reads qword value from stack, disassembles back the instruction on the address preceeding that value (=instruction which end is on the address equal to the value read from stack) and if the instruction is call then the value from the stack will be used for RET instruction to return from the call.

Double clicking on desired value copies the data of your interest into Log where you can select any part of it and copy it into clipboard using Ctrl-C.

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 sorting 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)...

symbols (Ctrl-S)

symbols are designed for easy translation of raw hexa address into label, variable_name, etc. in your source code. You really appreciate symbols if your source code is big enough and you have to quickly locate a bug (crash point). Debugger outputs hexa address of the bug in the executable and symbols are responsible to locate the closest label in your sources. You can search symbol only if you have compiled your application with debug support (fdbg doesn't support FASM debug symbols, but don't worry, read Varia for some tricks, or look into fdbg0023_samples\symbols_easy\*.*). This menu supports only MS COFF symbols, not export-type (from symbols_easy\*.* samples). 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). 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. Note: According to LiveKD strange bahaviour, microsoft symbols are disabled by default. You must enable MS COFF symbols in Face -> Various settings -> Allow MS COFF symbols

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

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.

notes:

Hint - look into Log EDIT for finding module's begin and end before you try to search through it.

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

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.

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 memory save.

notes:

control menu

playing games with branches

for AMD CPUs it works on all x64 versions of windows at the time of releasing this fdbg version, for Intel CPUs DebugControl (SingleStepOnBranches, LastBranchesRecording) feature was firstly implemented in windows 2008 server x64 R2 (the same kernel as windows 7 x64)

for more info about these features, read my presentation at 2nd FASM conference, Brno, Czech Republic, 2007-august-25, or go to www.amd.com, download 24593.pdf and read chapter 13.2.5 Control-Transfer Breakpoint Features

Toggle DebugCtlMSR.LBR

enable/disable recording of branches (the best and most ultimate but very small back trace "buffer"), it is very useful to enable it to know instructions executed before exception (few steps backward before a buggy crash in your program), stepping forward is very easy (just pressing F7 or F8), but it is very painful to obtain steps backward and this is a tool to help you a bit (note that you can restart debuggee and put a breakpoint at LastBranchFromIP / LastExceptionFromIP and repeat these steps few times so you can do more steps backward)

You can also try very small and easy fdbg0023_samples\branches\a00.exe, I strongly recommend you to read branches\a00.asm too. If you don't have so much time then only small note: if you are using HW_BP (or e.g. Rambo -> CC Collateral damage is on) then when HW_BP or Single Step occures (int01, debug exception), then get the address from LastBranchFromIP instead of LastExceptionFromIP - it is because CPU clears DebugCtlMSR.LBR when transfering control from the exception to exception handler of int01 so the important address stays in LastBranchFromIP and is not copied into LastExceptionFromIP (executing ICEBP instruction = opcode 0F1h also doesn't update the LastException registers because it calls int01 handler).

Toggle DebugCtlMSR.BTF

changes the behaviour of RFLAGS.TF, switches between "normal" and "larger" single steps for doing Trace into F7 ("larger" means steps only on branching instructions instead of on every instruction)

Rambo menu

the main core of anti-antidebugs (fight against antidebugs).

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.
detecting this rambo fight is possible... so here one undetecteable manual way:
mov rcx,gs:[30h]
mov rax,[rcx+60h]
mov byte [rax+2],0
but how to obtain gs:[30h]... just grab the value ThreadLocalBase from the log window after creating a process or thread... simple, huh ?

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 changing 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.

TrapFlag anti-terminator terminator

if you request single step (Trace into F7) on PUSHF instruction, fdbg puts temporary 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. You can even combine it with CC Collateral damage so HW BP is set to the next instruction instead of SW BP. See fdbg0023_samples\TrapFlag\a00.exe for testing this feature.

CC Collateral damage

it is a usage of HW BP instead of SW BP if possible (don't forget the total limit of only 4 HW BP) - for Step over (F8), Return from procedure (Alt-F8), Excute to (Alt-F9), Run here (F4), Breakpoint at symbol, and at the time of CREATE_PROCESS_DEBUG_EVENT when setting a breakpoint at the process entry_point. It is useful for self modifying code, to calculate code-self-crc, for some antidebugs. If there is no space left for setting HW BP, setting a breakpoint falls back to normal way - setting SW BP).

You can try fdbg0023_samples\adbg\protected.exe to test this feature.

First Blood

weapon against fdbg0023_samples\entrypoint\a00.exe which is based on image offset 0 in exe header, so win must place it at least at 10000h and the shift is the core of returning bad ThreadStartAddress.

Stop on TLS Callback

weapon against fdbg0023_samples\TLS_callback\a00.exe

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. This feature 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).

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.

D-tox page attributes

you may change page attributes, e.g. make read-only page writeable or make a page guarded (MEMORY_BASIC_INFORMATION.AllocationProtect = PAGE_GUARD), or make a page nonexecutable

it is useful when analysing infection to make newly allocated suspicious pages guarded to capture code execution or data access on them, after capturing exception shown in Log (ExceptionCode=80000001h=EXCEPTION_GUARD_PAGE) you may restore the original access protection of the page

guard pages act as one-shot access alarms

note that the access protection value can be set only on committed pages (the column State must show commit)

PEB.BeingDebugged Eraser

it is similar to IsDebuggerPresent fight but this menu directly erases the PEB bit indicating debugging (IsDebuggerPresnt fight uses remote thread to erase it which is automatical but cannot be used in every case, try fdbg023_samples\entrypoint\a03.*)

face menu

font

choose font, its size and other parameters. Recommended fonts are: Terminal, Lucida Console. You can adjust font width in face -> various settings (see below).

various settings

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 restarting fdbg. This is due to chatching WM_MEASUREITEM when CreateWindowEx of SysListView32 with LVS_OWNERDRAWFIXED style.

children windows

here you can select any of the children windows, or alternatively, Ctrl-Tab / Shift-Ctrl-Tab rotates among them (Code, Data, Stack, Registers, Log)

help menu

help

launch the help which you are reading now.

left mouse doubleclick

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:

Notes:

Hint0:

For editing address in Code/Data/Stack you can use the goto command (Alt-G)

Hint1:

If you are double clicking too often and then selecting the content of the Item by doubleclick again (so by 4-click), you may reduce the count of clicks in the menu Face -> Various setting -> double clicking on item selects the content of the item also

right mouse menu

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.

colors

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.

Notes:

scrolling in code, data, stack

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.

Notes:

strange code 1st, code 2nd on single-core CPU... what does it mean?

Yeah, perhaps your first 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 watching 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 useful to watch several previous addresses, but it losts 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.

format of data 1st, data 2nd, data 3rd

Data may be displayed in various formats: qwords, dwords, words, bytes. To rotate among them, click on any column header of SysListView32 in Data 1st, Data2nd, Data 3rd - that is e.g. on any of these strings: address, +0 +2 +4 +6, +8 +A +C +E, ASCII

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 F11 thread, 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 until WaitForSingleObject. Running means that thread executes (read ResumeThread in microsoft API documentation).

varia

We will discuss some tricks here.

You can easy make symbols by making exports in exe (the same as in DLLs) - see fdbg0023_samples\symbols_easy\*.*
These symbols aren't show in Explore -> symbols (Ctrl-S), they are shown only in code window.

There 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):

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 int3 = 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 (int3).

method for capturing unpacked/decrypted executable:

most of console programs call GetStdHandle, WriteFile at the early begin of their execution, most of GUI programs call GetModuleHandleA, GetModuleHandleW, DialogBoxParamA, DialogBoxParamW, RegisterClassExA, RegisterClassExW, CreateWindowExA, CreateWindowExW

so you can easily uncompress/decrypt an executable by doing these 4 steps: