From 8ca5b1a05156ffa0dcb6ca67df693137e147d8d3 Mon Sep 17 00:00:00 2001 From: Bottersnike Date: Fri, 14 Jul 2023 20:26:25 +0100 Subject: [PATCH] Use handles as an index into the data array --- src/micetools/dll/comdevice.c | 2 +- src/micetools/dll/hooks/com.c | 18 ++--- src/micetools/dll/hooks/drive/hooks.c | 8 +-- src/micetools/dll/hooks/files.c | 16 ++--- src/micetools/dll/util/_util.h | 10 +-- src/micetools/dll/util/misc.c | 100 ++++++++++++++------------ src/micetools/lib/mice/da.c | 9 +++ src/micetools/lib/mice/da.h | 2 + 8 files changed, 89 insertions(+), 76 deletions(-) diff --git a/src/micetools/dll/comdevice.c b/src/micetools/dll/comdevice.c index 7a0df24..de4ac44 100644 --- a/src/micetools/dll/comdevice.c +++ b/src/micetools/dll/comdevice.c @@ -3,7 +3,7 @@ #define RESERVED_JVS_COM_PORT 4 com_device_t* GetComDevice(HANDLE hFile) { - open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); + open_hook_t* pHData = GetDataForHandle(hFile); if (pHData == NULL || pHData->hook == NULL || pHData->hook->com_hook == NULL) return NULL; return pHData->hook->com_hook->com_device; } diff --git a/src/micetools/dll/hooks/com.c b/src/micetools/dll/hooks/com.c index b5b8d51..019e4c5 100644 --- a/src/micetools/dll/hooks/com.c +++ b/src/micetools/dll/hooks/com.c @@ -27,7 +27,7 @@ com_hook_t* new_com_hook(BYTE port) { } BOOL WINAPI FakeGetCommState(HANDLE hFile, LPDCB lpDCB) { - open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); + open_hook_t* pHData = GetDataForHandle(hFile); log_misc(plfComm, "GetCommState(0x%p, 0x%p) (%08x)", hFile, lpDCB, hook); if (pHData == NULL || pHData->hook->com_hook == NULL) return TrueGetCommState(hFile, lpDCB); @@ -43,7 +43,7 @@ BOOL WINAPI FakeGetCommState(HANDLE hFile, LPDCB lpDCB) { BOOL WINAPI FakeSetCommState(HANDLE hFile, LPDCB lpDCB) { log_misc(plfComm, "SetCommState(0x%p, 0x%p)", hFile, lpDCB); - open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); + open_hook_t* pHData = GetDataForHandle(hFile); if (pHData == NULL || pHData->hook->com_hook == NULL) return TrueSetCommState(hFile, lpDCB); com_hook_t* com_hook = pHData->hook->com_hook; @@ -57,7 +57,7 @@ BOOL WINAPI FakeSetCommState(HANDLE hFile, LPDCB lpDCB) { BOOL WINAPI FakeGetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) { log_misc(plfComm, "GetCommTimeouts(0x%p, 0x%p)", hFile, lpCommTimeouts); - open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); + open_hook_t* pHData = GetDataForHandle(hFile); if (pHData == NULL || pHData->hook->com_hook == NULL) return TrueGetCommTimeouts(hFile, lpCommTimeouts); @@ -72,7 +72,7 @@ BOOL WINAPI FakeGetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) { BOOL WINAPI FakeSetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) { log_misc(plfComm, "SetCommTimeouts(0x%p, 0x%p)", hFile, lpCommTimeouts); - open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); + open_hook_t* pHData = GetDataForHandle(hFile); if (pHData == NULL || pHData->hook->com_hook == NULL) return TrueSetCommTimeouts(hFile, lpCommTimeouts); @@ -87,7 +87,7 @@ BOOL WINAPI FakeSetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) { BOOL WINAPI FakeSetupComm(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue) { log_misc(plfComm, "SetupCom(0x%p, 0x%08x, 0x%08x)", hFile, dwInQueue, dwOutQueue); - open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); + open_hook_t* pHData = GetDataForHandle(hFile); if (pHData == NULL || pHData->hook->com_hook == NULL) return TrueSetupComm(hFile, dwInQueue, dwOutQueue); @@ -102,7 +102,7 @@ BOOL WINAPI FakeSetupComm(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue) { BOOL WINAPI FakePurgeComm(HANDLE hFile, DWORD dwFlags) { log_misc(plfComm, "PurgeComm(0x%p, 0x%08x)", hFile, dwFlags); - open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); + open_hook_t* pHData = GetDataForHandle(hFile); if (pHData == NULL || pHData->hook->com_hook == NULL) return TruePurgeComm(hFile, dwFlags); com_hook_t* com_hook = pHData->hook->com_hook; @@ -116,7 +116,7 @@ BOOL WINAPI FakePurgeComm(HANDLE hFile, DWORD dwFlags) { BOOL WINAPI FakeGetCommModemStatus(HANDLE hFile, LPDWORD lpModelStat) { log_misc(plfComm, "GetCommModemStatus(0x%p, 0x%p)", hFile, lpModelStat); - open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); + open_hook_t* pHData = GetDataForHandle(hFile); if (pHData == NULL || pHData->hook->com_hook == NULL) return TrueGetCommModemStatus(hFile, lpModelStat); @@ -131,7 +131,7 @@ BOOL WINAPI FakeGetCommModemStatus(HANDLE hFile, LPDWORD lpModelStat) { BOOL WINAPI FakeWaitCommEvent(HANDLE hFile, LPDWORD lpEvtMask, LPOVERLAPPED lpOverlapped) { log_misc(plfComm, "WaitCommEvent(0x%p)", hFile); - open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); + open_hook_t* pHData = GetDataForHandle(hFile); if (pHData == NULL || pHData->hook->com_hook == NULL) return TrueWaitCommEvent(hFile, lpEvtMask, lpOverlapped); @@ -146,7 +146,7 @@ BOOL WINAPI FakeWaitCommEvent(HANDLE hFile, LPDWORD lpEvtMask, LPOVERLAPPED lpOv BOOL WINAPI FakeClearCommError(HANDLE hFile, LPDWORD lpErrors, LPCOMSTAT lpStat) { log_trace(plfComm, "ClearCommError(0x%p)", hFile); - open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); + open_hook_t* pHData = GetDataForHandle(hFile); if (pHData == NULL || pHData->hook->com_hook == NULL) return TrueClearCommError(hFile, lpErrors, lpStat); diff --git a/src/micetools/dll/hooks/drive/hooks.c b/src/micetools/dll/hooks/drive/hooks.c index 02af5c2..6593c0e 100644 --- a/src/micetools/dll/hooks/drive/hooks.c +++ b/src/micetools/dll/hooks/drive/hooks.c @@ -5,7 +5,7 @@ typedef struct { size_t partition; } find_index_t; disk_volume_t* incrementFindIndex(HANDLE hFindVolume) { - find_index_t* find_index = GetDataForHandle(hFindVolume, HDATA_FIND_VOLUME); + find_index_t* find_index = GetDataForHandle(hFindVolume); if (find_index == NULL) return NULL; while (1) { @@ -69,7 +69,7 @@ HANDLE WINAPI FakeFindFirstVolumeW(LPWSTR lpszVolumeName, DWORD cchBufferLength) find_index->disk = 0; find_index->partition = 0; HANDLE handle = GetDummyHandle(); - SetDataForHandle(handle, HDATA_FIND_VOLUME, find_index, TRUE); + SetDataForHandle(handle, find_index, TRUE); FakeFindNextVolumeW(handle, lpszVolumeName, cchBufferLength); return handle; @@ -79,13 +79,13 @@ HANDLE WINAPI FakeFindFirstVolumeA(LPSTR lpszVolumeName, DWORD cchBufferLength) find_index->disk = 0; find_index->partition = 0; HANDLE handle = GetDummyHandle(); - SetDataForHandle(handle, HDATA_FIND_VOLUME, find_index, TRUE); + SetDataForHandle(handle, find_index, TRUE); FakeFindNextVolumeA(handle, lpszVolumeName, cchBufferLength); return handle; } BOOL WINAPI FakeFindVolumeClose(HANDLE hFindVolume) { - if (RemoveDataForHandle(hFindVolume, HDATA_FIND_VOLUME)) return _CloseHandle(hFindVolume); + if (RemoveDataForHandle(hFindVolume)) return _CloseHandle(hFindVolume); return FALSE; } diff --git a/src/micetools/dll/hooks/files.c b/src/micetools/dll/hooks/files.c index db142af..859e945 100644 --- a/src/micetools/dll/hooks/files.c +++ b/src/micetools/dll/hooks/files.c @@ -30,7 +30,7 @@ HANDLE open_hook(file_hook_t* file_hook) { opened->ctx.m_Handle = handle; opened->ctx.m_HookData = file_hook->hook_data; - SetDataForHandle(handle, HDATA_FILE, opened, TRUE); + SetDataForHandle(handle, opened, TRUE); return handle; } @@ -213,7 +213,7 @@ BOOL WINAPI FakeDeleteFileW(LPCWSTR pszPath) { BOOL WINAPI FakeDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) { - open_hook_t* pHData = GetDataForHandle(hDevice, HDATA_FILE); + open_hook_t* pHData = GetDataForHandle(hDevice); if (pHData == NULL) { return TrueDeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped); @@ -239,7 +239,7 @@ BOOL WINAPI FakeDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lp DWORD WINAPI FakeSetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod) { - open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); + open_hook_t* pHData = GetDataForHandle(hFile); if (pHData == NULL) return TrueSetFilePointer(hFile, lDistanceToMove, lpDistanceToMoveHigh, dwMoveMethod); @@ -262,7 +262,7 @@ DWORD WINAPI FakeSetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDist BOOL WINAPI FakeSetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod) { - open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); + open_hook_t* pHData = GetDataForHandle(hFile); if (pHData != NULL) { if (dwMoveMethod == FILE_BEGIN) { pHData->ctx.m_Pointer = liDistanceToMove; @@ -281,7 +281,7 @@ BOOL WINAPI FakeSetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, } DWORD WINAPI FakeGetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize) { - open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); + open_hook_t* pHData = GetDataForHandle(hFile); if (pHData == NULL) { return TrueGetFileSizeEx(hFile, lpFileSize); } @@ -300,7 +300,7 @@ DWORD WINAPI FakeWriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesT lpOverlapped); } - open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); + open_hook_t* pHData = GetDataForHandle(hFile); if (pHData == NULL) { return TrueWriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped); @@ -327,7 +327,7 @@ BOOL WINAPI FakeReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRe } // log_misc(plfHooks, "ReadFile(%d) %d", hFile, nNumberOfBytesToRead); - open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); + open_hook_t* pHData = GetDataForHandle(hFile); if (pHData == NULL) { return TrueReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped); @@ -348,7 +348,7 @@ BOOL WINAPI FakeReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRe } BOOL WINAPI FakeCloseHandle(HANDLE hObject) { - RemoveDataForHandle(hObject, HDATA_ANY); + RemoveDataForHandle(hObject); return TrueCloseHandle(hObject); } diff --git a/src/micetools/dll/util/_util.h b/src/micetools/dll/util/_util.h index 9919278..1530529 100644 --- a/src/micetools/dll/util/_util.h +++ b/src/micetools/dll/util/_util.h @@ -2,15 +2,11 @@ #include "hook.h" -#define HDATA_FILE 0 -#define HDATA_FIND_VOLUME 1 -#define HDATA_ANY 0xFFFFFFFF - BOOL FileExistsW(const wchar_t* szPath); BOOL FileExistsA(const char* szPath); -PVOID GetDataForHandle(HANDLE hObject, DWORD type); -void SetDataForHandle(HANDLE hObject, DWORD type, PVOID pData, BOOL isHeap); -BOOL RemoveDataForHandle(HANDLE hObject, DWORD type); +PVOID GetDataForHandle(HANDLE hObject); +void SetDataForHandle(HANDLE hObject, PVOID pData, BOOL isHeap); +BOOL RemoveDataForHandle(HANDLE hObject); HANDLE GetDummyHandle(); void BytesToHex(char* hex_buffer, BYTE* bytes, DWORD nbytes); diff --git a/src/micetools/dll/util/misc.c b/src/micetools/dll/util/misc.c index c94c6c0..205c18a 100644 --- a/src/micetools/dll/util/misc.c +++ b/src/micetools/dll/util/misc.c @@ -7,6 +7,9 @@ #include "../hooks/files.h" +// Use the second tag bit to indicate a mice handle +#define MICE_HANDLE_MASK 0x00000002 + void PrintStack(void) { unsigned int i; void* stack[100]; @@ -43,70 +46,73 @@ BOOL FileExistsA(const char* szPath) { } typedef struct HANDLE_DATA { - HANDLE m_Handle; + BOOL m_bOccupied; PVOID m_pData; - DWORD m_Type; BOOL m_IsOnHeap; -} HANDLE_DATA; +} HANDLE_DATA, *PHANDLE_DATA; MICE_DA_NEW(g_handleData, HANDLE_DATA) -PVOID GetDataForHandle(HANDLE hObject, DWORD type) { +PVOID GetDataForHandle(HANDLE hObject) { if (hObject == INVALID_HANDLE_VALUE) return NULL; + if (!hObject & MICE_HANDLE_MASK) return NULL; - MICE_DA_ITER(g_handleData, HANDLE_DATA, i) { - if (i->m_Handle == hObject && (type == HDATA_ANY || i->m_Type == type)) { - return i->m_pData; + DWORD_PTR dwIndex = (DWORD_PTR)hObject >> 2; + PHANDLE_DATA found = MiceDAGet(g_handleData, dwIndex); + if (found == NULL) return NULL; + return found->m_pData; +} +void SetDataForHandle(HANDLE hObject, PVOID pData, BOOL isHeap) { + if (hObject == INVALID_HANDLE_VALUE) return; + if (!hObject & MICE_HANDLE_MASK) return; + + DWORD_PTR dwIndex = (DWORD_PTR)hObject >> 2; + if (dwIndex < g_handleData->m_Length) { + PHANDLE_DATA found = MiceDAGet(g_handleData, dwIndex); + if (found) { + found->m_bOccupied = TRUE; + if (found->m_IsOnHeap && found->m_pData) free(found->m_pData); + found->m_pData = pData; + found->m_IsOnHeap = isHeap; + return; } } - MICE_DA_ITER_END - return NULL; -} -void SetDataForHandle(HANDLE hObject, DWORD type, PVOID pData, BOOL isHeap) { - if (hObject == INVALID_HANDLE_VALUE) return; + HANDLE_DATA newHandleData = { + .m_bOccupied = TRUE, + .m_pData = pData, + .m_IsOnHeap = isHeap, + }; + MiceDAGrowAndSet(g_handleData, dwIndex, &newHandleData); +} +BOOL RemoveDataForHandle(HANDLE hObject, DWORD type) { + if (hObject == INVALID_HANDLE_VALUE) return FALSE; + if (!hObject & MICE_HANDLE_MASK) return FALSE; + DWORD_PTR dwIndex = (DWORD_PTR)hObject >> 2; + + PHANDLE_DATA found = MiceDAGet(g_handleData, dwIndex); + if (found) { + if (found->m_IsOnHeap && found->m_pData) free(found->m_pData); + found->m_pData = NULL; + found->m_bOccupied = FALSE; + } +} + +HANDLE GetDummyHandle() { MICE_DA_ITER(g_handleData, HANDLE_DATA, i) { - if (i->m_Handle == hObject && (type == HDATA_ANY || i->m_Type == type)) { - if (i->m_IsOnHeap) free(i->m_pData); - i->m_pData = pData; - i->m_IsOnHeap = isHeap; - return; + if (!i->m_bOccupied) { + i->m_bOccupied = TRUE; + return (HANDLE)((MICE_DA_INDEX(g_handleData) << 2) | MICE_HANDLE_MASK); } } MICE_DA_ITER_END HANDLE_DATA newHandleData = { - .m_Handle = hObject, - .m_pData = pData, - .m_IsOnHeap = isHeap, - .m_Type = type, + .m_bOccupied = TRUE, + .m_pData = NULL, + .m_IsOnHeap = FALSE, }; MiceDAPush(g_handleData, &newHandleData); -} -BOOL RemoveDataForHandle(HANDLE hObject, DWORD type) { - if (hObject == INVALID_HANDLE_VALUE) return FALSE; - - MICE_DA_ITER(g_handleData, HANDLE_DATA, i) { - if (i->m_Handle == hObject && (type == HDATA_ANY || i->m_Type == type)) { - if (i->m_IsOnHeap) free(i->m_pData); - MICE_DA_REMOVE_CURRENT(g_handleData); - return TRUE; - } - } - MICE_DA_ITER_END - return FALSE; -} - -HANDLE GetDummyHandle() { - CHAR path[MAX_PATH]; - GetModuleFileNameA(NULL, path, MAX_PATH); - HANDLE hObject = - _CreateFileA(path, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - - if (hObject == INVALID_HANDLE_VALUE) { - log_error(plfMisc, "Failed to create dummy handle: %03x", GetLastError()); - } - - return hObject; + return (HANDLE)(((g_handleData->m_Length - 1) << 2) | MICE_HANDLE_MASK); } void BytesToHex(char* hex_buffer, BYTE* bytes, DWORD nbytes) { diff --git a/src/micetools/lib/mice/da.c b/src/micetools/lib/mice/da.c index 6c19b87..1136ec7 100644 --- a/src/micetools/lib/mice/da.c +++ b/src/micetools/lib/mice/da.c @@ -55,6 +55,15 @@ BOOL MiceDAUnshift(PMICE_DA lpDa, LPVOID lpDst) { } return TRUE; } +BOOL MiceDAGrowAndSet(PMICE_DA lpDa, DWORD_PTR dwIndex, LPVOID lpValue) { + if (!lpDa || !lpValue) return FALSE; + if (dwIndex >= lpDa->m_Length) { + while (dwIndex >= lpDa->m_Capacity) _MiceDAGrow(lpDa); + lpDa->m_Length = dwIndex + 1; + } + _MICE_DA_COPY_INTO_DA(lpDa, dwIndex, lpValue); + return TRUE; +} BOOL MiceDASet(PMICE_DA lpDa, DWORD_PTR dwIndex, LPVOID lpValue) { if (!lpDa || !lpValue) return FALSE; if (dwIndex >= lpDa->m_Length) return FALSE; diff --git a/src/micetools/lib/mice/da.h b/src/micetools/lib/mice/da.h index e1bb09e..58da075 100644 --- a/src/micetools/lib/mice/da.h +++ b/src/micetools/lib/mice/da.h @@ -23,6 +23,7 @@ typedef struct MICE_DA { for (DWORD_PTR __mdaI##lpDa = 0; __mdaI##lpDa < (lpDa)->m_Length; __mdaI##lpDa++) { \ type* name = (type*)_MICE_DA_INDEX_P((lpDa), __mdaI##lpDa); #define MICE_DA_ITER_END } +#define MICE_DA_INDEX(lpDa) (__mdaI##lpDa) #define MICE_DA_REMOVE_CURRENT(lpDa) MiceDARemove((lpDa), __mdaI##lpDa) BOOL MiceDAPush(PMICE_DA lpDa, LPVOID lpSrc); @@ -30,6 +31,7 @@ BOOL MiceDAPop(PMICE_DA lpDa, LPVOID lpDst); BOOL MiceDAShift(PMICE_DA lpDa, LPVOID lpSrc); BOOL MiceDAUnshift(PMICE_DA lpDa, LPVOID lpDst); BOOL MiceDASet(PMICE_DA lpDa, DWORD_PTR dwIndex, LPVOID lpValue); +BOOL MiceDAGrowAndSet(PMICE_DA lpDa, DWORD_PTR dwIndex, LPVOID lpValue); LPVOID MiceDAGet(PMICE_DA lpDa, DWORD_PTR dwIndex); BOOL MiceDARemove(PMICE_DA lpDa, DWORD_PTR dwIndex); DWORD_PTR MiceDALength(PMICE_DA lpDa);