Closed plowsec closed 3 years ago
As suggested on the Telegram group chat, I added emu_error
before saving the snapshot and after restoring:
before saving, at the moment of a crash:
sens.dll:UNKNOWN @ 0x428d1d
:: 0x428d1d: push dword ptr [esp + 0x44]
sens.dll:UNKNOWN @ 0x428d21
:: 0x428d21: ret 0x4c
[!] api ExpandEnvironmentStringsA is not implemented
[+] ERROR: unmapped memory access at 0xa6aa8
[x] CPU Context:
[x] ah : 0x54
[x] al : 0xd0
[x] ch : 0x0
[x] cl : 0x30
[x] dh : 0x0
[x] dl : 0x8
[x] bh : 0xcf
[x] bl : 0xbc
[x] ax : 0x54d0
[x] cx : 0x30
[x] dx : 0x8
[x] bx : 0xcfbc
[x] sp : 0xce28
[x] bp : 0xcf3c
[x] si : 0xd65c
[x] di : 0xcfec
[x] ip : 0x6aa8
[x] eax : 0x4054d0
[x] ecx : 0x30
[x] edx : 0x8
[x] ebx : 0xffffcfbc
[x] esp : 0xffffce28
[x] ebp : 0xffffcf3c
[x] esi : 0x40d65c
[x] edi : 0xffffcfec
[x] eip : 0xa6aa8
[x] cr0 : 0x11
[x] cr1 : 0x0
[x] cr2 : 0x0
[x] cr3 : 0x0
[x] cr4 : 0x0
[x] cr5 : 0x0
[x] cr6 : 0x0
[x] cr7 : 0x0
[x] cr8 : 0x0
[x] cr9 : 0x0
[x] cr10 : 0x0
[x] cr11 : 0x0
[x] cr12 : 0x0
[x] cr13 : 0x0
[x] cr14 : 0x0
[x] cr15 : 0x0
[x] st0 : 0x0
[x] st1 : 0x0
[x] st2 : 0x0
[x] st3 : 0x0
[x] st4 : 0x0
[x] st5 : 0x0
[x] st6 : 0x0
[x] st7 : 0x0
[x] ef : 0x2
[x] cs : 0x1b
[x] ss : 0x28
[x] ds : 0x28
[x] es : 0x28
[x] fs : 0x73
[x] gs : 0x78
[x] PC = 0x000a6aa8 (unreachable)
[=] Memory map:
[=] Start End Perm Label Image
[=] 00006000 - 0000c000 rwx [FS/GS]
[=] 00030000 - 00031000 rwx [GDT]
[=] 00400000 - 00488000 rwx [PE] sens.dll
[=] 05000000 - 05001000 rwx [heap]
[=] 05001000 - 05011000 rwx [heap]
[=] 05011000 - 05021000 rwx [heap]
[=] 05021000 - 05031000 rwx [heap]
[=] 05031000 - 05041000 rwx [heap]
[=] 05041000 - 05051000 rwx [heap]
[=] 05051000 - 05151000 rwx [heap]
[=] 06000000 - 0c000000 rwx [FS/GS]
[=] 10000000 - 10096000 rwx oleaut32.dll /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/oleaut32.dll
[=] 4b280000 - 4b423000 rwx ntdll.dll /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/ntdll.dll
[=] 4c300000 - 4c37a000 rwx advapi32.dll /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/advapi32.dll
[=] 69e00000 - 69f96000 rwx user32.dll /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/user32.dll
[=] 6b800000 - 6b8e5000 rwx kernel32.dll /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/kernel32.dll
[=] fffdd000 - ffffe000 rwx [stack]
[x] CPU Context:
[x] ah : 0x54
[x] al : 0xd0
[x] ch : 0x0
[x] cl : 0x30
[x] dh : 0x0
[x] dl : 0x8
[x] bh : 0xcf
[x] bl : 0xbc
[x] ax : 0x54d0
[x] cx : 0x30
[x] dx : 0x8
[x] bx : 0xcfbc
[x] sp : 0xce28
[x] bp : 0xcf3c
[x] si : 0xd65c
[x] di : 0xcfec
[x] ip : 0x6aa8
[x] eax : 0x4054d0
[x] ecx : 0x30
[x] edx : 0x8
[x] ebx : 0xffffcfbc
[x] esp : 0xffffce28
[x] ebp : 0xffffcf3c
[x] esi : 0x40d65c
[x] edi : 0xffffcfec
[x] eip : 0xa6aa8
[x] cr0 : 0x11
[x] cr1 : 0x0
[x] cr2 : 0x0
[x] cr3 : 0x0
[x] cr4 : 0x0
[x] cr5 : 0x0
[x] cr6 : 0x0
[x] cr7 : 0x0
[x] cr8 : 0x0
[x] cr9 : 0x0
[x] cr10 : 0x0
[x] cr11 : 0x0
[x] cr12 : 0x0
[x] cr13 : 0x0
[x] cr14 : 0x0
[x] cr15 : 0x0
[x] st0 : 0x0
[x] st1 : 0x0
[x] st2 : 0x0
[x] st3 : 0x0
[x] st4 : 0x0
[x] st5 : 0x0
[x] st6 : 0x0
[x] st7 : 0x0
[x] ef : 0x2
[x] cs : 0x1b
[x] ss : 0x28
[x] ds : 0x28
[x] es : 0x28
[x] fs : 0x73
[x] gs : 0x78
[x] PC = 0x000a6aa8 (unreachable)
[=] Memory map:
[=] Start End Perm Label Image
[=] 00006000 - 0000c000 rwx [FS/GS]
[=] 00030000 - 00031000 rwx [GDT]
[=] 00400000 - 00488000 rwx [PE] sens.dll
[=] 05000000 - 05001000 rwx [heap]
[=] 05001000 - 05011000 rwx [heap]
[=] 05011000 - 05021000 rwx [heap]
[=] 05021000 - 05031000 rwx [heap]
[=] 05031000 - 05041000 rwx [heap]
[=] 05041000 - 05051000 rwx [heap]
[=] 05051000 - 05151000 rwx [heap]
[=] 06000000 - 0c000000 rwx [FS/GS]
[=] 10000000 - 10096000 rwx oleaut32.dll /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/oleaut32.dll
[=] 4b280000 - 4b423000 rwx ntdll.dll /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/ntdll.dll
[=] 4c300000 - 4c37a000 rwx advapi32.dll /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/advapi32.dll
[=] 69e00000 - 69f96000 rwx user32.dll /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/user32.dll
[=] 6b800000 - 6b8e5000 rwx kernel32.dll /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/kernel32.dll
[=] fffdd000 - ffffe000 rwx [stack]
Traceback (most recent call last):
File "qunpack.py", line 161, in main
ql.run(begin=DLL_MAIN, end=DLL_MAIN+4)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/qiling/core.py", line 728, in run
self.os.run()
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/qiling/os/windows/windows.py", line 179, in run
self.ql.emu_start(self.ql.loader.entry_point, self.exit_point, self.ql.timeout, self.ql.count)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/qiling/core.py", line 875, in emu_start
self.uc.emu_start(begin, end, timeout, count)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/unicorn/unicorn.py", line 341, in emu_start
raise UcError(status)
unicorn.unicorn.UcError: Invalid memory fetch (UC_ERR_FETCH_UNMAPPED)
Python 3.8.7 (v3.8.7:6503f05dd5, Dec 21 2020, 12:45:15)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.22.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]:
after restoring
python3 qunpack.py restore
[+] Profile: Default
[+] Map GDT at 0x30000 with GDT_LIMIT=4096
[+] Write to 0x30018 for new entry b'\x00\xf0\x00\x00\x00\xfeO\x00'
[+] Write to 0x30028 for new entry b'\x00\xf0\x00\x00\x00\x96O\x00'
[+] Write to 0x30070 for new entry b'\x00`\x00`\x00\xf6@\x00'
[+] Write to 0x30078 for new entry b'\x00\x00\x00\x00\x00\xf6@\x06'
[+] Windows Registry PATH: /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/registry
[=] Initiate stack address at 0xfffdd000
[=] Loading sens.dll to 0x400000
[=] PE entry point at 0x482a0e
[+] Setting up DllMain args
[+] Writing 0x00400000 (IMAGE_BASE) to [ESP+4](0xFFFFD004)
[+] Writing 0x01 (DLL_PROCESS_ATTACH) to [ESP+8](0xFFFFD008)
[=] TEB addr is 0x6000
[=] PEB addr is 0x6044
[=] Loading /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/ntdll.dll ...
[=] Loaded /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/ntdll.dll from cache
[=] Done with loading /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/ntdll.dll
[=] Loading /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/kernel32.dll ...
[=] Loaded /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/kernel32.dll from cache
[=] Done with loading /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/kernel32.dll
[=] Loading /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/user32.dll ...
[=] Loaded /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/user32.dll from cache
[=] Done with loading /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/user32.dll
[=] Loading /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/advapi32.dll ...
[=] Loaded /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/advapi32.dll from cache
[=] Done with loading /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/advapi32.dll
[=] Loading /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/oleaut32.dll ...
[=] Loaded /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/oleaut32.dll from cache
[=] Done with loading /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/oleaut32.dll
[+] Done with loading sens.dll
[x] CPU Context:
[x] ah : 0x0
[x] al : 0x0
[x] ch : 0x0
[x] cl : 0x0
[x] dh : 0x0
[x] dl : 0x0
[x] bh : 0x0
[x] bl : 0x0
[x] ax : 0x0
[x] cx : 0x0
[x] dx : 0x0
[x] bx : 0x0
[x] sp : 0xd000
[x] bp : 0xd000
[x] si : 0x0
[x] di : 0x0
[x] ip : 0x0
[x] eax : 0x0
[x] ecx : 0x0
[x] edx : 0x0
[x] ebx : 0x0
[x] esp : 0xffffd000
[x] ebp : 0xffffd000
[x] esi : 0x0
[x] edi : 0x0
[x] eip : 0x0
[x] cr0 : 0x11
[x] cr1 : 0x0
[x] cr2 : 0x0
[x] cr3 : 0x0
[x] cr4 : 0x0
[x] cr5 : 0x0
[x] cr6 : 0x0
[x] cr7 : 0x0
[x] cr8 : 0x0
[x] cr9 : 0x0
[x] cr10 : 0x0
[x] cr11 : 0x0
[x] cr12 : 0x0
[x] cr13 : 0x0
[x] cr14 : 0x0
[x] cr15 : 0x0
[x] st0 : 0x0
[x] st1 : 0x0
[x] st2 : 0x0
[x] st3 : 0x0
[x] st4 : 0x0
[x] st5 : 0x0
[x] st6 : 0x0
[x] st7 : 0x0
[x] ef : 0x0
[x] cs : 0x1b
[x] ss : 0x28
[x] ds : 0x28
[x] es : 0x28
[x] fs : 0x73
[x] gs : 0x78
[x] PC = 0x00000000 (unreachable)
[=] Memory map:
[=] Start End Perm Label Image
[=] 00006000 - 0000c000 rwx [FS/GS]
[=] 00030000 - 00031000 rwx [GDT]
[=] 00400000 - 00488000 rwx [PE] sens.dll
[=] 05000000 - 05001000 rwx [heap]
[=] 06000000 - 0c000000 rwx [FS/GS]
[=] 10000000 - 10096000 rwx oleaut32.dll /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/oleaut32.dll
[=] 4b280000 - 4b423000 rwx ntdll.dll /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/ntdll.dll
[=] 4c300000 - 4c37a000 rwx advapi32.dll /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/advapi32.dll
[=] 69e00000 - 69f96000 rwx user32.dll /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/user32.dll
[=] 6b800000 - 6b8e5000 rwx kernel32.dll /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/kernel32.dll
[=] fffdd000 - ffffe000 rwx [stack]
[=] 00428d21 [[PE] + 0x028d21] 00 00 add byte ptr [eax], al
[+] ERROR: unmapped memory access at 0x0
[x] CPU Context:
[x] ah : 0x0
[x] al : 0x0
[x] ch : 0x0
[x] cl : 0x0
[x] dh : 0x0
[x] dl : 0x0
[x] bh : 0x0
[x] bl : 0x0
[x] ax : 0x0
[x] cx : 0x0
[x] dx : 0x0
[x] bx : 0x0
[x] sp : 0xd000
[x] bp : 0xd000
[x] si : 0x0
[x] di : 0x0
[x] ip : 0x8d21
[x] eax : 0x0
[x] ecx : 0x0
[x] edx : 0x0
[x] ebx : 0x0
[x] esp : 0xffffd000
[x] ebp : 0xffffd000
[x] esi : 0x0
[x] edi : 0x0
[x] eip : 0x428d21
[x] cr0 : 0x11
[x] cr1 : 0x0
[x] cr2 : 0x0
[x] cr3 : 0x0
[x] cr4 : 0x0
[x] cr5 : 0x0
[x] cr6 : 0x0
[x] cr7 : 0x0
[x] cr8 : 0x0
[x] cr9 : 0x0
[x] cr10 : 0x0
[x] cr11 : 0x0
[x] cr12 : 0x0
[x] cr13 : 0x0
[x] cr14 : 0x0
[x] cr15 : 0x0
[x] st0 : 0x0
[x] st1 : 0x0
[x] st2 : 0x0
[x] st3 : 0x0
[x] st4 : 0x0
[x] st5 : 0x0
[x] st6 : 0x0
[x] st7 : 0x0
[x] ef : 0x0
[x] cs : 0x1b
[x] ss : 0x28
[x] ds : 0x28
[x] es : 0x28
[x] fs : 0x73
[x] gs : 0x78
[x] Hexdump:
[x] 00 00 00 00 00 00 00 00
[x] Disassembly:
[=] 00428d21 [[PE] + 0x028d21] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
> add byte ptr [eax], al
[x] PC = 0x00428d21 (sens.dll + 0x28d21)
[=] Memory map:
[=] Start End Perm Label Image
[=] 00006000 - 0000c000 rwx [FS/GS]
[=] 00030000 - 00031000 rwx [GDT]
[=] 00400000 - 00488000 rwx [PE] sens.dll
[=] 05000000 - 05001000 rwx [heap]
[=] 06000000 - 0c000000 rwx [FS/GS]
[=] 10000000 - 10096000 rwx oleaut32.dll /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/oleaut32.dll
[=] 4b280000 - 4b423000 rwx ntdll.dll /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/ntdll.dll
[=] 4c300000 - 4c37a000 rwx advapi32.dll /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/advapi32.dll
[=] 69e00000 - 69f96000 rwx user32.dll /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/user32.dll
[=] 6b800000 - 6b8e5000 rwx kernel32.dll /Users/vladimir/Tools/qiling/examples/rootfs/x86_windows/Windows/System32/kernel32.dll
[=] fffdd000 - ffffe000 rwx [stack]
Traceback (most recent call last):
File "qunpack.py", line 214, in restore_continue
ql.run(begin=ql.reg.eip, end=DLL_MAIN)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/qiling/core.py", line 728, in run
self.os.run()
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/qiling/os/windows/windows.py", line 179, in run
self.ql.emu_start(self.ql.loader.entry_point, self.exit_point, self.ql.timeout, self.ql.count)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/qiling/core.py", line 875, in emu_start
self.uc.emu_start(begin, end, timeout, count)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/unicorn/unicorn.py", line 341, in emu_start
raise UcError(status)
unicorn.unicorn.UcError: Invalid memory read (UC_ERR_READ_UNMAPPED)
Worth noting that now it takes 2 hours to reach this point
ql.restore
accepts 2 parameters, and the first one is "saved_states", which is expected to be a unserialised pickle object. I forgot to use the named argument like so:
ql.restore(snapshot="snapshot.bin")
Thanks for the help on the Telegram group chat :)
*Describe the bug
Complex malware that takes a long time for Qiling to emulate, so I periodically take snaphosts with ql.save, and when I meet an unhandled API, I implement it and would like to resume execution where it stopped with ql.restore.
However the stack appears mostly empty, and the memory map is missing most of the allocated heaps.
Sample Code
Expected behavior I expected ql.restore to provide a healthy state where execution could safely resume.
Additional context
Crash while emulating because of ZwSetInformationProcess:
Attempt to resume execution:
right after the crash, pre-restore:
with ql.restore
and the good stack:
and the bad stack (with restore):