From x64dbg-skills
Finds OEP in packed/protected PE executables using x64dbg: traces packer stubs with anti-debug evasion, heuristic detection, captures state snapshot.
npx claudepluginhub dariushoule/x64dbg-skillsThis skill is limited to using the following tools:
Smart trace-based OEP finder for packed/protected PE executables. Walks through unpacking stages using intelligent stepping, anti-debug evasion, and heuristic OEP detection. Once the OEP is found, captures a state snapshot for downstream use (PE reconstruction, analysis, etc.).
Hunts vulnerabilities in x64dbg debuggees: analyzes imports/exports, triages I/O attack surfaces, tests bugs like overflows/wraps, generates PoCs.
Unpacks UPX-packed malware samples to expose original executable code for static analysis, handling modified headers when automated tools fail. Useful for high-entropy binaries or packer detection via DIE/PEiD.
Identifies anti-debugging checks like IsDebuggerPresent, NtQueryInformationProcess in Windows binaries; suggests bypasses via patches/hooks/scripts for malware analysis, CTFs, authorized RE.
Share bugs, ideas, or general feedback.
Smart trace-based OEP finder for packed/protected PE executables. Walks through unpacking stages using intelligent stepping, anti-debug evasion, and heuristic OEP detection. Once the OEP is found, captures a state snapshot for downstream use (PE reconstruction, analysis, etc.).
Ask the user (via AskUserQuestion) for any information not already provided:
Determine the CIP register name: rip for 64-bit, eip for 32-bit.
Determine the stack pointer register: rsp for 64-bit, esp for 32-bit.
Determine the debugger variant: x64dbg.exe for 64-bit, x32dbg.exe for 32-bit.
Use mcp__x64dbg__start_session with:
executable_path: the packed PE pathx64dbg_path: the appropriate debugger binaryAlways start a new session for a clean environment. Wait for the debugger to settle — call mcp__x64dbg__get_debugger_status and confirm the debuggee is paused at the entry point. If running, call mcp__x64dbg__pause.
Record the session PID and x64dbg path for later reconnection.
Gather information about the packed binary to inform the unpacking strategy:
mcp__x64dbg__get_all_registers to record the initial register state (especially the stack pointer — packers often restore it before jumping to OEP).mcp__x64dbg__get_memory_map to identify the module's sections, their protections, and any suspicious characteristics (e.g., sections with write+execute, sections with zero raw size but large virtual size, non-standard section names).mcp__x64dbg__disassemble to identify the packer stub pattern./yara-sigs via Skill("yara-sigs") to identify the packer and obvious crypto/anti-debug signatures.
Summarize findings to the user:
This is the main unpacking loop. The goal is to trace through the packer stub and identify when execution transfers to the original, unpacked code.
The OEP is likely reached when several of these conditions align:
| Heuristic | Description |
|---|---|
| Section transition | CIP moves from a packer section (e.g., .rsrc, .aspack, last section) into the original code section (usually .text or the first section) |
| Stack restoration | ESP/RSP returns to (or near) its initial value from step 3 |
| Common OEP patterns | Disassembly shows typical compiler entry sequences: push ebp; mov ebp, esp, sub rsp, N, call __security_init_cookie, MSVC/GCC/Delphi/Borland CRT init patterns |
| Large code region | After writes settle, a large contiguous region of valid-looking code exists in the original code section |
| IAT populated | The import table region contains valid pointers to API functions |
Start at the packed entry point. Disassemble the current location.
Identify the current phase:
go. If you cannot determine the loop exit, use mcp__x64dbg__trace_over with a break_condition that detects leaving the loop (e.g., a CIP range check).GetProcAddress, LoadLibrary*, hash-based API resolution. Step over these — they are building the IAT.jmp or push+ret that lands in a different section — potential OEP. Verify with the heuristics above.When in a repetitive region (same addresses appearing repeatedly):
mcp__x64dbg__trace_over with a break_condition like cip < <loop_start> || cip > <loop_end> to escape the loop efficiently.mcp__x64dbg__set_breakpoint with an appropriate condition.At each significant transition, disassemble 20–30 instructions at the new location, check the memory section it belongs to, and evaluate the OEP heuristics.
Label and comment key addresses as you go: decode loop entries, API resolution routines, anti-debug checks, stage transitions, and the final OEP. Use mcp__x64dbg__set_comment and mcp__x64dbg__set_label.
Packers frequently employ anti-debug techniques. When you encounter them, work around them to simulate non-debugged execution:
| Technique | Detection | Evasion |
|---|---|---|
| IsDebuggerPresent | Call to kernel32.IsDebuggerPresent or direct PEB.BeingDebugged read | Step to the call, then set eax/rax to 0 after it returns (mcp__x64dbg__set_register) |
| NtQueryInformationProcess (DebugPort) | Call with class 0x7 | Step over the call, then zero the output buffer (mcp__x64dbg__write_memory) |
| PEB.BeingDebugged | Direct memory read of fs:[30]+2 (x86) or gs:[60]+2 (x64) | Write 0x00 to the BeingDebugged byte in the PEB (mcp__x64dbg__write_memory). Find PEB address via mcp__x64dbg__eval_expression with peb(). |
| PEB.NtGlobalFlag | Read of PEB+0x68 (x86) or PEB+0xBC (x64) | Write 0x00000000 to clear debug flags |
| Heap flags | PEB.ProcessHeap flags check | Patch the heap flags to remove debug indicators |
| Timing checks | rdtsc, GetTickCount, QueryPerformanceCounter | Step over the first call, note the result, step over the second, then patch the result to show minimal elapsed time |
| Hardware breakpoint detection | GetThreadContext / direct DR register reads | Clear debug registers before the check or patch the return values |
| INT 2D / INT 3 tricks | Exception-based anti-debug | Set the appropriate exception handler breakpoint and ensure execution continues as if no debugger is present |
| Self-checksum | CRC/hash of code regions (detects software breakpoints) | Use hardware breakpoints instead of software breakpoints in checksummed regions |
This list is not exhaustive. Always analyze the disassembly to understand the anti-debug technique being used and apply the appropriate evasion.
When you detect anti-debug behavior:
Proactive anti-debug setup: At the start of unpacking, consider preemptively patching common PEB fields:
0x00 to PEB.BeingDebugged0x00000000 to PEB.NtGlobalFlag
This can be done via mcp__x64dbg__eval_expression to find peb(), then mcp__x64dbg__write_memory.When you believe you've reached the OEP:
.text or first section).mcp__x64dbg__get_symbol to verify.Ask the user via AskUserQuestion: "OEP found at <address>. Take a state snapshot?"
If the user says no or wants to adjust, continue stepping as directed.
Invoke /state-snapshot via Skill("state-snapshot") to dump the full debuggee memory state at the OEP. Note the snapshot output directory.
Report the final results to the user:
Always call mcp__x64dbg__refresh_gui as the final step.