A debugger is a kind of interrupt subroutine that temporarily
stops the operation of the process that is being performed. When the debugger
execution is completed, the process logic will continue. The debugger sets the
breakpoint in the instruction that you want to debug and continuously monitors
the occurrence of an event. When the operating system detects a break point
while processing an instruction, it calls the callback function that is
specified.
Hackers normally
place the hacking script inside the callback function
when hacking with the debugger. Typically the
API Hooking technology is used, and when the program calls a function
to store the data, if the value in memory changes, the data stored in the file
can be manipulated.
Let’s take a
brief look at how the debugger works. For
each stage, it is possible to use the Win32 API.
It is possible to call the Win32 API by using the ctypes module in Python.
Moreover, Python can use the pydbg module and can more easily provide debugging.
Debugger Operation Procedure
For (1), (2), (3), (4), (5),
(7), the programmer directly implements using pydbg. For (6), (8), the
operating system performs operations based on the information that programmer
has registered.
(1) Getting the PID: The running process
has its own ID (PID, Process ID), which is an identification number that is
assigned to each process by the OS. The Win32 API can be used to obtain the PID
of the process that you want to debug.
(2) Getting Instruction Address: Check all
lists of the modules that are mapped into the process’s address space to obtain
the address of the function in order to try to set the breakpoint.
(3) Setting the Breakpoint: Set a breakpoint by replacing
the first two bytes of the instruction code with “CC”. The debugger saves the
original instructioin code into the breakpoint list that is managed internally.
Therefore, there is no problem in returning to the original process.
(4) Registering Callback Function: When the process
executes the instruction that the breakpoint has set, a debug event occurs. The
operating system then generates an interrupt and starts to perform an interrupt
subroutine. The interrupt subroutine is the callback function that the
programmer has previously registered.
(5) Waiting for the Debug Event: The
Win32 API is used for the debugger to indefinitely wait for the debug event to
occur and to call the callback function.
(6) Debug Event Occurs: When the debug process finds a
break point during execution, an interrupt is generated.
(7) Executing the Callback Function: The interrupt
subroutine is executed when the interrupt occurs. Previously the registered
callback function corresponded to the interrupt subroutine, and the hacking
code was planted to the callback function, which makes it possible to perform
the desired behavior.
(8) Returning to the
Original Process: If a
callback function is finished, the program will return to the normal process
flow. The Windows operating system supports the Win32 API at each stage, and it
is possible to call it by using the ctypes, as described above. Pydbg is then
used to call the Win32 APIs as well. Let's examine the basic concept of hacking
by installing the pydbg module that simplifies complicated procedures.