qilingframework / qiling

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

set_api: api is not implemented #427

Closed 0xdarkfloyd closed 4 years ago

0xdarkfloyd commented 4 years ago

*Describe the bug Dear folks,

I have tried to implement CryptStringToBinaryW (in fact, I simply copy CryptStringToBinaryA) and see whether I can call it. I have found Crypt32.py and add method, it gives CryptStringToBinaryW is not implemented. After discussing with KJ, I have used set_api and refer to the example, it still can't find the method with the same error as I try to emulate a malware.

Thank you so much to your advice.

Regards, Anthony

Sample Code

from qiling import *
from qiling.os.windows.fncc import *
from qiling.os.windows.utils import *
from qiling.os.windows.dlls import *
from qiling.const import *

@winsdkapi(cc=STDCALL, dllname=dllname, replace_params_type={'BYTE': 'POINTER'},replace_params={"pcbBinary": POINTER, "pdwSkip": POINTER, "pdwFlags": POINTER})
def CryptStringToBinaryW(self, address, params):
    flag_src = params["dwFlags"]
    string_src = params["pszString"]
    size_src = params["cchString"]
    size_dst_pointer = params["pcbBinary"]
    string_dst = params["pbBinary"]
    flag_dst = params["pdwFlags"]

    size_dst = int.from_bytes(ql.mem.read(size_dst_pointer, 4), byteorder="little")
    if size_dst != 0 and size_dst < size_src:
        raise QlErrorNotImplemented("[!] API not implemented")
    if flag_src == CRYPT_STRING_BASE64:
        # Had a padding error, hope this always works
        add_pad = 4 - (len(string_src) % 4)
        if add_pad != 4:
            string_src += "=" * add_pad
        output = base64.b64decode(string_src).decode("utf-16le") + "\x00"
    else:
        ql.dprint(D_INFO, "Flag")
        ql.dprint(D_INFO, flag_src)
        raise QlErrorNotImplemented("[!] API not implemented")

    if string_dst == 0:
        # Only wants the length
        return len(output)
    else:
        if flag_dst != 0:
            # Is optional
            ql.mem.write(flag_dst, flag_src.to_bytes(length=4, byteorder='little'))
        # Write size
        ql.mem.write(size_dst_pointer, len(output).to_bytes(length=4, byteorder='little'))
        # Write result
        ql.mem.write(string_dst, bytes(output, encoding="utf-16le"))
    return 1

def my_sandbox(path,rootfs):
        ql = Qiling(path, rootfs)
        ql.set_api("CryptStringToBinaryW",CryptStringToBinaryW)
        ql.run()

if __name__ == "__main__":

     my_sandbox(["/home/hacker/Desktop/qiling/examples/rootfs/x86_windows/bin/hhh.bin"],"rootfs/x86_windows")

Expected behavior A clear and concise description of what you expected to happen.

Screenshots I have attached an emulation logs as below:

....... RtlAllocateHeap(HeapHandle = 0x5051774, Flags = 0x8, Size = 0xb4) = 0x5160c70 MultiByteToWideChar(CodePage = 0x0, dwFlags = 0x0, lpMultiByteStr = "PoHHWlVx1wsDR7XMMPaEWJr71mr/jSBC/B4hkwJTN0c=", cbMultiByte = 0xffffffff, lpWideCharStr = 0x5160c70, cchWideChar = 0x5a) = 0x5a [!] CryptStringToBinaryW is not implemented [!] Emulation Error

[-] ah : 0xcd [-] al : 0xcc [-] ch : 0x98 [-] cl : 0x6c [-] dh : 0x8a [-] dl : 0xb0 [-] bh : 0x0 [-] bl : 0x0 [-] ax : 0xcdcc [-] cx : 0x986c [-] dx : 0x8ab0 [-] bx : 0x0 [-] sp : 0xcd40 [-] bp : 0xcd94 [-] si : 0xc70 [-] di : 0xcde4 [-] ip : 0x8388 [-] eax : 0xffffcdcc [-] ecx : 0x515986c [-] edx : 0x5158ab0 [-] ebx : 0x0 [-] esp : 0xffffcd40 [-] ebp : 0xffffcd94 [-] esi : 0x5160c70 [-] edi : 0xffffcde4 [-] eip : 0x107b8388 [-] cr0 : 0x11 [-] cr1 : 0x0 [-] cr2 : 0x0 [-] cr3 : 0x0 [-] cr4 : 0x0 [-] cr5 : 0x0 [-] cr6 : 0x0 [-] cr7 : 0x0 [-] cr8 : 0x0 [-] cr9 : 0x0 [-] cr10 : 0x0 [-] cr11 : 0x0 [-] cr12 : 0x0 [-] cr13 : 0x0 [-] cr14 : 0x0 [-] cr15 : 0x0 [-] st0 : 0x0 [-] st1 : 0x0 [-] st2 : 0x0 [-] st3 : 0x0 [-] st4 : 0x0 [-] st5 : 0x0 [-] st6 : 0x0 [-] st7 : 0xa000000000000000 [-] ef : 0x80 [-] cs : 0x1b [-] ss : 0x28 [-] ds : 0x28 [-] es : 0x28 [-] fs : 0x73 [-] gs : 0x78

[+] PC = 0x107b8388 (rootfs/x86_windows/Windows/SysWOW64/crypt32.dll+0x46388) [+] Start End Perm. Path [+] 00003000 - 00004000 - rwx [GDT] [+] 00006000 - 0000c000 - rwx [FS/GS] [+] 00400000 - 00421000 - rwx [PE] (/home/hacker/Desktop/qiling/examples/rootfs/x86_windows/bin/hhh.bin) [+] 05000000 - 05001000 - rwx [heap] [+] 05001000 - 05002000 - rwx [heap] [+] 05002000 - 05003000 - rwx [heap] [+] 05003000 - 05004000 - rwx [heap] [+] 05004000 - 05005000 - rwx [heap] [+] 05005000 - 05006000 - rwx [heap] [+] 05006000 - 05007000 - rwx [heap] [+] 05007000 - 05008000 - rwx [heap] [+] 05008000 - 05009000 - rwx [heap] [+] 05009000 - 0500a000 - rwx [heap] [+] 0500a000 - 0500b000 - rwx [heap] [+] 0500b000 - 0500c000 - rwx [heap] [+] 0500c000 - 0500d000 - rwx [heap] [+] 0500d000 - 0500e000 - rwx [heap] [+] 0500e000 - 0500f000 - rwx [heap] [+] 0500f000 - 05010000 - rwx [heap] [+] 05010000 - 05011000 - rwx [heap] [+] 05011000 - 05012000 - rwx [heap] [+] 05012000 - 05013000 - rwx [heap] [+] 05013000 - 05014000 - rwx [heap] [+] 05014000 - 05015000 - rwx [heap] [+] 05015000 - 05016000 - rwx [heap] [+] 05016000 - 05017000 - rwx [heap] [+] 05017000 - 05018000 - rwx [heap] [+] 05018000 - 05019000 - rwx [heap] [+] 05019000 - 0501a000 - rwx [heap] [+] 0501a000 - 0501b000 - rwx [heap] [+] 0501b000 - 0501c000 - rwx [heap] [+] 0501c000 - 0501d000 - rwx [heap] [+] 0501d000 - 0501e000 - rwx [heap] [+] 0501e000 - 0501f000 - rwx [heap] [+] 0501f000 - 05020000 - rwx [heap] [+] 05020000 - 05021000 - rwx [heap] [+] 05021000 - 05022000 - rwx [heap] [+] 05022000 - 05023000 - rwx [heap] [+] 05023000 - 05024000 - rwx [heap] [+] 05024000 - 05025000 - rwx [heap] [+] 05025000 - 05026000 - rwx [heap] [+] 05026000 - 05027000 - rwx [heap] [+] 05027000 - 05028000 - rwx [heap] [+] 05028000 - 05029000 - rwx [heap] [+] 05029000 - 0502a000 - rwx [heap] [+] 0502a000 - 0502b000 - rwx [heap] [+] 0502b000 - 0502c000 - rwx [heap] [+] 0502c000 - 0502d000 - rwx [heap] [+] 0502d000 - 0502e000 - rwx [heap] [+] 0502e000 - 0502f000 - rwx [heap] [+] 0502f000 - 05030000 - rwx [heap] [+] 05030000 - 05031000 - rwx [heap] [+] 05031000 - 05032000 - rwx [heap] [+] 05032000 - 05033000 - rwx [heap] [+] 05033000 - 05034000 - rwx [heap] [+] 05034000 - 05035000 - rwx [heap] [+] 05035000 - 05036000 - rwx [heap] [+] 05036000 - 05037000 - rwx [heap] [+] 05037000 - 05038000 - rwx [heap] [+] 05038000 - 05039000 - rwx [heap] [+] 05039000 - 0503a000 - rwx [heap] [+] 0503a000 - 0503b000 - rwx [heap] [+] 0503b000 - 0503c000 - rwx [heap] [+] 0503c000 - 0503d000 - rwx [heap] [+] 0503d000 - 0503e000 - rwx [heap] [+] 0503e000 - 0503f000 - rwx [heap] [+] 0503f000 - 05040000 - rwx [heap] [+] 05040000 - 05041000 - rwx [heap] [+] 05041000 - 05042000 - rwx [heap] [+] 05042000 - 05043000 - rwx [heap] [+] 05043000 - 05044000 - rwx [heap] [+] 05044000 - 05045000 - rwx [heap] [+] 05045000 - 05046000 - rwx [heap] [+] 05046000 - 05047000 - rwx [heap] [+] 05047000 - 05048000 - rwx [heap] [+] 05048000 - 05049000 - rwx [heap] [+] 05049000 - 0504a000 - rwx [heap] [+] 0504a000 - 0504b000 - rwx [heap] [+] 0504b000 - 0504c000 - rwx [heap] [+] 0504c000 - 0504d000 - rwx [heap] [+] 0504d000 - 0504e000 - rwx [heap] [+] 0504e000 - 0504f000 - rwx [heap] [+] 0504f000 - 05050000 - rwx [heap] [+] 05050000 - 05051000 - rwx [heap] [+] 05051000 - 05052000 - rwx [heap] [+] 05052000 - 05152000 - rwx [heap] [+] 05152000 - 0515a000 - rwx [heap] [+] 0515a000 - 05160000 - rwx [heap] [+] 05160000 - 05162000 - rwx [heap] [+] 10000000 - 1019a000 - rwx ntdll.dll (rootfs/x86_windows/Windows/SysWOW64/ntdll.dll) [+] 1019a000 - 1026f000 - rwx kernel32.dll (rootfs/x86_windows/Windows/SysWOW64/ntdll.dll) [+] 1026f000 - 10406000 - rwx user32.dll (rootfs/x86_windows/Windows/SysWOW64/kernel32.dll) [+] 10406000 - 104c3000 - rwx winhttp.dll (rootfs/x86_windows/Windows/SysWOW64/user32.dll) [+] 104c3000 - 105ba000 - rwx ole32.dll (rootfs/x86_windows/Windows/SysWOW64/winhttp.dll) [+] 105ba000 - 10633000 - rwx advapi32.dll (rootfs/x86_windows/Windows/SysWOW64/ole32.dll) [+] 10633000 - 10677000 - rwx shlwapi.dll (rootfs/x86_windows/Windows/SysWOW64/advapi32.dll) [+] 10677000 - 106a7000 - rwx rstrtmgr.dll (rootfs/x86_windows/Windows/SysWOW64/shlwapi.dll) [+] 106a7000 - 10739000 - rwx oleaut32.dll (rootfs/x86_windows/Windows/SysWOW64/rstrtmgr.dll) [+] 10739000 - 1075a000 - rwx gdi32.dll (rootfs/x86_windows/Windows/SysWOW64/oleaut32.dll) [+] 1075a000 - 10772000 - rwx mpr.dll (rootfs/x86_windows/Windows/SysWOW64/gdi32.dll) [+] 10772000 - 1086d000 - rwx crypt32.dll (rootfs/x86_windows/Windows/SysWOW64/mpr.dll) [+] 1086d000 - 10de6000 - rwx shell32.dll (rootfs/x86_windows/Windows/SysWOW64/crypt32.dll) [+] 10de6000 - 10e0a000 - rwx winmm.dll (rootfs/x86_windows/Windows/SysWOW64/shell32.dll) [+] fffdd000 - ffffe000 - rwx [stack] [+] ['0xa1', '0xe4', '0x83', '0xfe', '0x5c', '0x33', '0xc5', '0x89']

[+] 0x107b8388 a1 e4 83 fe 5c 33 c5 89 45 fc 8b 45 14 33 d2 8b 4d 18 89 45 b0 8b 45 1c 53 8b 5d 08 89 45 b4 8b 45 20 56 8b 75 0c 89 45 b8 8b 45 10 89 4d c4 89 55 bc 89 55 c0 89 45 ac 57 8b fa 83 f8 07 0f 84 mov eax, dword ptr [0x5cfe83e4] xor eax, ebp mov dword ptr [ebp - 4], eax mov eax, dword ptr [ebp + 0x14] xor edx, edx mov ecx, dword ptr [ebp + 0x18] mov dword ptr [ebp - 0x50], eax mov eax, dword ptr [ebp + 0x1c] push ebx mov ebx, dword ptr [ebp + 8] mov dword ptr [ebp - 0x4c], eax mov eax, dword ptr [ebp + 0x20] push esi mov esi, dword ptr [ebp + 0xc] mov dword ptr [ebp - 0x48], eax mov eax, dword ptr [ebp + 0x10] mov dword ptr [ebp - 0x3c], ecx mov dword ptr [ebp - 0x44], edx mov dword ptr [ebp - 0x40], edx mov dword ptr [ebp - 0x54], eax push edi mov edi, edx cmp eax, 7 Traceback (most recent call last): File "x86_hello.py", line 53, in my_sandbox(["/home/hacker/Desktop/qiling/examples/rootfs/x86_windows/bin/hhh.bin"],"rootfs/x86_windows") File "x86_hello.py", line 47, in my_sandbox q1.run() File "/home/hacker/.local/lib/python3.6/site-packages/qiling/core.py", line 198, in run self.os.run() File "/home/hacker/.local/lib/python3.6/site-packages/qiling/os/windows/windows.py", line 141, in run self.ql.emu_start(self.ql.loader.entry_point, self.exit_point, self.ql.timeout, self.ql.count) File "/home/hacker/.local/lib/python3.6/site-packages/qiling/core.py", line 257, in emu_start self.uc.emu_start(begin, end, timeout, count) File "/home/hacker/.local/lib/python3.6/site-packages/unicorn/unicorn.py", line 317, in emu_start raise UcError(status) unicorn.unicorn.UcError: Invalid memory read (UC_ERR_READ_UNMAPPED)

Additional context Add any other context about the problem here.

xwings commented 4 years ago

Do u have the binary ?

0xdarkfloyd commented 4 years ago

hhh.bin.zip

password: infected

xwings commented 4 years ago

There are some syntax error in your code, so i guess that could be one issue. I tested with set api it works. so your next issue is RtlAllocateHeap.

image

Btw, From Wide Char and Ascii conversion, please refer to

https://docs.qiling.io/en/latest/faq/#windows-api-often-comes-with-functionsa-and-functionw-do-i-need-to-implement-both

FYI, i added CryptStringToBinaryW into the code, so checkout dev will help.

0xdarkfloyd commented 4 years ago

Thank you so much.