Skip to content

Commit f96ea5d

Browse files
committed
Workaround for (yet another) bug in unicorn where eip isn't increased after a sysenter
1 parent 5d3fe8d commit f96ea5d

File tree

3 files changed

+23
-10
lines changed

3 files changed

+23
-10
lines changed

.github/workflows/build.yml

+6-7
Original file line numberDiff line numberDiff line change
@@ -55,31 +55,30 @@ jobs:
5555
curl -sSOJL https://github.com/mrexodia/dumpulator/releases/download/v0.0.1/StringEncryptionFun_x86.dmp
5656
python download_artifacts.py
5757
58-
- name: StringEncryptionFun_x64
58+
- name: 'Test: StringEncryptionFun_x64'
5959
run: |
6060
cd tests
6161
python getting-started.py
6262
63-
- name: StringEncryptionFun_x86
63+
- name: 'Test: StringEncryptionFun_x86'
6464
run: |
6565
cd tests
6666
python getting-started32.py
6767
68-
- name: Run DumpulatorTests
68+
- name: 'Test: DumpulatorTests'
6969
run: |
7070
cd tests
7171
python harness-tests.py
7272
73-
- name: ExceptionTest_x64
73+
- name: 'Test: ExceptionTest_x64'
7474
run: |
7575
cd tests
7676
python execute-dump.py ExceptionTest_x64.dmp
7777
78-
# TODO: remove the trace argument once the bug is fixed
79-
- name: ExceptionTest_x86
78+
- name: 'Test: ExceptionTest_x86'
8079
run: |
8180
cd tests
82-
python execute-dump.py ExceptionTest_x86.dmp trace
81+
python execute-dump.py ExceptionTest_x86.dmp
8382
8483
publish:
8584
if: ${{ startsWith(github.ref, 'refs/tags/v') }}

src/dumpulator/dumpulator.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class ExceptionType(Enum):
3737
Memory = 1
3838
Interrupt = 2
3939
ContextSwitch = 3
40+
Terminate = 4
4041

4142
@dataclass
4243
class ExceptionInfo:
@@ -783,7 +784,7 @@ def _setup_syscalls(self):
783784
self.info(f"Patching Wow64Transition: {export.address:x} -> {patch_addr:x}")
784785
# See: https://opcode0x90.wordpress.com/2007/05/18/kifastsystemcall-hook/
785786
# mov edx, esp; sysenter; ret
786-
KiFastSystemCall = b"\x8B\xD4\x0F\x34\xC3"
787+
KiFastSystemCall = b"\x8B\xD4\x0F\x34\x90\x90\xC3"
787788
self.write(patch_addr, KiFastSystemCall)
788789
elif export.name == "KiUserExceptionDispatcher":
789790
self.KiUserExceptionDispatcher = export.address
@@ -1003,6 +1004,12 @@ def start(self, begin, end=0xffffffffffffffff, count=0) -> None:
10031004
# Restore the context (unicorn might mess with it before stopping)
10041005
if self.exception.context is not None:
10051006
self._uc.context_restore(self.exception.context)
1007+
1008+
if self.exception.type == ExceptionType.Terminate:
1009+
if self.exit_code is not None:
1010+
self.info(f"exit code: {self.exit_code:x}")
1011+
break
1012+
10061013
try:
10071014
emu_begin = self.handle_exception()
10081015
except:
@@ -1465,7 +1472,7 @@ def syscall_arg(index):
14651472
return dp.regs.r10
14661473
return dp.args[index]
14671474

1468-
dp.info(f"[{dp.sequence_id}] syscall: {name}(")
1475+
dp.info(f"[{dp.sequence_id}] syscall (index: {hex(index)}): {name}(")
14691476
for i in range(0, argcount):
14701477
argname = argspec.args[1 + i]
14711478
argtype = argspec.annotations[argname]
@@ -1513,6 +1520,9 @@ def syscall_arg(index):
15131520
if dp.x64:
15141521
dp.regs.rcx = dp.regs.cip + 2
15151522
dp.regs.r11 = dp.regs.eflags
1523+
else:
1524+
# HACK: there is a bug in unicorn that doesn't increment EIP
1525+
dp.regs.eip += 2
15161526
except UcError as err:
15171527
raise err
15181528
except Exception as exc:

src/dumpulator/ntsyscalls.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -4475,7 +4475,11 @@ def ZwTerminateProcess(dp: Dumpulator,
44754475
):
44764476
assert ProcessHandle == 0 or ProcessHandle == dp.NtCurrentProcess()
44774477
dp.stop(ExitStatus)
4478-
return STATUS_SUCCESS
4478+
exception = ExceptionInfo()
4479+
exception.type = ExceptionType.Terminate
4480+
exception.final = True
4481+
exception.context = dp._uc.context_save()
4482+
return exception
44794483

44804484
@syscall
44814485
def ZwTerminateThread(dp: Dumpulator,

0 commit comments

Comments
 (0)