Skip to content

Instantly share code, notes, and snippets.

@KpwnZ
Created March 24, 2021 13:40
Show Gist options
  • Save KpwnZ/028a2f656d85f65c6e24e9c38ef10456 to your computer and use it in GitHub Desktop.
Save KpwnZ/028a2f656d85f65c6e24e9c38ef10456 to your computer and use it in GitHub Desktop.
Debug BIOS and boot loader in real mode with lldb
import lldb
def get_current_addr():
# get current address cs:ip
interpreter = lldb.debugger.GetCommandInterpreter()
return_object = lldb.SBCommandReturnObject()
interpreter.HandleCommand('reg r cs', return_object)
cs = int(return_object.GetOutput()[return_object.GetOutput().find("0"):], 0)
interpreter.HandleCommand('reg r eip', return_object)
eip = int(return_object.GetOutput()[return_object.GetOutput().find("0"):], 0)
addr = '0x{:08x}'.format(cs * 16 + eip)
return [cs, eip, addr]
def ins_addr(debugger, command, result, internal_dict):
addr = get_current_addr()
print("\t cs: 0x{:08x}\n\t eip: 0x{:08x}\n\taddr: {}".format(addr[0], addr[1], addr[2]))
def run_to_real_addr(debugger, command, result, internal_dict):
# check cr0 register to detect real mode
interpreter = lldb.debugger.GetCommandInterpreter()
return_object = lldb.SBCommandReturnObject()
interpreter.HandleCommand('reg r cr0', return_object)
real_mode_enabled = int(return_object.GetOutput()[return_object.GetOutput().find("0x"):], 0) & 0x1
if real_mode_enabled != 0:
print("not in real mode")
return
# shit code here :-(
while True:
addr = get_current_addr()
if addr[0] * 16 + addr[1] == int(command, 0):
print("at " + addr[2])
interpreter.HandleCommand('x/10i ' + addr[2], return_object)
print(return_object.GetOutput())
break
interpreter.HandleCommand('reg r cr0', return_object)
def sigtrap_stop_hook(bpaddr):
# a simple stop hook, check the whether the breakpoint addr == current addr
# when the breakpoint hit, a SIGTRAP is sent actually, so we can catch it by writing a stop-hook
addr = get_current_addr()
if bpaddr == int(addr[2], 0): # the breakpoint addr
print("current address: " + addr[2])
print("Hit real mode breakpoint with cs:ip")
lldb.debugger.HandleCommand("x/10i " + addr[2]) # print the instructions
def break_real_addr(debugger, command, result, internal_dict):
target = debugger.GetSelectedTarget()
breakpoint = target.BreakpointCreateByAddress(int(command, 0))
index = target.GetNumBreakpoints()
# add stop-hook, use the real mode address of breakpoint as argument
log_cmd = 'target stop-hook add -o \"script lldb_custom_command.sigtrap_stop_hook({})\"'.format(command)
debugger.HandleCommand(log_cmd)
# print("set real addr breakpoint: "+command)
# breakpoint.SetScriptCallbackFunction('lldb_custom_command.breakpointHandler')
def __lldb_init_module(debugger, internal_dict):
debugger.HandleCommand("command script add -f lldb_custom_command.ins_addr addr")
debugger.HandleCommand("command script add -f lldb_custom_command.break_real_addr bkr")
debugger.HandleCommand("command script add -f lldb_custom_command.run_to_real_addr rtr")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment