Skip to content
Draft
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ on:
pull_request:
branches: [master]

permissions: read-all

jobs:
lint:
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion speakeasy/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "2.0.0a1"
__version__ = "2.0.0b1"
17 changes: 17 additions & 0 deletions speakeasy/windows/winemu.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,11 +410,28 @@ def call(self, addr, params=[]):
run.args = params

if not self.run_queue:
self._ensure_process_context()
self.add_run(run)
self.start()
else:
self.add_run(run)

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
Copy Markdown
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.

def _prepare_run_context(self, run):
"""
Prepare CPU and memory state for the given run without starting emulation.
Expand Down
40 changes: 40 additions & 0 deletions tests/test_call_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import pytest

from speakeasy import Speakeasy


@pytest.mark.parametrize(
"bin_file",
[
"dll_test_x86.dll.xz",
"dll_test_x64.dll.xz",
],
)
def test_call_without_run_module(config, load_test_bin, bin_file):
"""call() should work without run_module() being called first (GH-21)."""
data = load_test_bin(bin_file)
se = Speakeasy(config=config)
try:
mod = se.load_module(data=data)
se.call(mod.base + mod.ep, [mod.base, 1, 0])
finally:
se.shutdown()


@pytest.mark.parametrize(
"bin_file",
[
"dll_test_x86.dll.xz",
"dll_test_x64.dll.xz",
],
)
def test_call_after_run_module(config, load_test_bin, bin_file):
"""call() should still work after run_module() has set up context."""
data = load_test_bin(bin_file)
se = Speakeasy(config=config)
try:
mod = se.load_module(data=data)
se.run_module(mod)
se.call(mod.base + mod.ep, [mod.base, 1, 0])
finally:
se.shutdown()
Loading