from idaapi import *
from idc import *
import idautils

EXTERNALMETHOD             = "__ZN12IOUserClient14externalMethodEjP25IOExternalMethodArgumentsP24IOExternalMethodDispatchP8OSObjectPv"
GETNOTIFICATIONSEMAPHORE   = "__ZN12IOUserClient24getNotificationSemaphoreEmPP9semaphore"
GETTARGETANDMETHODFORINDEX = "__ZN12IOUserClient26getTargetAndMethodForIndexEPP9IOServicem"

EXTERNALMETHOD_OFFSET             = -8;
GETTARGETANDMETHODFORINDEX_OFFSET = 7;

def find_sMethods():

    func_ea = LocByName(GETNOTIFICATIONSEMAPHORE)
    print "IOUserClient::getNotificationSemaphore at %08x" % func_ea

    xrefs = XrefsTo(func_ea)

    for xref in xrefs:

        extra_msg = ""

        external_method_ea = xref.frm + EXTERNALMETHOD_OFFSET * 4;
        content_ea = Dword(external_method_ea) & 0xFFFFFFFE;
        if content_ea & 0xFFFFFFFE != LocByName(EXTERNALMETHOD):
            extra_msg += "IOUserClient::externalMethod overriden (%08x - %s) " % (content_ea & 0xFFFFFFFE, GetFunctionName(content_ea))

        gettarget_method_ea = xref.frm + GETTARGETANDMETHODFORINDEX_OFFSET * 4;
        content_ea = Dword(gettarget_method_ea) & 0xFFFFFFFE;
        if content_ea != LocByName(GETTARGETANDMETHODFORINDEX):
            extra_msg += "IOUserClient::getTargetAndMethodFromIndex overriden (%08x - %s) " % (content_ea & 0xFFFFFFFE, GetFunctionName(content_ea))

        driver=SegName(xref.frm)
        driver=driver[:driver.index(':')]

        print "%s - %s" % (driver, extra_msg)



if __name__ == '__main__':
    find_sMethods()
    print "Done!"
