def getKernelNextPc(self): #Get SP of thread_invoke. From Switch_context's frame kernel_saved_state = ThreadSavedState(self.kernel_stack_ptr) stack_ptr_thread_invoke = kernel_saved_state.sp #we are in thread_invoke context frame. Look at LR and see if the next function is thread_invoke or thread_run next_to_thread_invoke = getPointerAt( stack_ptr_thread_invoke + NextPcHelpOffsets.STORED_LR_IN_THREAD_INVOKE_FRAME.value) if next_to_thread_invoke == NextPcHelpOffsets.NEXT_IN_THREAD_RUN.value: #we came to thread invoke from thread_run. The next LR will point to the function that we want kernel_next_pc = getPointerAt( stack_ptr_thread_invoke + NextPcHelpOffsets.THREAD_INVOKE_FRAME_SIZE.value + 0x38) elif next_to_thread_invoke == NextPcHelpOffsets.NEXT_IN_THREAD_BLOCK.value: #we came to thread invoke from thread_block. The next LR will point to the function that we want or to exception return kernel_next_pc = getPointerAt( stack_ptr_thread_invoke + NextPcHelpOffsets.THREAD_INVOKE_FRAME_SIZE.value + 0x48) else: raise gdb.GdbError( "Something went wrong with getting the next pc, maybe running on another kernel?" ) #Now we can check whether the next running function is exception_return. If so, we need to go one more frame further if kernel_next_pc == NextPcHelpOffsets.EXEPTION_RETURN_PTR.value: #From the kernel code (Switch_context) we know that the pointer to saved state is stored in x21 next_x21_ptr = getPointerAt( stack_ptr_thread_invoke + NextPcHelpOffsets.THREAD_INVOKE_FRAME_SIZE.value + NextPcHelpOffsets.X21_IN_THREAD_INVOKE_FRAME.value) saved_state_exception_return = ThreadSavedState(next_x21_ptr) #now we have the saved state we can get the PC pc_from_saved_state = saved_state_exception_return.pc kernel_next_pc = pc_from_saved_state return kernel_next_pc
def __init__(self, address): if address != NULL_PTR: self.address = address self.task_ptr = getPointerAt(address + ThreadOffsets.TASK.value) self.tid = getLongAt(address + ThreadOffsets.THREAD_ID.value) self.continuation = getPointerAt(address + ThreadOffsets.CONTINUATION.value) self.global_threads_ptr = address + ThreadOffsets.GLOBAL_THREADS.value self.curr_task_threads_ptr = address + ThreadOffsets.TASK_THREADS.value self.uContextData = getPointerAt( address + ThreadOffsets.CONTEXT_USER_DATA_PTR.value) self.kernel_stack_ptr = getPointerAt( address + ThreadOffsets.KSTACK_PTR.value) self.voucher_ptr = getPointerAt(address + ThreadOffsets.VOUCHER_PTR.value) #Meta Data self.next_pc = NULL_PTR if self.isCurrect(): self.next_pc = printValueOf('$pc') elif self.uContextData != NULL_PTR: userSavedState = ThreadSavedState(self.uContextData) self.next_pc = userSavedState.pc elif self.kernel_stack_ptr != NULL_PTR: self.next_pc = self.getKernelNextPc() self.task_object = Task(self.task_ptr) else: raise gdb.GdbError(f"Null pointer in {__name__}")
def __iter__(self): if self.type == ThrdItrType.GLOBAL: self.next_thread_ptr = getPointerAt(GLOBAL_THREADS_PTR) self.stop_contition = GLOBAL_THREADS_PTR else: relevant_task = Task(self.task_ptr) self.next_thread_ptr = getPointerAt(relevant_task.threads_lst_ptr) self.stop_contition = self.task_ptr + TaskOffsets.THREAD_LST_FROM_TASK.value return self
def __next__(self): if self.next_thread_ptr != self.stop_contition: self.result = Thread(self.next_thread_ptr) if self.type == ThrdItrType.GLOBAL: self.next_thread_ptr = getPointerAt( self.result.global_threads_ptr) else: self.next_thread_ptr = getPointerAt( self.result.curr_task_threads_ptr) return self.result else: raise StopIteration
def __next__(self): if self.next_task_ptr != self.stop_contition: self.result = Task(self.next_task_ptr) self.next_task_ptr = getPointerAt(self.result.task_lst_ptr) return self.result else: raise StopIteration
def __init__(self, address): if address != NULL_PTR: self.iv_hash = getPointerAt(address) self.iv_sum = getPointerAt(address + 0x04) self.iv_refs = getPointerAt(address + 0x08) self.iv_table_size = getPointerAt(address + 0x0c) self.iv_inline_table = getPointerAt(address + 0x10) self.iv_table = getPointerAt(address + 0x30) self.iv_port = getPointerAt(address + 0x38) self.iv_hash_link = getPointerAt(address + 0x40)
def __init__(self, address): if address != NULL_PTR: self.address = address self.task_lst_ptr = address + TaskOffsets.TASK_NEXT.value self.threads_lst_ptr = address + TaskOffsets.THREAD_LST_FROM_TASK.value self.bsd_info_ptr = getPointerAt(address + TaskOffsets.BSD_INFO.value) self.bsdinfo_object = BsdInfo(self.bsd_info_ptr) else: raise gdb.GdbError(f"Null pointer in {__name__}")
def isValidPtr(ptr): try: getPointerAt(ptr) except: raise gdb.GdbError(f"Wrong pointer! {hex(ptr)}")
def getCurrentTaskPtr(): try: address = printValueOf(CURRENT_THREAD) return getPointerAt(address + ThreadOffsets.TASK.value) except Exception: raise gdb.GdbError(f"Error occured, maybe in user land?")
def __init__(self): self.stop_contition = GLOBAL_TASKS_PTR self.next_task_ptr = getPointerAt(GLOBAL_TASKS_PTR)
def __init__(self, address): if address != NULL_PTR: address += 0x08 # skip arm_state_hdr_t ash at arm_saved_state self.x0 = getPointerAt(address) self.x1 = getPointerAt(address + 0x08) self.x2 = getPointerAt(address + 0x10) self.x3 = getPointerAt(address + 0x18) self.x4 = getPointerAt(address + 0x20) self.x5 = getPointerAt(address + 0x28) self.x6 = getPointerAt(address + 0x30) self.x7 = getPointerAt(address + 0x38) self.x8 = getPointerAt(address + 0x40) self.x9 = getPointerAt(address + 0x48) self.x10 = getPointerAt(address + 0x50) self.x11 = getPointerAt(address + 0x58) self.x12 = getPointerAt(address + 0x60) self.x13 = getPointerAt(address + 0x68) self.x14 = getPointerAt(address + 0x70) self.x15 = getPointerAt(address + 0x78) self.x16 = getPointerAt(address + 0x80) self.x17 = getPointerAt(address + 0x88) self.x18 = getPointerAt(address + 0x90) self.x19 = getPointerAt(address + 0x98) self.x20 = getPointerAt(address + 0xa0) self.x21 = getPointerAt(address + 0xa8) self.x22 = getPointerAt(address + 0xb0) self.x23 = getPointerAt(address + 0xb8) self.x24 = getPointerAt(address + 0xc0) self.x25 = getPointerAt(address + 0xc8) self.x26 = getPointerAt(address + 0xd0) self.x27 = getPointerAt(address + 0xd8) self.x28 = getPointerAt(address + 0xe0) self.fp = getPointerAt(address + 0xe8) self.lr = getPointerAt(address + 0xf0) self.sp = getPointerAt(address + 0xf8) self.pc = getPointerAt(address + 0x100) self.cpsr = getIntAt(address + 0x108) self.reserved = getIntAt(address + 0x10c) self.far = getPointerAt(address + 0x110) self.esr = getIntAt(address + 0x118) self.exception = getIntAt(address + 0x11c)