Description
A Windows console binary detects debuggers via IsDebuggerPresent and refuses to show the flag if a debugger is attached. By intercepting the anti-debug check in x64dbg and skipping the alert path, you can read the embedded flag string.
This is a gentle intro to anti-debug bypass: find the check, break on it, and set EIP past the failure branch so execution continues as if no debugger was detected.
Setup
Download WinAntiDbg0x100.zip (password: picoctf) and extract the executable.
Open WinAntiDbg0x100.exe inside x64dbg (32-bit).
wget https://artifacts.picoctf.net/c_titan/84/WinAntiDbg0x100.zip && \
unzip WinAntiDbg0x100.zipSolution
- Step 1Locate IsDebuggerPresentIn x64dbg, use View → Symbol Info → search for IsDebuggerPresent. Double-click it and set a breakpoint so execution halts at the anti-debug call.
Learn more
IsDebuggerPresent is a Windows API function (in
kernel32.dll) that returns non-zero if the calling process has a debugger attached. It works by reading a flag in the Process Environment Block (PEB) - a kernel data structure describing the process - specifically theBeingDebuggedbyte at offset 0x2.This is the most basic and most well-known anti-debug technique. Malware uses it to detect analysis environments and either crash, behave differently, or decrypt themselves only when no debugger is present. Hundreds of documented anti-debug tricks exist, ranging from simple API calls to timing attacks, exception handling abuse, and hardware register manipulation.
- x64dbg is a free, open-source Windows debugger for 32-bit and 64-bit executables - the modern replacement for OllyDbg.
- Symbol resolution lets you set breakpoints by API name rather than memory address, which is crucial since addresses change between runs (ASLR).
- The 32-bit version (x32dbg) is required for 32-bit binaries like this one.
- Step 2Step past the checkRun until the breakpoint hits, then Step Into to reach the ret instruction. Set EIP to the branch that executes when no debugger is present (address FA161B in the provided build).
Learn more
EIP(Extended Instruction Pointer) is the x86 register that holds the address of the next instruction to execute. By directly setting EIP to a different address in x64dbg (right-click the address in the disassembly view and choose "Set EIP here"), you force execution to skip the conditional branch that would otherwise terminate the program.
This technique - manually redirecting execution past an anti-debug check - is called an EIP redirect or jump patch. A more permanent approach is to NOP out the conditional jump instruction (replace it with
90bytes), which makes the bypass survive multiple runs without needing to reset EIP each time.The ret instruction returns from the current function by popping the return address from the stack into EIP. Setting EIP just after the
retofIsDebuggerPresentmeans the check runs but its result is never used - execution flows directly to the non-debugger code path. - Step 3Continue to the flagStep over the subsequent instructions. The MOV eax, dword ptr ds:[FA5408] line reveals the flag string; copy it from memory to retrieve picoCTF{...}.
Learn more
Once the anti-debug check is bypassed, the program executes its "no debugger" code path, which reads and displays the flag. The
MOV eax, dword ptr ds:[FA5408]instruction loads the flag's memory address into theeaxregister. In x64dbg, you can right-click this instruction and follow the address in the memory dump or string dump to see the flag content.Embedded strings in executables are stored in the binary's data segment (
.dataor.rdatasection). Even without running the program,stringson the executable often reveals flag-like content - though anti-debug challenges sometimes encrypt the flag and decrypt it only at runtime, making dynamic analysis (actually running with a debugger) the only viable approach.The WinAntiDbg series progressively introduces more sophisticated techniques: this level uses the simple API call; later levels use timing-based detection, exception handler checks, and parent process inspection - techniques that require more creative bypasses than a simple EIP redirect.
Flag
picoCTF{d3bug_f0r_th3_Win_0x100_e7...}
Skipping the failure branch reveals the stored flag string immediately.