定义了三个类和一个函数
这个.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