I'm using the qiling framework to emulate a snake game which runs fine in my x86 64 Windows environment, but it's failing in the emulated environment. It works fine run normally, but I'm having trouble getting a breakpoint to work in WinDbg at the place it's failing. My question is more about understanding my problem in WinDbg, but I'll provide the emulator logs for context:
[=] Initiate stack address at 0xfffdd000
[=] Loading snake.exe to 0x400000
[=] PE entry point at 0x4033ae
[=] TEB addr is 0x6000
[=] PEB addr is 0x6044
[=] Loading ../examples/rootfs/x8664_windows\Windows\System32\ntdll.dll ...
[!] Warnings while loading ../examples/rootfs/x8664_windows\Windows\System32\ntdll.dll:
[!] - SizeOfHeaders is smaller than AddressOfEntryPoint: this file cannot run under Windows 8.
[!] - AddressOfEntryPoint lies outside the sections' boundaries. AddressOfEntryPoint: 0x0
[=] Done with loading ../examples/rootfs/x8664_windows\Windows\System32\ntdll.dll
[=] Loading ../examples/rootfs/x8664_windows\Windows\System32\kernel32.dll ...
[=] Done with loading ../examples/rootfs/x8664_windows\Windows\System32\kernel32.dll
[=] Loading ../examples/rootfs/x8664_windows\Windows\System32\mscoree.dll ...
[=] Done with loading ../examples/rootfs/x8664_windows\Windows\System32\mscoree.dll
0x4033ae: jmp qword ptr [rip + 0x402000]
[!] api _CorExeMain is not implemented
This seems like a likely culprit, so I try to set a breakpoint at 0x4033ae
in WinDbg with the command bu 0x4033ae
. I also tried bp
.
0x102bdbd1: push rbx
0x102bdbd3: sub esp, 0x20
0x102bdbd7: and dword ptr [rsp + 0x30], 0
0x102bdbdd: lea ecx, [rsp + 0x30]
0x102bdbe1: call 0x102b4548
0x102b4549: push rbx
0x102b454b: sub esp, 0x20
0x102b454e: mov eax, dword ptr [rip + 0x5b4dc]
[x] CPU Context:
[x] ah : 0xff
... snip ...
[x] gs : 0x78
[x] Hexdump:
[x] 8b 05 dc b4 05 00 48 8b
[x] Disassembly:
[=] 102b454e [mscoree.dll + 0x00154e] 8b 05 dc b4 05 00 48 8b d9 85 c0 75 05 e8 c4 fc ff ff 8b 05 ca b4 05 00 83 f8 02 75 0f 48 85 db 74 0a 48 8b 05 c9 b4 05 00 48 89 03 8b 05 b0 b4 05 00 48 83 c4 20 5b c3 cc cc cc cc cc cc cc ccmov eax, dword ptr [0x5b4dc]
> dec eax
> mov ebx, ecx
> test eax, eax
> jne 0x102b4560
> call 0x102b4224
> mov eax, dword ptr [0x5b4ca]
> cmp eax, 2
> jne 0x102b457a
> dec eax
> test ebx, ebx
> je 0x102b457a
> dec eax
> mov eax, dword ptr [0x5b4c9]
> dec eax
> mov dword ptr [ebx], eax
> mov eax, dword ptr [0x5b4b0]
> dec eax
> add esp, 0x20
> pop ebx
> ret
> int3
> int3
> int3
> int3
> int3
> int3
> int3
> int3
[x] PC = 0x102b454e (../examples/rootfs/x8664_windows\Windows\System32\mscoree.dll + 0x154e)
[=] Memory map:
[=] Start End Perm Label Image
[=] 00006000 - 0000c000 rwx [FS/GS]
[=] 00030000 - 00031000 rwx [GDT]
[=] 00400000 - 00408000 rwx [PE] snake.exe
[=] 05000000 - 05001000 rwx [heap]
[=] 06000000 - 0c000000 rwx [FS/GS]
[=] 10000000 - 101f5000 rwx ntdll.dll ../examples/rootfs/x8664_windows\Windows\System32\ntdll.dll
[=] 101f5000 - 102b3000 rwx kernel32.dll ../examples/rootfs/x8664_windows\Windows\System32\kernel32.dll
[=] 102b3000 - 10318000 rwx mscoree.dll ../examples/rootfs/x8664_windows\Windows\System32\mscoree.dll
[=] fffdd000 - ffffe000 rwx [stack]
Traceback (most recent call last):
... snip ...
File "C:\Users\jonat\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\unicorn\unicorn.py", line 465, in emu_start
raise UcError(status)
unicorn.unicorn.UcError: Invalid memory mapping (UC_ERR_MAP)
In WinDbg, I get:
CommandLine: C:\Users\jonat\Documents\GitHub\synthesis\obfu\snake.exe
************* Path validation summary **************
Response Time (ms) Location
Deferred srv*
Symbol search path is: srv*
Executable search path is:
ModLoad: 00e60000 00e68000 ConsoleGraphics.exe
ModLoad: 770f0000 77293000 ntdll.dll
ModLoad: 74810000 74862000 C:\WINDOWS\SysWOW64\MSCOREE.DLL
ModLoad: 74fb0000 750a0000 C:\WINDOWS\SysWOW64\KERNEL32.dll
ModLoad: 75fa0000 761b5000 C:\WINDOWS\SysWOW64\KERNELBASE.dll
(9b8.7854): Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=00000000 ecx=3c560000 edx=00000000 esi=77102054 edi=7710261c
eip=771a1ba2 esp=00fff9cc ebp=00fff9f8 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
ntdll!LdrpDoDebuggerBreak+0x2b:
771a1ba2 cc int 3
Which seems to be a standard breakpoint triggered by ntdll
but by the time this is triggered, we have already passed the address 0x4033ae
where I was trying to apply it. I realized that this is probably because the addressing scheme of the process seems to be mapped differently by the execution context within my OS / WinDbg and the qiling emulation. How can I begin debugging this problem, or at least finding the relevant breakpoint in WinDbg.
the query isn't exactly related to windbg
as I commented Qiling Framework hasn't yet implemented dotnet and needs someone to contribute the implementation
since this query has a windbg tag and a debugging tag too and
I have been wanting to test the Qiling framework for sometime now on a windows machine
I took this query as an opportunity to do so
Qiling is built upon unicorn emulation framework
I have dabbled with unicorn and found it quiet useful
installed Qiling [pip3 install Qiling] on a x64 windows10 machine windows documentation is quiet scarce and the one example disasm_x886_windows.py indicated in github repo is missing in the repo
had to scratch around to get a working setup
after installing Qiling it needs a virtual filesystem to operate upon with pertient windows dlls and registry hives
this is done by using the dllcollector.bat provided by in the repo
basically the collector.bat xcopies relevent 32 bit and 64 bit dlls and reg saves registry hives
now that we have collected the dlls lets copy two test binaries
one an x64 console app and
another a .net console binary and
write a python script to emulate them using QILING framework
the script as follows
the stop_on_exit_trap is added to avoid crashing of mcall.exe when it returns to crt from main() due to unreachable PC (0x0 as rip)
trace traces and prints all executed instructions
verbose provides some additional logs
executing the script we get
copying the mscoree.dll from system32 to rootfs/system2 and checking it crashes again with unmapped error as pointed in query
lets open the .net binary in an x64 windbg and check
so this binary needs the mscoree from syswow
Execution now doesnt crash