├── .gitignore ├── Android ├── SDK23 │ ├── dev │ │ └── __properties__ │ ├── lib │ │ ├── libc.so │ │ ├── libcpp.so │ │ ├── libcrypto.so │ │ ├── libdl.so │ │ ├── liblog.so │ │ ├── libm.so │ │ ├── libssl.so │ │ ├── libstdcpp.so │ │ └── libz.so │ ├── lib64 │ │ ├── libc.so │ │ ├── libcpp.so │ │ ├── libcrypto.so │ │ ├── libdl.so │ │ ├── liblog.so │ │ ├── libm.so │ │ ├── libssl.so │ │ ├── libstdcpp.so │ │ └── libz.so │ ├── proc │ │ └── stat │ └── system │ │ └── usr │ │ └── share │ │ └── zoneinfo │ │ └── tzdata └── rootfs │ ├── stderr.txt │ └── stdout.txt ├── BridgeScript ├── AttachBridge.py └── BridgeScript.js ├── Emulator ├── Emulator.py ├── debugger │ ├── ARM32Debugger.py │ ├── ARM64Debugger.py │ └── ConsoleDebugger.py ├── dvm │ ├── DalvikVM.py │ ├── DvmClass.py │ ├── DvmField.py │ ├── DvmMethod.py │ ├── DvmObject.py │ └── JniConst.py ├── hooks │ ├── ARMConst.py │ ├── Hooker.py │ ├── JniHooks.py │ └── NativeHooks.py ├── linker │ ├── AndroidRelocationIterator.py │ ├── ElfConst.py │ ├── ElfReader.py │ ├── ElfStruct.txt │ ├── Linker.py │ ├── Module.py │ └── SLEB128Decoder.py ├── utils │ ├── Dvm_Helpers.py │ ├── Memory_Helpers.py │ └── Open_Helpers.py └── vm │ ├── ARM32SyscallHandler.py │ ├── ARM64SyscallHandler.py │ ├── Memory.py │ └── PCB.py ├── README.md └── UniDa.py /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | bin/apks/*.apk 3 | bin/*.so 4 | test* 5 | *.pyc 6 | __pycache__/ -------------------------------------------------------------------------------- /Android/SDK23/dev/__properties__: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/SDK23/dev/__properties__ -------------------------------------------------------------------------------- /Android/SDK23/lib/libc.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/SDK23/lib/libc.so -------------------------------------------------------------------------------- /Android/SDK23/lib/libcpp.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/SDK23/lib/libcpp.so -------------------------------------------------------------------------------- /Android/SDK23/lib/libcrypto.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/SDK23/lib/libcrypto.so -------------------------------------------------------------------------------- /Android/SDK23/lib/libdl.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/SDK23/lib/libdl.so -------------------------------------------------------------------------------- /Android/SDK23/lib/liblog.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/SDK23/lib/liblog.so -------------------------------------------------------------------------------- /Android/SDK23/lib/libm.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/SDK23/lib/libm.so -------------------------------------------------------------------------------- /Android/SDK23/lib/libssl.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/SDK23/lib/libssl.so -------------------------------------------------------------------------------- /Android/SDK23/lib/libstdcpp.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/SDK23/lib/libstdcpp.so -------------------------------------------------------------------------------- /Android/SDK23/lib/libz.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/SDK23/lib/libz.so -------------------------------------------------------------------------------- /Android/SDK23/lib64/libc.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/SDK23/lib64/libc.so -------------------------------------------------------------------------------- /Android/SDK23/lib64/libcpp.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/SDK23/lib64/libcpp.so -------------------------------------------------------------------------------- /Android/SDK23/lib64/libcrypto.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/SDK23/lib64/libcrypto.so -------------------------------------------------------------------------------- /Android/SDK23/lib64/libdl.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/SDK23/lib64/libdl.so -------------------------------------------------------------------------------- /Android/SDK23/lib64/liblog.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/SDK23/lib64/liblog.so -------------------------------------------------------------------------------- /Android/SDK23/lib64/libm.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/SDK23/lib64/libm.so -------------------------------------------------------------------------------- /Android/SDK23/lib64/libssl.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/SDK23/lib64/libssl.so -------------------------------------------------------------------------------- /Android/SDK23/lib64/libstdcpp.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/SDK23/lib64/libstdcpp.so -------------------------------------------------------------------------------- /Android/SDK23/lib64/libz.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/SDK23/lib64/libz.so -------------------------------------------------------------------------------- /Android/SDK23/proc/stat: -------------------------------------------------------------------------------- 1 | cpu 4421 1123 3145 10469 1223 142 89 0 0 0 2 | cpu0 1379 118 819 838 253 57 50 0 0 0 3 | cpu1 645 377 642 1546 262 20 10 0 0 0 4 | cpu2 566 313 615 1720 251 40 14 0 0 0 5 | cpu3 429 296 542 1958 275 13 8 0 0 0 6 | cpu4 747 10 339 2084 109 7 4 0 0 0 7 | cpu5 655 9 188 2323 73 5 3 0 0 0 8 | intr 208793 0 1 0 1 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 37745 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 870 0 0 0 0 0 0 0 52 0 0 121 0 0 0 0 0 978 2 4 0 0 0 0 0 1910 0 0 0 0 0 0 0 0 0 0 212 0 0 0 0 2 416 2 0 2 0 0 0 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2488 0 0 0 0 0 0 0 0 0 0 0 0 132 0 0 0 45 0 0 151 0 23 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 29550 0 0 0 0 0 0 0 12703 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 80 0 8 0 0 0 0 4313 581 0 0 0 2411 0 0 0 0 0 0 0 0 0 0 0 1 0 0 185 196 0 0 0 0 0 30 0 68 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 242 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 148 0 0 0 0 3431 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 48 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 22 0 0 0 0 0 0 1 2 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 63 144 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 | ctxt 488103 10 | btime 1420201874 11 | processes 5073 12 | procs_running 9 13 | procs_blocked 0 14 | softirq 123031 2 13947 4 0 2 2 28364 14892 12 65806 -------------------------------------------------------------------------------- /Android/SDK23/system/usr/share/zoneinfo/tzdata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/SDK23/system/usr/share/zoneinfo/tzdata -------------------------------------------------------------------------------- /Android/rootfs/stderr.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/rootfs/stderr.txt -------------------------------------------------------------------------------- /Android/rootfs/stdout.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abbbbbi/UniDa/bf81bcead5a516018730984259cba8a0f719b6e3/Android/rootfs/stdout.txt -------------------------------------------------------------------------------- /BridgeScript/AttachBridge.py: -------------------------------------------------------------------------------- 1 | import os 2 | import pprint 3 | import signal 4 | from pathlib import Path 5 | 6 | import frida 7 | 8 | 9 | class AttachBridge: 10 | def __init__(self, process): 11 | device = frida.get_usb_device() 12 | print("attach") 13 | session = device.attach(process) 14 | with open(Path(__file__).resolve().parent.joinpath("./BridgeScript.js"), encoding="utf-8") as f: 15 | ScriptFile = f.read() 16 | script = session.create_script(ScriptFile) 17 | script.on("message", self.onMessage) 18 | script.load() 19 | self.exports = script.exports 20 | self.process = process 21 | 22 | @staticmethod 23 | def onMessage(message, data): 24 | if message["type"] == "error": 25 | pprint.pprint(message) 26 | os.kill(os.getpid(), signal.SIGTERM) 27 | return 28 | -------------------------------------------------------------------------------- /BridgeScript/BridgeScript.js: -------------------------------------------------------------------------------- 1 | rpc.exports = { 2 | callNativeFunc(soName, exportName, argsTypeArr, retType, args) { 3 | var funcAddr = Module.findExportByName(soName, exportName) 4 | var nativeFunc = new NativeFunction(funcAddr, retType, argsTypeArr); 5 | return nativeFunc.apply(null, args) 6 | }, 7 | callJniEnvFunc(funcName, args) { 8 | return Java.vm.tryGetEnv()[funcName].apply(null, args) 9 | }, 10 | testFunc(soName, exportName) { 11 | return Module.findExportByName(soName, exportName) 12 | } 13 | } -------------------------------------------------------------------------------- /Emulator/Emulator.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from random import randint 3 | 4 | from unicorn import * 5 | from keystone import * 6 | from unicorn.arm64_const import * 7 | from unicorn.arm_const import * 8 | 9 | from Emulator.dvm.DalvikVM import DalvikVM 10 | from Emulator.hooks.Hooker import Hooker 11 | from Emulator.linker.Linker import Linker 12 | from Emulator.utils.Memory_Helpers import ptrStr 13 | from Emulator.vm.Memory import Memory 14 | from Emulator.vm.ARM32SyscallHandler import ARM32SyscallHandler 15 | from Emulator.vm.ARM64SyscallHandler import ARM64SyscallHandler 16 | from Emulator.vm.PCB import PCB 17 | 18 | logger = logging.getLogger(__name__) 19 | 20 | 21 | def hook_code(uc, address, size, userdata): 22 | print(">>> Tracing instruction at 0x%x, instruction size = 0x%x %s" % (address, size, ptrStr(userdata, address))) 23 | print( 24 | "UC_ARM_REG_R0 0x%X UC_ARM_REG_R1 0x%X UC_ARM_REG_R2 0x%X UC_ARM_REG_R3 0x%X UC_ARM_REG_R4 0x%X" 25 | "UC_ARM_REG_R5 0x%X UC_ARM_REG_R6 0x%X UC_ARM_REG_R7 0x%X UC_ARM_REG_R8 0x%X" % ( 26 | uc.reg_read(UC_ARM_REG_R0), uc.reg_read(UC_ARM_REG_R1), uc.reg_read(UC_ARM_REG_R2), 27 | uc.reg_read(UC_ARM_REG_R3), uc.reg_read(UC_ARM_REG_R4), uc.reg_read(UC_ARM_REG_R5), 28 | uc.reg_read(UC_ARM_REG_R6), uc.reg_read(UC_ARM_REG_R7), 29 | uc.reg_read(UC_ARM_REG_R8))) 30 | print( 31 | "PC 0x%X SP 0x%X" % (uc.reg_read(UC_ARM_REG_PC), uc.reg_read(UC_ARM_REG_SP))) 32 | 33 | 34 | def hook_memory(uc, access, address, size, value, userdata): 35 | print(userdata) 36 | pc = uc.reg_read(UC_ARM_REG_PC) 37 | print("memory error: pc:%s address:%X size:%x" % (ptrStr(userdata, pc), address, size)) 38 | 39 | 40 | class Emulator: 41 | def __init__(self, fridaBridge, is64Bit=True, apkPath="", processName="UniDa"): 42 | self.processName = processName 43 | self.apkPath = apkPath 44 | self.fridaBridge = fridaBridge 45 | self.is64Bit = is64Bit 46 | self.mu = Uc(UC_ARCH_ARM64 if is64Bit else UC_ARCH_ARM, UC_MODE_ARM) 47 | self.keystone = Ks(KS_ARCH_ARM64 if is64Bit else KS_ARCH_ARM, KS_MODE_LITTLE_ENDIAN if is64Bit else KS_MODE_ARM) 48 | self.enableVFP() 49 | self.PCB = PCB() 50 | self.memory = Memory(self) 51 | self.vm = DalvikVM() 52 | self.hooker = Hooker(self) 53 | self.syscallHandler = ARM64SyscallHandler(self) if is64Bit else ARM32SyscallHandler(self) 54 | self.linker = Linker(self) 55 | self.mu.hook_add(UC_HOOK_CODE, hook_code, self.linker) 56 | # self.mu.hook_add(UC_HOOK_MEM_FETCH_PROT, hook_memory, self.linker) 57 | 58 | def loadLibrary(self, fileName, callInit=False): 59 | return self.linker.do_dlopen(fileName, callInit) 60 | 61 | def call_native(self, addr, *argv): 62 | if addr is None: 63 | raise Exception("Call addr is None") 64 | LR_REG = UC_ARM_REG_LR 65 | R0_REG = UC_ARM_REG_R0 66 | LR = self.hooker.hooker_area_base 67 | if self.is64Bit: 68 | LR_REG = UC_ARM64_REG_LR 69 | R0_REG = UC_ARM64_REG_X0 70 | self.mu.reg_write(LR_REG, LR) 71 | try: 72 | self.mu.emu_start(addr, LR) 73 | except UcError: 74 | raise Exception(UcError) 75 | res = self.mu.reg_read(R0_REG) 76 | return res 77 | 78 | def enableVFP(self): 79 | if self.is64Bit: 80 | value = self.mu.reg_read(UC_ARM64_REG_CPACR_EL1) 81 | value |= 0x300000 82 | self.mu.reg_write(UC_ARM64_REG_CPACR_EL1, value) 83 | else: 84 | value = self.mu.reg_read(UC_ARM_REG_C1_C0_2) 85 | value |= (0xf << 20) 86 | self.mu.reg_write(UC_ARM_REG_C1_C0_2, value) 87 | self.mu.reg_write(UC_ARM_REG_FPEXC, 0x40000000) 88 | 89 | def getPointSize(self): 90 | return 8 if self.is64Bit else 4 91 | -------------------------------------------------------------------------------- /Emulator/debugger/ARM32Debugger.py: -------------------------------------------------------------------------------- 1 | class ARM32Debugger: 2 | def __init__(self): 3 | pass 4 | -------------------------------------------------------------------------------- /Emulator/debugger/ARM64Debugger.py: -------------------------------------------------------------------------------- 1 | class ARM64Debugger: 2 | def __init__(self): 3 | pass -------------------------------------------------------------------------------- /Emulator/debugger/ConsoleDebugger.py: -------------------------------------------------------------------------------- 1 | class ConsoleDebugger: 2 | def __init__(self): 3 | pass 4 | -------------------------------------------------------------------------------- /Emulator/dvm/DalvikVM.py: -------------------------------------------------------------------------------- 1 | from numpy import int32 2 | 3 | from Emulator.dvm.DvmClass import DvmClass 4 | from Emulator.dvm.JniConst import * 5 | from Emulator.utils.Dvm_Helpers import hashCode 6 | 7 | 8 | class DalvikVM: 9 | def __init__(self): 10 | self.classMaps = dict() 11 | self.localObjectMaps = dict() 12 | self.globalObjectMaps = dict() 13 | 14 | def resolveClass(self, className, interfaceClasses=None): 15 | superClass = None 16 | if interfaceClasses is None: 17 | interfaceClasses = [] 18 | elif len(interfaceClasses) > 0: 19 | superClass = interfaceClasses[0] 20 | interfaceClasses = interfaceClasses[1:len(interfaceClasses)] 21 | classHash = hashCode(className) 22 | if classHash not in self.classMaps: 23 | dvmClass = DvmClass(self, className, superClass, interfaceClasses) 24 | self.classMaps[classHash] = dvmClass 25 | self.addObject(dvmClass) 26 | dvmClass = self.classMaps[classHash] 27 | return dvmClass 28 | 29 | def addObject(self, obj, isGlobal=True, weak=False): 30 | if obj is None: 31 | return JNI_NULL 32 | h = obj.hashCode() 33 | if isGlobal: 34 | self.globalObjectMaps[h] = {"obj": obj, "weak": weak} 35 | else: 36 | self.localObjectMaps[h] = {"obj": obj, "weak": weak} 37 | return h 38 | 39 | def getObject(self, h): 40 | if h in self.globalObjectMaps: 41 | return self.globalObjectMaps[h].obj 42 | elif h in self.localObjectMaps: 43 | return self.localObjectMaps[h].obj 44 | return None 45 | -------------------------------------------------------------------------------- /Emulator/dvm/DvmClass.py: -------------------------------------------------------------------------------- 1 | from Emulator.dvm.DvmMethod import DvmMethod 2 | from Emulator.dvm.DvmObject import DvmObject 3 | from Emulator.utils.Dvm_Helpers import hashCode 4 | 5 | 6 | class DvmClass: 7 | def __init__(self, vm, className, superClass, interfaceClasses): 8 | self.vm = vm 9 | self.className = className 10 | self.superClass = superClass 11 | self.staticMethodMaps = dict() 12 | self.methodMaps = dict() 13 | self.interfaceClasses = interfaceClasses 14 | 15 | def newObject(self, value): 16 | return DvmObject(self, value) 17 | 18 | def hashCode(self): 19 | return hashCode(self.className) 20 | 21 | def getMethodID(self, methodName, args, isStatic=False): 22 | signature = self.className + "->" + methodName + args 23 | h = hashCode(signature) 24 | mapsName = "staticMethodMaps" if isStatic else "methodMaps" 25 | if h not in getattr(self, mapsName)[h]: 26 | setattr(self, mapsName, DvmMethod(self, methodName, args, isStatic)) 27 | 28 | def getMethod(self, h, isStatic=False): 29 | mapsName = "staticMethodMaps" if isStatic else "methodMaps" 30 | if h in getattr(self, mapsName): 31 | return getattr(self, mapsName)[h] 32 | elif self.superClass is not None and h in getattr(self.superClass, mapsName): 33 | return getattr(self.superClass, mapsName)[h] 34 | else: 35 | for interfaceClass in self.interfaceClasses: 36 | if h in getattr(interfaceClass, mapsName): 37 | return getattr(interfaceClass, mapsName)[h] 38 | return None 39 | -------------------------------------------------------------------------------- /Emulator/dvm/DvmField.py: -------------------------------------------------------------------------------- 1 | class DvmField: 2 | def __init__(self): 3 | pass 4 | -------------------------------------------------------------------------------- /Emulator/dvm/DvmMethod.py: -------------------------------------------------------------------------------- 1 | class DvmMethod: 2 | def __init__(self, dvmClass, methodName, args, isStatic=False): 3 | self.args = args 4 | self.dvmClass = dvmClass 5 | self.isStatic = isStatic 6 | self.methodName = methodName 7 | -------------------------------------------------------------------------------- /Emulator/dvm/DvmObject.py: -------------------------------------------------------------------------------- 1 | class DvmObject: 2 | def __init__(self, dvmClass, value): 3 | self.vm = dvmClass.vm 4 | self.value = value 5 | self.dvmClass = dvmClass 6 | 7 | def hashCode(self): 8 | return self.__hash__() 9 | -------------------------------------------------------------------------------- /Emulator/dvm/JniConst.py: -------------------------------------------------------------------------------- 1 | JNI_FALSE = 0 2 | JNI_TRUE = 1 3 | 4 | JNI_VERSION_1_1 = 0x00010001 5 | JNI_VERSION_1_2 = 0x00010002 6 | JNI_VERSION_1_4 = 0x00010004 7 | JNI_VERSION_1_6 = 0x00010006 8 | 9 | JNI_OK = 0 # no error 10 | JNI_ERR = -1 # generic error 11 | JNI_EDETACHED = -2 # thread detached from the VM 12 | JNI_EVERSION = -3 # JNI version error 13 | JNI_ENOMEM = -4 # Out of memory 14 | JNI_EEXIST = -5 # VM already created 15 | JNI_EINVAL = -6 # Invalid argument 16 | JNI_NULL = 0 17 | 18 | JNI_COMMIT = 1 # copy content, do not free buffer 19 | JNI_ABORT = 2 # free buffer w/o copying back 20 | -------------------------------------------------------------------------------- /Emulator/hooks/ARMConst.py: -------------------------------------------------------------------------------- 1 | EXCP_SWI = 2 2 | EXCP_BKPT = 7 3 | -------------------------------------------------------------------------------- /Emulator/hooks/Hooker.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from unicorn import UC_PROT_WRITE, UC_PROT_READ, UC_PROT_EXEC, UC_HOOK_INTR 4 | 5 | from Emulator.hooks.JniHooks import JniHooks 6 | from Emulator.hooks.NativeHooks import NativeHooks 7 | 8 | logger = logging.getLogger(__name__) 9 | 10 | 11 | class Hooker: 12 | def __init__(self, emulator): 13 | self.emulator = emulator 14 | self.hookMaps = dict() 15 | 16 | self.hooker_area_size = 0x10000 17 | self.hooker_area_base = 0xffff0000 18 | emulator.mu.mem_map(self.hooker_area_base, self.hooker_area_size, 19 | UC_PROT_WRITE | UC_PROT_READ | UC_PROT_EXEC) 20 | 21 | logger.debug("Hooker init hooker_area_base= 0x%X hooker_area_size= 0x%X" % ( 22 | self.hooker_area_base, self.hooker_area_size)) 23 | 24 | self.nativeHooks = NativeHooks(self) 25 | self.jniHooks = JniHooks(self, emulator) 26 | 27 | def write_function(self, func): 28 | hookId = self.findMinHookId() 29 | asm = "SVC #%s\nRET" % hex(hookId) if self.emulator.is64Bit else "SVC #%s\nbx lr" % hex(hookId) 30 | asm_bytes_list, asm_count = self.emulator.keystone.asm(bytes(asm, encoding='ascii')) 31 | if asm_count != 2: 32 | raise ValueError("Expected asm_count to be 2 instead of %u." % asm_count) 33 | func_addr = self.hooker_area_base 34 | self.emulator.mu.mem_write(self.hooker_area_base, bytes(asm_bytes_list)) 35 | self.hooker_area_base += len(asm_bytes_list) 36 | self.hookMaps[hookId] = func 37 | return func_addr 38 | 39 | def write_function_table(self, struct_table): 40 | pointSize = self.emulator.getPointSize() 41 | tab_len = max(struct_table.keys()) + 1 42 | struct_table_bytes = b"" 43 | struct_table_addr = self.hooker_area_base 44 | for index in range(0, tab_len): 45 | addr = self.write_function(struct_table[index]) if index in struct_table else 0 46 | struct_table_bytes += int(addr).to_bytes(pointSize, byteorder='little') 47 | self.emulator.mu.mem_write(struct_table_addr, struct_table_bytes) 48 | self.hooker_area_base += len(struct_table_bytes) 49 | struct_table_addr_ptr = self.hooker_area_base 50 | self.emulator.mu.mem_write(struct_table_addr_ptr, struct_table_addr.to_bytes(pointSize, byteorder='little')) 51 | self.hooker_area_base += pointSize 52 | return struct_table_addr_ptr, struct_table_addr 53 | 54 | def findMinHookId(self): 55 | hookId = 0xFF00 56 | for key in self.hookMaps.keys(): 57 | if hookId < key: 58 | hookId = key 59 | return hookId + 1 60 | 61 | def add_symbol_hook(self, symbol_name, addr): 62 | self.emulator.linker.symbol_hooks[symbol_name] = addr 63 | -------------------------------------------------------------------------------- /Emulator/hooks/JniHooks.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from Emulator.dvm.JniConst import * 4 | from Emulator.utils.Memory_Helpers import * 5 | 6 | logger = logging.getLogger(__name__) 7 | 8 | 9 | class JniHooks: 10 | # https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html 11 | def __init__(self, hooker, emulator): 12 | self.emulator = emulator 13 | self.vm = emulator.vm 14 | self.throwable = None 15 | self.JniEnvAddr, self.JniEnvTableAddr = hooker.write_function_table({ 16 | 4: self._GetVersion, 17 | 5: self._DefineClass, 18 | 6: self._FindClass, 19 | 7: self._FromReflectedMethod, 20 | 8: self._FromReflectedField, 21 | 9: self._ToReflectedMethod, 22 | 10: self._GetSuperclass, 23 | 11: self._IsAssignableFrom, 24 | 12: self._ToReflectedField, 25 | 13: self._Throw, 26 | 14: self._ThrowNew, 27 | 15: self._ExceptionOccurred, 28 | 16: self._ExceptionDescribe, 29 | 17: self._ExceptionClear, 30 | 18: self._FatalError, 31 | 19: self._PushLocalFrame, 32 | 20: self._PopLocalFrame, 33 | 21: self._NewGlobalRef, 34 | 22: self._DeleteGlobalRef, 35 | 23: self._DeleteLocalRef, 36 | 24: self._IsSameObject, 37 | 25: self._NewLocalRef, 38 | 26: self._EnsureLocalCapacity, 39 | 27: self._AllocObject, 40 | 28: self._NewObject, 41 | 29: self._NewObjectV, 42 | 30: self._NewObjectA, 43 | 31: self._GetObjectClass, 44 | 32: self._IsInstanceOf, 45 | 33: self._GetMethodID, 46 | 34: self._CallObjectMethod, 47 | 35: self._CallObjectMethodV, 48 | 36: self._CallObjectMethodA, 49 | 37: self._CallBooleanMethod, 50 | 38: self._CallBooleanMethodV, 51 | 39: self._CallBooleanMethodA, 52 | 40: self._CallByteMethod, 53 | 41: self._CallByteMethodV, 54 | 42: self._CallByteMethodA, 55 | 43: self._CallCharMethod, 56 | 44: self._CallCharMethodV, 57 | 45: self._CallCharMethodA, 58 | 46: self._CallShortMethod, 59 | 47: self._CallShortMethodV, 60 | 48: self._CallShortMethodA, 61 | 49: self._CallIntMethod, 62 | 50: self._CallIntMethodV, 63 | 51: self._CallIntMethodA, 64 | 52: self._CallLongMethod, 65 | 53: self._CallLongMethodV, 66 | 54: self._CallLongMethodA, 67 | 55: self._CallFloatMethod, 68 | 56: self._CallFloatMethodV, 69 | 57: self._CallFloatMethodA, 70 | 58: self._CallDoubleMethod, 71 | 59: self._CallDoubleMethodV, 72 | 60: self._CallDoubleMethodA, 73 | 61: self._CallVoidMethod, 74 | 62: self._CallVoidMethodV, 75 | 63: self._CallVoidMethodA, 76 | 64: self._CallNonvirtualObjectMethod, 77 | 65: self._CallNonvirtualObjectMethodV, 78 | 66: self._CallNonvirtualObjectMethodA, 79 | 67: self._CallNonvirtualBooleanMethod, 80 | 68: self._CallNonvirtualBooleanMethodV, 81 | 69: self._CallNonvirtualBooleanMethodA, 82 | 70: self._CallNonvirtualByteMethod, 83 | 71: self._CallNonvirtualByteMethodV, 84 | 72: self._CallNonvirtualByteMethodA, 85 | 73: self._CallNonvirtualCharMethod, 86 | 74: self._CallNonvirtualCharMethodV, 87 | 75: self._CallNonvirtualCharMethodA, 88 | 76: self._CallNonvirtualShortMethod, 89 | 77: self._CallNonvirtualShortMethodV, 90 | 78: self._CallNonvirtualShortMethodA, 91 | 79: self._CallNonvirtualIntMethod, 92 | 80: self._CallNonvirtualIntMethodV, 93 | 81: self._CallNonvirtualIntMethodA, 94 | 82: self._CallNonvirtualLongMethod, 95 | 83: self._CallNonvirtualLongMethodV, 96 | 84: self._CallNonvirtualLongMethodA, 97 | 85: self._CallNonvirtualFloatMethod, 98 | 86: self._CallNonvirtualFloatMethodV, 99 | 87: self._CallNonvirtualFloatMethodA, 100 | 88: self._CallNonvirtualDoubleMethod, 101 | 89: self._CallNonvirtualDoubleMethodV, 102 | 90: self._CallNonvirtualDoubleMethodA, 103 | 91: self._CallNonvirtualVoidMethod, 104 | 92: self._CallNonvirtualVoidMethodV, 105 | 93: self._CallNonvirtualVoidMethodA, 106 | 94: self._GetFieldID, 107 | 95: self._GetObjectField, 108 | 96: self._GetBooleanField, 109 | 97: self._GetByteField, 110 | 98: self._GetCharField, 111 | 99: self._GetShortField, 112 | 100: self._GetIntField, 113 | 101: self._GetLongField, 114 | 102: self._GetFloatField, 115 | 103: self._GetDoubleField, 116 | 104: self._SetObjectField, 117 | 105: self._SetBooleanField, 118 | 106: self._SetByteField, 119 | 107: self._SetCharField, 120 | 108: self._SetShortField, 121 | 109: self._SetIntField, 122 | 110: self._SetLongField, 123 | 111: self._SetFloatField, 124 | 112: self._SetDoubleField, 125 | 113: self._GetStaticMethodID, 126 | 114: self._CallStaticObjectMethod, 127 | 115: self._CallStaticObjectMethodV, 128 | 116: self._CallStaticObjectMethodA, 129 | 117: self._CallStaticBooleanMethod, 130 | 118: self._CallStaticBooleanMethodV, 131 | 119: self._CallStaticBooleanMethodA, 132 | 120: self._CallStaticByteMethod, 133 | 121: self._CallStaticByteMethodV, 134 | 122: self._CallStaticByteMethodA, 135 | 123: self._CallStaticCharMethod, 136 | 124: self._CallStaticCharMethodV, 137 | 125: self._CallStaticCharMethodA, 138 | 126: self._CallStaticShortMethod, 139 | 127: self._CallStaticShortMethodV, 140 | 128: self._CallStaticShortMethodA, 141 | 129: self._CallStaticIntMethod, 142 | 130: self._CallStaticIntMethodV, 143 | 131: self._CallStaticIntMethodA, 144 | 132: self._CallStaticLongMethod, 145 | 133: self._CallStaticLongMethodV, 146 | 134: self._CallStaticLongMethodA, 147 | 135: self._CallStaticFloatMethod, 148 | 136: self._CallStaticFloatMethodV, 149 | 137: self._CallStaticFloatMethodA, 150 | 138: self._CallStaticDoubleMethod, 151 | 139: self._CallStaticDoubleMethodV, 152 | 140: self._CallStaticDoubleMethodA, 153 | 141: self._CallStaticVoidMethod, 154 | 142: self._CallStaticVoidMethodV, 155 | 143: self._CallStaticVoidMethodA, 156 | 144: self._GetStaticFieldID, 157 | 145: self._GetStaticObjectField, 158 | 146: self._GetStaticBooleanField, 159 | 147: self._GetStaticByteField, 160 | 148: self._GetStaticCharField, 161 | 149: self._GetStaticShortField, 162 | 150: self._GetStaticIntField, 163 | 151: self._GetStaticLongField, 164 | 152: self._GetStaticFloatField, 165 | 153: self._GetStaticDoubleField, 166 | 154: self._SetStaticObjectField, 167 | 155: self._SetStaticBooleanField, 168 | 156: self._SetStaticByteField, 169 | 157: self._SetStaticCharField, 170 | 158: self._SetStaticShortField, 171 | 159: self._SetStaticIntField, 172 | 160: self._SetStaticLongField, 173 | 161: self._SetStaticFloatField, 174 | 162: self._SetStaticDoubleField, 175 | 163: self._NewString, 176 | 164: self._GetStringLength, 177 | 165: self._GetStringChars, 178 | 166: self._ReleaseStringChars, 179 | 167: self._NewStringUTF, 180 | 168: self._GetStringUTFLength, 181 | 169: self._GetStringUTFChars, 182 | 170: self._ReleaseStringUTFChars, 183 | 171: self._GetArrayLength, 184 | 172: self._NewObjectArray, 185 | 173: self._GetObjectArrayElement, 186 | 174: self._SetObjectArrayElement, 187 | 175: self._NewBooleanArray, 188 | 176: self._NewByteArray, 189 | 177: self._NewCharArray, 190 | 178: self._NewShortArray, 191 | 179: self._NewIntArray, 192 | 180: self._NewLongArray, 193 | 181: self._NewFloatArray, 194 | 182: self._NewDoubleArray, 195 | 183: self._GetBooleanArrayElements, 196 | 184: self._GetByteArrayElements, 197 | 185: self._GetCharArrayElements, 198 | 186: self._GetShortArrayElements, 199 | 187: self._GetIntArrayElements, 200 | 188: self._GetLongArrayElements, 201 | 189: self._GetFloatArrayElements, 202 | 190: self._GetDoubleArrayElements, 203 | 191: self._ReleaseBooleanArrayElements, 204 | 192: self._ReleaseByteArrayElements, 205 | 193: self._ReleaseCharArrayElements, 206 | 194: self._ReleaseShortArrayElements, 207 | 195: self._ReleaseIntArrayElements, 208 | 196: self._ReleaseLongArrayElements, 209 | 197: self._ReleaseFloatArrayElements, 210 | 198: self._ReleaseDoubleArrayElements, 211 | 199: self._GetBooleanArrayRegion, 212 | 200: self._GetByteArrayRegion, 213 | 201: self._GetCharArrayRegion, 214 | 202: self._GetShortArrayRegion, 215 | 203: self._GetIntArrayRegion, 216 | 204: self._GetLongArrayRegion, 217 | 205: self._GetFloatArrayRegion, 218 | 206: self._GetDoubleArrayRegion, 219 | 207: self._SetBooleanArrayRegion, 220 | 208: self._SetByteArrayRegion, 221 | 209: self._SetCharArrayRegion, 222 | 210: self._SetShortArrayRegion, 223 | 211: self._SetIntArrayRegion, 224 | 212: self._SetLongArrayRegion, 225 | 213: self._SetFloatArrayRegion, 226 | 214: self._SetDoubleArrayRegion, 227 | 215: self._RegisterNatives, 228 | 216: self._UnregisterNatives, 229 | 217: self._MonitorEnter, 230 | 218: self._MonitorExit, 231 | 219: self._GetJavaVM, 232 | 220: self._GetStringRegion, 233 | 221: self._GetStringUTFRegion, 234 | 222: self._GetPrimitiveArrayCritical, 235 | 223: self._ReleasePrimitiveArrayCritical, 236 | 224: self._GetStringCritical, 237 | 225: self._ReleaseStringCritical, 238 | 226: self._NewWeakGlobalRef, 239 | 227: self._DeleteWeakGlobalRef, 240 | 228: self._ExceptionCheck, 241 | 229: self._NewDirectByteBuffer, 242 | 230: self._GetDirectBufferAddress, 243 | 231: self._GetDirectBufferCapacity, 244 | 232: self._GetObjectRefType 245 | }) 246 | self.JavaVMAddr, self.JNIInvokeInterface = hooker.write_function_table({ 247 | 3: self._DestroyJavaVM, 248 | 4: self._AttachCurrentThread, 249 | 5: self._DetachCurrentThread, 250 | 6: self._GetEnv, 251 | 7: self._AttachCurrentThreadAsDaemon 252 | }) 253 | 254 | def _DestroyJavaVM(self, mu): 255 | raise NotImplementedError() 256 | 257 | def _AttachCurrentThread(self, mu): 258 | vm = getPointerArg(mu, 0) 259 | env = getPointerArg(mu, 1) 260 | version = getPointerArg(mu, 3) 261 | mu.mem_write(env, self.JniEnvAddr) 262 | logger.info("JavaVM->AttachCurrentThread() was called from %s vm=0x%x env=0x%x version=0x%x" % ( 263 | ptrStr(self.emulator.linker, getLRPointer(mu)), vm, env, version)) 264 | return JNI_OK 265 | 266 | def _DetachCurrentThread(self, mu): 267 | raise NotImplementedError() 268 | 269 | def _GetEnv(self, mu): 270 | vm = getPointerArg(mu, 0) 271 | env = getPointerArg(mu, 1) 272 | version = getPointerArg(mu, 3) 273 | mu.mem_write(env, self.JniEnvAddr) 274 | logger.info("JavaVM->GetEnv() was called from %s vm=0x%x env=0x%x version=0x%x" % ( 275 | ptrStr(self.emulator.linker, getLRPointer(mu)), vm, env, version)) 276 | return JNI_OK 277 | 278 | def _AttachCurrentThreadAsDaemon(self, mu): 279 | raise NotImplementedError() 280 | 281 | def _GetVersion(self, mu): 282 | raise NotImplementedError() 283 | 284 | def _DefineClass(self, mu): 285 | raise NotImplementedError() 286 | 287 | def _FindClass(self, mu): 288 | className = getPointerArg(mu, 1) 289 | name = read_utf8(mu, className) 290 | dvmClass = self.vm.resolveClass(name) 291 | h = toIntPeer(dvmClass.hashCode()) 292 | logger.info("JNIEnv->FindClass(%s) was called from %s" % (name, ptrStr(self.emulator.linker, getLRPointer(mu)))) 293 | return h 294 | 295 | def _FromReflectedMethod(self, mu): 296 | raise NotImplementedError() 297 | 298 | def _FromReflectedField(self, mu): 299 | raise NotImplementedError() 300 | 301 | def _ToReflectedMethod(self, mu): 302 | clazz = getPointerArg(mu, 1) 303 | jmethodID = getPointerArg(mu, 2) 304 | h = toIntPeer(clazz) 305 | if h in self.vm.classMaps: 306 | dvmClass = self.vm.classMaps[h] 307 | mh = toIntPeer(jmethodID) 308 | dvmMethod = dvmClass.getMethod() 309 | if dvmMethod is None: 310 | dvmMethod = dvmClass.getMethod(mh, True) 311 | if dvmMethod is not None: 312 | return self.vm.addObject(dvmMethod, False) 313 | else: 314 | raise Exception('Method Not Found hash 0x%x' % mh) 315 | else: 316 | raise Exception('Class Not Found hash 0x%x' % h) 317 | 318 | def _GetSuperclass(self, mu): 319 | raise NotImplementedError() 320 | 321 | def _IsAssignableFrom(self, mu): 322 | raise NotImplementedError() 323 | 324 | def _ToReflectedField(self, mu): 325 | raise NotImplementedError() 326 | 327 | def _Throw(self, mu): 328 | obj = getPointerArg(mu, 1) 329 | self.throwable = self.vm.getObject(toIntPeer(obj)) 330 | logger.warning( 331 | "Throw object=0x%x dvmObject=%s class=%s" % (obj, str(self.throwable), str(self.throwable.dvmClass))) 332 | return 0 333 | 334 | def _ThrowNew(self, mu): 335 | raise NotImplementedError() 336 | 337 | def _ExceptionOccurred(self, mu): 338 | logger.debug("ExceptionOccurred") 339 | return JNI_NULL if self.throwable is None else toIntPeer(self.throwable.hashCode()) 340 | 341 | def _ExceptionDescribe(self, mu): 342 | raise NotImplementedError() 343 | 344 | def _ExceptionClear(self, mu): 345 | logger.debug("ExceptionClear") 346 | self.throwable = None 347 | return 0 348 | 349 | def _FatalError(self, mu): 350 | raise NotImplementedError() 351 | 352 | def _PushLocalFrame(self, mu): 353 | capacity = getPointerArg(mu, 1) 354 | logger.debug("PushLocalFrame capacity=%d" % capacity) 355 | return JNI_OK 356 | 357 | def _PopLocalFrame(self, mu): 358 | jresult = getPointerArg(mu, 1) 359 | logger.debug("PopLocalFrame jresult=%d" % jresult) 360 | return 0 if jresult is None else toIntPeer(jresult) 361 | 362 | def _NewGlobalRef(self, mu): 363 | obj = getPointerArg(mu, 1) 364 | dvmObject = self.vm.getObject(toIntPeer(obj)) 365 | logger.debug("NewGlobalRef object=0x%x dvmObject=%s" % (obj, str(dvmObject))) 366 | return self.vm.addObject(dvmObject) 367 | 368 | def _DeleteGlobalRef(self, mu): 369 | obj = getPointerArg(mu, 1) 370 | del self.vm.globalObjectMaps[toIntPeer(obj)] 371 | return 0 372 | 373 | def _DeleteLocalRef(self, mu): 374 | obj = getPointerArg(mu, 1) 375 | del self.vm.localObjectMaps[toIntPeer(obj)] 376 | return 0 377 | 378 | def _IsSameObject(self, mu): 379 | raise NotImplementedError() 380 | 381 | def _NewLocalRef(self, mu): 382 | raise NotImplementedError() 383 | 384 | def _EnsureLocalCapacity(self, mu): 385 | raise NotImplementedError() 386 | 387 | def _AllocObject(self, mu): 388 | raise NotImplementedError() 389 | 390 | def _NewObject(self, mu): 391 | raise NotImplementedError() 392 | 393 | def _NewObjectV(self, mu): 394 | raise NotImplementedError() 395 | 396 | def _NewObjectA(self, mu): 397 | raise NotImplementedError() 398 | 399 | def _GetObjectClass(self, mu): 400 | raise NotImplementedError() 401 | 402 | def _IsInstanceOf(self, mu): 403 | raise NotImplementedError() 404 | 405 | def _GetMethodID(self, mu): 406 | raise NotImplementedError() 407 | 408 | def _CallObjectMethod(self, mu): 409 | raise NotImplementedError() 410 | 411 | def _CallObjectMethodV(self, mu): 412 | raise NotImplementedError() 413 | 414 | def _CallObjectMethodA(self, mu): 415 | raise NotImplementedError() 416 | 417 | def _CallBooleanMethod(self, mu): 418 | raise NotImplementedError() 419 | 420 | def _CallBooleanMethodV(self, mu): 421 | raise NotImplementedError() 422 | 423 | def _CallBooleanMethodA(self, mu): 424 | raise NotImplementedError() 425 | 426 | def _CallByteMethod(self, mu): 427 | raise NotImplementedError() 428 | 429 | def _CallByteMethodV(self, mu): 430 | raise NotImplementedError() 431 | 432 | def _CallByteMethodA(self, mu): 433 | raise NotImplementedError() 434 | 435 | def _CallCharMethod(self, mu): 436 | raise NotImplementedError() 437 | 438 | def _CallCharMethodV(self, mu): 439 | raise NotImplementedError() 440 | 441 | def _CallCharMethodA(self, mu): 442 | raise NotImplementedError() 443 | 444 | def _CallShortMethod(self, mu): 445 | raise NotImplementedError() 446 | 447 | def _CallShortMethodV(self, mu): 448 | raise NotImplementedError() 449 | 450 | def _CallShortMethodA(self, mu): 451 | raise NotImplementedError() 452 | 453 | def _CallIntMethod(self, mu): 454 | raise NotImplementedError() 455 | 456 | def _CallIntMethodV(self, mu): 457 | raise NotImplementedError() 458 | 459 | def _CallIntMethodA(self, mu): 460 | raise NotImplementedError() 461 | 462 | def _CallLongMethod(self, mu): 463 | raise NotImplementedError() 464 | 465 | def _CallLongMethodV(self, mu): 466 | raise NotImplementedError() 467 | 468 | def _CallLongMethodA(self, mu): 469 | raise NotImplementedError() 470 | 471 | def _CallFloatMethod(self, mu): 472 | raise NotImplementedError() 473 | 474 | def _CallFloatMethodV(self, mu): 475 | raise NotImplementedError() 476 | 477 | def _CallFloatMethodA(self, mu): 478 | raise NotImplementedError() 479 | 480 | def _CallDoubleMethod(self, mu): 481 | raise NotImplementedError() 482 | 483 | def _CallDoubleMethodV(self, mu): 484 | raise NotImplementedError() 485 | 486 | def _CallDoubleMethodA(self, mu): 487 | raise NotImplementedError() 488 | 489 | def _CallVoidMethod(self, mu): 490 | raise NotImplementedError() 491 | 492 | def _CallVoidMethodV(self, mu): 493 | raise NotImplementedError() 494 | 495 | def _CallVoidMethodA(self, mu): 496 | raise NotImplementedError() 497 | 498 | def _CallNonvirtualObjectMethod(self, mu): 499 | raise NotImplementedError() 500 | 501 | def _CallNonvirtualObjectMethodV(self, mu): 502 | raise NotImplementedError() 503 | 504 | def _CallNonvirtualObjectMethodA(self, mu): 505 | raise NotImplementedError() 506 | 507 | def _CallNonvirtualBooleanMethod(self, mu): 508 | raise NotImplementedError() 509 | 510 | def _CallNonvirtualBooleanMethodV(self, mu): 511 | raise NotImplementedError() 512 | 513 | def _CallNonvirtualBooleanMethodA(self, mu): 514 | raise NotImplementedError() 515 | 516 | def _CallNonvirtualByteMethod(self, mu): 517 | raise NotImplementedError() 518 | 519 | def _CallNonvirtualByteMethodV(self, mu): 520 | raise NotImplementedError() 521 | 522 | def _CallNonvirtualByteMethodA(self, mu): 523 | raise NotImplementedError() 524 | 525 | def _CallNonvirtualCharMethod(self, mu): 526 | raise NotImplementedError() 527 | 528 | def _CallNonvirtualCharMethodV(self, mu): 529 | raise NotImplementedError() 530 | 531 | def _CallNonvirtualCharMethodA(self, mu): 532 | raise NotImplementedError() 533 | 534 | def _CallNonvirtualShortMethod(self, mu): 535 | raise NotImplementedError() 536 | 537 | def _CallNonvirtualShortMethodV(self, mu): 538 | raise NotImplementedError() 539 | 540 | def _CallNonvirtualShortMethodA(self, mu): 541 | raise NotImplementedError() 542 | 543 | def _CallNonvirtualIntMethod(self, mu): 544 | raise NotImplementedError() 545 | 546 | def _CallNonvirtualIntMethodV(self, mu): 547 | raise NotImplementedError() 548 | 549 | def _CallNonvirtualIntMethodA(self, mu): 550 | raise NotImplementedError() 551 | 552 | def _CallNonvirtualLongMethod(self, mu): 553 | raise NotImplementedError() 554 | 555 | def _CallNonvirtualLongMethodV(self, mu): 556 | raise NotImplementedError() 557 | 558 | def _CallNonvirtualLongMethodA(self, mu): 559 | raise NotImplementedError() 560 | 561 | def _CallNonvirtualFloatMethod(self, mu): 562 | raise NotImplementedError() 563 | 564 | def _CallNonvirtualFloatMethodV(self, mu): 565 | raise NotImplementedError() 566 | 567 | def _CallNonvirtualFloatMethodA(self, mu): 568 | raise NotImplementedError() 569 | 570 | def _CallNonvirtualDoubleMethod(self, mu): 571 | raise NotImplementedError() 572 | 573 | def _CallNonvirtualDoubleMethodV(self, mu): 574 | raise NotImplementedError() 575 | 576 | def _CallNonvirtualDoubleMethodA(self, mu): 577 | raise NotImplementedError() 578 | 579 | def _CallNonvirtualVoidMethod(self, mu): 580 | raise NotImplementedError() 581 | 582 | def _CallNonvirtualVoidMethodV(self, mu): 583 | raise NotImplementedError() 584 | 585 | def _CallNonvirtualVoidMethodA(self, mu): 586 | raise NotImplementedError() 587 | 588 | def _GetFieldID(self, mu): 589 | raise NotImplementedError() 590 | 591 | def _GetObjectField(self, mu): 592 | raise NotImplementedError() 593 | 594 | def _GetBooleanField(self, mu): 595 | raise NotImplementedError() 596 | 597 | def _GetByteField(self, mu): 598 | raise NotImplementedError() 599 | 600 | def _GetCharField(self, mu): 601 | raise NotImplementedError() 602 | 603 | def _GetShortField(self, mu): 604 | raise NotImplementedError() 605 | 606 | def _GetIntField(self, mu): 607 | raise NotImplementedError() 608 | 609 | def _GetLongField(self, mu): 610 | raise NotImplementedError() 611 | 612 | def _GetFloatField(self, mu): 613 | raise NotImplementedError() 614 | 615 | def _GetDoubleField(self, mu): 616 | raise NotImplementedError() 617 | 618 | def _SetObjectField(self, mu): 619 | raise NotImplementedError() 620 | 621 | def _SetBooleanField(self, mu): 622 | raise NotImplementedError() 623 | 624 | def _SetByteField(self, mu): 625 | raise NotImplementedError() 626 | 627 | def _SetCharField(self, mu): 628 | raise NotImplementedError() 629 | 630 | def _SetShortField(self, mu): 631 | raise NotImplementedError() 632 | 633 | def _SetIntField(self, mu): 634 | raise NotImplementedError() 635 | 636 | def _SetLongField(self, mu): 637 | raise NotImplementedError() 638 | 639 | def _SetFloatField(self, mu): 640 | raise NotImplementedError() 641 | 642 | def _SetDoubleField(self, mu): 643 | raise NotImplementedError() 644 | 645 | def _GetStaticMethodID(self, mu): 646 | raise NotImplementedError() 647 | 648 | def _CallStaticObjectMethod(self, mu): 649 | raise NotImplementedError() 650 | 651 | def _CallStaticObjectMethodV(self, mu): 652 | raise NotImplementedError() 653 | 654 | def _CallStaticObjectMethodA(self, mu): 655 | raise NotImplementedError() 656 | 657 | def _CallStaticBooleanMethod(self, mu): 658 | raise NotImplementedError() 659 | 660 | def _CallStaticBooleanMethodV(self, mu): 661 | raise NotImplementedError() 662 | 663 | def _CallStaticBooleanMethodA(self, mu): 664 | raise NotImplementedError() 665 | 666 | def _CallStaticByteMethod(self, mu): 667 | raise NotImplementedError() 668 | 669 | def _CallStaticByteMethodV(self, mu): 670 | raise NotImplementedError() 671 | 672 | def _CallStaticByteMethodA(self, mu): 673 | raise NotImplementedError() 674 | 675 | def _CallStaticCharMethod(self, mu): 676 | raise NotImplementedError() 677 | 678 | def _CallStaticCharMethodV(self, mu): 679 | raise NotImplementedError() 680 | 681 | def _CallStaticCharMethodA(self, mu): 682 | raise NotImplementedError() 683 | 684 | def _CallStaticShortMethod(self, mu): 685 | raise NotImplementedError() 686 | 687 | def _CallStaticShortMethodV(self, mu): 688 | raise NotImplementedError() 689 | 690 | def _CallStaticShortMethodA(self, mu): 691 | raise NotImplementedError() 692 | 693 | def _CallStaticIntMethod(self, mu): 694 | raise NotImplementedError() 695 | 696 | def _CallStaticIntMethodV(self, mu): 697 | raise NotImplementedError() 698 | 699 | def _CallStaticIntMethodA(self, mu): 700 | raise NotImplementedError() 701 | 702 | def _CallStaticLongMethod(self, mu): 703 | raise NotImplementedError() 704 | 705 | def _CallStaticLongMethodV(self, mu): 706 | raise NotImplementedError() 707 | 708 | def _CallStaticLongMethodA(self, mu): 709 | raise NotImplementedError() 710 | 711 | def _CallStaticFloatMethod(self, mu): 712 | raise NotImplementedError() 713 | 714 | def _CallStaticFloatMethodV(self, mu): 715 | raise NotImplementedError() 716 | 717 | def _CallStaticFloatMethodA(self, mu): 718 | raise NotImplementedError() 719 | 720 | def _CallStaticDoubleMethod(self, mu): 721 | raise NotImplementedError() 722 | 723 | def _CallStaticDoubleMethodV(self, mu): 724 | raise NotImplementedError() 725 | 726 | def _CallStaticDoubleMethodA(self, mu): 727 | raise NotImplementedError() 728 | 729 | def _CallStaticVoidMethod(self, mu): 730 | raise NotImplementedError() 731 | 732 | def _CallStaticVoidMethodV(self, mu): 733 | raise NotImplementedError() 734 | 735 | def _CallStaticVoidMethodA(self, mu): 736 | raise NotImplementedError() 737 | 738 | def _GetStaticFieldID(self, mu): 739 | raise NotImplementedError() 740 | 741 | def _GetStaticObjectField(self, mu): 742 | raise NotImplementedError() 743 | 744 | def _GetStaticBooleanField(self, mu): 745 | raise NotImplementedError() 746 | 747 | def _GetStaticByteField(self, mu): 748 | raise NotImplementedError() 749 | 750 | def _GetStaticCharField(self, mu): 751 | raise NotImplementedError() 752 | 753 | def _GetStaticShortField(self, mu): 754 | raise NotImplementedError() 755 | 756 | def _GetStaticIntField(self, mu): 757 | raise NotImplementedError() 758 | 759 | def _GetStaticLongField(self, mu): 760 | raise NotImplementedError() 761 | 762 | def _GetStaticFloatField(self, mu): 763 | raise NotImplementedError() 764 | 765 | def _GetStaticDoubleField(self, mu): 766 | raise NotImplementedError() 767 | 768 | def _SetStaticObjectField(self, mu): 769 | raise NotImplementedError() 770 | 771 | def _SetStaticBooleanField(self, mu): 772 | raise NotImplementedError() 773 | 774 | def _SetStaticByteField(self, mu): 775 | raise NotImplementedError() 776 | 777 | def _SetStaticCharField(self, mu): 778 | raise NotImplementedError() 779 | 780 | def _SetStaticShortField(self, mu): 781 | raise NotImplementedError() 782 | 783 | def _SetStaticIntField(self, mu): 784 | raise NotImplementedError() 785 | 786 | def _SetStaticLongField(self, mu): 787 | raise NotImplementedError() 788 | 789 | def _SetStaticFloatField(self, mu): 790 | raise NotImplementedError() 791 | 792 | def _SetStaticDoubleField(self, mu): 793 | raise NotImplementedError() 794 | 795 | def _NewString(self, mu): 796 | raise NotImplementedError() 797 | 798 | def _GetStringLength(self, mu): 799 | raise NotImplementedError() 800 | 801 | def _GetStringChars(self, mu): 802 | raise NotImplementedError() 803 | 804 | def _ReleaseStringChars(self, mu): 805 | raise NotImplementedError() 806 | 807 | def _NewStringUTF(self, mu): 808 | raise NotImplementedError() 809 | 810 | def _GetStringUTFLength(self, mu): 811 | raise NotImplementedError() 812 | 813 | def _GetStringUTFChars(self, mu): 814 | raise NotImplementedError() 815 | 816 | def _ReleaseStringUTFChars(self, mu): 817 | raise NotImplementedError() 818 | 819 | def _GetArrayLength(self, mu): 820 | raise NotImplementedError() 821 | 822 | def _NewObjectArray(self, mu): 823 | raise NotImplementedError() 824 | 825 | def _GetObjectArrayElement(self, mu): 826 | raise NotImplementedError() 827 | 828 | def _SetObjectArrayElement(self, mu): 829 | raise NotImplementedError() 830 | 831 | def _NewBooleanArray(self, mu): 832 | raise NotImplementedError() 833 | 834 | def _NewByteArray(self, mu): 835 | raise NotImplementedError() 836 | 837 | def _NewCharArray(self, mu): 838 | raise NotImplementedError() 839 | 840 | def _NewShortArray(self, mu): 841 | raise NotImplementedError() 842 | 843 | def _NewIntArray(self, mu): 844 | raise NotImplementedError() 845 | 846 | def _NewLongArray(self, mu): 847 | raise NotImplementedError() 848 | 849 | def _NewFloatArray(self, mu): 850 | raise NotImplementedError() 851 | 852 | def _NewDoubleArray(self, mu): 853 | raise NotImplementedError() 854 | 855 | def _GetBooleanArrayElements(self, mu): 856 | raise NotImplementedError() 857 | 858 | def _GetByteArrayElements(self, mu): 859 | raise NotImplementedError() 860 | 861 | def _GetCharArrayElements(self, mu): 862 | raise NotImplementedError() 863 | 864 | def _GetShortArrayElements(self, mu): 865 | raise NotImplementedError() 866 | 867 | def _GetIntArrayElements(self, mu): 868 | raise NotImplementedError() 869 | 870 | def _GetLongArrayElements(self, mu): 871 | raise NotImplementedError() 872 | 873 | def _GetFloatArrayElements(self, mu): 874 | raise NotImplementedError() 875 | 876 | def _GetDoubleArrayElements(self, mu): 877 | raise NotImplementedError() 878 | 879 | def _ReleaseBooleanArrayElements(self, mu): 880 | raise NotImplementedError() 881 | 882 | def _ReleaseByteArrayElements(self, mu): 883 | raise NotImplementedError() 884 | 885 | def _ReleaseCharArrayElements(self, mu): 886 | raise NotImplementedError() 887 | 888 | def _ReleaseShortArrayElements(self, mu): 889 | raise NotImplementedError() 890 | 891 | def _ReleaseIntArrayElements(self, mu): 892 | raise NotImplementedError() 893 | 894 | def _ReleaseLongArrayElements(self, mu): 895 | raise NotImplementedError() 896 | 897 | def _ReleaseFloatArrayElements(self, mu): 898 | raise NotImplementedError() 899 | 900 | def _ReleaseDoubleArrayElements(self, mu): 901 | raise NotImplementedError() 902 | 903 | def _GetBooleanArrayRegion(self, mu): 904 | raise NotImplementedError() 905 | 906 | def _GetByteArrayRegion(self, mu): 907 | raise NotImplementedError() 908 | 909 | def _GetCharArrayRegion(self, mu): 910 | raise NotImplementedError() 911 | 912 | def _GetShortArrayRegion(self, mu): 913 | raise NotImplementedError() 914 | 915 | def _GetIntArrayRegion(self, mu): 916 | raise NotImplementedError() 917 | 918 | def _GetLongArrayRegion(self, mu): 919 | raise NotImplementedError() 920 | 921 | def _GetFloatArrayRegion(self, mu): 922 | raise NotImplementedError() 923 | 924 | def _GetDoubleArrayRegion(self, mu): 925 | raise NotImplementedError() 926 | 927 | def _SetBooleanArrayRegion(self, mu): 928 | raise NotImplementedError() 929 | 930 | def _SetByteArrayRegion(self, mu): 931 | raise NotImplementedError() 932 | 933 | def _SetCharArrayRegion(self, mu): 934 | raise NotImplementedError() 935 | 936 | def _SetShortArrayRegion(self, mu): 937 | raise NotImplementedError() 938 | 939 | def _SetIntArrayRegion(self, mu): 940 | raise NotImplementedError() 941 | 942 | def _SetLongArrayRegion(self, mu): 943 | raise NotImplementedError() 944 | 945 | def _SetFloatArrayRegion(self, mu): 946 | raise NotImplementedError() 947 | 948 | def _SetDoubleArrayRegion(self, mu): 949 | raise NotImplementedError() 950 | 951 | def _RegisterNatives(self, mu): 952 | raise NotImplementedError() 953 | 954 | def _UnregisterNatives(self, mu): 955 | raise NotImplementedError() 956 | 957 | def _MonitorEnter(self, mu): 958 | raise NotImplementedError() 959 | 960 | def _MonitorExit(self, mu): 961 | raise NotImplementedError() 962 | 963 | def _GetJavaVM(self, mu): 964 | vm = getPointerArg(mu, 1) 965 | mu.mem_write(vm, self.JavaVMAddr) 966 | return JNI_OK 967 | 968 | def _GetStringRegion(self, mu): 969 | raise NotImplementedError() 970 | 971 | def _GetStringUTFRegion(self, mu): 972 | raise NotImplementedError() 973 | 974 | def _GetPrimitiveArrayCritical(self, mu): 975 | raise NotImplementedError() 976 | 977 | def _ReleasePrimitiveArrayCritical(self, mu): 978 | raise NotImplementedError() 979 | 980 | def _GetStringCritical(self, mu): 981 | raise NotImplementedError() 982 | 983 | def _ReleaseStringCritical(self, mu): 984 | raise NotImplementedError() 985 | 986 | def _NewWeakGlobalRef(self, mu): 987 | raise NotImplementedError() 988 | 989 | def _DeleteWeakGlobalRef(self, mu): 990 | raise NotImplementedError() 991 | 992 | def _ExceptionCheck(self, mu): 993 | raise NotImplementedError() 994 | 995 | def _NewDirectByteBuffer(self, mu): 996 | raise NotImplementedError() 997 | 998 | def _GetDirectBufferAddress(self, mu): 999 | raise NotImplementedError() 1000 | 1001 | def _GetDirectBufferCapacity(self, mu): 1002 | raise NotImplementedError() 1003 | 1004 | def _GetObjectRefType(self, mu): 1005 | raise NotImplementedError() 1006 | 1007 | def getJniEnv(self): 1008 | return self.JniEnvAddr 1009 | 1010 | def getJavaVM(self): 1011 | return self.JavaVMAddr 1012 | -------------------------------------------------------------------------------- /Emulator/hooks/NativeHooks.py: -------------------------------------------------------------------------------- 1 | class NativeHooks: 2 | def __init__(self, hooker): 3 | pass 4 | -------------------------------------------------------------------------------- /Emulator/linker/AndroidRelocationIterator.py: -------------------------------------------------------------------------------- 1 | import copy 2 | 3 | from Emulator.linker.SLEB128Decoder import SLEB128Decoder 4 | 5 | RELOCATION_GROUPED_BY_INFO_FLAG = 1 6 | RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG = 2 7 | RELOCATION_GROUPED_BY_ADDEND_FLAG = 4 8 | RELOCATION_GROUP_HAS_ADDEND_FLAG = 8 9 | 10 | 11 | class AndroidRelocationIterator: 12 | def __init__(self, buffer, elfClass, rela=False): 13 | self.rela = rela 14 | self.buffer = buffer 15 | self.elfClass = elfClass 16 | self.decoder = SLEB128Decoder(buffer, 32 if self.elfClass == b'\x01' else 64) 17 | self.reloc = {"r_offset": 0, "r_info": 0, "r_addend": 0, "r_info_type": 0, "r_info_sym": 0} 18 | 19 | self.relocation_count_ = self.decoder.pop_front() 20 | self.reloc["r_offset"] = self.decoder.pop_front() 21 | 22 | self.relocation_index_ = 0 23 | self.relocation_group_index_ = 0 24 | self.group_size_ = 0 25 | self.group_flags_ = 0 26 | self.group_r_offset_delta_ = 0 27 | 28 | def __iter__(self): 29 | return self 30 | 31 | def __next__(self): 32 | if self.relocation_index_ >= self.relocation_count_: 33 | raise StopIteration 34 | 35 | if self.relocation_group_index_ == self.group_size_: 36 | if self.read_group_fields() is not True: 37 | self.relocation_index_ = 0 38 | self.relocation_count_ = 0 39 | return None 40 | 41 | if self.is_relocation_grouped_by_offset_delta(): 42 | self.reloc["r_offset"] += self.group_r_offset_delta_ 43 | else: 44 | self.reloc["r_offset"] += self.decoder.pop_front() 45 | 46 | if self.is_relocation_grouped_by_info() is not True: 47 | self.reloc["r_info"] = self.decoder.pop_front() 48 | 49 | if self.is_relocation_group_has_addend() and self.is_relocation_grouped_by_addend() is not True: 50 | if self.rela is not True: 51 | raise Exception("unexpected r_addend in android.rel section") 52 | self.reloc["r_addend"] += self.decoder.pop_front() 53 | 54 | self.relocation_index_ += 1 55 | self.relocation_group_index_ += 1 56 | 57 | self.reloc["r_info_sym"] = self.reloc["r_info"] >> 8 if self.elfClass == b'\x01' else self.reloc["r_info"] >> 32 58 | self.reloc["r_info_type"] = self.reloc["r_info"] & 0x0ff if self.elfClass == b'\x01' else self.reloc["r_info"] & 0xffffffff 59 | 60 | return copy.deepcopy(self.reloc) 61 | 62 | def read_group_fields(self): 63 | self.group_size_ = self.decoder.pop_front() 64 | self.group_flags_ = self.decoder.pop_front() 65 | 66 | if self.is_relocation_grouped_by_offset_delta(): 67 | self.group_r_offset_delta_ = self.decoder.pop_front() 68 | 69 | if self.is_relocation_grouped_by_info(): 70 | self.reloc["r_info"] = self.decoder.pop_front() 71 | 72 | if self.is_relocation_group_has_addend() and self.is_relocation_grouped_by_addend(): 73 | if self.rela is not True: 74 | raise Exception("unexpected r_addend in android.rel section") 75 | self.reloc["r_addend"] += self.decoder.pop_front() 76 | elif self.is_relocation_group_has_addend() is not True: 77 | if self.rela: 78 | self.reloc["r_addend"] = 0 79 | 80 | self.relocation_group_index_ = 0 81 | return True 82 | 83 | def is_relocation_grouped_by_info(self): 84 | return (self.group_flags_ & RELOCATION_GROUPED_BY_INFO_FLAG) != 0 85 | 86 | def is_relocation_grouped_by_offset_delta(self): 87 | return (self.group_flags_ & RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG) != 0 88 | 89 | def is_relocation_grouped_by_addend(self): 90 | return (self.group_flags_ & RELOCATION_GROUPED_BY_ADDEND_FLAG) != 0 91 | 92 | def is_relocation_group_has_addend(self): 93 | return (self.group_flags_ & RELOCATION_GROUP_HAS_ADDEND_FLAG) != 0 94 | -------------------------------------------------------------------------------- /Emulator/linker/ElfConst.py: -------------------------------------------------------------------------------- 1 | ElfMagic = b'\x7fELF' 2 | ElfClass32 = b'\x01' 3 | ElfClass64 = b'\x02' 4 | ElfData2LSB = b'\x01' 5 | ElfData2MSB = b'\x02' 6 | ElfVersion = b'\x01' 7 | 8 | Ehdr32_size = 52 9 | Ehdr64_size = 64 10 | 11 | Dyn32_size = 8 12 | Dyn64_size = 16 13 | 14 | DynSym32_size = 16 15 | DynSym64_size = 24 16 | 17 | Rel32_size = 8 18 | Rel64_size = 16 19 | 20 | ARCH_ARM = 40 21 | ARCH_ARM64 = 183 22 | 23 | PT_LOAD = 1 24 | PT_DYNAMIC = 2 25 | 26 | UINT64_MAX = 18446744073709551615 27 | 28 | DT_NULL = 0 29 | DT_NEEDED = 1 30 | DT_PLTRELSZ = 2 31 | DT_PLTGOT = 3 32 | DT_HASH = 4 33 | DT_STRTAB = 5 34 | DT_SYMTAB = 6 35 | DT_RELA = 7 36 | DT_RELASZ = 8 37 | DT_RELAENT = 9 38 | DT_STRSZ = 10 39 | DT_SYMENT = 11 40 | DT_INIT = 0x0c 41 | DT_INIT_ARRAY = 0x19 42 | DT_FINI_ARRAY = 0x1a 43 | DT_INIT_ARRAYSZ = 0x1b 44 | DT_FINI_ARRAYSZ = 0x1c 45 | DT_SONAME = 14 46 | DT_RPATH = 15 47 | DT_SYMBOLIC = 16 48 | DT_REL = 17 49 | DT_RELSZ = 18 50 | DT_RELENT = 19 51 | DT_PLTREL = 20 52 | DT_DEBUG = 21 53 | DT_TEXTREL = 22 54 | DT_JMPREL = 23 55 | DT_LOPROC = 0x70000000 56 | DT_HIPROC = 0x7fffffff 57 | DT_GNU_HASH = 0x6ffffef5 58 | 59 | DT_ANDROID_REL = 0x6000000f 60 | DT_ANDROID_RELSZ = 0x60000010 61 | DT_ANDROID_RELA = 0x60000011 62 | DT_ANDROID_RELASZ = 0x60000012 63 | 64 | SHN_UNDEF = 0 65 | SHN_LORESERVE = 0xff00 66 | SHN_LOPROC = 0xff00 67 | SHN_HIPROC = 0xff1f 68 | SHN_ABS = 0xfff1 69 | SHN_COMMON = 0xfff2 70 | SHN_HIRESERVE = 0xffff 71 | SHN_MIPS_ACCOMON = 0xff00 72 | 73 | STB_LOCAL = 0 74 | STB_GLOBAL = 1 75 | STB_WEAK = 2 76 | STT_NOTYPE = 0 77 | STT_OBJECT = 1 78 | STT_FUNC = 2 79 | STT_SECTION = 3 80 | STT_FILE = 4 81 | 82 | 83 | R_ARM_ABS32 = 2 84 | R_ARM_REL32 = 3 85 | R_ARM_COPY = 20 86 | R_ARM_GLOB_DAT = 21 87 | R_ARM_JUMP_SLOT = 22 88 | R_ARM_RELATIVE = 23 89 | R_ARM_IRELATIVE = 160 90 | 91 | R_AARCH64_ABS64 = 257 92 | R_AARCH64_ABS32 = 258 93 | R_AARCH64_ABS16 = 259 94 | R_AARCH64_PREL64 = 260 95 | R_AARCH64_PREL32 = 261 96 | R_AARCH64_PREL16 = 262 97 | R_AARCH64_COPY = 1024 98 | R_AARCH64_GLOB_DAT = 1025 99 | R_AARCH64_JUMP_SLOT = 1026 100 | R_AARCH64_RELATIVE = 1027 101 | R_AARCH64_TLS_TPREL64 = 1030 102 | R_AARCH64_TLS_DTPREL32 = 1031 103 | R_AARCH64_IRELATIVE = 1032 -------------------------------------------------------------------------------- /Emulator/linker/ElfReader.py: -------------------------------------------------------------------------------- 1 | import struct 2 | 3 | from Emulator.linker import ElfConst 4 | from Emulator.linker.AndroidRelocationIterator import AndroidRelocationIterator 5 | from Emulator.utils.Memory_Helpers import PAGE_START, PAGE_END, PFLAGS_TO_PROT 6 | 7 | 8 | class ElfReader: 9 | def __init__(self, emulator, fileName, fo): 10 | self.fo = fo 11 | self.fileName = fileName 12 | self.soName = "" 13 | self.emulator = emulator 14 | self.fdKey = emulator.PCB.findMinFd() 15 | emulator.PCB.FDMaps[self.fdKey] = {"pathname": fileName, "fo": fo, "fd": -1, "addr": -1} 16 | 17 | self.elfData = None 18 | self.elfClass = None 19 | self.arch = 0 20 | self.phOffset = 0 21 | self.phNum = 0 22 | self.phEntrySize = 0 23 | self.programHeaderTable = [] 24 | self.load_start = 0 25 | self.load_size = 0 26 | 27 | self.dyn_off = 0 28 | self.rel_off = 0 29 | self.rel_size = 0 30 | self.relplt_off = 0 31 | self.relplt_size = 0 32 | self.androidRel_off = 0 33 | self.androidRel_size = 0 34 | self.androidRelA_off = 0 35 | self.androidRelA_size = 0 36 | self.androidRel_buf = b'' 37 | self.rel_entry_size = 0 38 | self.init_off = 0 39 | self.init_array_off = 0 40 | self.init_array_size = 0 41 | self.dt_need = [] 42 | self.plt_got_off = 0 43 | self.dyn_str_off = 0 44 | self.dyn_str_size = 0 45 | self.dyn_str_buf = b'' 46 | self.dyn_sym_off = 0 47 | self.sym_entry_size = 0 48 | self.hash_off = 0 49 | self.gnu_hash_off = 0 50 | self.nbucket = 0 51 | self.nchain = 0 52 | self.bucket = 0 53 | self.chain = 0 54 | self.soname_off = 0 55 | self.dynsymols = [] 56 | self.rels = {} 57 | self.so_needed = [] 58 | self.is_gnu_hash = False 59 | 60 | def load(self): 61 | return self.readAndVerifyElfHeader() \ 62 | and self.readProgramHeaders() \ 63 | and self.reserveAddressSpace() \ 64 | and self.loadSegments() \ 65 | and self.loadDynamicSection() \ 66 | and self.loadDone() 67 | 68 | def readAndVerifyElfHeader(self): 69 | self.fo.seek(0, 0) 70 | e_ident_size = 0x10 71 | e_ident_bytes = self.fo.read(e_ident_size) 72 | ElfMagic, self.elfClass, self.elfData, ElfVersion, _ = struct.unpack("<4ssss9s", e_ident_bytes) 73 | if ElfMagic != ElfConst.ElfMagic: 74 | raise Exception('ElfMagic is Invalid : %s' % str(ElfMagic)) 75 | if (self.elfClass == ElfConst.ElfClass32 or self.elfClass == ElfConst.ElfClass64) is not True: 76 | raise Exception('ElfClass is Invalid : %s' % str(self.elfClass)) 77 | if self.elfData != ElfConst.ElfData2LSB: 78 | raise Exception('ElfData is Invalid Must be LSB : %s' % str(self.elfData)) 79 | if ElfVersion != ElfConst.ElfVersion: 80 | raise Exception('ElfVersion is Invalid : %s' % str(ElfVersion)) 81 | 82 | Ehdr_size = ElfConst.Ehdr32_size if self.elfClass == b'\x01' else ElfConst.Ehdr64_size 83 | Ehdr_fmt = " max_vaddr: 119 | max_vaddr = high 120 | 121 | if found_pt_load: 122 | min_vaddr = 0 123 | max_vaddr = PAGE_END(max_vaddr) 124 | min_vaddr = PAGE_START(min_vaddr) 125 | self.load_size = max_vaddr - min_vaddr 126 | if self.load_size == 0: 127 | raise Exception('%s has no loadable segments' % self.fileName) 128 | self.load_start = self.emulator.memory.mmap(min_vaddr, self.load_size, mem_reserve=True) 129 | self.emulator.PCB.FDMaps[self.fdKey]["addr"] = self.load_start 130 | return True 131 | 132 | def loadSegments(self): 133 | for Phdr in self.programHeaderTable: 134 | if Phdr["p_type"] == ElfConst.PT_DYNAMIC: 135 | self.dyn_off = Phdr["p_offset"] 136 | if self.dyn_off == 0: 137 | raise Exception('no dynamic in this elf.') 138 | if Phdr["p_type"] != ElfConst.PT_LOAD: 139 | continue 140 | # segment在内存中地址 141 | seg_start = Phdr["p_vaddr"] + self.load_start 142 | seg_end = seg_start + Phdr["p_memsz"] 143 | 144 | seg_page_start = PAGE_START(seg_start) 145 | seg_page_end = PAGE_END(seg_end) 146 | 147 | seg_file_end = seg_start + Phdr["p_filesz"] 148 | 149 | file_start = Phdr["p_offset"] 150 | file_end = file_start + Phdr["p_filesz"] 151 | 152 | file_page_start = PAGE_START(file_start) 153 | file_length = file_end - file_page_start 154 | 155 | if file_length >= 0: 156 | self.emulator.memory.mmap(seg_page_start, file_length, PFLAGS_TO_PROT(Phdr["p_flags"]), 157 | self.fdKey, file_page_start) 158 | 159 | seg_file_end = PAGE_END(seg_file_end) 160 | if seg_page_end > seg_file_end: 161 | self.emulator.memory.mmap(seg_file_end, seg_page_end - seg_file_end, 162 | PFLAGS_TO_PROT(Phdr["p_flags"])) 163 | 164 | return True 165 | 166 | def loadDynamicSection(self): 167 | Dyn_size = ElfConst.Dyn32_size if self.elfClass == b'\x01' else ElfConst.Dyn64_size 168 | Dyn_fmt = " 0: 220 | self.fo.seek(self.virtualMemoryAddrToFileOffset(self.hash_off), 0) 221 | self.nbucket, self.nchain = struct.unpack(" 0: 226 | self.is_gnu_hash = True 227 | self.fo.seek(self.virtualMemoryAddrToFileOffset(self.gnu_hash_off), 0) 228 | gnu_nbucket, symndx, gnu_maskwords, gnu_shift2 = struct.unpack(" 0: 244 | self.fo.seek(self.virtualMemoryAddrToFileOffset(self.dyn_str_off), 0) 245 | self.dyn_str_buf = self.fo.read(self.dyn_str_size) 246 | 247 | if self.soname_off > 0: 248 | self.soName = self.st_name_to_name(self.soname_off) 249 | 250 | if self.dyn_sym_off > 0: 251 | self.fo.seek(self.virtualMemoryAddrToFileOffset(self.dyn_sym_off), 0) 252 | for i in range(0, nsyms): 253 | sym_bytes = self.fo.read(self.sym_entry_size) 254 | if self.elfClass == b'\x01': 255 | st_name, st_value, st_size, st_info, st_other, st_shndx = struct.unpack("> 4 260 | st_info_type = int_st_info & 0x0f 261 | name = self.st_name_to_name(st_name) 262 | self.dynsymols.append( 263 | {"name": name, "st_name": st_name, "st_value": st_value, "st_size": st_size, "st_info": st_info, 264 | "st_other": st_other, 265 | "st_shndx": st_shndx, "st_info_bind": st_info_bind, "st_info_type": st_info_type}) 266 | 267 | if self.rel_off > 0: 268 | self.fo.seek(self.virtualMemoryAddrToFileOffset(self.rel_off), 0) 269 | rel_table = [] 270 | rel_count = int(self.rel_size / self.rel_entry_size) 271 | for i in range(0, rel_count): 272 | rel_item_bytes = self.fo.read(self.rel_entry_size) 273 | r_offset, r_info, r_addend = 0, 0, 0 274 | if self.rel_entry_size == 8 or self.rel_entry_size == 16: 275 | rel_fmt = "> 8 if self.elfClass == b'\x01' else r_info >> 32 281 | r_info_type = r_info & 0x0ff if self.elfClass == b'\x01' else r_info & 0xffffffff 282 | rel_table.append( 283 | {"r_offset": r_offset, "r_info": r_info, "r_addend": r_addend, "r_info_type": r_info_type, 284 | "r_info_sym": r_info_sym}) 285 | self.rels["dynrel"] = rel_table 286 | 287 | if self.relplt_off > 0: 288 | self.fo.seek(self.virtualMemoryAddrToFileOffset(self.relplt_off), 0) 289 | relplt_table = [] 290 | relplt_count = int(self.relplt_size / self.rel_entry_size) 291 | for i in range(0, relplt_count): 292 | relplt_item_bytes = self.fo.read(self.rel_entry_size) 293 | r_offset, r_info, r_addend = 0, 0, 0 294 | if self.rel_entry_size == 8 or self.rel_entry_size == 16: 295 | relplt_fmt = "> 8 if self.elfClass == b'\x01' else r_info >> 32 301 | r_info_type = r_info & 0x0ff if self.elfClass == b'\x01' else r_info & 0xffffffff 302 | relplt_table.append( 303 | {"r_offset": r_offset, "r_info": r_info, "r_addend": r_addend, "r_info_type": r_info_type, 304 | "r_info_sym": r_info_sym}) 305 | self.rels["relplt"] = relplt_table 306 | 307 | if self.androidRel_off > 0: 308 | self.fo.seek(self.virtualMemoryAddrToFileOffset(self.androidRel_off), 0) 309 | magic = bytes.decode(self.fo.read(4)) 310 | androidRel_table = [] 311 | if self.androidRel_size >= 4 and "APS2" == magic: 312 | packed_relocs_size = self.androidRel_size - 4 313 | self.androidRel_buf = self.fo.read(packed_relocs_size) 314 | androidRelocationIterator = iter(AndroidRelocationIterator(self.androidRel_buf, self.elfClass)) 315 | for androidRelocation in androidRelocationIterator: 316 | if androidRelocation is not None: 317 | androidRel_table.append(androidRelocation) 318 | self.rels["androidRel"] = androidRel_table 319 | elif self.androidRelA_off > 0: 320 | self.fo.seek(self.virtualMemoryAddrToFileOffset(self.androidRelA_off), 0) 321 | magic = bytes.decode(self.fo.read(4)) 322 | androidRel_table = [] 323 | if self.androidRelA_size >= 4 and "APS2" == magic: 324 | packed_relocs_size = self.androidRelA_size - 4 325 | self.androidRel_buf = self.fo.read(packed_relocs_size) 326 | androidRelocationIterator = iter(AndroidRelocationIterator(self.androidRel_buf, self.elfClass, True)) 327 | for androidRelocation in androidRelocationIterator: 328 | if androidRelocation is not None: 329 | androidRel_table.append(androidRelocation) 330 | self.rels["androidRel"] = androidRel_table 331 | 332 | for str_off in self.dt_need: 333 | self.so_needed.append(self.st_name_to_name(str_off)) 334 | 335 | return True 336 | 337 | def loadDone(self): 338 | self.fo.close() 339 | del self.emulator.PCB.FDMaps[self.fdKey] 340 | return True 341 | 342 | def st_name_to_name(self, st_name): 343 | if not st_name < self.dyn_str_size: 344 | raise Exception('st_name_to_name st_name %d out of range %d' % (st_name, self.dyn_str_size)) 345 | 346 | endId = self.dyn_str_buf.find(b"\x00", st_name) 347 | r = self.dyn_str_buf[st_name:endId] 348 | name = r.decode("utf-8") 349 | return name 350 | 351 | def virtualMemoryAddrToFileOffset(self, address): 352 | for Phdr in self.programHeaderTable: 353 | if Phdr["p_vaddr"] <= address < (Phdr["p_vaddr"] + Phdr["p_memsz"]): 354 | relativeOffset = address - Phdr["p_vaddr"] 355 | if relativeOffset >= Phdr["p_filesz"]: 356 | raise Exception( 357 | "Can not convert virtual memory address 0x%x to file offset - found segment %s but address " 358 | "maps " 359 | "to memory outside file range" % (address, str(Phdr))) 360 | return Phdr["p_offset"] + relativeOffset 361 | raise Exception("Cannot find segment for address 0x%x" % address) 362 | 363 | def get_init_array(self): 364 | return self.init_array_off, self.init_array_size 365 | 366 | def soinfo_alloc(self): 367 | pass 368 | -------------------------------------------------------------------------------- /Emulator/linker/ElfStruct.txt: -------------------------------------------------------------------------------- 1 | typedef uint32_t Elf32_Addr; // Program address 2 | typedef uint32_t Elf32_Off; // File offset 3 | typedef uint16_t Elf32_Half; 4 | typedef uint32_t Elf32_Word; 5 | typedef int32_t Elf32_Sword; 6 | 7 | typedef uint64_t Elf64_Addr; 8 | typedef uint64_t Elf64_Off; 9 | typedef uint16_t Elf64_Half; 10 | typedef uint32_t Elf64_Word; 11 | typedef int32_t Elf64_Sword; 12 | typedef uint64_t Elf64_Xword; 13 | typedef int64_t Elf64_Sxword; 14 | 15 | > 4; } 102 | unsigned char getType() const { return st_info & 0x0f; } 103 | void setBinding(unsigned char b) { setBindingAndType(b, getType()); } 104 | void setType(unsigned char t) { setBindingAndType(getBinding(), t); } 105 | void setBindingAndType(unsigned char b, unsigned char t) { 106 | st_info = (b << 4) + (t & 0x0f); 107 | } 108 | }; 109 | 110 | // Symbol table entries for ELF64. 111 | struct Elf64_Sym { 112 | Elf64_Word st_name; // Symbol name (index into string table) 113 | unsigned char st_info; // Symbol's type and binding attributes 114 | unsigned char st_other; // Must be zero; reserved 115 | Elf64_Half st_shndx; // Which section (header tbl index) it's defined in 116 | Elf64_Addr st_value; // Value or address associated with the symbol 117 | Elf64_Xword st_size; // Size of the symbol 118 | 119 | // These accessors and mutators are identical to those defined for ELF32 120 | // symbol table entries. 121 | unsigned char getBinding() const { return st_info >> 4; } 122 | unsigned char getType() const { return st_info & 0x0f; } 123 | void setBinding(unsigned char b) { setBindingAndType(b, getType()); } 124 | void setType(unsigned char t) { setBindingAndType(getBinding(), t); } 125 | void setBindingAndType(unsigned char b, unsigned char t) { 126 | st_info = (b << 4) + (t & 0x0f); 127 | } 128 | }; 129 | 130 | // Relocation entry, without explicit addend. 131 | struct Elf32_Rel { 132 | Elf32_Addr r_offset; // Location (file byte offset, or program virtual addr) 133 | Elf32_Word r_info; // Symbol table index and type of relocation to apply 134 | 135 | // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE, 136 | // and ELF32_R_INFO macros defined in the ELF specification: 137 | Elf32_Word getSymbol() const { return (r_info >> 8); } 138 | unsigned char getType() const { return (unsigned char) (r_info & 0x0ff); } 139 | void setSymbol(Elf32_Word s) { setSymbolAndType(s, getType()); } 140 | void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); } 141 | void setSymbolAndType(Elf32_Word s, unsigned char t) { 142 | r_info = (s << 8) + t; 143 | } 144 | }; 145 | 146 | // Relocation entry, without explicit addend. 147 | struct Elf64_Rel { 148 | Elf64_Addr r_offset; // Location (file byte offset, or program virtual addr). 149 | Elf64_Xword r_info; // Symbol table index and type of relocation to apply. 150 | 151 | // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE, 152 | // and ELF64_R_INFO macros defined in the ELF specification: 153 | Elf64_Word getSymbol() const { return (r_info >> 32); } 154 | Elf64_Word getType() const { 155 | return (Elf64_Word) (r_info & 0xffffffffL); 156 | } 157 | void setSymbol(Elf64_Word s) { setSymbolAndType(s, getType()); } 158 | void setType(Elf64_Word t) { setSymbolAndType(getSymbol(), t); } 159 | void setSymbolAndType(Elf64_Word s, Elf64_Word t) { 160 | r_info = ((Elf64_Xword)s << 32) + (t&0xffffffffL); 161 | } 162 | }; -------------------------------------------------------------------------------- /Emulator/linker/Linker.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from Emulator.linker import ElfConst 4 | from Emulator.linker.ElfReader import ElfReader 5 | from Emulator.linker.Module import Module 6 | from Emulator.utils.Open_Helpers import openSOByName 7 | from unicorn import UC_PROT_WRITE, UC_PROT_READ 8 | 9 | logger = logging.getLogger(__name__) 10 | 11 | 12 | class Linker: 13 | def __init__(self, emulator): 14 | self.emulator = emulator 15 | self.symbol_hooks = dict() 16 | self.modules = dict() 17 | soinfo_area_sz = 0x40000 18 | self.soinfo_area_base = emulator.memory.mmap(0, soinfo_area_sz, UC_PROT_WRITE | UC_PROT_READ) 19 | 20 | def load_library(self, soName): 21 | logger.debug("Loading %s" % soName) 22 | fd = openSOByName(self.emulator, soName) 23 | if fd is None: 24 | raise Exception("Lib %s open failed" % soName) 25 | 26 | reader = ElfReader(self.emulator, soName, fd) 27 | 28 | if not reader.load(): 29 | raise Exception("ElfReader load Failed") 30 | 31 | for so_name in reader.so_needed: 32 | self.do_dlopen(so_name, True) 33 | 34 | symbols_resolved = dict() 35 | 36 | for symbol in reader.dynsymols: 37 | symbol_address = self.elf_get_symAddr(reader.load_start, symbol) 38 | if symbol_address is not None: 39 | name = symbol["name"] 40 | symbols_resolved[name] = symbol_address 41 | 42 | init_array_offset, init_array_size = reader.get_init_array() 43 | init_array = [] 44 | 45 | for relName in reader.rels: 46 | for rel in reader.rels[relName]: 47 | r_type = rel["r_info_type"] 48 | r_sym = rel["r_info_sym"] 49 | r_addend = rel["r_addend"] 50 | reloc = reader.load_start + rel["r_offset"] 51 | 52 | if r_type == 0: 53 | logger.debug("Unhandled relocation type " + str(r_type)) 54 | continue 55 | 56 | symbol = None if r_sym == 0 else reader.dynsymols[r_sym] 57 | sym_addr = 0 if symbol is None else symbols_resolved[symbol["name"]] if symbol[ 58 | "name"] in symbols_resolved else 0 59 | 60 | if r_type == ElfConst.R_ARM_ABS32: 61 | reloc_bytes = self.emulator.mu.mem_read(reloc, 4) 62 | reloc_value = int.from_bytes(reloc_bytes, byteorder='little') 63 | value = sym_addr + reloc_value 64 | self.emulator.mu.mem_write(reloc, value.to_bytes(4, byteorder='little')) 65 | elif r_type == ElfConst.R_AARCH64_ABS64: 66 | value = sym_addr + r_addend 67 | self.emulator.mu.mem_write(reloc, value.to_bytes(8, byteorder='little')) 68 | elif r_type in (ElfConst.R_ARM_GLOB_DAT, ElfConst.R_ARM_JUMP_SLOT): 69 | self.emulator.mu.mem_write(reloc, sym_addr.to_bytes(4, byteorder='little')) 70 | elif r_type in (ElfConst.R_AARCH64_GLOB_DAT, ElfConst.R_AARCH64_JUMP_SLOT): 71 | value = sym_addr + r_addend 72 | self.emulator.mu.mem_write(reloc, value.to_bytes(8, byteorder='little')) 73 | elif r_type == ElfConst.R_ARM_RELATIVE: 74 | reloc_bytes = self.emulator.mu.mem_read(reloc, 4) 75 | reloc_value = int.from_bytes(reloc_bytes, byteorder='little') 76 | value = reader.load_start + reloc_value 77 | self.emulator.mu.mem_write(reloc, value.to_bytes(4, byteorder='little')) 78 | elif r_type == ElfConst.R_AARCH64_RELATIVE: 79 | value = reader.load_start + r_addend 80 | self.emulator.mu.mem_write(reloc, value.to_bytes(8, byteorder='little')) 81 | else: 82 | logger.debug("Unhandled relocation type %i." % r_type) 83 | 84 | if reader.init_off != 0: 85 | init_array.append(reader.init_off) 86 | 87 | PointerSize = self.emulator.getPointSize() 88 | 89 | for _ in range(int(init_array_size / PointerSize)): 90 | b = self.emulator.mu.mem_read(reader.load_start + init_array_offset, PointerSize) 91 | fun_ptr = int.from_bytes(b, byteorder='little', signed=False) 92 | if fun_ptr != 0: 93 | init_array.append(fun_ptr) 94 | init_array_offset += PointerSize 95 | 96 | module = Module(reader.load_start, reader.load_size, reader.soName, symbols_resolved, init_array, 97 | self.soinfo_area_base) 98 | self.modules[reader.soName] = module 99 | logger.debug("Load Done %s" % soName) 100 | return module 101 | 102 | def find_loaded_library_by_name(self, soName): 103 | return self.modules[soName] if soName in self.modules.keys() else None 104 | 105 | def do_dlopen(self, soName, callInit=True): 106 | module = self.find_loaded_library_by_name(soName) 107 | if module is not None: 108 | return module 109 | module = self.load_library(soName) 110 | if module is None: 111 | raise Exception('Module %s not found' % soName) 112 | if callInit: 113 | module.callInit(self.emulator) 114 | 115 | def add_symbol_hook(self, symbol_name, addr): 116 | self.symbol_hooks[symbol_name] = addr 117 | 118 | def elf_get_symAddr(self, elf_base, symbol): 119 | name = symbol["name"] 120 | if name in self.symbol_hooks: 121 | return self.symbol_hooks[name] 122 | 123 | if symbol['st_shndx'] == ElfConst.SHN_UNDEF: 124 | target = self.elf_lookup_symbol(name) 125 | if target is None: 126 | if symbol['st_info_bind'] == ElfConst.STB_WEAK: 127 | return 0 128 | else: 129 | logger.debug('=> Undefined external symbol: %s' % name) 130 | return None 131 | else: 132 | return target 133 | elif symbol['st_shndx'] == ElfConst.SHN_ABS: 134 | return elf_base + symbol['st_value'] 135 | else: 136 | return elf_base + symbol['st_value'] 137 | 138 | def elf_lookup_symbol(self, name): 139 | for _, module in self.modules.items(): 140 | if name in module.symbols: 141 | addr = module.symbols[name] 142 | if addr != 0: 143 | return addr 144 | return None 145 | 146 | def findModuleByAddress(self, addr): 147 | for _, m in self.modules.items(): 148 | if m.base <= addr < m.base + m.size: 149 | return m 150 | return None 151 | -------------------------------------------------------------------------------- /Emulator/linker/Module.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | logger = logging.getLogger(__name__) 4 | 5 | 6 | class Module: 7 | def __init__(self, base, size, so_name, symbols_resolved, init_array, soinfo_addr): 8 | self.base = base 9 | self.size = size 10 | self.so_name = so_name 11 | self.symbol_lookup = dict() 12 | self.symbols = symbols_resolved 13 | self.init_array = init_array 14 | self.soinfo_addr = soinfo_addr 15 | 16 | for symbol_name in self.symbols: 17 | addr = self.symbols[symbol_name] 18 | if addr != 0: 19 | self.symbol_lookup[addr] = symbol_name 20 | 21 | def callInit(self, emulator): 22 | for fun_addr in self.init_array: 23 | logger.info("Calling Init_Array %s 0x%X function: 0x%X " % (self.so_name, fun_addr, fun_addr - self.base)) 24 | emulator.call_native(fun_addr) 25 | 26 | def callJniOnload(self): 27 | pass 28 | -------------------------------------------------------------------------------- /Emulator/linker/SLEB128Decoder.py: -------------------------------------------------------------------------------- 1 | class SLEB128Decoder: 2 | def __init__(self, buffer, size): 3 | self.buffer = buffer 4 | self.current = 0 5 | self.count = len(buffer) 6 | self.size = size 7 | 8 | def pop_front(self): 9 | shift = 0 10 | value = 0 11 | b = 0 12 | while True: 13 | if self.current > self.count: 14 | raise Exception("SLEB128Decoder ran out of bounds") 15 | b = self.buffer[self.current] & 0xff 16 | self.current += 1 17 | value |= ((b & 0x7f) << shift) 18 | shift += 7 19 | if (b & 0x80) == 0: 20 | break 21 | if shift < self.size and (b & 0x40) != 0: 22 | value |= -(1 << shift) 23 | return value 24 | -------------------------------------------------------------------------------- /Emulator/utils/Dvm_Helpers.py: -------------------------------------------------------------------------------- 1 | from numpy import int32 2 | 3 | 4 | def hashCode(s): 5 | seed = 31 6 | h = 0 7 | for c in s: 8 | h = int32(seed * h) + ord(c) 9 | return h 10 | -------------------------------------------------------------------------------- /Emulator/utils/Memory_Helpers.py: -------------------------------------------------------------------------------- 1 | from unicorn import UC_PROT_READ, UC_PROT_WRITE, UC_PROT_EXEC 2 | from unicorn.arm64_const import * 3 | 4 | from unicorn.arm_const import * 5 | 6 | PAGE_SIZE = 0x1000 7 | 8 | PF_X = 0x1 # Executable 9 | PF_W = 0x2 # Writable 10 | PF_R = 0x4 # Readable 11 | 12 | MAP_ANONYMOUS = 0x20 13 | MAP_FIXED = 0x10 14 | 15 | MAP_ALLOC_BASE = 0x40000000 16 | MAP_ALLOC_SIZE = 0xA0000000 - MAP_ALLOC_BASE 17 | 18 | STACK_ALLOC_BASE = 0xc0000000 19 | STACK_ALLOC_SIZE = 256 * PAGE_SIZE 20 | 21 | 22 | def PAGE_START(addr): 23 | return addr & (~(PAGE_SIZE - 1)) 24 | 25 | 26 | def PAGE_END(addr): 27 | return PAGE_START(addr) + PAGE_SIZE 28 | 29 | 30 | def alignSize(size): 31 | return (int((size - 1) / PAGE_SIZE) + 1) * PAGE_SIZE 32 | 33 | 34 | def PFLAGS_TO_PROT(prot_in): 35 | prot = 0 36 | 37 | if prot_in & PF_R != 0: 38 | prot |= 1 39 | 40 | if prot_in & PF_W != 0: 41 | prot |= 2 42 | 43 | if prot_in & PF_X != 0: 44 | prot |= 4 45 | 46 | return prot 47 | 48 | 49 | def getPointerArg(mu, index): 50 | regArgCount = 4 51 | R0_REG = UC_ARM_REG_R0 52 | SP_REG = UC_ARM_REG_SP 53 | pointerSize = 4 54 | if mu._arch == 2: 55 | regArgCount = 8 56 | R0_REG = UC_ARM64_REG_X0 57 | SP_REG = UC_ARM64_REG_SP 58 | pointerSize = 8 59 | if index < regArgCount: 60 | return mu.reg_read(R0_REG + index) 61 | sp = mu.reg_read(SP_REG) 62 | return int.from_bytes(mu.mem_read(sp + (index - regArgCount) * pointerSize), byteorder='little') 63 | 64 | 65 | def getLRPointer(mu): 66 | LR_REG = UC_ARM_REG_LR 67 | if mu._arch == 2: 68 | LR_REG = UC_ARM64_REG_LR 69 | return mu.reg_read(LR_REG) 70 | 71 | 72 | def ptrStr(linker, addr): 73 | m = linker.findModuleByAddress(addr) 74 | base = 0 75 | mName = "UniDa" 76 | if m is not None: 77 | base = m.base 78 | mName = m.so_name 79 | protName = "" 80 | for r in linker.emulator.mu.mem_regions(): 81 | if r[0] <= addr < r[1]: 82 | base = r[0] 83 | prot = r[2] 84 | if prot & UC_PROT_READ != 0: 85 | protName += "R" 86 | if prot & UC_PROT_WRITE != 0: 87 | protName += "W" 88 | if prot & UC_PROT_EXEC != 0: 89 | protName += "X" 90 | 91 | return "%s@0x%X[%s:0x%X]0x%X" % (protName, addr, mName, base, addr - base) 92 | 93 | 94 | def toIntPeer(addr): 95 | return addr & 0xffffffff 96 | 97 | 98 | def read_utf8(mu, address): 99 | buffer_address = address 100 | buffer_read_size = 32 101 | buffer = b"" 102 | null_pos = None 103 | 104 | # Keep reading until we read something that contains a null terminator. 105 | while null_pos is None: 106 | buf_read = mu.mem_read(buffer_address, buffer_read_size) 107 | if b'\x00' in buf_read: 108 | null_pos = len(buffer) + buf_read.index(b'\x00') 109 | buffer += buf_read 110 | buffer_address += buffer_read_size 111 | 112 | return buffer[:null_pos].decode("utf-8") 113 | 114 | 115 | def write_utf8(mu, address, value): 116 | mu.mem_write(address, value.encode(encoding="utf-8") + b"\x00") 117 | return address 118 | 119 | 120 | def isThumb(mu): 121 | CPSR = mu.reg_read(UC_ARM_REG_CPSR) 122 | THUMB_BIT = 5 123 | return ((CPSR >> THUMB_BIT) & 1) == 1 124 | -------------------------------------------------------------------------------- /Emulator/utils/Open_Helpers.py: -------------------------------------------------------------------------------- 1 | import os 2 | import zipfile 3 | 4 | 5 | def openSOByName(emu, soName): 6 | if emu.apkPath != "": 7 | apkFD = openApkLib(emu, soName) 8 | if apkFD is not None: 9 | return apkFD 10 | baseLibPath = "Android/SDK23/%s" % ("lib64" if emu.is64Bit else "lib") 11 | for fileName in os.listdir(baseLibPath): 12 | if soName.replace("+", "p") in fileName: 13 | return open(baseLibPath + "/" + fileName, 'rb') 14 | return None 15 | 16 | 17 | def openApkLib(emu, soName): 18 | if not zipfile.is_zipfile(emu.apkPath): 19 | raise Exception("%s is not a zipfile" % emu.apkPath) 20 | z = zipfile.ZipFile(emu.apkPath) 21 | for filePath in z.namelist(): 22 | if soName in filePath and ("arm64-v8a" if emu.is64Bit else "armeabi-v7a") in filePath: 23 | return z.open(filePath) 24 | z.close() 25 | return None 26 | -------------------------------------------------------------------------------- /Emulator/vm/ARM32SyscallHandler.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from unicorn import UC_HOOK_INTR 4 | from unicorn.arm_const import * 5 | 6 | from Emulator.hooks.ARMConst import * 7 | from Emulator.utils.Memory_Helpers import isThumb, read_utf8, ptrStr, getLRPointer, write_utf8, PAGE_SIZE, alignSize 8 | 9 | logger = logging.getLogger(__name__) 10 | 11 | MMAP2_SHIFT = 12 12 | 13 | FUTEX_WAIT = 0 14 | FUTEX_WAKE = 1 15 | 16 | PR_GET_DUMPABLE = 3 17 | PR_SET_DUMPABLE = 4 18 | PR_SET_NAME = 15 19 | PR_GET_NAME = 16 20 | BIONIC_PR_SET_VMA = 0x53564d41 21 | PR_SET_PTRACER = 0x59616d61 22 | 23 | 24 | class ARM32SyscallHandler: 25 | def __init__(self, emulator): 26 | self.emulator = emulator 27 | self.syscallHandlerMaps = { 28 | 0: self.restart_syscall, 29 | 1: self.exit, 30 | 2: self.fork, 31 | 3: self.read, 32 | 4: self.write, 33 | 5: self.open, 34 | 6: self.close, 35 | 8: self.creat, 36 | 9: self.link, 37 | 10: self.unlink, 38 | 11: self.execve, 39 | 12: self.chdir, 40 | 14: self.mknod, 41 | 15: self.chmod, 42 | 16: self.lchown, 43 | 19: self.lseek, 44 | 20: self.getpid, 45 | 21: self.mount, 46 | 23: self.setuid, 47 | 24: self.getuid, 48 | 26: self.ptrace, 49 | 29: self.pause, 50 | 33: self.access, 51 | 34: self.nice, 52 | 36: self.sync, 53 | 37: self.kill, 54 | 38: self.rename, 55 | 39: self.mkdir, 56 | 40: self.rmdir, 57 | 41: self.dup, 58 | 42: self.pipe, 59 | 43: self.times, 60 | 45: self.brk, 61 | 46: self.setgid, 62 | 47: self.getgid, 63 | 49: self.geteuid, 64 | 50: self.getegid, 65 | 51: self.acct, 66 | 52: self.umount2, 67 | 54: self.ioctl, 68 | 55: self.fcntl, 69 | 57: self.setpgid, 70 | 60: self.umask, 71 | 61: self.chroot, 72 | 62: self.ustat, 73 | 63: self.dup2, 74 | 64: self.getppid, 75 | 65: self.getpgrp, 76 | 66: self.setsid, 77 | 67: self.sigaction, 78 | 70: self.setreuid, 79 | 71: self.setregid, 80 | 72: self.sigsuspend, 81 | 73: self.sigpending, 82 | 74: self.sethostname, 83 | 75: self.setrlimit, 84 | 77: self.getrusage, 85 | 78: self.gettimeofday, 86 | 79: self.settimeofday, 87 | 80: self.getgroups, 88 | 81: self.setgroups, 89 | 83: self.symlink, 90 | 85: self.readlink, 91 | 86: self.uselib, 92 | 87: self.swapon, 93 | 88: self.reboot, 94 | 91: self.munmap, 95 | 92: self.truncate, 96 | 93: self.ftruncate, 97 | 94: self.fchmod, 98 | 95: self.fchown, 99 | 96: self.getpriority, 100 | 97: self.setpriority, 101 | 99: self.statfs, 102 | 100: self.fstatfs, 103 | 103: self.syslog, 104 | 104: self.setitimer, 105 | 105: self.getitimer, 106 | 106: self.stat, 107 | 107: self.lstat, 108 | 108: self.fstat, 109 | 111: self.vhangup, 110 | 114: self.wait4, 111 | 115: self.swapoff, 112 | 116: self.sysinfo, 113 | 118: self.fsync, 114 | 119: self.sigreturn, 115 | 120: self.clone, 116 | 121: self.setdomainname, 117 | 122: self.uname, 118 | 124: self.adjtimex, 119 | 125: self.mprotect, 120 | 126: self.sigprocmask, 121 | 128: self.init_module, 122 | 129: self.delete_module, 123 | 131: self.quotactl, 124 | 132: self.getpgid, 125 | 133: self.fchdir, 126 | 134: self.bdflush, 127 | 135: self.sysfs, 128 | 136: self.personality, 129 | 138: self.setfsuid, 130 | 139: self.setfsgid, 131 | 140: self._llseek, 132 | 141: self.getdents, 133 | 142: self._newselect, 134 | 143: self.flock, 135 | 144: self.msync, 136 | 145: self.readv, 137 | 146: self.writev, 138 | 147: self.getsid, 139 | 148: self.fdatasync, 140 | 149: self._sysctl, 141 | 150: self.mlock, 142 | 151: self.munlock, 143 | 152: self.mlockall, 144 | 153: self.munlockall, 145 | 154: self.sched_setparam, 146 | 155: self.sched_getparam, 147 | 156: self.sched_setscheduler, 148 | 157: self.sched_getscheduler, 149 | 158: self.sched_yield, 150 | 159: self.sched_get_priority_max, 151 | 160: self.sched_get_priority_min, 152 | 161: self.sched_rr_get_interval, 153 | 162: self.nanosleep, 154 | 163: self.mremap, 155 | 164: self.setresuid, 156 | 165: self.getresuid, 157 | 168: self.poll, 158 | 169: self.nfsservctl, 159 | 170: self.setresgid, 160 | 171: self.getresgid, 161 | 172: self.prctl, 162 | 173: self.rt_sigreturn, 163 | 174: self.rt_sigaction, 164 | 175: self.rt_sigprocmask, 165 | 176: self.rt_sigpending, 166 | 177: self.rt_sigtimedwait, 167 | 178: self.rt_sigqueueinfo, 168 | 179: self.rt_sigsuspend, 169 | 180: self.pread64, 170 | 181: self.pwrite64, 171 | 182: self.chown, 172 | 183: self.getcwd, 173 | 184: self.capget, 174 | 185: self.capset, 175 | 186: self.sigaltstack, 176 | 187: self.sendfile, 177 | 190: self.vfork, 178 | 191: self.ugetrlimit, 179 | 192: self.mmap2, 180 | 193: self.truncate64, 181 | 194: self.ftruncate64, 182 | 195: self.stat64, 183 | 196: self.lstat64, 184 | 197: self.fstat64, 185 | 198: self.lchown32, 186 | 199: self.getuid32, 187 | 200: self.getgid32, 188 | 201: self.geteuid32, 189 | 202: self.getegid32, 190 | 203: self.setreuid32, 191 | 204: self.setregid32, 192 | 205: self.getgroups32, 193 | 206: self.setgroups32, 194 | 207: self.fchown32, 195 | 208: self.setresuid32, 196 | 209: self.getresuid32, 197 | 210: self.setresgid32, 198 | 211: self.getresgid32, 199 | 212: self.chown32, 200 | 213: self.setuid32, 201 | 214: self.setgid32, 202 | 215: self.setfsuid32, 203 | 216: self.setfsgid32, 204 | 217: self.getdents64, 205 | 218: self.pivot_root, 206 | 219: self.mincore, 207 | 220: self.madvise, 208 | 221: self.fcntl64, 209 | 224: self.gettid, 210 | 225: self.readahead, 211 | 226: self.setxattr, 212 | 227: self.lsetxattr, 213 | 228: self.fsetxattr, 214 | 229: self.getxattr, 215 | 230: self.lgetxattr, 216 | 231: self.fgetxattr, 217 | 232: self.listxattr, 218 | 233: self.llistxattr, 219 | 234: self.flistxattr, 220 | 235: self.removexattr, 221 | 236: self.lremovexattr, 222 | 237: self.fremovexattr, 223 | 238: self.tkill, 224 | 239: self.sendfile64, 225 | 240: self.futex, 226 | 241: self.sched_setaffinity, 227 | 242: self.sched_getaffinity, 228 | 243: self.io_setup, 229 | 244: self.io_destroy, 230 | 245: self.io_getevents, 231 | 246: self.io_submit, 232 | 247: self.io_cancel, 233 | 248: self.exit_group, 234 | 249: self.lookup_dcookie, 235 | 250: self.epoll_create, 236 | 251: self.epoll_ctl, 237 | 252: self.epoll_wait, 238 | 253: self.remap_file_pages, 239 | 256: self.set_tid_address, 240 | 257: self.timer_create, 241 | 258: self.timer_settime, 242 | 259: self.timer_gettime, 243 | 260: self.timer_getoverrun, 244 | 261: self.timer_delete, 245 | 262: self.clock_settime, 246 | 263: self.clock_gettime, 247 | 264: self.clock_getres, 248 | 265: self.clock_nanosleep, 249 | 266: self.statfs64, 250 | 267: self.fstatfs64, 251 | 268: self.tgkill, 252 | 269: self.utimes, 253 | 270: self.arm_fadvise64_64, 254 | 271: self.pciconfig_iobase, 255 | 272: self.pciconfig_read, 256 | 273: self.pciconfig_write, 257 | 274: self.mq_open, 258 | 275: self.mq_unlink, 259 | 276: self.mq_timedsend, 260 | 277: self.mq_timedreceive, 261 | 278: self.mq_notify, 262 | 279: self.mq_getsetattr, 263 | 280: self.waitid, 264 | 281: self.socket, 265 | 282: self.bind, 266 | 283: self.connect, 267 | 284: self.listen, 268 | 285: self.accept, 269 | 286: self.getsockname, 270 | 287: self.getpeername, 271 | 288: self.socketpair, 272 | 289: self.send, 273 | 290: self.sendto, 274 | 291: self.recv, 275 | 292: self.recvfrom, 276 | 293: self.shutdown, 277 | 294: self.setsockopt, 278 | 295: self.getsockopt, 279 | 296: self.sendmsg, 280 | 297: self.recvmsg, 281 | 298: self.semop, 282 | 299: self.semget, 283 | 300: self.semctl, 284 | 301: self.msgsnd, 285 | 302: self.msgrcv, 286 | 303: self.msgget, 287 | 304: self.msgctl, 288 | 305: self.shmat, 289 | 306: self.shmdt, 290 | 307: self.shmget, 291 | 308: self.shmctl, 292 | 309: self.add_key, 293 | 310: self.request_key, 294 | 311: self.keyctl, 295 | 312: self.semtimedop, 296 | 314: self.ioprio_set, 297 | 315: self.ioprio_get, 298 | 316: self.inotify_init, 299 | 317: self.inotify_add_watch, 300 | 318: self.inotify_rm_watch, 301 | 319: self.mbind, 302 | 320: self.get_mempolicy, 303 | 321: self.set_mempolicy, 304 | 322: self.openat, 305 | 323: self.mkdirat, 306 | 324: self.mknodat, 307 | 325: self.fchownat, 308 | 326: self.futimesat, 309 | 327: self.fstatat64, 310 | 328: self.unlinkat, 311 | 329: self.renameat, 312 | 330: self.linkat, 313 | 331: self.symlinkat, 314 | 332: self.readlinkat, 315 | 333: self.fchmodat, 316 | 334: self.faccessat, 317 | 335: self.pselect6, 318 | 336: self.ppoll, 319 | 337: self.unshare, 320 | 338: self.set_robust_list, 321 | 339: self.get_robust_list, 322 | 340: self.splice, 323 | 341: self.sync_file_range2, 324 | 342: self.tee, 325 | 343: self.vmsplice, 326 | 344: self.move_pages, 327 | 345: self.getcpu, 328 | 346: self.epoll_pwait, 329 | 347: self.kexec_load, 330 | 348: self.utimensat, 331 | 349: self.signalfd, 332 | 350: self.timerfd_create, 333 | 351: self.eventfd, 334 | 352: self.fallocate, 335 | 353: self.timerfd_settime, 336 | 354: self.timerfd_gettime, 337 | 355: self.signalfd4, 338 | 356: self.eventfd2, 339 | 357: self.epoll_create1, 340 | 358: self.dup3, 341 | 359: self.pipe2, 342 | 360: self.inotify_init1, 343 | 361: self.preadv, 344 | 362: self.pwritev, 345 | 363: self.rt_tgsigqueueinfo, 346 | 364: self.perf_event_open, 347 | 365: self.recvmmsg, 348 | 366: self.accept4, 349 | 367: self.fanotify_init, 350 | 368: self.fanotify_mark, 351 | 369: self.prlimit64, 352 | 370: self.name_to_handle_at, 353 | 371: self.open_by_handle_at, 354 | 372: self.clock_adjtime, 355 | 373: self.syncfs, 356 | 374: self.sendmmsg, 357 | 375: self.setns, 358 | 376: self.process_vm_readv, 359 | 377: self.process_vm_writev, 360 | 378: self.kcmp, 361 | 379: self.finit_module, 362 | 380: self.sched_setattr, 363 | 381: self.sched_getattr, 364 | 382: self.renameat2, 365 | 383: self.seccomp, 366 | 384: self.getrandom, 367 | 385: self.memfd_create, 368 | 386: self.bpf, 369 | 387: self.execveat, 370 | 388: self.userfaultfd, 371 | 389: self.membarrier, 372 | 390: self.mlock2, 373 | 391: self.copy_file_range, 374 | 392: self.preadv2, 375 | 393: self.pwritev2, 376 | 394: self.pkey_mprotect, 377 | 395: self.pkey_alloc, 378 | 396: self.pkey_free, 379 | 397: self.statx, 380 | 398: self.rseq, 381 | 399: self.io_pgetevents, 382 | 400: self.migrate_pages, 383 | 401: self.kexec_file_load, 384 | 403: self.clock_gettime64, 385 | 404: self.clock_settime64, 386 | 405: self.clock_adjtime64, 387 | 406: self.clock_getres_time64, 388 | 407: self.clock_nanosleep_time64, 389 | 408: self.timer_gettime64, 390 | 409: self.timer_settime64, 391 | 410: self.timerfd_gettime64, 392 | 411: self.timerfd_settime64, 393 | 412: self.utimensat_time64, 394 | 413: self.pselect6_time64, 395 | 414: self.ppoll_time64, 396 | 416: self.io_pgetevents_time64, 397 | 417: self.recvmmsg_time64, 398 | 418: self.mq_timedsend_time64, 399 | 419: self.mq_timedreceive_time64, 400 | 420: self.semtimedop_time64, 401 | 421: self.rt_sigtimedwait_time64, 402 | 422: self.futex_time64, 403 | 423: self.sched_rr_get_interval_time64, 404 | 424: self.pidfd_send_signal, 405 | 425: self.io_uring_setup, 406 | 426: self.io_uring_enter, 407 | 427: self.io_uring_register, 408 | 428: self.open_tree, 409 | 429: self.move_mount, 410 | 430: self.fsopen, 411 | 431: self.fsconfig, 412 | 432: self.fsmount, 413 | 433: self.fspick, 414 | 434: self.pidfd_open, 415 | 435: self.clone3, 416 | 436: self.close_range, 417 | 437: self.openat2, 418 | 438: self.pidfd_getfd, 419 | 439: self.faccessat2, 420 | 440: self.process_madvise, 421 | 441: self.epoll_pwait2, 422 | 442: self.mount_setattr, 423 | 443: self.quotactl_fd, 424 | 444: self.landlock_create_ruleset, 425 | 445: self.landlock_add_rule, 426 | 446: self.landlock_restrict_self, 427 | 448: self.process_mrelease 428 | } 429 | self.emulator.mu.hook_add(UC_HOOK_INTR, self.hook) 430 | 431 | def hook(self, mu, intno, userdata): 432 | # 断点 433 | pc = mu.reg_read(UC_ARM_REG_PC) 434 | if isThumb(mu): 435 | swi = int.from_bytes(mu.mem_read(pc - 2, 2), byteorder='little') & 0xff 436 | else: 437 | swi = int.from_bytes(mu.mem_read(pc - 4, 4), byteorder='little') & 0xffffff 438 | if intno == EXCP_BKPT: 439 | return 440 | if intno != EXCP_SWI: 441 | mu.emu_stop() 442 | raise Exception("Unhandled interrupt %d" % intno) 443 | NR = mu.reg_read(UC_ARM_REG_R7) 444 | if swi != 0: 445 | if swi in self.emulator.hooker.hookMaps: 446 | mu.reg_write(UC_ARM_REG_R0, self.emulator.hooker.hookMaps[swi](mu)) 447 | return 448 | mu.emu_stop() 449 | raise Exception("Unhandled svcHook %d" % swi) 450 | if NR in self.syscallHandlerMaps: 451 | mu.reg_write(UC_ARM_REG_R0, self.syscallHandlerMaps[NR](mu)) 452 | return 453 | mu.emu_stop() 454 | raise Exception("Unhandled svc %d" % NR) 455 | 456 | def restart_syscall(self, mu): 457 | raise NotImplementedError() 458 | 459 | def exit(self, mu): 460 | status = mu.reg_read(UC_ARM_REG_R0) 461 | logger.info("exit status= %d" % status) 462 | mu.emu_stop() 463 | return 464 | 465 | def fork(self, mu): 466 | raise NotImplementedError() 467 | 468 | def read(self, mu): 469 | fd = mu.reg_read(UC_ARM_REG_R0) 470 | buffer_ptr = mu.reg_read(UC_ARM_REG_R1) 471 | count = mu.reg_read(UC_ARM_REG_R3) 472 | logger.debug("Read fd= %d, buffer_ptr= 0x%X,count= %d" % (fd, buffer_ptr, count)) 473 | return self.emulator.PCB.read(mu, fd, buffer_ptr, count) 474 | 475 | def write(self, mu): 476 | raise NotImplementedError() 477 | 478 | def open(self, mu): 479 | raise NotImplementedError() 480 | 481 | def close(self, mu): 482 | fd = mu.reg_read(UC_ARM_REG_R0) 483 | logger.debug("close fd= %d" % fd) 484 | return self.emulator.PCB.close(fd) 485 | 486 | def creat(self, mu): 487 | raise NotImplementedError() 488 | 489 | def link(self, mu): 490 | raise NotImplementedError() 491 | 492 | def unlink(self, mu): 493 | raise NotImplementedError() 494 | 495 | def execve(self, mu): 496 | raise NotImplementedError() 497 | 498 | def chdir(self, mu): 499 | raise NotImplementedError() 500 | 501 | def mknod(self, mu): 502 | raise NotImplementedError() 503 | 504 | def chmod(self, mu): 505 | raise NotImplementedError() 506 | 507 | def lchown(self, mu): 508 | raise NotImplementedError() 509 | 510 | def lseek(self, mu): 511 | raise NotImplementedError() 512 | 513 | def getpid(self, mu): 514 | raise NotImplementedError() 515 | 516 | def mount(self, mu): 517 | raise NotImplementedError() 518 | 519 | def setuid(self, mu): 520 | raise NotImplementedError() 521 | 522 | def getuid(self, mu): 523 | raise NotImplementedError() 524 | 525 | def ptrace(self, mu): 526 | raise NotImplementedError() 527 | 528 | def pause(self, mu): 529 | raise NotImplementedError() 530 | 531 | def access(self, mu): 532 | raise NotImplementedError() 533 | 534 | def nice(self, mu): 535 | raise NotImplementedError() 536 | 537 | def sync(self, mu): 538 | raise NotImplementedError() 539 | 540 | def kill(self, mu): 541 | raise NotImplementedError() 542 | 543 | def rename(self, mu): 544 | raise NotImplementedError() 545 | 546 | def mkdir(self, mu): 547 | raise NotImplementedError() 548 | 549 | def rmdir(self, mu): 550 | raise NotImplementedError() 551 | 552 | def dup(self, mu): 553 | raise NotImplementedError() 554 | 555 | def pipe(self, mu): 556 | raise NotImplementedError() 557 | 558 | def times(self, mu): 559 | raise NotImplementedError() 560 | 561 | def brk(self, mu): 562 | address = mu.reg_read(UC_ARM_REG_R0) & 0xffffffff 563 | logger.debug("brk address= 0x%X " % address) 564 | return self.emulator.memory.brk(address) 565 | 566 | def setgid(self, mu): 567 | raise NotImplementedError() 568 | 569 | def getgid(self, mu): 570 | raise NotImplementedError() 571 | 572 | def geteuid(self, mu): 573 | raise NotImplementedError() 574 | 575 | def getegid(self, mu): 576 | raise NotImplementedError() 577 | 578 | def acct(self, mu): 579 | raise NotImplementedError() 580 | 581 | def umount2(self, mu): 582 | raise NotImplementedError() 583 | 584 | def ioctl(self, mu): 585 | fd = mu.reg_read(UC_ARM_REG_R0) 586 | request = mu.reg_read(UC_ARM_REG_R1) 587 | argp = mu.reg_read(UC_ARM_REG_R2) 588 | return self.emulator.PCB.ioctl(mu,fd, request, argp) 589 | 590 | def fcntl(self, mu): 591 | raise NotImplementedError() 592 | 593 | def setpgid(self, mu): 594 | raise NotImplementedError() 595 | 596 | def umask(self, mu): 597 | raise NotImplementedError() 598 | 599 | def chroot(self, mu): 600 | raise NotImplementedError() 601 | 602 | def ustat(self, mu): 603 | raise NotImplementedError() 604 | 605 | def dup2(self, mu): 606 | raise NotImplementedError() 607 | 608 | def getppid(self, mu): 609 | raise NotImplementedError() 610 | 611 | def getpgrp(self, mu): 612 | raise NotImplementedError() 613 | 614 | def setsid(self, mu): 615 | raise NotImplementedError() 616 | 617 | def sigaction(self, mu): 618 | raise NotImplementedError() 619 | 620 | def setreuid(self, mu): 621 | raise NotImplementedError() 622 | 623 | def setregid(self, mu): 624 | raise NotImplementedError() 625 | 626 | def sigsuspend(self, mu): 627 | raise NotImplementedError() 628 | 629 | def sigpending(self, mu): 630 | raise NotImplementedError() 631 | 632 | def sethostname(self, mu): 633 | raise NotImplementedError() 634 | 635 | def setrlimit(self, mu): 636 | raise NotImplementedError() 637 | 638 | def getrusage(self, mu): 639 | raise NotImplementedError() 640 | 641 | def gettimeofday(self, mu): 642 | raise NotImplementedError() 643 | 644 | def settimeofday(self, mu): 645 | raise NotImplementedError() 646 | 647 | def getgroups(self, mu): 648 | raise NotImplementedError() 649 | 650 | def setgroups(self, mu): 651 | raise NotImplementedError() 652 | 653 | def symlink(self, mu): 654 | raise NotImplementedError() 655 | 656 | def readlink(self, mu): 657 | raise NotImplementedError() 658 | 659 | def uselib(self, mu): 660 | raise NotImplementedError() 661 | 662 | def swapon(self, mu): 663 | raise NotImplementedError() 664 | 665 | def reboot(self, mu): 666 | raise NotImplementedError() 667 | 668 | def munmap(self, mu): 669 | start = mu.reg_read(UC_ARM_REG_R0) & 0xffffffff 670 | len = mu.reg_read(UC_ARM_REG_R1) 671 | self.emulator.memory.munmap(start, len) 672 | logger.debug( 673 | "munmap start= 0x%X ,len= %d ,from= %s" % (start, len, ptrStr(self.emulator.linker, getLRPointer(mu)))) 674 | return 0 675 | 676 | def truncate(self, mu): 677 | raise NotImplementedError() 678 | 679 | def ftruncate(self, mu): 680 | raise NotImplementedError() 681 | 682 | def fchmod(self, mu): 683 | raise NotImplementedError() 684 | 685 | def fchown(self, mu): 686 | raise NotImplementedError() 687 | 688 | def getpriority(self, mu): 689 | raise NotImplementedError() 690 | 691 | def setpriority(self, mu): 692 | raise NotImplementedError() 693 | 694 | def statfs(self, mu): 695 | raise NotImplementedError() 696 | 697 | def fstatfs(self, mu): 698 | raise NotImplementedError() 699 | 700 | def syslog(self, mu): 701 | raise NotImplementedError() 702 | 703 | def setitimer(self, mu): 704 | raise NotImplementedError() 705 | 706 | def getitimer(self, mu): 707 | raise NotImplementedError() 708 | 709 | def stat(self, mu): 710 | raise NotImplementedError() 711 | 712 | def lstat(self, mu): 713 | raise NotImplementedError() 714 | 715 | def fstat(self, mu): 716 | raise NotImplementedError() 717 | 718 | def vhangup(self, mu): 719 | raise NotImplementedError() 720 | 721 | def wait4(self, mu): 722 | raise NotImplementedError() 723 | 724 | def swapoff(self, mu): 725 | raise NotImplementedError() 726 | 727 | def sysinfo(self, mu): 728 | raise NotImplementedError() 729 | 730 | def fsync(self, mu): 731 | raise NotImplementedError() 732 | 733 | def sigreturn(self, mu): 734 | raise NotImplementedError() 735 | 736 | def clone(self, mu): 737 | raise NotImplementedError() 738 | 739 | def setdomainname(self, mu): 740 | raise NotImplementedError() 741 | 742 | def uname(self, mu): 743 | raise NotImplementedError() 744 | 745 | def adjtimex(self, mu): 746 | raise NotImplementedError() 747 | 748 | def mprotect(self, mu): 749 | addr = mu.reg_read(UC_ARM_REG_R0) & 0xffffffff 750 | len = mu.reg_read(UC_ARM_REG_R1) 751 | prot = mu.reg_read(UC_ARM_REG_R2) 752 | alignedAddress = int(addr / PAGE_SIZE * PAGE_SIZE) 753 | off = addr - alignedAddress 754 | alignedLen = alignSize(len + off) 755 | logger.debug( 756 | "mprotect address= 0x%X, alignedAddress= 0x%X, offset= %d, length= %d, alignedLength= %d, prot= 0x%X" % ( 757 | addr, alignedAddress, off, len, alignedLen, prot)) 758 | 759 | self.emulator.memory.protect(alignedAddress, alignedLen, prot) 760 | return 0 761 | 762 | def sigprocmask(self, mu): 763 | raise NotImplementedError() 764 | 765 | def init_module(self, mu): 766 | raise NotImplementedError() 767 | 768 | def delete_module(self, mu): 769 | raise NotImplementedError() 770 | 771 | def quotactl(self, mu): 772 | raise NotImplementedError() 773 | 774 | def getpgid(self, mu): 775 | raise NotImplementedError() 776 | 777 | def fchdir(self, mu): 778 | raise NotImplementedError() 779 | 780 | def bdflush(self, mu): 781 | raise NotImplementedError() 782 | 783 | def sysfs(self, mu): 784 | raise NotImplementedError() 785 | 786 | def personality(self, mu): 787 | raise NotImplementedError() 788 | 789 | def setfsuid(self, mu): 790 | raise NotImplementedError() 791 | 792 | def setfsgid(self, mu): 793 | raise NotImplementedError() 794 | 795 | def _llseek(self, mu): 796 | raise NotImplementedError() 797 | 798 | def getdents(self, mu): 799 | raise NotImplementedError() 800 | 801 | def _newselect(self, mu): 802 | raise NotImplementedError() 803 | 804 | def flock(self, mu): 805 | raise NotImplementedError() 806 | 807 | def msync(self, mu): 808 | raise NotImplementedError() 809 | 810 | def readv(self, mu): 811 | raise NotImplementedError() 812 | 813 | def writev(self, mu): 814 | raise NotImplementedError() 815 | 816 | def getsid(self, mu): 817 | raise NotImplementedError() 818 | 819 | def fdatasync(self, mu): 820 | raise NotImplementedError() 821 | 822 | def _sysctl(self, mu): 823 | raise NotImplementedError() 824 | 825 | def mlock(self, mu): 826 | raise NotImplementedError() 827 | 828 | def munlock(self, mu): 829 | raise NotImplementedError() 830 | 831 | def mlockall(self, mu): 832 | raise NotImplementedError() 833 | 834 | def munlockall(self, mu): 835 | raise NotImplementedError() 836 | 837 | def sched_setparam(self, mu): 838 | raise NotImplementedError() 839 | 840 | def sched_getparam(self, mu): 841 | raise NotImplementedError() 842 | 843 | def sched_setscheduler(self, mu): 844 | raise NotImplementedError() 845 | 846 | def sched_getscheduler(self, mu): 847 | raise NotImplementedError() 848 | 849 | def sched_yield(self, mu): 850 | raise NotImplementedError() 851 | 852 | def sched_get_priority_max(self, mu): 853 | raise NotImplementedError() 854 | 855 | def sched_get_priority_min(self, mu): 856 | raise NotImplementedError() 857 | 858 | def sched_rr_get_interval(self, mu): 859 | raise NotImplementedError() 860 | 861 | def nanosleep(self, mu): 862 | raise NotImplementedError() 863 | 864 | def mremap(self, mu): 865 | raise NotImplementedError() 866 | 867 | def setresuid(self, mu): 868 | raise NotImplementedError() 869 | 870 | def getresuid(self, mu): 871 | raise NotImplementedError() 872 | 873 | def poll(self, mu): 874 | raise NotImplementedError() 875 | 876 | def nfsservctl(self, mu): 877 | raise NotImplementedError() 878 | 879 | def setresgid(self, mu): 880 | raise NotImplementedError() 881 | 882 | def getresgid(self, mu): 883 | raise NotImplementedError() 884 | 885 | def prctl(self, mu): 886 | option = mu.reg_read(UC_ARM_REG_R0) 887 | arg2 = mu.reg_read(UC_ARM_REG_R1) & 0xffffffff 888 | logger.debug("prctl option= 0x%X ,arg2= 0x%X" % (option, arg2)) 889 | if option in (PR_SET_DUMPABLE, PR_SET_DUMPABLE): 890 | return 0 891 | if option == PR_SET_NAME: 892 | threadNamePtr = mu.reg_read(UC_ARM_REG_R1) 893 | write_utf8(mu, threadNamePtr, self.emulator.processName) 894 | logger.debug("prctl set thread name: %s" % self.emulator.processName) 895 | return 0 896 | if option == PR_GET_NAME: 897 | threadNamePtr = mu.reg_read(UC_ARM_REG_R1) 898 | name = read_utf8(mu, threadNamePtr) 899 | self.emulator.processName = name 900 | logger.debug("prctl get thread name: %s" % self.emulator.processName) 901 | return 0 902 | if option == BIONIC_PR_SET_VMA: 903 | addr = mu.reg_read(UC_ARM_REG_R2) 904 | len = mu.reg_read(UC_ARM_REG_R3) 905 | ptr = mu.reg_read(UC_ARM_REG_R4) 906 | logger.debug( 907 | "prctl set vma addr= 0x%X, len= %d, pointer= 0x%X, name= %s" % (addr, len, ptr, read_utf8(mu, ptr))) 908 | return 0 909 | if option == PR_SET_PTRACER: 910 | pid = arg2 911 | logger.debug("prctl set ptracer: %d" % pid) 912 | return 0 913 | raise NotImplementedError("Unsupported prctl option= %d" % option) 914 | 915 | def rt_sigreturn(self, mu): 916 | raise NotImplementedError() 917 | 918 | def rt_sigaction(self, mu): 919 | raise NotImplementedError() 920 | 921 | def rt_sigprocmask(self, mu): 922 | raise NotImplementedError() 923 | 924 | def rt_sigpending(self, mu): 925 | raise NotImplementedError() 926 | 927 | def rt_sigtimedwait(self, mu): 928 | raise NotImplementedError() 929 | 930 | def rt_sigqueueinfo(self, mu): 931 | raise NotImplementedError() 932 | 933 | def rt_sigsuspend(self, mu): 934 | raise NotImplementedError() 935 | 936 | def pread64(self, mu): 937 | raise NotImplementedError() 938 | 939 | def pwrite64(self, mu): 940 | raise NotImplementedError() 941 | 942 | def chown(self, mu): 943 | raise NotImplementedError() 944 | 945 | def getcwd(self, mu): 946 | raise NotImplementedError() 947 | 948 | def capget(self, mu): 949 | raise NotImplementedError() 950 | 951 | def capset(self, mu): 952 | raise NotImplementedError() 953 | 954 | def sigaltstack(self, mu): 955 | raise NotImplementedError() 956 | 957 | def sendfile(self, mu): 958 | raise NotImplementedError() 959 | 960 | def vfork(self, mu): 961 | raise NotImplementedError() 962 | 963 | def ugetrlimit(self, mu): 964 | raise NotImplementedError() 965 | 966 | def mmap2(self, mu): 967 | start = mu.reg_read(UC_ARM_REG_R0) & 0xffffffff 968 | len = mu.reg_read(UC_ARM_REG_R1) 969 | prot = mu.reg_read(UC_ARM_REG_R2) 970 | flags = mu.reg_read(UC_ARM_REG_R3) 971 | fd = mu.reg_read(UC_ARM_REG_R4) 972 | offset = mu.reg_read(UC_ARM_REG_R5) << MMAP2_SHIFT 973 | msg = "mmap2 start= 0x%X, length= %d, prot= 0x%X, flags= 0x%X, fd= 0x%x, offset= %d, from= %s" % ( 974 | start, len, prot, flags, fd, offset, ptrStr(self.emulator.linker, getLRPointer(mu))) 975 | logger.debug(msg) 976 | if fd != 0xffffffff: 977 | if fd < 2: 978 | raise NotImplementedError("Unsupported read operation for file descriptor %d." % fd) 979 | if fd not in self.emulator.PCB.FDMaps: 980 | raise NotImplementedError() 981 | return self.emulator.memory.mmap(start, len, prot, fd, offset) 982 | else: 983 | return self.emulator.memory.mmap(start, len, prot) 984 | 985 | def truncate64(self, mu): 986 | raise NotImplementedError() 987 | 988 | def ftruncate64(self, mu): 989 | raise NotImplementedError() 990 | 991 | def stat64(self, mu): 992 | raise NotImplementedError() 993 | 994 | def lstat64(self, mu): 995 | raise NotImplementedError() 996 | 997 | def fstat64(self, mu): 998 | fd = mu.reg_read(UC_ARM_REG_R0) 999 | stat_ptr = mu.reg_read(UC_ARM_REG_R1) 1000 | logger.debug("fstat64 fd= %d, stat= 0x%X" % (fd, stat_ptr)) 1001 | return self.emulator.PCB.fstat(mu, fd, stat_ptr) 1002 | 1003 | def lchown32(self, mu): 1004 | raise NotImplementedError() 1005 | 1006 | def getuid32(self, mu): 1007 | raise NotImplementedError() 1008 | 1009 | def getgid32(self, mu): 1010 | raise NotImplementedError() 1011 | 1012 | def geteuid32(self, mu): 1013 | raise NotImplementedError() 1014 | 1015 | def getegid32(self, mu): 1016 | raise NotImplementedError() 1017 | 1018 | def setreuid32(self, mu): 1019 | raise NotImplementedError() 1020 | 1021 | def setregid32(self, mu): 1022 | raise NotImplementedError() 1023 | 1024 | def getgroups32(self, mu): 1025 | raise NotImplementedError() 1026 | 1027 | def setgroups32(self, mu): 1028 | raise NotImplementedError() 1029 | 1030 | def fchown32(self, mu): 1031 | raise NotImplementedError() 1032 | 1033 | def setresuid32(self, mu): 1034 | raise NotImplementedError() 1035 | 1036 | def getresuid32(self, mu): 1037 | raise NotImplementedError() 1038 | 1039 | def setresgid32(self, mu): 1040 | raise NotImplementedError() 1041 | 1042 | def getresgid32(self, mu): 1043 | raise NotImplementedError() 1044 | 1045 | def chown32(self, mu): 1046 | raise NotImplementedError() 1047 | 1048 | def setuid32(self, mu): 1049 | raise NotImplementedError() 1050 | 1051 | def setgid32(self, mu): 1052 | raise NotImplementedError() 1053 | 1054 | def setfsuid32(self, mu): 1055 | raise NotImplementedError() 1056 | 1057 | def setfsgid32(self, mu): 1058 | raise NotImplementedError() 1059 | 1060 | def getdents64(self, mu): 1061 | raise NotImplementedError() 1062 | 1063 | def pivot_root(self, mu): 1064 | raise NotImplementedError() 1065 | 1066 | def mincore(self, mu): 1067 | raise NotImplementedError() 1068 | 1069 | def madvise(self, mu): 1070 | return 0 1071 | 1072 | def fcntl64(self, mu): 1073 | raise NotImplementedError() 1074 | 1075 | def gettid(self, mu): 1076 | raise NotImplementedError() 1077 | 1078 | def readahead(self, mu): 1079 | raise NotImplementedError() 1080 | 1081 | def setxattr(self, mu): 1082 | raise NotImplementedError() 1083 | 1084 | def lsetxattr(self, mu): 1085 | raise NotImplementedError() 1086 | 1087 | def fsetxattr(self, mu): 1088 | raise NotImplementedError() 1089 | 1090 | def getxattr(self, mu): 1091 | raise NotImplementedError() 1092 | 1093 | def lgetxattr(self, mu): 1094 | raise NotImplementedError() 1095 | 1096 | def fgetxattr(self, mu): 1097 | raise NotImplementedError() 1098 | 1099 | def listxattr(self, mu): 1100 | raise NotImplementedError() 1101 | 1102 | def llistxattr(self, mu): 1103 | raise NotImplementedError() 1104 | 1105 | def flistxattr(self, mu): 1106 | raise NotImplementedError() 1107 | 1108 | def removexattr(self, mu): 1109 | raise NotImplementedError() 1110 | 1111 | def lremovexattr(self, mu): 1112 | raise NotImplementedError() 1113 | 1114 | def fremovexattr(self, mu): 1115 | raise NotImplementedError() 1116 | 1117 | def tkill(self, mu): 1118 | raise NotImplementedError() 1119 | 1120 | def sendfile64(self, mu): 1121 | raise NotImplementedError() 1122 | 1123 | def futex(self, mu): 1124 | uaddr = mu.reg_read(UC_ARM_REG_R0) 1125 | futex_op = mu.reg_read(UC_ARM_REG_R1) 1126 | val = mu.reg_read(UC_ARM_REG_R2) 1127 | old = int.from_bytes((mu.mem_read(uaddr, 4)), byteorder='little') 1128 | op = futex_op & 0x7f 1129 | msg = "futex uaddr= %s , _futexop= %d, op= %d, val= %d, old= %d" % ( 1130 | ptrStr(self.emulator.linker, uaddr), futex_op, op, val, old) 1131 | logger.debug(msg) 1132 | if op == FUTEX_WAIT: 1133 | if old != val: 1134 | raise Exception("old %d val %d" % (old, val)) 1135 | # TODO:未完善 1136 | timeout = mu.reg_read(UC_ARM_REG_R3) 1137 | mytype = val & 0xc000 1138 | shared = val & 0x2000 1139 | logger.debug("futex FUTEX_WAIT mytype= %d , shared= %d, timeout= %d , test= %d " % ( 1140 | mytype, shared, timeout, (mytype | shared))) 1141 | mu.mem_write(uaddr, int(mytype | shared).to_bytes(4, byteorder='little')) 1142 | return 0 1143 | if op == FUTEX_WAKE: 1144 | return 0 1145 | raise NotImplementedError() 1146 | 1147 | def sched_setaffinity(self, mu): 1148 | raise NotImplementedError() 1149 | 1150 | def sched_getaffinity(self, mu): 1151 | raise NotImplementedError() 1152 | 1153 | def io_setup(self, mu): 1154 | raise NotImplementedError() 1155 | 1156 | def io_destroy(self, mu): 1157 | raise NotImplementedError() 1158 | 1159 | def io_getevents(self, mu): 1160 | raise NotImplementedError() 1161 | 1162 | def io_submit(self, mu): 1163 | raise NotImplementedError() 1164 | 1165 | def io_cancel(self, mu): 1166 | raise NotImplementedError() 1167 | 1168 | def exit_group(self, mu): 1169 | raise NotImplementedError() 1170 | 1171 | def lookup_dcookie(self, mu): 1172 | raise NotImplementedError() 1173 | 1174 | def epoll_create(self, mu): 1175 | raise NotImplementedError() 1176 | 1177 | def epoll_ctl(self, mu): 1178 | raise NotImplementedError() 1179 | 1180 | def epoll_wait(self, mu): 1181 | raise NotImplementedError() 1182 | 1183 | def remap_file_pages(self, mu): 1184 | raise NotImplementedError() 1185 | 1186 | def set_tid_address(self, mu): 1187 | raise NotImplementedError() 1188 | 1189 | def timer_create(self, mu): 1190 | raise NotImplementedError() 1191 | 1192 | def timer_settime(self, mu): 1193 | raise NotImplementedError() 1194 | 1195 | def timer_gettime(self, mu): 1196 | raise NotImplementedError() 1197 | 1198 | def timer_getoverrun(self, mu): 1199 | raise NotImplementedError() 1200 | 1201 | def timer_delete(self, mu): 1202 | raise NotImplementedError() 1203 | 1204 | def clock_settime(self, mu): 1205 | raise NotImplementedError() 1206 | 1207 | def clock_gettime(self, mu): 1208 | raise NotImplementedError() 1209 | 1210 | def clock_getres(self, mu): 1211 | raise NotImplementedError() 1212 | 1213 | def clock_nanosleep(self, mu): 1214 | raise NotImplementedError() 1215 | 1216 | def statfs64(self, mu): 1217 | raise NotImplementedError() 1218 | 1219 | def fstatfs64(self, mu): 1220 | raise NotImplementedError() 1221 | 1222 | def tgkill(self, mu): 1223 | raise NotImplementedError() 1224 | 1225 | def utimes(self, mu): 1226 | raise NotImplementedError() 1227 | 1228 | def arm_fadvise64_64(self, mu): 1229 | raise NotImplementedError() 1230 | 1231 | def pciconfig_iobase(self, mu): 1232 | raise NotImplementedError() 1233 | 1234 | def pciconfig_read(self, mu): 1235 | raise NotImplementedError() 1236 | 1237 | def pciconfig_write(self, mu): 1238 | raise NotImplementedError() 1239 | 1240 | def mq_open(self, mu): 1241 | raise NotImplementedError() 1242 | 1243 | def mq_unlink(self, mu): 1244 | raise NotImplementedError() 1245 | 1246 | def mq_timedsend(self, mu): 1247 | raise NotImplementedError() 1248 | 1249 | def mq_timedreceive(self, mu): 1250 | raise NotImplementedError() 1251 | 1252 | def mq_notify(self, mu): 1253 | raise NotImplementedError() 1254 | 1255 | def mq_getsetattr(self, mu): 1256 | raise NotImplementedError() 1257 | 1258 | def waitid(self, mu): 1259 | raise NotImplementedError() 1260 | 1261 | def socket(self, mu): 1262 | raise NotImplementedError() 1263 | 1264 | def bind(self, mu): 1265 | raise NotImplementedError() 1266 | 1267 | def connect(self, mu): 1268 | raise NotImplementedError() 1269 | 1270 | def listen(self, mu): 1271 | raise NotImplementedError() 1272 | 1273 | def accept(self, mu): 1274 | raise NotImplementedError() 1275 | 1276 | def getsockname(self, mu): 1277 | raise NotImplementedError() 1278 | 1279 | def getpeername(self, mu): 1280 | raise NotImplementedError() 1281 | 1282 | def socketpair(self, mu): 1283 | raise NotImplementedError() 1284 | 1285 | def send(self, mu): 1286 | raise NotImplementedError() 1287 | 1288 | def sendto(self, mu): 1289 | raise NotImplementedError() 1290 | 1291 | def recv(self, mu): 1292 | raise NotImplementedError() 1293 | 1294 | def recvfrom(self, mu): 1295 | raise NotImplementedError() 1296 | 1297 | def shutdown(self, mu): 1298 | raise NotImplementedError() 1299 | 1300 | def setsockopt(self, mu): 1301 | raise NotImplementedError() 1302 | 1303 | def getsockopt(self, mu): 1304 | raise NotImplementedError() 1305 | 1306 | def sendmsg(self, mu): 1307 | raise NotImplementedError() 1308 | 1309 | def recvmsg(self, mu): 1310 | raise NotImplementedError() 1311 | 1312 | def semop(self, mu): 1313 | raise NotImplementedError() 1314 | 1315 | def semget(self, mu): 1316 | raise NotImplementedError() 1317 | 1318 | def semctl(self, mu): 1319 | raise NotImplementedError() 1320 | 1321 | def msgsnd(self, mu): 1322 | raise NotImplementedError() 1323 | 1324 | def msgrcv(self, mu): 1325 | raise NotImplementedError() 1326 | 1327 | def msgget(self, mu): 1328 | raise NotImplementedError() 1329 | 1330 | def msgctl(self, mu): 1331 | raise NotImplementedError() 1332 | 1333 | def shmat(self, mu): 1334 | raise NotImplementedError() 1335 | 1336 | def shmdt(self, mu): 1337 | raise NotImplementedError() 1338 | 1339 | def shmget(self, mu): 1340 | raise NotImplementedError() 1341 | 1342 | def shmctl(self, mu): 1343 | raise NotImplementedError() 1344 | 1345 | def add_key(self, mu): 1346 | raise NotImplementedError() 1347 | 1348 | def request_key(self, mu): 1349 | raise NotImplementedError() 1350 | 1351 | def keyctl(self, mu): 1352 | raise NotImplementedError() 1353 | 1354 | def semtimedop(self, mu): 1355 | raise NotImplementedError() 1356 | 1357 | def ioprio_set(self, mu): 1358 | raise NotImplementedError() 1359 | 1360 | def ioprio_get(self, mu): 1361 | raise NotImplementedError() 1362 | 1363 | def inotify_init(self, mu): 1364 | raise NotImplementedError() 1365 | 1366 | def inotify_add_watch(self, mu): 1367 | raise NotImplementedError() 1368 | 1369 | def inotify_rm_watch(self, mu): 1370 | raise NotImplementedError() 1371 | 1372 | def mbind(self, mu): 1373 | raise NotImplementedError() 1374 | 1375 | def get_mempolicy(self, mu): 1376 | raise NotImplementedError() 1377 | 1378 | def set_mempolicy(self, mu): 1379 | raise NotImplementedError() 1380 | 1381 | def openat(self, mu): 1382 | dirfd = mu.reg_read(UC_ARM_REG_R0) 1383 | pathname = read_utf8(mu, mu.reg_read(UC_ARM_REG_R1)) 1384 | oflags = mu.reg_read(UC_ARM_REG_R2) 1385 | mode = mu.reg_read(UC_ARM_REG_R3) 1386 | msg = "openat dirfd= 0x%X, pathname= %s, oflags= 0x%X, mode= 0x%X" % (dirfd, pathname, oflags, mode) 1387 | logger.debug(msg) 1388 | if pathname.startswith("/"): 1389 | fd = self.emulator.PCB.open(self.emulator, pathname, oflags) 1390 | if fd == -1: 1391 | logger.warning(msg) 1392 | return fd 1393 | else: 1394 | if dirfd != -100: 1395 | raise Exception(msg) 1396 | fd = self.emulator.PCB.open(self.emulator, pathname, oflags) 1397 | if fd == -1: 1398 | logger.warning(msg) 1399 | return fd 1400 | 1401 | def mkdirat(self, mu): 1402 | raise NotImplementedError() 1403 | 1404 | def mknodat(self, mu): 1405 | raise NotImplementedError() 1406 | 1407 | def fchownat(self, mu): 1408 | raise NotImplementedError() 1409 | 1410 | def futimesat(self, mu): 1411 | raise NotImplementedError() 1412 | 1413 | def fstatat64(self, mu): 1414 | raise NotImplementedError() 1415 | 1416 | def unlinkat(self, mu): 1417 | raise NotImplementedError() 1418 | 1419 | def renameat(self, mu): 1420 | raise NotImplementedError() 1421 | 1422 | def linkat(self, mu): 1423 | raise NotImplementedError() 1424 | 1425 | def symlinkat(self, mu): 1426 | raise NotImplementedError() 1427 | 1428 | def readlinkat(self, mu): 1429 | raise NotImplementedError() 1430 | 1431 | def fchmodat(self, mu): 1432 | raise NotImplementedError() 1433 | 1434 | def faccessat(self, mu): 1435 | raise NotImplementedError() 1436 | 1437 | def pselect6(self, mu): 1438 | raise NotImplementedError() 1439 | 1440 | def ppoll(self, mu): 1441 | raise NotImplementedError() 1442 | 1443 | def unshare(self, mu): 1444 | raise NotImplementedError() 1445 | 1446 | def set_robust_list(self, mu): 1447 | raise NotImplementedError() 1448 | 1449 | def get_robust_list(self, mu): 1450 | raise NotImplementedError() 1451 | 1452 | def splice(self, mu): 1453 | raise NotImplementedError() 1454 | 1455 | def sync_file_range2(self, mu): 1456 | raise NotImplementedError() 1457 | 1458 | def tee(self, mu): 1459 | raise NotImplementedError() 1460 | 1461 | def vmsplice(self, mu): 1462 | raise NotImplementedError() 1463 | 1464 | def move_pages(self, mu): 1465 | raise NotImplementedError() 1466 | 1467 | def getcpu(self, mu): 1468 | raise NotImplementedError() 1469 | 1470 | def epoll_pwait(self, mu): 1471 | raise NotImplementedError() 1472 | 1473 | def kexec_load(self, mu): 1474 | raise NotImplementedError() 1475 | 1476 | def utimensat(self, mu): 1477 | raise NotImplementedError() 1478 | 1479 | def signalfd(self, mu): 1480 | raise NotImplementedError() 1481 | 1482 | def timerfd_create(self, mu): 1483 | raise NotImplementedError() 1484 | 1485 | def eventfd(self, mu): 1486 | raise NotImplementedError() 1487 | 1488 | def fallocate(self, mu): 1489 | raise NotImplementedError() 1490 | 1491 | def timerfd_settime(self, mu): 1492 | raise NotImplementedError() 1493 | 1494 | def timerfd_gettime(self, mu): 1495 | raise NotImplementedError() 1496 | 1497 | def signalfd4(self, mu): 1498 | raise NotImplementedError() 1499 | 1500 | def eventfd2(self, mu): 1501 | raise NotImplementedError() 1502 | 1503 | def epoll_create1(self, mu): 1504 | raise NotImplementedError() 1505 | 1506 | def dup3(self, mu): 1507 | raise NotImplementedError() 1508 | 1509 | def pipe2(self, mu): 1510 | raise NotImplementedError() 1511 | 1512 | def inotify_init1(self, mu): 1513 | raise NotImplementedError() 1514 | 1515 | def preadv(self, mu): 1516 | raise NotImplementedError() 1517 | 1518 | def pwritev(self, mu): 1519 | raise NotImplementedError() 1520 | 1521 | def rt_tgsigqueueinfo(self, mu): 1522 | raise NotImplementedError() 1523 | 1524 | def perf_event_open(self, mu): 1525 | raise NotImplementedError() 1526 | 1527 | def recvmmsg(self, mu): 1528 | raise NotImplementedError() 1529 | 1530 | def accept4(self, mu): 1531 | raise NotImplementedError() 1532 | 1533 | def fanotify_init(self, mu): 1534 | raise NotImplementedError() 1535 | 1536 | def fanotify_mark(self, mu): 1537 | raise NotImplementedError() 1538 | 1539 | def prlimit64(self, mu): 1540 | raise NotImplementedError() 1541 | 1542 | def name_to_handle_at(self, mu): 1543 | raise NotImplementedError() 1544 | 1545 | def open_by_handle_at(self, mu): 1546 | raise NotImplementedError() 1547 | 1548 | def clock_adjtime(self, mu): 1549 | raise NotImplementedError() 1550 | 1551 | def syncfs(self, mu): 1552 | raise NotImplementedError() 1553 | 1554 | def sendmmsg(self, mu): 1555 | raise NotImplementedError() 1556 | 1557 | def setns(self, mu): 1558 | raise NotImplementedError() 1559 | 1560 | def process_vm_readv(self, mu): 1561 | raise NotImplementedError() 1562 | 1563 | def process_vm_writev(self, mu): 1564 | raise NotImplementedError() 1565 | 1566 | def kcmp(self, mu): 1567 | raise NotImplementedError() 1568 | 1569 | def finit_module(self, mu): 1570 | raise NotImplementedError() 1571 | 1572 | def sched_setattr(self, mu): 1573 | raise NotImplementedError() 1574 | 1575 | def sched_getattr(self, mu): 1576 | raise NotImplementedError() 1577 | 1578 | def renameat2(self, mu): 1579 | raise NotImplementedError() 1580 | 1581 | def seccomp(self, mu): 1582 | raise NotImplementedError() 1583 | 1584 | def getrandom(self, mu): 1585 | raise NotImplementedError() 1586 | 1587 | def memfd_create(self, mu): 1588 | raise NotImplementedError() 1589 | 1590 | def bpf(self, mu): 1591 | raise NotImplementedError() 1592 | 1593 | def execveat(self, mu): 1594 | raise NotImplementedError() 1595 | 1596 | def userfaultfd(self, mu): 1597 | raise NotImplementedError() 1598 | 1599 | def membarrier(self, mu): 1600 | raise NotImplementedError() 1601 | 1602 | def mlock2(self, mu): 1603 | raise NotImplementedError() 1604 | 1605 | def copy_file_range(self, mu): 1606 | raise NotImplementedError() 1607 | 1608 | def preadv2(self, mu): 1609 | raise NotImplementedError() 1610 | 1611 | def pwritev2(self, mu): 1612 | raise NotImplementedError() 1613 | 1614 | def pkey_mprotect(self, mu): 1615 | raise NotImplementedError() 1616 | 1617 | def pkey_alloc(self, mu): 1618 | raise NotImplementedError() 1619 | 1620 | def pkey_free(self, mu): 1621 | raise NotImplementedError() 1622 | 1623 | def statx(self, mu): 1624 | raise NotImplementedError() 1625 | 1626 | def rseq(self, mu): 1627 | raise NotImplementedError() 1628 | 1629 | def io_pgetevents(self, mu): 1630 | raise NotImplementedError() 1631 | 1632 | def migrate_pages(self, mu): 1633 | raise NotImplementedError() 1634 | 1635 | def kexec_file_load(self, mu): 1636 | raise NotImplementedError() 1637 | 1638 | def clock_gettime64(self, mu): 1639 | raise NotImplementedError() 1640 | 1641 | def clock_settime64(self, mu): 1642 | raise NotImplementedError() 1643 | 1644 | def clock_adjtime64(self, mu): 1645 | raise NotImplementedError() 1646 | 1647 | def clock_getres_time64(self, mu): 1648 | raise NotImplementedError() 1649 | 1650 | def clock_nanosleep_time64(self, mu): 1651 | raise NotImplementedError() 1652 | 1653 | def timer_gettime64(self, mu): 1654 | raise NotImplementedError() 1655 | 1656 | def timer_settime64(self, mu): 1657 | raise NotImplementedError() 1658 | 1659 | def timerfd_gettime64(self, mu): 1660 | raise NotImplementedError() 1661 | 1662 | def timerfd_settime64(self, mu): 1663 | raise NotImplementedError() 1664 | 1665 | def utimensat_time64(self, mu): 1666 | raise NotImplementedError() 1667 | 1668 | def pselect6_time64(self, mu): 1669 | raise NotImplementedError() 1670 | 1671 | def ppoll_time64(self, mu): 1672 | raise NotImplementedError() 1673 | 1674 | def io_pgetevents_time64(self, mu): 1675 | raise NotImplementedError() 1676 | 1677 | def recvmmsg_time64(self, mu): 1678 | raise NotImplementedError() 1679 | 1680 | def mq_timedsend_time64(self, mu): 1681 | raise NotImplementedError() 1682 | 1683 | def mq_timedreceive_time64(self, mu): 1684 | raise NotImplementedError() 1685 | 1686 | def semtimedop_time64(self, mu): 1687 | raise NotImplementedError() 1688 | 1689 | def rt_sigtimedwait_time64(self, mu): 1690 | raise NotImplementedError() 1691 | 1692 | def futex_time64(self, mu): 1693 | raise NotImplementedError() 1694 | 1695 | def sched_rr_get_interval_time64(self, mu): 1696 | raise NotImplementedError() 1697 | 1698 | def pidfd_send_signal(self, mu): 1699 | raise NotImplementedError() 1700 | 1701 | def io_uring_setup(self, mu): 1702 | raise NotImplementedError() 1703 | 1704 | def io_uring_enter(self, mu): 1705 | raise NotImplementedError() 1706 | 1707 | def io_uring_register(self, mu): 1708 | raise NotImplementedError() 1709 | 1710 | def open_tree(self, mu): 1711 | raise NotImplementedError() 1712 | 1713 | def move_mount(self, mu): 1714 | raise NotImplementedError() 1715 | 1716 | def fsopen(self, mu): 1717 | raise NotImplementedError() 1718 | 1719 | def fsconfig(self, mu): 1720 | raise NotImplementedError() 1721 | 1722 | def fsmount(self, mu): 1723 | raise NotImplementedError() 1724 | 1725 | def fspick(self, mu): 1726 | raise NotImplementedError() 1727 | 1728 | def pidfd_open(self, mu): 1729 | raise NotImplementedError() 1730 | 1731 | def clone3(self, mu): 1732 | raise NotImplementedError() 1733 | 1734 | def close_range(self, mu): 1735 | raise NotImplementedError() 1736 | 1737 | def openat2(self, mu): 1738 | raise NotImplementedError() 1739 | 1740 | def pidfd_getfd(self, mu): 1741 | raise NotImplementedError() 1742 | 1743 | def faccessat2(self, mu): 1744 | raise NotImplementedError() 1745 | 1746 | def process_madvise(self, mu): 1747 | raise NotImplementedError() 1748 | 1749 | def epoll_pwait2(self, mu): 1750 | raise NotImplementedError() 1751 | 1752 | def mount_setattr(self, mu): 1753 | raise NotImplementedError() 1754 | 1755 | def quotactl_fd(self, mu): 1756 | raise NotImplementedError() 1757 | 1758 | def landlock_create_ruleset(self, mu): 1759 | raise NotImplementedError() 1760 | 1761 | def landlock_add_rule(self, mu): 1762 | raise NotImplementedError() 1763 | 1764 | def landlock_restrict_self(self, mu): 1765 | raise NotImplementedError() 1766 | 1767 | def process_mrelease(self, mu): 1768 | raise NotImplementedError() 1769 | -------------------------------------------------------------------------------- /Emulator/vm/ARM64SyscallHandler.py: -------------------------------------------------------------------------------- 1 | from unicorn import UC_HOOK_INTR 2 | from unicorn.arm64_const import * 3 | 4 | from Emulator.hooks.ARMConst import * 5 | 6 | 7 | class ARM64SyscallHandler: 8 | def __init__(self, emulator): 9 | self.emulator = emulator 10 | self.syscallHandlerMaps = { 11 | 0: self.io_setup, 12 | 1: self.io_destroy, 13 | 2: self.io_submit, 14 | 3: self.io_cancel, 15 | 4: self.io_getevents, 16 | 5: self.setxattr, 17 | 6: self.lsetxattr, 18 | 7: self.fsetxattr, 19 | 8: self.getxattr, 20 | 9: self.lgetxattr, 21 | 10: self.fgetxattr, 22 | 11: self.listxattr, 23 | 12: self.llistxattr, 24 | 13: self.flistxattr, 25 | 14: self.removexattr, 26 | 15: self.lremovexattr, 27 | 16: self.fremovexattr, 28 | 17: self.getcwd, 29 | 18: self.lookup_dcookie, 30 | 19: self.eventfd2, 31 | 20: self.epoll_create1, 32 | 21: self.epoll_ctl, 33 | 22: self.epoll_pwait, 34 | 23: self.dup, 35 | 24: self.dup3, 36 | 25: self.fcntl, 37 | 26: self.inotify_init1, 38 | 27: self.inotify_add_watch, 39 | 28: self.inotify_rm_watch, 40 | 29: self.ioctl, 41 | 30: self.ioprio_set, 42 | 31: self.ioprio_get, 43 | 32: self.flock, 44 | 33: self.mknodat, 45 | 34: self.mkdirat, 46 | 35: self.unlinkat, 47 | 36: self.symlinkat, 48 | 37: self.linkat, 49 | 38: self.renameat, 50 | 39: self.umount2, 51 | 40: self.mount, 52 | 41: self.pivot_root, 53 | 42: self.nfsservctl, 54 | 43: self.statfs, 55 | 44: self.fstatfs, 56 | 45: self.truncate, 57 | 46: self.ftruncate, 58 | 47: self.fallocate, 59 | 48: self.faccessat, 60 | 49: self.chdir, 61 | 50: self.fchdir, 62 | 51: self.chroot, 63 | 52: self.fchmod, 64 | 53: self.fchmodat, 65 | 54: self.fchownat, 66 | 55: self.fchown, 67 | 56: self.openat, 68 | 57: self.close, 69 | 58: self.vhangup, 70 | 59: self.pipe2, 71 | 60: self.quotactl, 72 | 61: self.getdents64, 73 | 62: self.lseek, 74 | 63: self.read, 75 | 64: self.write, 76 | 65: self.readv, 77 | 66: self.writev, 78 | 67: self.pread64, 79 | 68: self.pwrite64, 80 | 69: self.preadv, 81 | 70: self.pwritev, 82 | 71: self.sendfile, 83 | 72: self.pselect6, 84 | 73: self.ppoll, 85 | 74: self.signalfd4, 86 | 75: self.vmsplice, 87 | 76: self.splice, 88 | 77: self.tee, 89 | 78: self.readlinkat, 90 | 79: self.newfstatat, 91 | 80: self.fstat, 92 | 81: self.sync, 93 | 82: self.fsync, 94 | 83: self.fdatasync, 95 | 84: self.sync_file_range, 96 | 85: self.timerfd_create, 97 | 86: self.timerfd_settime, 98 | 87: self.timerfd_gettime, 99 | 88: self.utimensat, 100 | 89: self.acct, 101 | 90: self.capget, 102 | 91: self.capset, 103 | 92: self.personality, 104 | 93: self.exit, 105 | 94: self.exit_group, 106 | 95: self.waitid, 107 | 96: self.set_tid_address, 108 | 97: self.unshare, 109 | 98: self.futex, 110 | 99: self.set_robust_list, 111 | 100: self.get_robust_list, 112 | 101: self.nanosleep, 113 | 102: self.getitimer, 114 | 103: self.setitimer, 115 | 104: self.kexec_load, 116 | 105: self.init_module, 117 | 106: self.delete_module, 118 | 107: self.timer_create, 119 | 108: self.timer_gettime, 120 | 109: self.timer_getoverrun, 121 | 110: self.timer_settime, 122 | 111: self.timer_delete, 123 | 112: self.clock_settime, 124 | 113: self.clock_gettime, 125 | 114: self.clock_getres, 126 | 115: self.clock_nanosleep, 127 | 116: self.syslog, 128 | 117: self.ptrace, 129 | 118: self.sched_setparam, 130 | 119: self.sched_setscheduler, 131 | 120: self.sched_getscheduler, 132 | 121: self.sched_getparam, 133 | 122: self.sched_setaffinity, 134 | 123: self.sched_getaffinity, 135 | 124: self.sched_yield, 136 | 125: self.sched_get_priority_max, 137 | 126: self.sched_get_priority_min, 138 | 127: self.sched_rr_get_interval, 139 | 128: self.restart_syscall, 140 | 129: self.kill, 141 | 130: self.tkill, 142 | 131: self.tgkill, 143 | 132: self.sigaltstack, 144 | 133: self.rt_sigsuspend, 145 | 134: self.rt_sigaction, 146 | 135: self.rt_sigprocmask, 147 | 136: self.rt_sigpending, 148 | 137: self.rt_sigtimedwait, 149 | 138: self.rt_sigqueueinfo, 150 | 139: self.rt_sigreturn, 151 | 140: self.setpriority, 152 | 141: self.getpriority, 153 | 142: self.reboot, 154 | 143: self.setregid, 155 | 144: self.setgid, 156 | 145: self.setreuid, 157 | 146: self.setuid, 158 | 147: self.setresuid, 159 | 148: self.getresuid, 160 | 149: self.setresgid, 161 | 150: self.getresgid, 162 | 151: self.setfsuid, 163 | 152: self.setfsgid, 164 | 153: self.times, 165 | 154: self.setpgid, 166 | 155: self.getpgid, 167 | 156: self.getsid, 168 | 157: self.setsid, 169 | 158: self.getgroups, 170 | 159: self.setgroups, 171 | 160: self.uname, 172 | 161: self.sethostname, 173 | 162: self.setdomainname, 174 | 163: self.getrlimit, 175 | 164: self.setrlimit, 176 | 165: self.getrusage, 177 | 166: self.umask, 178 | 167: self.prctl, 179 | 168: self.getcpu, 180 | 169: self.gettimeofday, 181 | 170: self.settimeofday, 182 | 171: self.adjtimex, 183 | 172: self.getpid, 184 | 173: self.getppid, 185 | 174: self.getuid, 186 | 175: self.geteuid, 187 | 176: self.getgid, 188 | 177: self.getegid, 189 | 178: self.gettid, 190 | 179: self.sysinfo, 191 | 180: self.mq_open, 192 | 181: self.mq_unlink, 193 | 182: self.mq_timedsend, 194 | 183: self.mq_timedreceive, 195 | 184: self.mq_notify, 196 | 185: self.mq_getsetattr, 197 | 186: self.msgget, 198 | 187: self.msgctl, 199 | 188: self.msgrcv, 200 | 189: self.msgsnd, 201 | 190: self.semget, 202 | 191: self.semctl, 203 | 192: self.semtimedop, 204 | 193: self.semop, 205 | 194: self.shmget, 206 | 195: self.shmctl, 207 | 196: self.shmat, 208 | 197: self.shmdt, 209 | 198: self.socket, 210 | 199: self.socketpair, 211 | 200: self.bind, 212 | 201: self.listen, 213 | 202: self.accept, 214 | 203: self.connect, 215 | 204: self.getsockname, 216 | 205: self.getpeername, 217 | 206: self.sendto, 218 | 207: self.recvfrom, 219 | 208: self.setsockopt, 220 | 209: self.getsockopt, 221 | 210: self.shutdown, 222 | 211: self.sendmsg, 223 | 212: self.recvmsg, 224 | 213: self.readahead, 225 | 214: self.brk, 226 | 215: self.munmap, 227 | 216: self.mremap, 228 | 217: self.add_key, 229 | 218: self.request_key, 230 | 219: self.keyctl, 231 | 220: self.clone, 232 | 221: self.execve, 233 | 222: self.mmap, 234 | 223: self.fadvise64, 235 | 224: self.swapon, 236 | 225: self.swapoff, 237 | 226: self.mprotect, 238 | 227: self.msync, 239 | 228: self.mlock, 240 | 229: self.munlock, 241 | 230: self.mlockall, 242 | 231: self.munlockall, 243 | 232: self.mincore, 244 | 233: self.madvise, 245 | 234: self.remap_file_pages, 246 | 235: self.mbind, 247 | 236: self.get_mempolicy, 248 | 237: self.set_mempolicy, 249 | 238: self.migrate_pages, 250 | 239: self.move_pages, 251 | 240: self.rt_tgsigqueueinfo, 252 | 241: self.perf_event_open, 253 | 242: self.accept4, 254 | 243: self.recvmmsg, 255 | 260: self.wait4, 256 | 261: self.prlimit64, 257 | 262: self.fanotify_init, 258 | 263: self.fanotify_mark, 259 | 264: self.name_to_handle_at, 260 | 265: self.open_by_handle_at, 261 | 266: self.clock_adjtime, 262 | 267: self.syncfs, 263 | 268: self.setns, 264 | 269: self.sendmmsg, 265 | 270: self.process_vm_readv, 266 | 271: self.process_vm_writev, 267 | 272: self.kcmp, 268 | 273: self.finit_module, 269 | 274: self.sched_setattr, 270 | 275: self.sched_getattr, 271 | 276: self.renameat2, 272 | 277: self.seccomp, 273 | 278: self.getrandom, 274 | 279: self.memfd_create, 275 | 280: self.bpf, 276 | 281: self.execveat, 277 | 282: self.userfaultfd, 278 | 283: self.membarrier, 279 | 284: self.mlock2, 280 | 285: self.copy_file_range, 281 | 286: self.preadv2, 282 | 287: self.pwritev2, 283 | 288: self.pkey_mprotect, 284 | 289: self.pkey_alloc, 285 | 290: self.pkey_free, 286 | 291: self.statx, 287 | 292: self.io_pgetevents, 288 | 293: self.rseq, 289 | 294: self.kexec_file_load, 290 | 424: self.pidfd_send_signal, 291 | 425: self.io_uring_setup, 292 | 426: self.io_uring_enter, 293 | 427: self.io_uring_register, 294 | 428: self.open_tree, 295 | 429: self.move_mount, 296 | 430: self.fsopen, 297 | 431: self.fsconfig, 298 | 432: self.fsmount, 299 | 433: self.fspick, 300 | 434: self.pidfd_open, 301 | 435: self.clone3, 302 | 436: self.close_range, 303 | 437: self.openat2, 304 | 438: self.pidfd_getfd, 305 | 439: self.faccessat2, 306 | 440: self.process_madvise, 307 | 441: self.epoll_pwait2, 308 | 442: self.mount_setattr, 309 | 443: self.quotactl_fd, 310 | 444: self.landlock_create_ruleset, 311 | 445: self.landlock_add_rule, 312 | 446: self.landlock_restrict_self, 313 | 447: self.memfd_secret, 314 | 448: self.process_mrelease 315 | } 316 | self.emulator.mu.hook_add(UC_HOOK_INTR, self.hook) 317 | 318 | def hook(self, mu, intno, userdata): 319 | # 断点 320 | pc = mu.reg_read(UC_ARM64_REG_PC) 321 | swi = (int.from_bytes(mu.mem_read(pc - 4, 4), byteorder='little') >> 5) & 0xff 322 | if intno == EXCP_BKPT: 323 | return 324 | if intno != EXCP_SWI: 325 | mu.emu_stop() 326 | raise Exception("Unhandled interrupt %d" % intno) 327 | NR = mu.reg_read(UC_ARM64_REG_X8) 328 | if swi != 0: 329 | if swi in self.emulator.hooker.hookMaps: 330 | mu.reg_write(UC_ARM64_REG_X0, self.emulator.hooker.hookMaps[swi](mu)) 331 | return 332 | mu.emu_stop() 333 | raise Exception("Unhandled svcHook %d" % swi) 334 | if NR in self.syscallHandlerMaps: 335 | mu.reg_write(UC_ARM64_REG_X0, self.syscallHandlerMaps[NR](mu)) 336 | return 337 | mu.emu_stop() 338 | raise Exception("Unhandled svc %d" % NR) 339 | 340 | def io_setup(self, mu): 341 | raise NotImplementedError() 342 | 343 | def io_destroy(self, mu): 344 | raise NotImplementedError() 345 | 346 | def io_submit(self, mu): 347 | raise NotImplementedError() 348 | 349 | def io_cancel(self, mu): 350 | raise NotImplementedError() 351 | 352 | def io_getevents(self, mu): 353 | raise NotImplementedError() 354 | 355 | def setxattr(self, mu): 356 | raise NotImplementedError() 357 | 358 | def lsetxattr(self, mu): 359 | raise NotImplementedError() 360 | 361 | def fsetxattr(self, mu): 362 | raise NotImplementedError() 363 | 364 | def getxattr(self, mu): 365 | raise NotImplementedError() 366 | 367 | def lgetxattr(self, mu): 368 | raise NotImplementedError() 369 | 370 | def fgetxattr(self, mu): 371 | raise NotImplementedError() 372 | 373 | def listxattr(self, mu): 374 | raise NotImplementedError() 375 | 376 | def llistxattr(self, mu): 377 | raise NotImplementedError() 378 | 379 | def flistxattr(self, mu): 380 | raise NotImplementedError() 381 | 382 | def removexattr(self, mu): 383 | raise NotImplementedError() 384 | 385 | def lremovexattr(self, mu): 386 | raise NotImplementedError() 387 | 388 | def fremovexattr(self, mu): 389 | raise NotImplementedError() 390 | 391 | def getcwd(self, mu): 392 | raise NotImplementedError() 393 | 394 | def lookup_dcookie(self, mu): 395 | raise NotImplementedError() 396 | 397 | def eventfd2(self, mu): 398 | raise NotImplementedError() 399 | 400 | def epoll_create1(self, mu): 401 | raise NotImplementedError() 402 | 403 | def epoll_ctl(self, mu): 404 | raise NotImplementedError() 405 | 406 | def epoll_pwait(self, mu): 407 | raise NotImplementedError() 408 | 409 | def dup(self, mu): 410 | raise NotImplementedError() 411 | 412 | def dup3(self, mu): 413 | raise NotImplementedError() 414 | 415 | def fcntl(self, mu): 416 | raise NotImplementedError() 417 | 418 | def inotify_init1(self, mu): 419 | raise NotImplementedError() 420 | 421 | def inotify_add_watch(self, mu): 422 | raise NotImplementedError() 423 | 424 | def inotify_rm_watch(self, mu): 425 | raise NotImplementedError() 426 | 427 | def ioctl(self, mu): 428 | raise NotImplementedError() 429 | 430 | def ioprio_set(self, mu): 431 | raise NotImplementedError() 432 | 433 | def ioprio_get(self, mu): 434 | raise NotImplementedError() 435 | 436 | def flock(self, mu): 437 | raise NotImplementedError() 438 | 439 | def mknodat(self, mu): 440 | raise NotImplementedError() 441 | 442 | def mkdirat(self, mu): 443 | raise NotImplementedError() 444 | 445 | def unlinkat(self, mu): 446 | raise NotImplementedError() 447 | 448 | def symlinkat(self, mu): 449 | raise NotImplementedError() 450 | 451 | def linkat(self, mu): 452 | raise NotImplementedError() 453 | 454 | def renameat(self, mu): 455 | raise NotImplementedError() 456 | 457 | def umount2(self, mu): 458 | raise NotImplementedError() 459 | 460 | def mount(self, mu): 461 | raise NotImplementedError() 462 | 463 | def pivot_root(self, mu): 464 | raise NotImplementedError() 465 | 466 | def nfsservctl(self, mu): 467 | raise NotImplementedError() 468 | 469 | def statfs(self, mu): 470 | raise NotImplementedError() 471 | 472 | def fstatfs(self, mu): 473 | raise NotImplementedError() 474 | 475 | def truncate(self, mu): 476 | raise NotImplementedError() 477 | 478 | def ftruncate(self, mu): 479 | raise NotImplementedError() 480 | 481 | def fallocate(self, mu): 482 | raise NotImplementedError() 483 | 484 | def faccessat(self, mu): 485 | raise NotImplementedError() 486 | 487 | def chdir(self, mu): 488 | raise NotImplementedError() 489 | 490 | def fchdir(self, mu): 491 | raise NotImplementedError() 492 | 493 | def chroot(self, mu): 494 | raise NotImplementedError() 495 | 496 | def fchmod(self, mu): 497 | raise NotImplementedError() 498 | 499 | def fchmodat(self, mu): 500 | raise NotImplementedError() 501 | 502 | def fchownat(self, mu): 503 | raise NotImplementedError() 504 | 505 | def fchown(self, mu): 506 | raise NotImplementedError() 507 | 508 | def openat(self, mu): 509 | raise NotImplementedError() 510 | 511 | def close(self, mu): 512 | raise NotImplementedError() 513 | 514 | def vhangup(self, mu): 515 | raise NotImplementedError() 516 | 517 | def pipe2(self, mu): 518 | raise NotImplementedError() 519 | 520 | def quotactl(self, mu): 521 | raise NotImplementedError() 522 | 523 | def getdents64(self, mu): 524 | raise NotImplementedError() 525 | 526 | def lseek(self, mu): 527 | raise NotImplementedError() 528 | 529 | def read(self, mu): 530 | raise NotImplementedError() 531 | 532 | def write(self, mu): 533 | raise NotImplementedError() 534 | 535 | def readv(self, mu): 536 | raise NotImplementedError() 537 | 538 | def writev(self, mu): 539 | raise NotImplementedError() 540 | 541 | def pread64(self, mu): 542 | raise NotImplementedError() 543 | 544 | def pwrite64(self, mu): 545 | raise NotImplementedError() 546 | 547 | def preadv(self, mu): 548 | raise NotImplementedError() 549 | 550 | def pwritev(self, mu): 551 | raise NotImplementedError() 552 | 553 | def sendfile(self, mu): 554 | raise NotImplementedError() 555 | 556 | def pselect6(self, mu): 557 | raise NotImplementedError() 558 | 559 | def ppoll(self, mu): 560 | raise NotImplementedError() 561 | 562 | def signalfd4(self, mu): 563 | raise NotImplementedError() 564 | 565 | def vmsplice(self, mu): 566 | raise NotImplementedError() 567 | 568 | def splice(self, mu): 569 | raise NotImplementedError() 570 | 571 | def tee(self, mu): 572 | raise NotImplementedError() 573 | 574 | def readlinkat(self, mu): 575 | raise NotImplementedError() 576 | 577 | def newfstatat(self, mu): 578 | raise NotImplementedError() 579 | 580 | def fstat(self, mu): 581 | raise NotImplementedError() 582 | 583 | def sync(self, mu): 584 | raise NotImplementedError() 585 | 586 | def fsync(self, mu): 587 | raise NotImplementedError() 588 | 589 | def fdatasync(self, mu): 590 | raise NotImplementedError() 591 | 592 | def sync_file_range(self, mu): 593 | raise NotImplementedError() 594 | 595 | def timerfd_create(self, mu): 596 | raise NotImplementedError() 597 | 598 | def timerfd_settime(self, mu): 599 | raise NotImplementedError() 600 | 601 | def timerfd_gettime(self, mu): 602 | raise NotImplementedError() 603 | 604 | def utimensat(self, mu): 605 | raise NotImplementedError() 606 | 607 | def acct(self, mu): 608 | raise NotImplementedError() 609 | 610 | def capget(self, mu): 611 | raise NotImplementedError() 612 | 613 | def capset(self, mu): 614 | raise NotImplementedError() 615 | 616 | def personality(self, mu): 617 | raise NotImplementedError() 618 | 619 | def exit(self, mu): 620 | raise NotImplementedError() 621 | 622 | def exit_group(self, mu): 623 | raise NotImplementedError() 624 | 625 | def waitid(self, mu): 626 | raise NotImplementedError() 627 | 628 | def set_tid_address(self, mu): 629 | raise NotImplementedError() 630 | 631 | def unshare(self, mu): 632 | raise NotImplementedError() 633 | 634 | def futex(self, mu): 635 | raise NotImplementedError() 636 | 637 | def set_robust_list(self, mu): 638 | raise NotImplementedError() 639 | 640 | def get_robust_list(self, mu): 641 | raise NotImplementedError() 642 | 643 | def nanosleep(self, mu): 644 | raise NotImplementedError() 645 | 646 | def getitimer(self, mu): 647 | raise NotImplementedError() 648 | 649 | def setitimer(self, mu): 650 | raise NotImplementedError() 651 | 652 | def kexec_load(self, mu): 653 | raise NotImplementedError() 654 | 655 | def init_module(self, mu): 656 | raise NotImplementedError() 657 | 658 | def delete_module(self, mu): 659 | raise NotImplementedError() 660 | 661 | def timer_create(self, mu): 662 | raise NotImplementedError() 663 | 664 | def timer_gettime(self, mu): 665 | raise NotImplementedError() 666 | 667 | def timer_getoverrun(self, mu): 668 | raise NotImplementedError() 669 | 670 | def timer_settime(self, mu): 671 | raise NotImplementedError() 672 | 673 | def timer_delete(self, mu): 674 | raise NotImplementedError() 675 | 676 | def clock_settime(self, mu): 677 | raise NotImplementedError() 678 | 679 | def clock_gettime(self, mu): 680 | raise NotImplementedError() 681 | 682 | def clock_getres(self, mu): 683 | raise NotImplementedError() 684 | 685 | def clock_nanosleep(self, mu): 686 | raise NotImplementedError() 687 | 688 | def syslog(self, mu): 689 | raise NotImplementedError() 690 | 691 | def ptrace(self, mu): 692 | raise NotImplementedError() 693 | 694 | def sched_setparam(self, mu): 695 | raise NotImplementedError() 696 | 697 | def sched_setscheduler(self, mu): 698 | raise NotImplementedError() 699 | 700 | def sched_getscheduler(self, mu): 701 | raise NotImplementedError() 702 | 703 | def sched_getparam(self, mu): 704 | raise NotImplementedError() 705 | 706 | def sched_setaffinity(self, mu): 707 | raise NotImplementedError() 708 | 709 | def sched_getaffinity(self, mu): 710 | raise NotImplementedError() 711 | 712 | def sched_yield(self, mu): 713 | raise NotImplementedError() 714 | 715 | def sched_get_priority_max(self, mu): 716 | raise NotImplementedError() 717 | 718 | def sched_get_priority_min(self, mu): 719 | raise NotImplementedError() 720 | 721 | def sched_rr_get_interval(self, mu): 722 | raise NotImplementedError() 723 | 724 | def restart_syscall(self, mu): 725 | raise NotImplementedError() 726 | 727 | def kill(self, mu): 728 | raise NotImplementedError() 729 | 730 | def tkill(self, mu): 731 | raise NotImplementedError() 732 | 733 | def tgkill(self, mu): 734 | raise NotImplementedError() 735 | 736 | def sigaltstack(self, mu): 737 | raise NotImplementedError() 738 | 739 | def rt_sigsuspend(self, mu): 740 | raise NotImplementedError() 741 | 742 | def rt_sigaction(self, mu): 743 | raise NotImplementedError() 744 | 745 | def rt_sigprocmask(self, mu): 746 | raise NotImplementedError() 747 | 748 | def rt_sigpending(self, mu): 749 | raise NotImplementedError() 750 | 751 | def rt_sigtimedwait(self, mu): 752 | raise NotImplementedError() 753 | 754 | def rt_sigqueueinfo(self, mu): 755 | raise NotImplementedError() 756 | 757 | def rt_sigreturn(self, mu): 758 | raise NotImplementedError() 759 | 760 | def setpriority(self, mu): 761 | raise NotImplementedError() 762 | 763 | def getpriority(self, mu): 764 | raise NotImplementedError() 765 | 766 | def reboot(self, mu): 767 | raise NotImplementedError() 768 | 769 | def setregid(self, mu): 770 | raise NotImplementedError() 771 | 772 | def setgid(self, mu): 773 | raise NotImplementedError() 774 | 775 | def setreuid(self, mu): 776 | raise NotImplementedError() 777 | 778 | def setuid(self, mu): 779 | raise NotImplementedError() 780 | 781 | def setresuid(self, mu): 782 | raise NotImplementedError() 783 | 784 | def getresuid(self, mu): 785 | raise NotImplementedError() 786 | 787 | def setresgid(self, mu): 788 | raise NotImplementedError() 789 | 790 | def getresgid(self, mu): 791 | raise NotImplementedError() 792 | 793 | def setfsuid(self, mu): 794 | raise NotImplementedError() 795 | 796 | def setfsgid(self, mu): 797 | raise NotImplementedError() 798 | 799 | def times(self, mu): 800 | raise NotImplementedError() 801 | 802 | def setpgid(self, mu): 803 | raise NotImplementedError() 804 | 805 | def getpgid(self, mu): 806 | raise NotImplementedError() 807 | 808 | def getsid(self, mu): 809 | raise NotImplementedError() 810 | 811 | def setsid(self, mu): 812 | raise NotImplementedError() 813 | 814 | def getgroups(self, mu): 815 | raise NotImplementedError() 816 | 817 | def setgroups(self, mu): 818 | raise NotImplementedError() 819 | 820 | def uname(self, mu): 821 | raise NotImplementedError() 822 | 823 | def sethostname(self, mu): 824 | raise NotImplementedError() 825 | 826 | def setdomainname(self, mu): 827 | raise NotImplementedError() 828 | 829 | def getrlimit(self, mu): 830 | raise NotImplementedError() 831 | 832 | def setrlimit(self, mu): 833 | raise NotImplementedError() 834 | 835 | def getrusage(self, mu): 836 | raise NotImplementedError() 837 | 838 | def umask(self, mu): 839 | raise NotImplementedError() 840 | 841 | def prctl(self, mu): 842 | raise NotImplementedError() 843 | 844 | def getcpu(self, mu): 845 | raise NotImplementedError() 846 | 847 | def gettimeofday(self, mu): 848 | raise NotImplementedError() 849 | 850 | def settimeofday(self, mu): 851 | raise NotImplementedError() 852 | 853 | def adjtimex(self, mu): 854 | raise NotImplementedError() 855 | 856 | def getpid(self, mu): 857 | raise NotImplementedError() 858 | 859 | def getppid(self, mu): 860 | raise NotImplementedError() 861 | 862 | def getuid(self, mu): 863 | raise NotImplementedError() 864 | 865 | def geteuid(self, mu): 866 | raise NotImplementedError() 867 | 868 | def getgid(self, mu): 869 | raise NotImplementedError() 870 | 871 | def getegid(self, mu): 872 | raise NotImplementedError() 873 | 874 | def gettid(self, mu): 875 | raise NotImplementedError() 876 | 877 | def sysinfo(self, mu): 878 | raise NotImplementedError() 879 | 880 | def mq_open(self, mu): 881 | raise NotImplementedError() 882 | 883 | def mq_unlink(self, mu): 884 | raise NotImplementedError() 885 | 886 | def mq_timedsend(self, mu): 887 | raise NotImplementedError() 888 | 889 | def mq_timedreceive(self, mu): 890 | raise NotImplementedError() 891 | 892 | def mq_notify(self, mu): 893 | raise NotImplementedError() 894 | 895 | def mq_getsetattr(self, mu): 896 | raise NotImplementedError() 897 | 898 | def msgget(self, mu): 899 | raise NotImplementedError() 900 | 901 | def msgctl(self, mu): 902 | raise NotImplementedError() 903 | 904 | def msgrcv(self, mu): 905 | raise NotImplementedError() 906 | 907 | def msgsnd(self, mu): 908 | raise NotImplementedError() 909 | 910 | def semget(self, mu): 911 | raise NotImplementedError() 912 | 913 | def semctl(self, mu): 914 | raise NotImplementedError() 915 | 916 | def semtimedop(self, mu): 917 | raise NotImplementedError() 918 | 919 | def semop(self, mu): 920 | raise NotImplementedError() 921 | 922 | def shmget(self, mu): 923 | raise NotImplementedError() 924 | 925 | def shmctl(self, mu): 926 | raise NotImplementedError() 927 | 928 | def shmat(self, mu): 929 | raise NotImplementedError() 930 | 931 | def shmdt(self, mu): 932 | raise NotImplementedError() 933 | 934 | def socket(self, mu): 935 | raise NotImplementedError() 936 | 937 | def socketpair(self, mu): 938 | raise NotImplementedError() 939 | 940 | def bind(self, mu): 941 | raise NotImplementedError() 942 | 943 | def listen(self, mu): 944 | raise NotImplementedError() 945 | 946 | def accept(self, mu): 947 | raise NotImplementedError() 948 | 949 | def connect(self, mu): 950 | raise NotImplementedError() 951 | 952 | def getsockname(self, mu): 953 | raise NotImplementedError() 954 | 955 | def getpeername(self, mu): 956 | raise NotImplementedError() 957 | 958 | def sendto(self, mu): 959 | raise NotImplementedError() 960 | 961 | def recvfrom(self, mu): 962 | raise NotImplementedError() 963 | 964 | def setsockopt(self, mu): 965 | raise NotImplementedError() 966 | 967 | def getsockopt(self, mu): 968 | raise NotImplementedError() 969 | 970 | def shutdown(self, mu): 971 | raise NotImplementedError() 972 | 973 | def sendmsg(self, mu): 974 | raise NotImplementedError() 975 | 976 | def recvmsg(self, mu): 977 | raise NotImplementedError() 978 | 979 | def readahead(self, mu): 980 | raise NotImplementedError() 981 | 982 | def brk(self, mu): 983 | raise NotImplementedError() 984 | 985 | def munmap(self, mu): 986 | raise NotImplementedError() 987 | 988 | def mremap(self, mu): 989 | raise NotImplementedError() 990 | 991 | def add_key(self, mu): 992 | raise NotImplementedError() 993 | 994 | def request_key(self, mu): 995 | raise NotImplementedError() 996 | 997 | def keyctl(self, mu): 998 | raise NotImplementedError() 999 | 1000 | def clone(self, mu): 1001 | raise NotImplementedError() 1002 | 1003 | def execve(self, mu): 1004 | raise NotImplementedError() 1005 | 1006 | def mmap(self, mu): 1007 | raise NotImplementedError() 1008 | 1009 | def fadvise64(self, mu): 1010 | raise NotImplementedError() 1011 | 1012 | def swapon(self, mu): 1013 | raise NotImplementedError() 1014 | 1015 | def swapoff(self, mu): 1016 | raise NotImplementedError() 1017 | 1018 | def mprotect(self, mu): 1019 | raise NotImplementedError() 1020 | 1021 | def msync(self, mu): 1022 | raise NotImplementedError() 1023 | 1024 | def mlock(self, mu): 1025 | raise NotImplementedError() 1026 | 1027 | def munlock(self, mu): 1028 | raise NotImplementedError() 1029 | 1030 | def mlockall(self, mu): 1031 | raise NotImplementedError() 1032 | 1033 | def munlockall(self, mu): 1034 | raise NotImplementedError() 1035 | 1036 | def mincore(self, mu): 1037 | raise NotImplementedError() 1038 | 1039 | def madvise(self, mu): 1040 | raise NotImplementedError() 1041 | 1042 | def remap_file_pages(self, mu): 1043 | raise NotImplementedError() 1044 | 1045 | def mbind(self, mu): 1046 | raise NotImplementedError() 1047 | 1048 | def get_mempolicy(self, mu): 1049 | raise NotImplementedError() 1050 | 1051 | def set_mempolicy(self, mu): 1052 | raise NotImplementedError() 1053 | 1054 | def migrate_pages(self, mu): 1055 | raise NotImplementedError() 1056 | 1057 | def move_pages(self, mu): 1058 | raise NotImplementedError() 1059 | 1060 | def rt_tgsigqueueinfo(self, mu): 1061 | raise NotImplementedError() 1062 | 1063 | def perf_event_open(self, mu): 1064 | raise NotImplementedError() 1065 | 1066 | def accept4(self, mu): 1067 | raise NotImplementedError() 1068 | 1069 | def recvmmsg(self, mu): 1070 | raise NotImplementedError() 1071 | 1072 | def wait4(self, mu): 1073 | raise NotImplementedError() 1074 | 1075 | def prlimit64(self, mu): 1076 | raise NotImplementedError() 1077 | 1078 | def fanotify_init(self, mu): 1079 | raise NotImplementedError() 1080 | 1081 | def fanotify_mark(self, mu): 1082 | raise NotImplementedError() 1083 | 1084 | def name_to_handle_at(self, mu): 1085 | raise NotImplementedError() 1086 | 1087 | def open_by_handle_at(self, mu): 1088 | raise NotImplementedError() 1089 | 1090 | def clock_adjtime(self, mu): 1091 | raise NotImplementedError() 1092 | 1093 | def syncfs(self, mu): 1094 | raise NotImplementedError() 1095 | 1096 | def setns(self, mu): 1097 | raise NotImplementedError() 1098 | 1099 | def sendmmsg(self, mu): 1100 | raise NotImplementedError() 1101 | 1102 | def process_vm_readv(self, mu): 1103 | raise NotImplementedError() 1104 | 1105 | def process_vm_writev(self, mu): 1106 | raise NotImplementedError() 1107 | 1108 | def kcmp(self, mu): 1109 | raise NotImplementedError() 1110 | 1111 | def finit_module(self, mu): 1112 | raise NotImplementedError() 1113 | 1114 | def sched_setattr(self, mu): 1115 | raise NotImplementedError() 1116 | 1117 | def sched_getattr(self, mu): 1118 | raise NotImplementedError() 1119 | 1120 | def renameat2(self, mu): 1121 | raise NotImplementedError() 1122 | 1123 | def seccomp(self, mu): 1124 | raise NotImplementedError() 1125 | 1126 | def getrandom(self, mu): 1127 | raise NotImplementedError() 1128 | 1129 | def memfd_create(self, mu): 1130 | raise NotImplementedError() 1131 | 1132 | def bpf(self, mu): 1133 | raise NotImplementedError() 1134 | 1135 | def execveat(self, mu): 1136 | raise NotImplementedError() 1137 | 1138 | def userfaultfd(self, mu): 1139 | raise NotImplementedError() 1140 | 1141 | def membarrier(self, mu): 1142 | raise NotImplementedError() 1143 | 1144 | def mlock2(self, mu): 1145 | raise NotImplementedError() 1146 | 1147 | def copy_file_range(self, mu): 1148 | raise NotImplementedError() 1149 | 1150 | def preadv2(self, mu): 1151 | raise NotImplementedError() 1152 | 1153 | def pwritev2(self, mu): 1154 | raise NotImplementedError() 1155 | 1156 | def pkey_mprotect(self, mu): 1157 | raise NotImplementedError() 1158 | 1159 | def pkey_alloc(self, mu): 1160 | raise NotImplementedError() 1161 | 1162 | def pkey_free(self, mu): 1163 | raise NotImplementedError() 1164 | 1165 | def statx(self, mu): 1166 | raise NotImplementedError() 1167 | 1168 | def io_pgetevents(self, mu): 1169 | raise NotImplementedError() 1170 | 1171 | def rseq(self, mu): 1172 | raise NotImplementedError() 1173 | 1174 | def kexec_file_load(self, mu): 1175 | raise NotImplementedError() 1176 | 1177 | def pidfd_send_signal(self, mu): 1178 | raise NotImplementedError() 1179 | 1180 | def io_uring_setup(self, mu): 1181 | raise NotImplementedError() 1182 | 1183 | def io_uring_enter(self, mu): 1184 | raise NotImplementedError() 1185 | 1186 | def io_uring_register(self, mu): 1187 | raise NotImplementedError() 1188 | 1189 | def open_tree(self, mu): 1190 | raise NotImplementedError() 1191 | 1192 | def move_mount(self, mu): 1193 | raise NotImplementedError() 1194 | 1195 | def fsopen(self, mu): 1196 | raise NotImplementedError() 1197 | 1198 | def fsconfig(self, mu): 1199 | raise NotImplementedError() 1200 | 1201 | def fsmount(self, mu): 1202 | raise NotImplementedError() 1203 | 1204 | def fspick(self, mu): 1205 | raise NotImplementedError() 1206 | 1207 | def pidfd_open(self, mu): 1208 | raise NotImplementedError() 1209 | 1210 | def clone3(self, mu): 1211 | raise NotImplementedError() 1212 | 1213 | def close_range(self, mu): 1214 | raise NotImplementedError() 1215 | 1216 | def openat2(self, mu): 1217 | raise NotImplementedError() 1218 | 1219 | def pidfd_getfd(self, mu): 1220 | raise NotImplementedError() 1221 | 1222 | def faccessat2(self, mu): 1223 | raise NotImplementedError() 1224 | 1225 | def process_madvise(self, mu): 1226 | raise NotImplementedError() 1227 | 1228 | def epoll_pwait2(self, mu): 1229 | raise NotImplementedError() 1230 | 1231 | def mount_setattr(self, mu): 1232 | raise NotImplementedError() 1233 | 1234 | def quotactl_fd(self, mu): 1235 | raise NotImplementedError() 1236 | 1237 | def landlock_create_ruleset(self, mu): 1238 | raise NotImplementedError() 1239 | 1240 | def landlock_add_rule(self, mu): 1241 | raise NotImplementedError() 1242 | 1243 | def landlock_restrict_self(self, mu): 1244 | raise NotImplementedError() 1245 | 1246 | def memfd_secret(self, mu): 1247 | raise NotImplementedError() 1248 | 1249 | def process_mrelease(self, mu): 1250 | raise NotImplementedError() 1251 | -------------------------------------------------------------------------------- /Emulator/vm/Memory.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from unicorn import * 4 | from Emulator.utils.Memory_Helpers import * 5 | 6 | logger = logging.getLogger(__name__) 7 | 8 | 9 | class Memory: 10 | def __init__(self, emulator): 11 | self.emulator = emulator 12 | self.sp = 0 13 | self.brkAddr = 0 14 | self.errnoPtr = 0 15 | self.SP_REG = UC_ARM64_REG_SP if self.emulator.is64Bit else UC_ARM_REG_SP 16 | self.initStack() 17 | self.initializeTLS(["ANDROID_DATA=/data", 18 | "ANDROID_ROOT=/system"]) 19 | 20 | def brk(self,addr): 21 | if addr == 0: 22 | self.brkAddr = 0x8048000 23 | return self.brkAddr 24 | 25 | if addr % PAGE_SIZE != 0: 26 | raise NotImplementedError("Unsupported brk operation") 27 | 28 | if addr > self.brkAddr: 29 | self.emulator.mu.mem_map(self.brkAddr, addr-self.brkAddr,UC_PROT_READ|UC_PROT_WRITE) 30 | self.brkAddr = addr 31 | elif addr < self.brkAddr: 32 | self.emulator.mu.mem_unmap(addr,self.brkAddr - addr) 33 | self.brkAddr = addr 34 | 35 | return self.brkAddr 36 | 37 | def initStack(self): 38 | self.mmap(STACK_ALLOC_BASE - STACK_ALLOC_SIZE, STACK_ALLOC_SIZE, UC_PROT_READ | UC_PROT_WRITE) 39 | self.emulator.mu.reg_write(self.SP_REG, STACK_ALLOC_BASE) 40 | self.sp = self.emulator.mu.reg_read(self.SP_REG) 41 | logger.debug("initStack Success addr=0x%X" % self.sp) 42 | 43 | def initializeTLS(self, envs): 44 | pointSize = self.emulator.getPointSize() 45 | 46 | thread = self.allocateStack(0x400) 47 | 48 | __stack_chk_guard = self.allocateStack(pointSize) 49 | 50 | processName = self.emulator.processName 51 | programName = write_utf8(self.emulator.mu, self.allocateStack(len(processName)), processName) 52 | programNamePtr = self.allocateStack(pointSize) 53 | self.emulator.mu.mem_write(programNamePtr, programName.to_bytes(pointSize, byteorder='little')) 54 | 55 | auxv = self.allocateStack(0x100) 56 | num = 25 57 | self.emulator.mu.mem_write(auxv, num.to_bytes(pointSize, byteorder='little')) 58 | self.emulator.mu.mem_write(auxv + pointSize, __stack_chk_guard.to_bytes(pointSize, byteorder='little')) 59 | 60 | environ = self.allocateStack(pointSize * (len(envs) + 1)) 61 | ptr = environ 62 | for env in envs: 63 | envPtr = write_utf8(self.emulator.mu, self.allocateStack(len(env)), env) 64 | self.emulator.mu.mem_write(ptr, envPtr.to_bytes(pointSize, byteorder='little')) 65 | ptr += pointSize 66 | self.emulator.mu.mem_write(ptr, b'\x00' * 4) 67 | argv = self.allocateStack(0x100) 68 | self.emulator.mu.mem_write(argv + pointSize, programNamePtr.to_bytes(pointSize, byteorder='little')) 69 | self.emulator.mu.mem_write(argv + 2 * pointSize, environ.to_bytes(pointSize, byteorder='little')) 70 | self.emulator.mu.mem_write(argv + 3 * pointSize, auxv.to_bytes(pointSize, byteorder='little')) 71 | tls = self.allocateStack(0x80 * 4) 72 | self.emulator.mu.mem_write(tls + pointSize, thread.to_bytes(pointSize, byteorder='little')) 73 | self.errnoPtr = tls + 2 * pointSize 74 | self.emulator.mu.mem_write(tls + 3 * pointSize, argv.to_bytes(pointSize, byteorder='little')) 75 | if self.emulator.is64Bit: 76 | self.emulator.mu.reg_write(UC_ARM64_REG_TPIDR_EL0, tls) 77 | else: 78 | self.emulator.mu.reg_write(UC_ARM_REG_C13_C0_3, tls) 79 | logger.debug( 80 | "initializeTLS Success tls=0x%X thread=0x%X errnoPtr=0x%X argv=0x%X auxv=0x%X environ=0x%X " 81 | "programNamePtr=0x%X __stack_chk_guard=0x%X" % ( 82 | tls, thread, self.errnoPtr, argv, auxv, environ, programNamePtr, __stack_chk_guard)) 83 | 84 | def allocateStack(self, size): 85 | self.sp = self.sp - size 86 | self.emulator.mu.reg_write(self.SP_REG, self.sp) 87 | return self.sp 88 | 89 | def mmap(self, address, size, prot=UC_PROT_READ | UC_PROT_WRITE | UC_PROT_EXEC, fdKey=-1, offset=0, 90 | mem_reserve=False): 91 | if not self._is_multiple(address): 92 | raise Exception('map address was not multiple of page size (%d, %d).' % (address, PAGE_SIZE)) 93 | logger.debug("map address:0x%X, end:0x%X, sz:0x%X offset=0x%X" % (address, address + size, size, offset)) 94 | 95 | al_address = address 96 | # al_size = PAGE_END(al_address + size) - al_address 97 | al_size = alignSize(size) 98 | res_addr = self._map(al_address, al_size, prot, mem_reserve) 99 | if res_addr != -1 and fdKey != -1: 100 | fo = self.emulator.PCB.FDMaps[fdKey]["fo"] 101 | fo.seek(offset, 0) 102 | data = self._read_fully(fo, size) 103 | self.emulator.mu.mem_write(res_addr, data) 104 | return res_addr 105 | 106 | def _map(self, address, size, prot=UC_PROT_READ | UC_PROT_WRITE | UC_PROT_EXEC, mem_reserve=False): 107 | if size <= 0: 108 | raise Exception('Heap map size was <= 0.') 109 | try: 110 | if address == 0: 111 | regions = [] 112 | for r in self.emulator.mu.mem_regions(): 113 | regions.append(r) 114 | regions.sort() 115 | map_base = -1 116 | l_regions = len(regions) 117 | if l_regions < 1: 118 | map_base = MAP_ALLOC_BASE 119 | else: 120 | prefer_start = MAP_ALLOC_BASE 121 | next_loop = True 122 | while next_loop: 123 | next_loop = False 124 | for r in regions: 125 | if self._is_overlap(prefer_start, prefer_start + size, r[0], r[1] + 1): 126 | prefer_start = r[1] + 1 127 | next_loop = True 128 | break 129 | map_base = prefer_start 130 | 131 | if map_base < MAP_ALLOC_BASE or map_base > MAP_ALLOC_BASE + MAP_ALLOC_SIZE: 132 | raise RuntimeError("mmap error map_base 0x%X out of range (0x%X-0x%X)!!!" % ( 133 | map_base, MAP_ALLOC_BASE, MAP_ALLOC_BASE + MAP_ALLOC_SIZE)) 134 | 135 | logger.debug("before mem_map address:0x%X, sz:0x%X" % (map_base, size)) 136 | 137 | if not mem_reserve: 138 | self.emulator.mu.mem_map(map_base, size, perms=prot) 139 | return map_base 140 | else: 141 | # MAP_FIXED 142 | try: 143 | self.emulator.mu.mem_map(address, size, perms=prot) 144 | except unicorn.UcError as e: 145 | if e.errno == UC_ERR_MAP: 146 | blocks = set() 147 | extra_protect = set() 148 | for b in range(address, address + size, 0x1000): 149 | blocks.add(b) 150 | 151 | for r in self.emulator.mu.mem_regions(): 152 | # 修改属性 153 | raddr = r[0] 154 | rend = r[1] + 1 155 | for b in range(raddr, rend, 0x1000): 156 | if b in blocks: 157 | blocks.remove(b) 158 | extra_protect.add(b) 159 | 160 | for b_map in blocks: 161 | self.emulator.mu.mem_map(b_map, 0x1000, prot) 162 | 163 | for b_protect in extra_protect: 164 | self.emulator.mu.mem_protect(b_protect, 0x1000, prot) 165 | 166 | return address 167 | 168 | except unicorn.UcError as e: 169 | for r in self.emulator.mu.mem_regions(): 170 | logger.debug("region begin :0x%X end:0x%X, prot:%d" % (r[0], r[1], r[2])) 171 | raise 172 | 173 | def protect(self, address, len, prot): 174 | if not self._is_multiple(address): 175 | raise Exception('address was not multiple of page size (%d, %d).' % (address, PAGE_SIZE)) 176 | 177 | try: 178 | self.emulator.mu.mem_protect(address, len, prot) 179 | except unicorn.UcError as e: 180 | logger.warning("Warning mprotect with address: 0x%X len: 0x%X prot:0x%X failed!!!" % (address, len, prot)) 181 | return -1 182 | return 0 183 | 184 | def munmap(self, address, size): 185 | if not self._is_multiple(address): 186 | raise Exception('address was not multiple of page size (%d, %d).' % (address, PAGE_SIZE)) 187 | # size = PAGE_END(address + size) - address 188 | size = alignSize(size) 189 | try: 190 | logger.debug("unmap 0x%X sz=0x%X end=0x%X" % (address, size, address + size)) 191 | for fdKey, fdMap in self.emulator.PCB.FDMaps.items(): 192 | if fdMap["addr"] == address: 193 | del self.emulator.PCB.FDMaps[fdKey] 194 | self.emulator.mu.mem_unmap(address, size) 195 | except unicorn.UcError as e: 196 | for r in self.emulator.mu.mem_regions(): 197 | logger.debug("region begin :0x%X end:0x%X, prot:%d" % (r[0], r[1], r[2])) 198 | raise 199 | return 0 200 | 201 | @staticmethod 202 | def _read_fully(fo, size): 203 | b_read = fo.read(size) 204 | sz_read = len(b_read) 205 | if sz_read <= 0: 206 | return b_read 207 | 208 | sz_left = size - sz_read 209 | while sz_left > 0: 210 | this_read = fo.read(sz_left) 211 | len_this_read = len(this_read) 212 | if len_this_read <= 0: 213 | break 214 | b_read = b_read + this_read 215 | sz_left = sz_left - len_this_read 216 | 217 | return b_read 218 | 219 | @staticmethod 220 | def _is_overlap(addr1, end1, addr2, end2): 221 | r = (addr1 <= addr2 and end1 >= end2) or (addr2 <= addr1 and end2 >= end1) or ( 222 | end1 > addr2 and addr1 < end2) or (end2 > addr1 and addr2 < end1) 223 | return r 224 | 225 | @staticmethod 226 | def _is_multiple(address): 227 | return address % PAGE_SIZE == 0 228 | -------------------------------------------------------------------------------- /Emulator/vm/PCB.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | import sys 4 | import time 5 | 6 | from Emulator.utils.Memory_Helpers import PAGE_SIZE 7 | 8 | logger = logging.getLogger(__name__) 9 | 10 | S_IFREG = 0x8000 11 | S_IFDIR = 0x4000 12 | S_IFCHR = 0x2000 13 | S_IFLNK = 0xa000 14 | S_IFSOCK = 0xc000 15 | 16 | _IOC_NRBITS = 8 17 | _IOC_TYPEBITS = 8 18 | _IOC_SIZEBITS = 14 19 | 20 | _IOC_WRITE = 1 21 | _IOC_READ = 2 22 | 23 | ANDROID_ALARM_GET_TIME = 4 24 | 25 | AndroidAlarmType = [ 26 | "ANDROID_ALARM_RTC_WAKEUP", 27 | "ANDROID_ALARM_RTC", 28 | "ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP", 29 | "ANDROID_ALARM_ELAPSED_REALTIME", 30 | "ANDROID_ALARM_SYSTEMTIME", 31 | "ANDROID_ALARM_TYPE_COUNT" 32 | ] 33 | 34 | 35 | class PCB: 36 | def __init__(self): 37 | self.FDMaps = dict() 38 | self.FDMaps[self.findMinFd()] = {"pathname": "stdin", "fo": sys.stdin, "fd": sys.stdin.fileno(), "addr": -1} 39 | self.FDMaps[self.findMinFd()] = {"pathname": "stdout", "fo": sys.stdout, "fd": sys.stdout.fileno(), "addr": -1} 40 | self.FDMaps[self.findMinFd()] = {"pathname": "stderr", "fo": sys.stderr, "fd": sys.stderr.fileno(), "addr": -1} 41 | 42 | def findMinFd(self): 43 | fd = -1 44 | for key in self.FDMaps.keys(): 45 | if fd < key: 46 | fd = key 47 | return fd + 1 48 | 49 | def open(self, emulator, pathname, oflags): 50 | minFd = self.findMinFd() 51 | filename = pathname 52 | if pathname.startswith("/dev") or pathname.startswith("/proc") or pathname.startswith("/system"): 53 | filename = "Android/SDK23%s" % pathname 54 | if pathname == "/dev/alarm": 55 | self.FDMaps[minFd] = {"pathname": pathname, "fo": -1, "fd": -1, "addr": -1} 56 | else: 57 | fd = os.open(filename, os.O_RDONLY | os.O_BINARY) 58 | fo = open(fd, 'rb') 59 | self.FDMaps[minFd] = {"pathname": pathname, "fo": fo, "fd": fd, "addr": -1} 60 | return minFd 61 | 62 | def fstat(self, mu, fd, stat_ptr): 63 | f = self.FDMaps[fd] 64 | stat = os.stat(f["fd"]) 65 | 66 | st_rdev = 0 67 | st_mode = S_IFREG 68 | st_blksize = PAGE_SIZE 69 | st_blocks = (stat.st_size + PAGE_SIZE - 1) / PAGE_SIZE 70 | stdev = stat.st_dev 71 | 72 | uid = 10086 73 | if f["pathname"] == "/dev/__properties__": 74 | uid = 0 75 | if hasattr(stat, "st_rdev"): 76 | st_rdev = stat.st_rdev 77 | if hasattr(stat, "st_blksize"): 78 | st_blksize = stat.st_blksize 79 | if hasattr(stat, "st_blocks"): 80 | st_blocks = stat.st_blocks 81 | if stdev < 0: 82 | stdev = stdev * -1 83 | 84 | mu.mem_write(stat_ptr, int(stdev).to_bytes(8, byteorder='little')) 85 | mu.mem_write(stat_ptr + 8, int(0).to_bytes(4, byteorder='little')) # PAD 4 86 | mu.mem_write(stat_ptr + 12, int(stat.st_ino).to_bytes(8, byteorder='little', signed=False)) 87 | mu.mem_write(stat_ptr + 16, int(st_mode).to_bytes(4, byteorder='little')) 88 | mu.mem_write(stat_ptr + 20, int(stat.st_nlink).to_bytes(4, byteorder='little')) 89 | mu.mem_write(stat_ptr + 24, int(uid).to_bytes(4, byteorder='little')) 90 | mu.mem_write(stat_ptr + 28, int(uid).to_bytes(4, byteorder='little')) 91 | mu.mem_write(stat_ptr + 32, int(st_rdev).to_bytes(8, byteorder='little')) 92 | mu.mem_write(stat_ptr + 40, int(0).to_bytes(4, byteorder='little')) # PAD 4 93 | mu.mem_write(stat_ptr + 48, int(stat.st_size).to_bytes(8, byteorder='little')) 94 | mu.mem_write(stat_ptr + 56, int(st_blksize).to_bytes(4, byteorder='little')) 95 | mu.mem_write(stat_ptr + 64, int(st_blocks).to_bytes(8, byteorder='little')) 96 | 97 | mu.mem_write(stat_ptr + 72, int(stat.st_atime).to_bytes(8, byteorder='little')) 98 | mu.mem_write(stat_ptr + 80, int(stat.st_mtime).to_bytes(8, byteorder='little')) 99 | mu.mem_write(stat_ptr + 88, int(stat.st_ctime).to_bytes(8, byteorder='little')) 100 | 101 | mu.mem_write(stat_ptr + 96, int(stat.st_ino).to_bytes(8, byteorder='little')) 102 | 103 | return 0 104 | 105 | def close(self, fd): 106 | os.close(self.FDMaps[fd]["fd"]) 107 | del self.FDMaps[fd] 108 | return 0 109 | 110 | def read(self, mu, fd, buffer_ptr, count): 111 | fo = self.FDMaps[fd]["fo"] 112 | buf = fo.read(count) 113 | mu.mem_write(buffer_ptr, buf) 114 | return len(buf) 115 | 116 | def ioctl(self, mu, fd, request, argp): 117 | fdMap = self.FDMaps[fd] 118 | if fdMap["pathname"] == "/dev/alarm": 119 | ioc = request 120 | nr = ioc & 0xff 121 | ioc >>= _IOC_NRBITS 122 | type = ioc & 0xff 123 | ioc >>= _IOC_TYPEBITS 124 | size = ioc & 0x3ff 125 | ioc >>= _IOC_SIZEBITS 126 | dir = ioc 127 | if chr(type) == 'a': 128 | c = nr & 0xf 129 | type = nr >> 4 130 | return self.androidAlarm(mu, dir, c, type, size, argp) 131 | logger.info("alarm ioctl request=0x%X, argp=0x%X, nr= %d, type= %d, size= %d, dir= %d" % ( 132 | request, argp, nr, type, size, dir)) 133 | 134 | return -1 135 | 136 | def androidAlarm(self, mu, dir, c, type, size, argp): 137 | if dir == _IOC_WRITE and c == ANDROID_ALARM_GET_TIME and AndroidAlarmType[type] == "ANDROID_ALARM_ELAPSED_REALTIME": 138 | t = int(round(time.time() * 1000)) 139 | tv_sec = int(t / 1000000000) 140 | tv_nsec = int(t % 1000000000) 141 | print(tv_sec) 142 | if size == 8: 143 | mu.mem_write(argp, tv_sec.to_bytes(4, byteorder='little')) 144 | mu.mem_write(argp + 4, tv_nsec.to_bytes(4, byteorder='little')) 145 | return 0 146 | elif self == 16: 147 | mu.mem_write(argp, tv_sec.to_bytes(8, byteorder='little')) 148 | mu.mem_write(argp + 8, tv_nsec.to_bytes(8, byteorder='little')) 149 | return 0 150 | else: 151 | raise Exception("androidAlarm invalid size= %d" % size) 152 | 153 | logger.info("androidAlarm argp=0x%X, c= %d, type= %s, size= %d, dir= %d" % (argp, c, type, size, dir)) 154 | return -1 155 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #UniDa 2 | 至尊纪念仓库(纪念本人对linker unidbg ExAndroidNativeEmu的学习),这个实现没有意义就此太监。 3 | -------------------------------------------------------------------------------- /UniDa.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import sys 3 | 4 | from Emulator.Emulator import Emulator 5 | from BridgeScript.AttachBridge import AttachBridge 6 | 7 | logging.basicConfig(level=logging.DEBUG, 8 | format='[%(asctime)s %(process)d] %(levelname)s [%(name)s] (%(filename)s:%(lineno)d) - %(message)s', 9 | datefmt="%H:%M:%S", stream=sys.stderr) 10 | 11 | if __name__ == "__main__": 12 | # fridaBridge = AttachBridge("com.tencent.mm") 13 | emulator = Emulator("fridaBridge", is64Bit=False, apkPath="bin/apks/weixin809android1940.apk") 14 | emulator.loadLibrary("libwechatnormsg.so", True) 15 | print(emulator.linker.modules.keys()) 16 | --------------------------------------------------------------------------------