Skip to content

Fix call() API crash when used without run_module()#283

Draft
williballenthin wants to merge 4 commits intomasterfrom
worktree-fix-issue-21
Draft

Fix call() API crash when used without run_module()#283
williballenthin wants to merge 4 commits intomasterfrom
worktree-fix-issue-21

Conversation

@williballenthin
Copy link
Collaborator

Summary

  • The call() API crashed when invoked after load_module() but before run_module() because it assumed process/thread context was already initialized
  • Added _ensure_process_context() to lazily create the minimal process, thread, PEB, and TEB state needed for emulation
  • Added tests for both the fix case (call without run_module) and the regression case (call after run_module), for x86 and x64

Closes #21

Test plan

  • test_call_without_run_module — x86 and x64 DLLs
  • test_call_after_run_module — x86 and x64 DLLs (regression)
  • Existing test suite passes (pre-existing failures unrelated)

🤖 Generated with Claude Code

williballenthin and others added 4 commits March 9, 2026 11:34
Co-authored-by: Moritz <mr-tz@users.noreply.github.com>
The call() API failed with an AttributeError (or UcError on older
versions) because it assumed process/thread context was already
initialized. This adds _ensure_process_context() to lazily create
the minimal process, thread, PEB, and TEB state when call() is
invoked before run_module().

Closes #21
@google-cla
Copy link

google-cla bot commented Mar 9, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

Comment on lines +419 to +434
def _ensure_process_context(self):
if self.curr_process:
return
p = objman.Process(self)
self.processes.append(p)
self.curr_process = p
self.om.objects.update({p.address: p})

t = objman.Thread(self, stack_base=self.stack_base)
self.om.objects.update({t.address: t})
self.curr_process.threads.append(t)
self.curr_thread = t

peb = self.alloc_peb(self.curr_process)
self.init_teb(t, peb)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't like having this second copy of the initialization. we should study this further and see if we can refactor/consolidate all the logic together. i'm not convinced the call to _ensure_process_context is the right way.

@williballenthin williballenthin marked this pull request as draft March 10, 2026 09:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

exception when calling speakeasy's "call" api

2 participants