Set future breakpoints

Here’s a bit of code for Immunity Debugger. It hooks LoadLibraryA and LoadLibraryW
to stalk a module until it’s loaded. Once it is, it adds breakpoints the user provides
inside that module

#!/usr/bin/env python
'''
Matthew Wollenweber
August 6 2009
mjw@cyberwart.com

I want to debug modules that are dynamically loaded at runtime and then unloaded.
It's a pain to set andreset breakpoints. This script watches for the module to be loaded.
When the module is loaded breakpoints are set. 

-r implies the use of a relative base for the target module
'''
DESC = "Set breakpoints when a specific library is loaded"
USAGE = "!stalkmod <-r> modname  ... "

import immlib
from immlib import LogBpHook
#import time
import struct
import unicodedata
import getopt

def main(args):
    imm = immlib.Debugger()
    imm.Log("starting modstalker")
    breakpoints = []
    module_name = ""

    try:
        opts, extra = getopt.getopt(args, "r")

        for flag, val in opts:
            if flag == "-r":
                imm.addKnowledge("getbase", 1)

        module_name = extra[0]
        for x in range(1, len(extra)):
            breakpoints.append(long(extra[x], 16))
    except:
        usage()
        imm.Log("ERROR in modstalker")
        return "ERROR. Exiting module"

    allmodules=imm.getAllModules()
    for x in allmodules:
        if x.getName().find(module_name) >= 0:
            for b in breakpoints:
                imm.setBreakpoint(b)
            imm.Log("Module Already loaded. Breakpoints set")
            return "Module already loaded. Breakpoints set"

    imm.addKnowledge("breakpoints", breakpoints)
    imm.addKnowledge("modname", module_name)

    load_hook = MyLoadHook()

    load_addr = imm.getAddress("kernel32.LoadLibraryW")
    load_hook.add("bp on loadlibraryW", load_addr, 0, 0, 0)
    load_addr = imm.getAddress("kernel32.LoadLibraryA")
    load_hook.add("bp on loadlibraryW", load_addr, 0, 0, 0)
    imm.Log("Placed hook on loadlibraryA and LoadLibraryW")

    return "Hooks loaded"

class MyLoadHook(LogBpHook):
    def __init__(self):
        LogBpHook.__init__(self)
        self.imm = immlib.Debugger()
        self.found = 0

    def run(self,regs):
        imm = self.imm
        ucode = 0
        getbase = 0
        baseoffset = long(0)

        modname = imm.getKnowledge("modname")
        getbase = imm.getKnowledge("getbase")

        regs = imm.getRegs()
        ptr = imm.readMemory(regs['ESP']+0x4, 0x4)
        ptr = int(struct.unpack("L", ptr)[0])
        filename = imm.readString(ptr)

        #fuck unicode
        if len(filename) < 3:
            ucode = 1
            tmp = imm.readWString(ptr)
            filename = ""
            x = 0
            while x <  len(tmp):
                filename += str(tmp[x])
                x+=2

        filename = filename.lower()

        #imm.Log("I'm in: " + filename)
        #imm.Log("I'm stalking: " + modname)

        if filename.find(modname) >= 0:
            imm.Log("MATCHED. Setting breakpoints")
            if ucode == 0:
                imm.setBreakpoint(0x7c801DAB) #End of LoadLibraryA
            else:
                imm.setBreakpoint(0x7c80AEEB) #End of LoadLibraryW

            imm.Run() #let it run until the end of loadlibrary so that our memory is mapped
            #time.sleep(2)
            if getbase == 1:
                allmodules=imm.getAllModules()
                for x in allmodules:
                    if x.getName().find(modname) >= 0:
                        baseoffset = x.getBase()
                        break

            bps = imm.getKnowledge("breakpoints")
            for x in bps:
                x = x + baseoffset
                imm.Log("set BP: %08x" % (x))
                imm.setBreakpoint(x)

            imm.Log("breakpoints set")
            self.found = 1
            self.UnHook()

        return 

def usage():
    print USAGE

if __name__=="__main__":
    print "This module is for use within Immunity Debugger only"

Thanks to Justin at Immunity for providing guidance. FYI it would appear simpler to use LoadDLL hooks — good luck with that.

Leave a Reply

You must be logged in to post a comment.