qiling icon indicating copy to clipboard operation
qiling copied to clipboard

Confirming That This Emulation Error Isn't Actually A Bug

Open the-wondersmith opened this issue 4 years ago • 9 comments

*Describe the bug I'm just trying to confirm that this behavior is what I think it is. I pulled all of the DLL's the program I'm playing with depends on in their expected places and then ran the program in Qiling using

qltool run -f C:\sandbox\windows_rootfs\investigation\program.exe --rootfs C:\sandbox\windows_rootfs\

Qiling then com plains that _lopen isn't implemented and throws an exception regarding an emulation error. The full output is in a gist here.

There appears to be a definition of some kind for _lopen in qiling/extensions/windows_sdk/defs/kernel32_dll.json, but I don't know if that's a stub of some kind or what....

I read through several issues opened in regards to the Unicorn error that's raised (UC_ERR_READ_UNMAPPED), and the general consensus seemed to be "the Windows APIs need more community support". Is this one of those "needs more community support" issues? Or did I mess up the rootfs setup or something?

If it's a community support issue, I'd be more than happy to help out if someone points me in the right direction.

the-wondersmith avatar Oct 11 '20 21:10 the-wondersmith

@xwings Is there any way you could point me in the right direction?

the-wondersmith avatar Oct 12 '20 22:10 the-wondersmith

Yes. The json file is just a header defination. The _lopen still need to be implemented

xwings avatar Oct 12 '20 23:10 xwings

@xwings I've been investigating this particular program in Ghidra and API Monitor, so I (conveniently) happen to have good records of all the API calls it's making, what it's supplying as arguments, what it's expecting for return values, and datatypes for both.

If you point me in the right direction (or give me a quick "how to") I'll do all of the implementation for all the calls it makes and file a PR.

the-wondersmith avatar Oct 12 '20 23:10 the-wondersmith

You can find most of the API in Wine. You just need to convert to Python + Qiling way (check how other API works)

https://github.com/wine-mirror/wine/blob/83e481fee20bc5c6598e65f8295be1b3f11fb70b/dlls/kernel32/file.c#L774

xwings avatar Oct 13 '20 00:10 xwings

@xwings I figured as much. Just having trouble finding a clear / simple example in the Qiling codebase. Can you point me to an example of Qiling's implementation of something like _lopen?

I.E. _lopen takes a str and an int (filepath and mode) as arguments and returns a file handle. What's that look like in the Qiling codebase?

the-wondersmith avatar Oct 13 '20 00:10 the-wondersmith

Maybe you can take a look at this

https://github.com/qilingframework/qiling/tree/dev/qiling/os/windows/dlls/kernel32

xwings avatar Oct 13 '20 00:10 xwings

@xwings That'll work!

Just to confirm, for every missing call I need to convert this into this. Do I have that correct?

the-wondersmith avatar Oct 13 '20 01:10 the-wondersmith

@xwings I'm pretty sure the rough-and-tumble mapping I've got here for file access modes isn't correct, but other than that I think this is a half-decent Python approximation of what _lopen is doing. Could I impose on you just a bit longer and ask for you to eyeball it for me?

from typing import Dict, Union

from qiling import Qiling
from qiling.os.const import STDCALL
from qiling.os.windows.fncc import winsdkapi


dllname = "kernel32_dll"


# HFILE _lopen(
#  LPCSTR lpPathName,
#  INT iReadWrite
#  );
@winsdkapi(cc=STDCALL, dllname=dllname, replace_params_type={"lpPathName": "LPCSTR", "iReadWrite": "int"})
def hook__lopen(ql: Qiling, address: int, params: Dict[str, Union[str, int]]):
    """ Hook and emulate `_lopen`.

    `lpPathName` is a pointer to a null-terminated string that names the file to open.
    The string must consist of characters from the Windows ANSI character set.

    `iReadWrite` specifies the modes in which to open the file. This parameter consists of one access mode
    and an optional share mode. The access mode must be one of the following values:

    OF_READ - 0x00000000
    OF_READWRITE - 0x00000002
    OF_WRITE - 0x00000001

    The share mode can be one of the following values:

    OF_SHARE_COMPAT - 0x00000000
    OF_SHARE_DENY_NONE - 0x00000040
    OF_SHARE_DENY_READ - 0x00000030
    OF_SHARE_DENY_WRITE - 0x00000020
    OF_SHARE_EXCLUSIVE - 0x00000010
    """
    mode = {0: "rb", 1: "ab+", 2: "ab+"}.get(params["iReadWrite"])
    return ql.os.fs_mapper.open(params["lpPathName"], mode)

Also, as a side note, there appears to be absolutely no type annotations in Qiling. Do I need to strip them from anything I submit in a PR?

the-wondersmith avatar Oct 13 '20 03:10 the-wondersmith

maybe you need a independent file file mapping for each cons. this could be os dependent.

checkout the linux implementation and do it ?

or we can move this discussion to during your PR

xwings avatar Oct 13 '20 03:10 xwings

Will you be able to try the latest version of Qiling and see if you still face same issue. There is lots of rework since Oct 2020. Feel free to open a new issue if you have any similar problem.

xwings avatar Oct 06 '22 03:10 xwings