Skip to content

Commit

Permalink
Merge pull request #39 from quarkslab/fix/fix-pthread-routines
Browse files Browse the repository at this point in the history
Fix pthread support
  • Loading branch information
cnheitman authored Dec 17, 2024
2 parents bf1cf0e + af9df3a commit 2f3fb0d
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 6 deletions.
19 changes: 16 additions & 3 deletions tritondse/process_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,16 +193,29 @@ def spawn_new_thread(self, new_pc: Addr, args: Addr) -> ThreadContext:
thread.save(self.tt_ctx)

# Concretize pc, bp, sp, and first (argument)
regs = [self.program_counter_register, self.stack_pointer_register, self.base_pointer_register, self._get_argument_register(0)]
regs = [
self.program_counter_register,
self.stack_pointer_register,
self.base_pointer_register,
self._get_argument_register(0)
]
for reg in regs:
if reg.getId() in thread.sregs:
del thread.sregs[reg.getId()]

thread.cregs[self.program_counter_register.getId()] = new_pc # set new pc
thread.cregs[self._get_argument_register(0).getId()] = args # set args pointer
stack = self.memory.map_from_name(self.STACK_SEG)
thread.cregs[self.base_pointer_register.getId()] = ((stack.start+stack.size) - ((1 << 28) * tid))
thread.cregs[self.stack_pointer_register.getId()] = ((stack.start+stack.size) - ((1 << 28) * tid))
stack_base_addr = ((stack.start + stack.size - self.ptr_size) - ((1 << 28) * tid))
thread.cregs[self.base_pointer_register.getId()] = stack_base_addr
thread.cregs[self.stack_pointer_register.getId()] = stack_base_addr

if self.architecture == Architecture.AARCH64:
thread.cregs[getattr(self.registers, 'x30').getId()] = 0xcafecafe
elif self.architecture == Architecture.ARM32:
thread.cregs[getattr(self.registers, 'r14').getId()] = 0xcafecafe
elif self.architecture in [Architecture.X86, Architecture.X86_64]:
self.memory.write_ptr(stack_base_addr, 0xcafecafe)

# Add the thread in the pool of threads
self._threads[tid] = thread
Expand Down
7 changes: 5 additions & 2 deletions tritondse/routines.py
Original file line number Diff line number Diff line change
Expand Up @@ -1219,9 +1219,12 @@ def rtn_pthread_join(se: 'SymbolicExecutor', pstate: 'ProcessState'):
arg0 = pstate.get_argument_value(0)
arg1 = pstate.get_argument_value(1)

if arg0 in pstate.threads:
if arg0 in pstate._threads:
# This will change the state of the current thread from RUNNING to
# JOINING. Therefore, it will not run until the joining thread
# finishes.
pstate.current_thread.join_thread(arg0)
logger.info(f"Thread id {pstate.current_thread.tid} joined thread id {arg0}")
logger.info(f"Thread id {pstate.current_thread.tid} is waiting thread id {arg0} to join")
else:
pstate.current_thread.cancel_join()
logger.debug(f"Thread id {arg0} already destroyed")
Expand Down
15 changes: 14 additions & 1 deletion tritondse/symbolic_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,9 @@ def __schedule_thread(self) -> None:
if len(threads_list) == 1: # If there is only one thread no need to schedule another thread
return

if self.pstate.current_thread.count > self.config.thread_scheduling:
if self.pstate.current_thread.count > self.config.thread_scheduling or \
self.pstate.current_thread.is_waiting_to_join() or \
not self.pstate.current_thread.is_running():
# Select the next thread to execute
next_th = self._fetch_next_thread(threads_list)

Expand Down Expand Up @@ -287,6 +289,17 @@ def step(self) -> bool:
# Fetch program counter (of the thread selected), at this point the current thread should be running!
self.current_pc = self.pstate.cpu.program_counter # should normally be already set but still.

if self.current_pc == 0xcafecafe:
logger.debug(f"Schedule thread ({self.pstate.current_thread.tid}) finished running")
self.pstate.current_thread.kill()

# Check whether the main thread was waiting for the schedule thread to join.
if self.pstate._threads[0]._join_th_id == self.pstate.current_thread.tid:
logger.debug(f"Set main thread state to RUNNING")
self.pstate._threads[0]._join_th_id = None
self.pstate._threads[0].state = ThreadState.RUNNING
return True

if self.current_pc == self._run_to_target: # Hit the location we wanted to reach
return False

Expand Down
5 changes: 5 additions & 0 deletions tritondse/thread_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
# third-party imports
from triton import TritonContext

# local imports
import tritondse.logging

logger = tritondse.logging.get("thread_context")


@enum_tools.documentation.document_enum
class ThreadState(Enum):
Expand Down

0 comments on commit 2f3fb0d

Please sign in to comment.