qilingframework / qiling

A True Instrumentable Binary Emulation Framework
https://qiling.io
GNU General Public License v2.0
5.07k stars 738 forks source link

Modify dll base address: msvbvm60.dll use hard-coded address in its instructions. #852

Closed frozenkp closed 3 years ago

frozenkp commented 3 years ago

Describe the bug We found that msvbvm60.dll uses several hard-coded addresses in its instructions. These addresses are based on the base address recorded in the dll header, and the base address should be 0x66000000. I read the code in loader/pe.py. The load_dll function maps each dll one by one from 0x10000000.

Here are the logs. Please look at instructions and machine codes in 0x102b2c96, 0x102b2c9b, and 0x102b2cbc.

[+] Sample is 32 bit
[+]     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: examples/rootfs/x86_windows\Windows\registry
[=]     Initiate stack address at 0xfffdd000
[=]     Loading c:\Users\VMadmin\Desktop\pestring\justificante_8726.exe\justificante_8726.exe to 0x400000
[=]     PE entry point at 0x401314
[=]     TEB addr is 0x6000
[=]     PEB addr is 0x6044
[=]     Loading examples/rootfs/x86_windows\Windows\System32\ntdll.dll to 0x10000000
[!]     Warnings while loading examples/rootfs/x86_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/x86_windows\Windows\System32\ntdll.dll
[=]     Loading examples/rootfs/x86_windows\Windows\System32\kernel32.dll to 0x101a3000
[=]     Done with loading examples/rootfs/x86_windows\Windows\System32\kernel32.dll
[=]     Loading examples/rootfs/x86_windows\Windows\System32\msvbvm60.dll to 0x10288000
[=]     Done with loading examples/rootfs/x86_windows\Windows\System32\msvbvm60.dll
[+]     Done with loading c:\Users\VMadmin\Desktop\pestring\justificante_8726.exe\justificante_8726.exe
[+]     00401314 | 6828144000               push       0x401428                                                 | esp = 0xffffd000
[+]     00401319 | e8f0ffffff               call       0x40130e                                                 | esp = 0xffffcffc, eip = 0x401319
[+]     0040130e | ff2500114000             jmp        dword ptr [0x401100]                                     |
[!]     api ThunRTMain is not implemented
[+]     102b2c91 | 55                       push       ebp                                                      | esp = 0xffffcff8, ebp = 0xffffd000
[+]     102b2c92 | 8bec                     mov        ebp, esp                                                 | esp = 0xffffcff4
[+]     102b2c94 | 6aff                     push       -0x1                                                     | esp = 0xffffcff4
[+]     102b2c96 | 6800b10266               push       0x6602b100                                               | esp = 0xffffcff0
[+]     102b2c9b | 68507c0f66               push       0x660f7c50                                               | esp = 0xffffcfec
[+]     102b2ca0 | 64a100000000             mov        eax, dword ptr [0x0]                                     | fs = 0x73
[+]     102b2ca6 | 50                       push       eax                                                      | esp = 0xffffcfe8, eax = 0x0
[+]     102b2ca7 | 64892500000000           mov        dword ptr [0x0], esp                                     | fs = 0x73, esp = 0xffffcfe4
[+]     102b2cae | 51                       push       ecx                                                      | esp = 0xffffcfe4, ecx = 0x0
[+]     102b2caf | 51                       push       ecx                                                      | esp = 0xffffcfe0, ecx = 0x0
[+]     102b2cb0 | 83ec4c                   sub        esp, 0x4c                                                | esp = 0xffffcfdc
[+]     102b2cb3 | 53                       push       ebx                                                      | esp = 0xffffcf90, ebx = 0x0
[+]     102b2cb4 | 56                       push       esi                                                      | esp = 0xffffcf8c, esi = 0x0
[+]     102b2cb5 | 57                       push       edi                                                      | esp = 0xffffcf88, edi = 0x0
[+]     102b2cb6 | 8965e8                   mov        dword ptr [0xffffcfdc], esp                              | ebp = 0xffffcff4, esp = 0xffffcf84
[+]     102b2cb9 | 8b7508                   mov        esi, dword ptr [0xffffcffc]                              | ebp = 0xffffcff4
[+]     102b2cbc | 8935c4411166             mov        dword ptr [0x661141c4], esi                              | esi = 0x401428
[+]     ERROR: unmapped memory access at 0x661141c4
[x]

[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      :        0xcf84
[x]     bp      :        0xcff4
[x]     si      :        0x1428
[x]     di      :        0x0
[x]     ip      :        0x2cbc
[x]     eax     :        0x0
[x]     ecx     :        0x0
[x]     edx     :        0x0
[x]     ebx     :        0x0
[x]     esp     :        0xffffcf84
[x]     ebp     :        0xffffcff4
[x]     esi     :        0x401428
[x]     edi     :        0x0
[x]     eip     :        0x102b2cbc
[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      :        0x84
[x]     cs      :        0x1b
[x]     ss      :        0x28
[x]     ds      :        0x28
[x]     es      :        0x28
[x]     fs      :        0x73
[x]     gs      :        0x78
[x]

[x]     PC = 0x102b2cbc
[x]      (examples/rootfs/x86_windows\Windows\System32\msvbvm60.dll+0x2acbc)
[=]     Start      End        Perm    Label          Image
[=]     00006000 - 0000c000   rwx     [FS/GS]
[=]     00030000 - 00031000   rwx     [GDT]
[=]     00400000 - 004b0000   rwx     [PE]           c:\Users\VMadmin\Desktop\pestring\justificante_8726.exe\justificante_8726.exe
[=]     05000000 - 05001000   rwx     [heap]
[=]     06000000 - 0c000000   rwx     [FS/GS]
[=]     10000000 - 101a3000   rwx     ntdll.dll      examples/rootfs/x86_windows\Windows\System32\ntdll.dll
[=]     101a3000 - 10288000   rwx     kernel32.dll   examples/rootfs/x86_windows\Windows\System32\kernel32.dll
[=]     10288000 - 103e5000   rwx     msvbvm60.dll   examples/rootfs/x86_windows\Windows\System32\msvbvm60.dll
[=]     fffdd000 - ffffe000   rwx     [stack]
[x]     ['0x89', '0x35', '0xc4', '0x41', '0x11', '0x66', '0x83', '0x65']
[=]

[=]     0x102b2cbc {msvbvm60.dll         + 0x02acbc}   89 35 c4 41 11 66 83 65 fc 00 8d 45 a0 50 ff 15 a0 10 00 66 0f b7 45 d0 a3 d0 44 11 66 ff 35 7c 93 11 66 56 be 80 40 11 66 8b ce e8 60 00 00 00 89 45 e4 85 c0 7d 17 50 e8 b0 3d ff ff 83 4d fc mov dword ptr [0x661141c4], esi
> and dword ptr [ebp - 4], 0
> lea eax, [ebp - 0x60]
> push eax
> call dword ptr [0x660010a0]
> movzx eax, word ptr [ebp - 0x30]
> mov dword ptr [0x661144d0], eax
> push dword ptr [0x6611937c]
> push esi
> mov esi, 0x66114080
> mov ecx, esi
> call 0x102b2d4c
> mov dword ptr [ebp - 0x1c], eax
> test eax, eax
> jge 0x102b2d0a
> push eax
> call 0x102a6aa9
Traceback (most recent call last):
  File "C:\Users\VMadmin\Desktop\pestring\qiling\latest.py", line 296, in <module>
    my_sandbox([exefile], "examples/rootfs/x86_windows")
  File "C:\Users\VMadmin\Desktop\pestring\qiling\latest.py", line 257, in my_sandbox
    ql.run()
  File "C:\Users\VMadmin\Desktop\pestring\qiling\qiling\core.py", line 755, in run
    self.os.run()
  File "C:\Users\VMadmin\Desktop\pestring\qiling\qiling\os\windows\windows.py", line 188, in run
    self.ql.emu_start(self.ql.loader.entry_point, self.exit_point, self.ql.timeout, self.ql.count)
  File "C:\Users\VMadmin\Desktop\pestring\qiling\qiling\core.py", line 896, in emu_start
    self.uc.emu_start(begin, end, timeout, count)
  File "C:\Users\VMadmin\AppData\Local\Programs\Python\Python39\lib\site-packages\unicorn\unicorn.py", line 341, in emu_start
    raise UcError(status)
unicorn.unicorn.UcError: Invalid memory write (UC_ERR_WRITE_UNMAPPED)

Sample Code nope

Expected behavior The msvbvm60.dll should be mapped to 0x66000000, instead of 0x10288000.

Screenshots Here is disasm of sym.MSVBVM60.DLL_ThunRTMain using radare2.

image

DLL header:

image

Additional context Add any other context about the problem here.

elicn commented 3 years ago

Hmm.. I think this is related to the risk of overlapping the heap. Let's try to push the heap base address a little bit further and give it another try.

Edit qiling/profiles/windows.ql and look for the [OS32] section. Under that section change the value of heap_address from its default 0x5000000 to 0x70000000 (note the additional 0). No other change needed, just save the file and re-run.

frozenkp commented 3 years ago

Hi, isn't libraries are loaded one by one on dll_address = 0x10000000? I think that we should load msvbvm60.dll into its base address 0x66000000.

Edit qiling/profiles/windows.ql and look for the [OS32] section. Under that section change the value of heap_address from its default 0x5000000 to 0x70000000 (note the additional 0). No other change needed, just save the file and re-run.

This move space for it, but the dll still be mapped on the same address. Is there any way to map it to the specific address?

elicn commented 3 years ago

Yes, you are right. I read the code the refers to PE loading and didn't notice DLL files are handled differently. As opposed to regular PE files, DLLs ImageBase property is not taken into acount and they are loaded to the same address every time. Let me see if I can qpply a quick patch.

elicn commented 3 years ago

The fix has been merged to the dev branch. Pull the latest changes and let me know if it works.

frozenkp commented 3 years ago

@elicn It works perfectly now. Thanks a lot. I really appreciate that.