美文网首页
IMF-hook.py

IMF-hook.py

作者: Dosi_X | 来源:发表于2018-04-18 15:46 被阅读0次

    定义了三个类和一个函数
    这个.py作用在于生成hook的文件

    class Hooker:

    def __init__(self):
        调用basic.load_apis(),返回值赋给self.apis
    
    def gen_hook(self, fn_hook):
        const.HEADER赋值给code
        const.HOOK_TABLE_TEMPLATE赋值给table
        const.HOOK_ENTRY_TEMPLATE赋值给entry
        tmp = ''
        name, api遍历self.apis:
            调用ApiHook(api)赋给h
            code += h.log()
            temp += entry%h.hook_entry()
        code += table%tmp
        以可写方式打开文件fn_hook,把code写入
    

    class ApiHook(basic.Api):

    def __init__(self, api):
        self.__dict__ = api.__dict__.copy()
        self.arghooks = []存放要hook的所有args
        遍历self.args:
            self.arghooks.append(ArgHook(arg))
    
    def list_args(self, show_type):
        ret = ''
        遍历self.arghooks:
            如果show_type为真:
                ret追加上arghook的type和name
            否则ret追加上name
        返回ret
    
    def log(self):
        body = self.log_intro()
        body += self.log_input()
        body += self.call_ori()
        body += self.log_output()
        args = self.list_args(True)True即要返回type
        返回self.rtype,self.name,args,body
    
    def log_intro(self):
        intro = '\tFILE *fp = fopen(log_path,"a");\n'
        intro +='\tflock(fileno(fp),LOCK_EX);\n'
        return intro
    
    def log_input(self):
        ret = ''
        遍历self.arghooks:
            如果arghook.is_input()为真:
                ret += arghook.log()
        ret = '''\tfprintf(fp,"IN ['%s',");\n'''%(self.name) +ret
        return ret +'''\tfprintf(fp,"]\\n");\n'''
    
    def call_ori(self):
        args = self.list_args(False)
        if self.is_void()为真:
            return  '\t%s(%s);\n'%(self.name, args)
        return '\t%s ret = %s(%s);\n'%(self.rtype,self.name, args)  
        
    def log_output(self):
        ret = ArgHook(self.rval).log()
        遍历self.arghooks:
            如果arg是output:
                ret += arghook.log()
        ret = '''\tfprintf(fp,"OUT ['%s',");\n'''%(self.name) +ret
        ret += '''\tfprintf(fp,"]\\n");\n'''
        ret += '\tfclose(fp);\n'
        如果返回值不为空:
            ret += '\treturn ret;\n'
        返回ret
    
    def hook_entry(self):
        return ('fake_%s'%self.name, self.name)
    

    class ArgHook(basic.Arg):

    def __init__(self, arg):
        self.__dict__ = arg.__dict__.copy()
    
    def log(self):
        如果self.name == const.RVAL并且self.type=='void':
            返回''
        ret, add, add_arg = '', '', ''
        如果self.is_input()为真且self.name不为const.RVAL且self.type在const.CHECK_ORIGINAL里:
            ret += '''\tchar name_buf[0x100];\n'''
            ret += '''\tIORegistryEntryGetName(%s,name_buf);\n'''%self.name 
            add += "'ori':'IOServiceGetMatchingService(0,IOServiceMatching(\\\"%s\\\"))',"
            add_arg+= ',name_buf'
        log_name = self.get_log_name()
        fmt = self.get_fmt()
        ret += '\tif(%s) '%(self.valid_ptr())
        ret += '''fprintf(fp,"{'name':'%s','''%self.name
        ret += ''''value': %s,'''%fmt
        ret += ''''size' : 0x%%lx,'cnt':0x%%x,%s '''%add
        ret += ''''data':[",%s, sizeof(%s),'''%(log_name, self.type)
        ret += '''%s%s);\n '''%(self.get_opt('cnt'), add_arg)
        ret += '''\telse fprintf(fp,"{'name':'%s','''%self.name
        ret += ''''value': %s, '''%fmt
        ret += ''''size' : 0x%%lx,'cnt':'undefined',%s '''%add
        ret += ''''data':[",%s,sizeof(%s)%s);\n'''%(log_name, self.type, add_arg)
        如果参数是指针:
            ret += self.log_ptr()
        如果self.is_input()为真且self.name不为const.RVAL且self.type在const.CHECK_CF里:
            ret += '''\tfprintf(fp,"],'ori':");\n'''
            ret += '''\tlog_CFTypeRef(fp,%s);\n'''%self.name
            ret += '''\tfprintf(fp,"},");\n'''
        否则 :
            ret += '''\tfprintf(fp,"]},");\n '''
        返回ret
    
    def log_ptr(self):如果是指针
        template = '''\tif(%s){\n\t\tfor(int i=0; i<%s;i++){\n%s\t\t}\n\t}\n'''
        name = self.name
        如果类型为void *:
            name = '((uint8_t *) %s)'%name
        body = '''\t\t\tfprintf(fp,"%s,",%s[i]);\n'''%(self.get_fmt(True), name)
        return template%(self.valid_ptr(self.name), self.get_opt('cnt'), body)
    
    def get_log_name(self):
        name = self.name
        如果类型为'CFStringRef':
            返回 'CFStringGetCStringPtr(%s,kCFStringEncodingMacRoman)'%name
        返回name
    
    def get_fmt(self, for_ptr = False):
        把self.type里的const替换为'',赋给ty
        如果ty在const.TYPE_FMT里:
            返回const.TYPE_FMT[ty]
        如果for_ptr为假且参数为指针:
            返回'%p'
        返回const.SIZE_FMT[self.get_opt('size')]
    
    def valid_ptr(self, init='1'):
        ret = init
        cnt = str(self.get_opt('cnt'))
        遍历cnt:
            如果出现了*就break
            ret = '%s && '%cnt[idx+1:]+ret
        返回ret

    相关文章

      网友评论

          本文标题:IMF-hook.py

          本文链接:https://www.haomeiwen.com/subject/nkfpkftx.html