mirror of
https://github.com/qilingframework/qiling.git
synced 2026-10-12 02:21:40 +00:00
Unify heap API hooks, address debug CRT init issues
This commit is contained in:
@@ -49,6 +49,17 @@ def hook_HeapCreate(ql: Qiling, address: int, params):
|
||||
|
||||
return ql.os.heap.alloc(dwInitialSize)
|
||||
|
||||
def _HeapAlloc(ql: Qiling, address: int, params):
|
||||
dwFlags = params["dwFlags"]
|
||||
dwBytes = params["dwBytes"]
|
||||
|
||||
ptr = ql.os.heap.alloc(dwBytes)
|
||||
|
||||
if ptr and (dwFlags & HEAP_ZERO_MEMORY):
|
||||
__zero_mem(ql.mem, ptr, dwBytes)
|
||||
|
||||
return ptr
|
||||
|
||||
# DECLSPEC_ALLOCATOR LPVOID HeapAlloc(
|
||||
# HANDLE hHeap,
|
||||
# DWORD dwFlags,
|
||||
@@ -60,15 +71,7 @@ def hook_HeapCreate(ql: Qiling, address: int, params):
|
||||
'dwBytes' : SIZE_T
|
||||
})
|
||||
def hook_HeapAlloc(ql: Qiling, address: int, params):
|
||||
dwFlags = params["dwFlags"]
|
||||
dwBytes = params["dwBytes"]
|
||||
|
||||
ptr = ql.os.heap.alloc(dwBytes)
|
||||
|
||||
if ptr and (dwFlags & HEAP_ZERO_MEMORY):
|
||||
__zero_mem(ql.mem, ptr, dwBytes)
|
||||
|
||||
return ptr
|
||||
return _HeapAlloc(ql, address, params)
|
||||
|
||||
# DECLSPEC_ALLOCATOR LPVOID HeapReAlloc(
|
||||
# HANDLE hHeap,
|
||||
@@ -86,6 +89,14 @@ def hook_HeapReAlloc(ql: Qiling, address: int, params):
|
||||
base = params["lpMem"]
|
||||
newSize = params["dwBytes"]
|
||||
|
||||
if not base:
|
||||
return _HeapAlloc(ql, address, params)
|
||||
|
||||
if newSize == 0:
|
||||
ql.os.heap.free(base)
|
||||
|
||||
return 0
|
||||
|
||||
oldSize = ql.os.heap.size(base)
|
||||
oldData = bytes(ql.mem.read(base, oldSize))
|
||||
|
||||
@@ -150,3 +161,29 @@ def hook_HeapSetInformation(ql: Qiling, address: int, params):
|
||||
@winsdkapi(cc=STDCALL, params={})
|
||||
def hook_GetProcessHeap(ql: Qiling, address: int, params):
|
||||
return ql.os.heap.start_address
|
||||
|
||||
# BOOL HeapValidate(
|
||||
# HANDLE hHeap,
|
||||
# DWORD dwFlags,
|
||||
# LPCVOID lpMem
|
||||
# );
|
||||
@winsdkapi(cc=STDCALL, params={
|
||||
'hHeap': PVOID,
|
||||
'dwFlags': DWORD,
|
||||
'lpMem': PVOID
|
||||
})
|
||||
def hook_HeapValidate(ql: Qiling, address: int, params):
|
||||
hHeap = params['hHeap']
|
||||
lpMem = params['lpMem']
|
||||
|
||||
if not hHeap:
|
||||
return 0
|
||||
|
||||
# TODO: Maybe _find is a heap manager implementation
|
||||
# detail, in which case we shouldn't rely on it.
|
||||
chunk = ql.os.heap._find(lpMem)
|
||||
|
||||
if not chunk:
|
||||
return 0
|
||||
|
||||
return chunk.inuse
|
||||
|
||||
@@ -135,10 +135,9 @@ def hook__controlfp(ql: Qiling, address: int, params):
|
||||
# );
|
||||
@winsdkapi(cc=CDECL, params={
|
||||
'func' : POINTER
|
||||
})
|
||||
}, passthru=True)
|
||||
def hook_atexit(ql: Qiling, address: int, params):
|
||||
ret = 0
|
||||
return ret
|
||||
return
|
||||
|
||||
# char*** __p__environ(void)
|
||||
@winsdkapi(cc=CDECL, params={})
|
||||
@@ -211,20 +210,12 @@ def hook___p___argc(ql: Qiling, address: int, params):
|
||||
return ret
|
||||
|
||||
# TODO: this one belongs to ucrtbase.dll
|
||||
@winsdkapi(cc=CDECL, params={})
|
||||
@winsdkapi(cc=CDECL, params={}, passthru=True)
|
||||
def hook__get_initial_narrow_environment(ql: Qiling, address: int, params):
|
||||
ret = 0
|
||||
|
||||
for i, (k, v) in enumerate(ql.env.items()):
|
||||
entry = bytes(f'{k}={v}', 'ascii') + b'\x00'
|
||||
p_entry = ql.os.heap.alloc(len(entry))
|
||||
|
||||
ql.mem.write(p_entry, entry)
|
||||
|
||||
if i == 0:
|
||||
ret = p_entry
|
||||
|
||||
return ret
|
||||
# If the native version of this function does not
|
||||
# get to run, then debug versions of the CRT DLLs can fail
|
||||
# their initialization.
|
||||
return
|
||||
|
||||
# int sprintf ( char * str, const char * format, ... );
|
||||
@winsdkapi(cc=CDECL, params={
|
||||
@@ -339,6 +330,18 @@ def __stdio_common_vsprintf(ql: Qiling, address: int, params, wstring: bool):
|
||||
def hook___stdio_common_vsprintf(ql: Qiling, address: int, params):
|
||||
return __stdio_common_vsprintf(ql, address, params, False)
|
||||
|
||||
@winsdkapi(cc=CDECL, params={
|
||||
'_Options' : PARAM_INT64,
|
||||
'_Buffer' : POINTER,
|
||||
'_BufferCount' : SIZE_T,
|
||||
'_MaxCount' : SIZE_T,
|
||||
'_Format' : STRING,
|
||||
'_Locale' : DWORD,
|
||||
'_ArgList' : POINTER
|
||||
})
|
||||
def hook___stdio_common_vsnprintf(ql: Qiling, address: int, params):
|
||||
return __stdio_common_vsprintf(ql, address, params, False)
|
||||
|
||||
@winsdkapi(cc=CDECL, params={
|
||||
'_Options' : PARAM_INT64,
|
||||
'_Buffer' : POINTER,
|
||||
@@ -350,6 +353,18 @@ def hook___stdio_common_vsprintf(ql: Qiling, address: int, params):
|
||||
def hook___stdio_common_vswprintf(ql: Qiling, address: int, params):
|
||||
return __stdio_common_vsprintf(ql, address, params, True)
|
||||
|
||||
@winsdkapi(cc=CDECL, params={
|
||||
'_Options' : PARAM_INT64,
|
||||
'_Buffer' : POINTER,
|
||||
'_BufferCount' : SIZE_T,
|
||||
'_MaxCount' : SIZE_T,
|
||||
'_Format' : WSTRING,
|
||||
'_Locale' : DWORD,
|
||||
'_ArgList' : POINTER
|
||||
})
|
||||
def hook___stdio_common_vsnwprintf(ql: Qiling, address: int, params):
|
||||
return __stdio_common_vsprintf(ql, address, params, True)
|
||||
|
||||
# all the "_s" versions are aliases to their non-"_s" counterparts
|
||||
|
||||
@winsdkapi(cc=CDECL, params={
|
||||
@@ -383,6 +398,18 @@ def hook___stdio_common_vfwprintf_s(ql: Qiling, address: int, params):
|
||||
def hook___stdio_common_vsprintf_s(ql: Qiling, address: int, params):
|
||||
return hook___stdio_common_vsprintf.__wrapped__(ql, address, params)
|
||||
|
||||
@winsdkapi(cc=CDECL, params={
|
||||
'_Options' : PARAM_INT64,
|
||||
'_Buffer' : POINTER,
|
||||
'_BufferCount' : SIZE_T,
|
||||
'_MaxCount' : SIZE_T,
|
||||
'_Format' : STRING,
|
||||
'_Locale' : DWORD,
|
||||
'_ArgList' : POINTER
|
||||
})
|
||||
def hook___stdio_common_vsnprintf_s(ql: Qiling, address: int, params):
|
||||
return hook___stdio_common_vsnprintf.__wrapped__(ql, address, params)
|
||||
|
||||
@winsdkapi(cc=CDECL, params={
|
||||
'_Options' : PARAM_INT64,
|
||||
'_Buffer' : POINTER,
|
||||
@@ -394,6 +421,18 @@ def hook___stdio_common_vsprintf_s(ql: Qiling, address: int, params):
|
||||
def hook___stdio_common_vswprintf_s(ql: Qiling, address: int, params):
|
||||
return hook___stdio_common_vswprintf.__wrapped__(ql, address, params)
|
||||
|
||||
@winsdkapi(cc=CDECL, params={
|
||||
'_Options' : PARAM_INT64,
|
||||
'_Buffer' : POINTER,
|
||||
'_BufferCount' : SIZE_T,
|
||||
'_MaxCount' : SIZE_T,
|
||||
'_Format' : WSTRING,
|
||||
'_Locale' : DWORD,
|
||||
'_ArgList' : POINTER
|
||||
})
|
||||
def hook___stdio_common_vsnwprintf_s(ql: Qiling, address: int, params):
|
||||
return hook___stdio_common_vsnwprintf.__wrapped__(ql, address, params)
|
||||
|
||||
@winsdkapi(cc=CDECL, params={})
|
||||
def hook___lconv_init(ql: Qiling, address: int, params):
|
||||
return 0
|
||||
@@ -449,50 +488,18 @@ def hook_strncmp(ql: Qiling, address: int, params):
|
||||
|
||||
return result
|
||||
|
||||
def __malloc(ql: Qiling, address: int, params):
|
||||
size = params['size']
|
||||
|
||||
return ql.os.heap.alloc(size)
|
||||
|
||||
@winsdkapi(cc=CDECL, params={
|
||||
'size' : UINT
|
||||
})
|
||||
}, passthru=True)
|
||||
def hook__malloc_base(ql: Qiling, address: int, params):
|
||||
return __malloc(ql, address, params)
|
||||
return
|
||||
|
||||
# void* malloc(unsigned int size)
|
||||
@winsdkapi(cc=CDECL, params={
|
||||
'size' : UINT
|
||||
})
|
||||
}, passthru=True)
|
||||
def hook_malloc(ql: Qiling, address: int, params):
|
||||
size = params['size']
|
||||
|
||||
return ql.os.heap.alloc(size)
|
||||
|
||||
def __realloc(ql: Qiling, address: int, params):
|
||||
block = params['block']
|
||||
size = params['size']
|
||||
|
||||
if not block:
|
||||
return ql.os.heap.alloc(size)
|
||||
|
||||
if size == 0:
|
||||
ql.os.heap.free(block)
|
||||
return 0
|
||||
|
||||
oldSize = ql.os.heap.size(block)
|
||||
oldData = bytes(ql.mem.read(block, size))
|
||||
ql.os.heap.free(block)
|
||||
|
||||
if size < oldSize:
|
||||
oldData = oldData[0:size]
|
||||
|
||||
newBase = ql.os.heap.alloc(size)
|
||||
|
||||
if newBase:
|
||||
ql.mem.write(newBase, oldData)
|
||||
|
||||
return newBase
|
||||
return
|
||||
|
||||
# void* __cdecl _realloc_base(
|
||||
# void* const block,
|
||||
@@ -501,27 +508,22 @@ def __realloc(ql: Qiling, address: int, params):
|
||||
@winsdkapi(cc=CDECL, params={
|
||||
'block' : POINTER,
|
||||
'size' : UINT
|
||||
})
|
||||
}, passthru=True)
|
||||
def hook__realloc_base(ql: Qiling, address: int, params):
|
||||
return __realloc(ql, address, params)
|
||||
|
||||
def __free(ql: Qiling, address: int, params):
|
||||
address = params['address']
|
||||
|
||||
ql.os.heap.free(address)
|
||||
return
|
||||
|
||||
@winsdkapi(cc=CDECL, params={
|
||||
'address': POINTER
|
||||
})
|
||||
}, passthru=True)
|
||||
def hook__free_base(ql: Qiling, address: int, params):
|
||||
return __free(ql, address, params)
|
||||
return
|
||||
|
||||
# void* free(void *address)
|
||||
@winsdkapi(cc=CDECL, params={
|
||||
'address': POINTER
|
||||
})
|
||||
}, passthru=True)
|
||||
def hook_free(ql: Qiling, address: int, params):
|
||||
return __free(ql, address, params)
|
||||
return
|
||||
|
||||
# _onexit_t _onexit(
|
||||
# _onexit_t function
|
||||
@@ -546,32 +548,16 @@ def hook__onexit(ql: Qiling, address: int, params):
|
||||
'dest' : POINTER,
|
||||
'c' : INT,
|
||||
'count' : SIZE_T
|
||||
})
|
||||
}, passthru=True)
|
||||
def hook_memset(ql: Qiling, address: int, params):
|
||||
dest = params["dest"]
|
||||
c = params["c"]
|
||||
count = params["count"]
|
||||
|
||||
ql.mem.write(dest, bytes([c] * count))
|
||||
|
||||
return dest
|
||||
|
||||
def __calloc(ql: Qiling, address: int, params):
|
||||
num = params['num']
|
||||
size = params['size']
|
||||
|
||||
count = num * size
|
||||
ret = ql.os.heap.alloc(count)
|
||||
ql.mem.write(ret, bytes([0] * count))
|
||||
|
||||
return ret
|
||||
return
|
||||
|
||||
@winsdkapi(cc=CDECL, params={
|
||||
'num' : SIZE_T,
|
||||
'size' : SIZE_T
|
||||
})
|
||||
}, passthru=True)
|
||||
def hook__calloc_base(ql: Qiling, address: int, params):
|
||||
return __calloc(ql, address, params)
|
||||
return
|
||||
|
||||
# void *calloc(
|
||||
# size_t num,
|
||||
@@ -580,9 +566,9 @@ def hook__calloc_base(ql: Qiling, address: int, params):
|
||||
@winsdkapi(cc=CDECL, params={
|
||||
'num' : SIZE_T,
|
||||
'size' : SIZE_T
|
||||
})
|
||||
}, passthru=True)
|
||||
def hook_calloc(ql: Qiling, address: int, params):
|
||||
return __calloc(ql, address, params)
|
||||
return
|
||||
|
||||
# void * memmove(
|
||||
# void *dest,
|
||||
@@ -593,12 +579,9 @@ def hook_calloc(ql: Qiling, address: int, params):
|
||||
'dest' : POINTER,
|
||||
'src' : POINTER,
|
||||
'num' : SIZE_T
|
||||
})
|
||||
}, passthru=True)
|
||||
def hook_memmove(ql: Qiling, address: int, params):
|
||||
data = ql.mem.read(params['src'], params['num'])
|
||||
ql.mem.write(params['dest'], bytes(data))
|
||||
|
||||
return params['dest']
|
||||
return
|
||||
|
||||
# int _ismbblead(
|
||||
# unsigned int c
|
||||
|
||||
Reference in New Issue
Block a user