Skip to main content
1 of 2
Peanut
  • 141
  • 6

I've written a small IDAPython script that searches for a string in the bytes preceding MmGetSystemRoutineAddress calls and then marks that call with the function being imported. It worked on the x64 and x86 drivers I had to hand but I've left my commented out debug prints in just in case.

There's definitely improvements that could be made:

  • Make sure that the MmGetSystemRoutineAddress xref is an actual call
  • The function pointer result is often put into a global pointer (i.e. mov dword_444E0, eax), having this pointer automatically named would be very useful.
  • The other common use case is seeing it being called straight after (i.e. call eax) so having this call marked would be nice.

I'll have a look at making these improvements and updating when I can.

#Using Sark would have made the line iteration a bit nicer but I wanted 
#something I could use anywhere without any external dependencies

import idc
import idautils
import idaapi

print "Trying to find MmGetSystemRoutineAddress..."
    
getsys_addr = idc.LocByName("MmGetSystemRoutineAddress")
print "Found MmGetSystemRoutineAddress @ %08X" % getsys_addr

num_xrefs = sum(1 for i in idautils.CodeRefsTo(getsys_addr, 0))
print "Found %d xrefs to MmGetSystemRoutineAddress" % num_xrefs

#Get the strings so we can see what might have been passed in
sc = idautils.Strings(default_setup = False)
# we want C & Unicode strings, and *only* existing strings.
sc.setup(strtypes=Strings.STR_C | Strings.STR_UNICODE, ignore_instructions = True, display_only_existing_strings = True)

#Make a list of all string locations
string_locs = []
for s in sc:
    string_locs.append((s.ea, str(s)))
    #print "%x: len=%d type=%d -> '%s'" % (s.ea, s.length, s.type, str(s))

#Make a dict of all places strings are Xrefs
string_xrefs = {}
for loc in string_locs:
    #print "%08X  %s" % (loc[0], loc[1])
    for xref in idautils.XrefsTo(loc[0]):
        #print "Xref @ %08X" % xref.frm
        string_xrefs[xref.frm] = loc
        
#Iterate through each Xref to MmGetSystemRoutineAddress and see if a string is used in the preceding instructions...
for getsys_ref in idautils.CodeRefsTo(getsys_addr, 0):
    print "\nMmGetSystemRoutineAddress called @ %08X" % getsys_ref
    
    #Start at line above MmGetSystemRoutineAddress call
    new_ea = idaapi.get_item_head(getsys_ref - 1)
    
    #Continue until we've gone back 50 bytes or found a string
    while new_ea > getsys_ref - 50:     
        print "    %08X  %s" % (new_ea, idc.GetDisasm(new_ea))
        
        #Go to the line above
        new_ea = idaapi.get_item_head(new_ea-1)
        
        if new_ea in string_xrefs:
            print "  Found an Xref to a string in preceding 50 bytes! Mark it up"
            print "    %08X  %s" % (new_ea, idc.GetDisasm(new_ea))
            idc.MakeComm(getsys_ref, string_xrefs[new_ea][1] + "  - auto added")
            break
    
Peanut
  • 141
  • 6