197 lines
6.3 KiB
Python
197 lines
6.3 KiB
Python
#!/usr/bin/python
|
|
|
|
import os
|
|
|
|
STUB_FILE_NAME = "MethodHookerStubs"
|
|
|
|
TEMP_STUB_CLASS_WRAPPER = """package com.swift.sandhook.xposedcompat.hookstub;
|
|
|
|
import static com.swift.sandhook.xposedcompat.hookstub.HookStubManager.hookBridge;
|
|
import static com.swift.sandhook.xposedcompat.hookstub.HookStubManager.getMethodId;
|
|
import static com.swift.sandhook.xposedcompat.hookstub.HookStubManager.originMethods;
|
|
import static com.swift.sandhook.xposedcompat.utils.DexLog.printCallOriginError;
|
|
|
|
/**
|
|
* this file is auto gen by genhookstubs.py
|
|
* it is for sandhook internal hooker & backup methods
|
|
**/
|
|
public class MethodHookerStubs%d {
|
|
%s
|
|
}
|
|
"""
|
|
|
|
TEMP_STUB_HOOK_METHOD_NAME = """stub_hook_%d"""
|
|
TEMP_STUB_HOOK_BACKUP_NAME = """stub_backup_%d"""
|
|
TEMP_STUB_CALL_ORIGIN_NAME = """call_origin_%d_%d"""
|
|
|
|
TEMP_STUB_GET_METHOD_ID_NAME = """getMethodId(%d, %d)"""
|
|
|
|
JAVA_TYPE_INT = "int"
|
|
JAVA_CAST_INT = "(int)"
|
|
JAVA_TYPE_LONG = "long"
|
|
|
|
TEMP_STUB_HOOK_METHOD = """
|
|
public static %s %s(%s) throws Throwable {
|
|
return %s hookBridge(%s, %s %s);
|
|
}
|
|
"""
|
|
|
|
TEMP_STUB_BACKUP_METHOD = """
|
|
public static %s %s(%s) throws Throwable {
|
|
try {
|
|
printCallOriginError(originMethods[%s]);
|
|
} catch (Throwable throwable) {}
|
|
return 0;
|
|
}
|
|
"""
|
|
|
|
TEMP_STUB_CALL_ORIGIN_CLASS = """
|
|
static class %s implements CallOriginCallBack {
|
|
@Override
|
|
public long call(long... args) throws Throwable {
|
|
return %s(%s);
|
|
}
|
|
}
|
|
"""
|
|
|
|
TEMP_STUB_INFO = """
|
|
public static boolean hasStubBackup = %s;
|
|
public static int[] stubSizes = {%s};
|
|
"""
|
|
|
|
|
|
STUB_SIZES_32 = [10,20,30,30,30,30,30,20,10,10,5,5,3]
|
|
STUB_SIZES_64 = [10,20,30,30,30,30,50,50]
|
|
HAS_BACKUP = False
|
|
|
|
|
|
def getMethodId(args, index):
|
|
return TEMP_STUB_GET_METHOD_ID_NAME % (args, index)
|
|
|
|
def getMethodHookName(index):
|
|
return TEMP_STUB_HOOK_METHOD_NAME % index
|
|
|
|
def getMethodBackupName(index):
|
|
return TEMP_STUB_HOOK_BACKUP_NAME % index
|
|
|
|
def getCallOriginClassName(args, index):
|
|
return TEMP_STUB_CALL_ORIGIN_NAME % (args, index)
|
|
|
|
|
|
def genArgsList(is64Bit, isDefine, length):
|
|
args_list = ""
|
|
for i in range(length):
|
|
if (i != 0):
|
|
args_list += ", "
|
|
if isDefine:
|
|
if (is64Bit):
|
|
args_list += (JAVA_TYPE_LONG + " " + "a" + str(i))
|
|
else:
|
|
args_list += (JAVA_TYPE_INT + " " + "a" + str(i))
|
|
else:
|
|
args_list += ("a" + str(i))
|
|
return args_list
|
|
|
|
|
|
def genArgsListForCallOriginMethod(is64Bit, length):
|
|
arg_name = """args[%s]"""
|
|
args_list = ""
|
|
for i in range(length):
|
|
if (i != 0):
|
|
args_list += ", "
|
|
if (is64Bit):
|
|
args_list += arg_name % i
|
|
else:
|
|
args_list += (JAVA_CAST_INT + arg_name % i)
|
|
return args_list
|
|
|
|
|
|
def genHookMethod(is64Bit, args, index):
|
|
java_type = JAVA_TYPE_LONG if is64Bit else JAVA_TYPE_INT
|
|
cast = "" if is64Bit else JAVA_CAST_INT
|
|
args_list_pre = ", " if args > 0 else ""
|
|
args_list = genArgsList(is64Bit, False, args)
|
|
args_list_def = genArgsList(is64Bit, True, args)
|
|
call_origin_obj = ("new " + getCallOriginClassName(args, index) + "()") if HAS_BACKUP else "null"
|
|
method = TEMP_STUB_HOOK_METHOD % (java_type, getMethodHookName(index), args_list_def, cast, getMethodId(args, index), call_origin_obj, args_list_pre + args_list)
|
|
return method
|
|
|
|
|
|
def genBackupMethod(is64Bit, args, index):
|
|
java_type = JAVA_TYPE_LONG if is64Bit else JAVA_TYPE_INT
|
|
args_list_def = genArgsList(is64Bit, True, args)
|
|
method = TEMP_STUB_BACKUP_METHOD % (java_type, getMethodBackupName(index), args_list_def, getMethodId(args, index))
|
|
return method
|
|
|
|
def genCallOriginClass(is64Bit, args, index):
|
|
method = TEMP_STUB_CALL_ORIGIN_CLASS % (getCallOriginClassName(args, index), getMethodBackupName(index), genArgsListForCallOriginMethod(is64Bit, args))
|
|
return method
|
|
|
|
def genStubInfo32():
|
|
hasStub = "true" if HAS_BACKUP else "false"
|
|
stubSizes = ""
|
|
for args in range(len(STUB_SIZES_32)):
|
|
if (args != 0):
|
|
stubSizes += ", "
|
|
stubSizes += str(STUB_SIZES_32[args])
|
|
return TEMP_STUB_INFO % (hasStub, stubSizes)
|
|
|
|
def genStubInfo64():
|
|
hasStub = "true" if HAS_BACKUP else "false"
|
|
stubSizes = ""
|
|
for args in range(len(STUB_SIZES_64)):
|
|
if (args != 0):
|
|
stubSizes += ", "
|
|
stubSizes += str(STUB_SIZES_64[args])
|
|
return TEMP_STUB_INFO % (hasStub, stubSizes)
|
|
|
|
def gen32Stub(packageDir):
|
|
class_content = genStubInfo32()
|
|
class_name = STUB_FILE_NAME + "32"
|
|
for args in range(len(STUB_SIZES_32)):
|
|
for index in range(STUB_SIZES_32[args]):
|
|
class_content += """\n\n\t//stub of arg size %d, index %d""" % (args, index)
|
|
class_content += genHookMethod(False, args, index)
|
|
if HAS_BACKUP:
|
|
class_content += "\n"
|
|
class_content += genCallOriginClass(False, args, index)
|
|
class_content += "\n"
|
|
class_content += genBackupMethod(False, args, index)
|
|
class_content += "\n"
|
|
class_str = TEMP_STUB_CLASS_WRAPPER % (32, class_content)
|
|
javaFile = open(os.path.join(packageDir, class_name + ".java"), "w")
|
|
javaFile.write(class_str)
|
|
javaFile.close()
|
|
|
|
|
|
def gen64Stub(packageDir):
|
|
class_content = genStubInfo64()
|
|
class_name = STUB_FILE_NAME + "64"
|
|
for args in range(len(STUB_SIZES_64)):
|
|
for index in range(STUB_SIZES_64[args]):
|
|
class_content += """\n\n\t//stub of arg size %d, index %d""" % (args, index)
|
|
class_content += genHookMethod(True, args, index)
|
|
if HAS_BACKUP:
|
|
class_content += "\n"
|
|
class_content += genCallOriginClass(True, args, index)
|
|
class_content += "\n"
|
|
class_content += genBackupMethod(True, args, index)
|
|
class_content += "\n"
|
|
class_str = TEMP_STUB_CLASS_WRAPPER % (64, class_content)
|
|
javaFile = open(os.path.join(packageDir, class_name + ".java"), "w")
|
|
javaFile.write(class_str)
|
|
javaFile.close()
|
|
|
|
|
|
def genStub(packageDir):
|
|
for fileName in os.listdir(packageDir):
|
|
if fileName.startswith(STUB_FILE_NAME):
|
|
os.remove(os.path.join(packageDir, fileName))
|
|
gen32Stub(packageDir)
|
|
gen64Stub(packageDir)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
genStub(os.path.join(os.path.dirname(os.path.realpath(__file__)),
|
|
"src/main/java/com/swift/sandhook/xposedcompat/hookstub"))
|