These are the notes I took while recently reading Practical Malware Analysis by Andrew Honig & Michael Sikorski.

Debugging is used for removing software bugs found during program exeuction. For malware analysts, it can also allow you to see locations in memory, registers, and arguments used inside of functions. It also allows you to dynamically modify these values which can aid in reverse engineering malware.

Types

  • Source-code level debuggers: often found in IDEs
  • Assembly level debuggers: use provided Assembly code
    • both can step-through programs

Modes

  • Kernel-mode: involves connecting your system to the victim system (w/no apps running)
    • the WinDbg debugger supports Kernel-mode debugging
  • User-mode: involves debugging only a single binary, separated by the OS; ex: OllyDbg

Methods

You can start the program you want debugged using one of two methods:

  1. Use the Debugger to start the app
  2. Attach the app if it’s already running

Techniques

Single-Stepping

  • runs a single CPU instruction then returns control back to the debugger
  • used for understanding more about a section of code
    • ex: watching a for-loop used in decoding a string (like a Polaroid wheel)

Stepping-over

  • next instruction comes after the bypassed function returns

Stepping-into

  • first instruction of the called function

Stepping-over v. Stepping-into

  • be weary of functions that never return (start over)
  • do not step into every function you come across; avoid rabbit holes

Breakpoints

  • used to pause program execution
  • allows you to view variables
  • apps paused by breakpoints are referred to as “broken” (a temporary context)
    • ex: “break app when you come across the EAX register; then, show its contents”

Types of Breakpoints

Software execution

  • replaces first byte of of an instruction w/0xCC (INT 3)
  • forces OS to generate an exemption, passing app control to debugger

Hardware execution

  • “breaks” when a specific, general purpose register is used
    • ex: the EAX register

Conditional breakpoints

  • “breaks” when specific conditions are met
    • ex: searching for a function name, when a parameter value is based, etc.

Opportunities to Control Program Execution

First-chance

  • when app is attached to debugger or via a registered Exception Handler

Second-chance

  • when malware crashes app because it knows its being debugged

Common Exceptions Thrown

  • when INT 3 is executed (breakpoints)
  • Single-stepping: generated after ea instruction is exec (while trap flag register is set)
  • Memory-access violations: generated when an address is invalid/restricted
  • User-mode: some instructions must be exec while processor is in Kernel-mode

Modifying Program Execution

  • Debuggers can modify control flags, instruction pointers, or code
  • ex: setting a breakpoint for a function then, setting EIP for instruction after function (to skip it)
  • ex: tweaking register values to avoid certain functions from running
    • a virus executes if GetSysDefaultLCID (a locale ID value) was not Chinese (EAX register is 0x0C04)

References