mirror of
https://github.com/DxWnd/DxWnd.reloaded
synced 2024-12-30 09:25:35 +01:00
331 lines
13 KiB
C++
331 lines
13 KiB
C++
#include "dxwnd.h"
|
|
#include "dxwcore.hpp"
|
|
#include "syslibs.h"
|
|
#include "dxhook.h"
|
|
|
|
void HookKernel32(HMODULE module)
|
|
{
|
|
void *tmp;
|
|
|
|
if(dxw.dwFlags2 & LIMITRESOURCES){
|
|
tmp = HookAPI(module, "kernel32.dll", GetDiskFreeSpaceA, "GetDiskFreeSpaceA", extGetDiskFreeSpaceA);
|
|
if(tmp) pGetDiskFreeSpaceA = (GetDiskFreeSpaceA_Type)tmp;
|
|
tmp = HookAPI(module, "kernel32.dll", GlobalMemoryStatus, "GlobalMemoryStatus", extGlobalMemoryStatus);
|
|
if(tmp) pGlobalMemoryStatus = (GlobalMemoryStatus_Type)tmp;
|
|
}
|
|
|
|
if(dxw.dwFlags2 & TIMESTRETCH){
|
|
tmp = HookAPI(module, "kernel32.dll", GetTickCount, "GetTickCount", extGetTickCount);
|
|
if(tmp) pGetTickCount = (GetTickCount_Type)tmp;
|
|
tmp = HookAPI(module, "kernel32.dll", GetLocalTime, "GetLocalTime", extGetLocalTime);
|
|
if(tmp) pGetLocalTime = (GetLocalTime_Type)tmp;
|
|
tmp = HookAPI(module, "kernel32.dll", GetSystemTime, "GetSystemTime", extGetSystemTime);
|
|
if(tmp) pGetSystemTime = (GetSystemTime_Type)tmp;
|
|
tmp = HookAPI(module, "kernel32.dll", GetSystemTimeAsFileTime, "GetSystemTimeAsFileTime", extGetSystemTimeAsFileTime);
|
|
if(tmp) pGetSystemTimeAsFileTime = (GetSystemTimeAsFileTime_Type)tmp;
|
|
tmp = HookAPI(module, "kernel32.dll", Sleep, "Sleep", extSleep);
|
|
if(tmp) pSleep = (Sleep_Type)tmp;
|
|
tmp = HookAPI(module, "kernel32.dll", SleepEx, "SleepEx", extSleepEx);
|
|
if(tmp) pSleepEx = (SleepEx_Type)tmp;
|
|
tmp = HookAPI(module, "user32.dll", SetTimer, "SetTimer", extSetTimer);
|
|
if(tmp) pSetTimer = (SetTimer_Type)tmp;
|
|
tmp = HookAPI(module, "winmm.dll", NULL, "timeGetTime", exttimeGetTime);
|
|
if(tmp) ptimeGetTime = (timeGetTime_Type)tmp;
|
|
}
|
|
|
|
if(dxw.dwFlags2 & FAKEVERSION){
|
|
tmp = HookAPI(module, "kernel32.dll", GetVersion, "GetVersion", extGetVersion);
|
|
if(tmp) pGetVersion = (GetVersion_Type)tmp;
|
|
tmp = HookAPI(module, "kernel32.dll", GetVersionEx, "GetVersionEx", extGetVersionEx);
|
|
if(tmp) pGetVersionEx = (GetVersionEx_Type)tmp;
|
|
}
|
|
}
|
|
|
|
FARPROC Remap_kernel32_ProcAddress(LPCSTR proc, HMODULE hModule)
|
|
{
|
|
if (!strcmp(proc,"IsDebuggerPresent")){
|
|
OutTraceD("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), extIsDebuggerPresent);
|
|
return (FARPROC)extIsDebuggerPresent;
|
|
}
|
|
if(dxw.dwFlags2 & LIMITRESOURCES){
|
|
if (!strcmp(proc,"GetDiskFreeSpaceA")){
|
|
pGetDiskFreeSpaceA=(GetDiskFreeSpaceA_Type)(*pGetProcAddress)(hModule, proc);
|
|
OutTraceD("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), extGetDiskFreeSpaceA);
|
|
return (FARPROC)extGetDiskFreeSpaceA;
|
|
}
|
|
if (!strcmp(proc,"GlobalMemoryStatus")){
|
|
pGlobalMemoryStatus=(GlobalMemoryStatus_Type)(*pGetProcAddress)(hModule, proc);
|
|
OutTraceD("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), extGlobalMemoryStatus);
|
|
return (FARPROC)extGlobalMemoryStatus;
|
|
}
|
|
}
|
|
if(dxw.dwFlags2 & TIMESTRETCH){
|
|
if (!strcmp(proc,"GetTickCount")){
|
|
pGetTickCount=(GetTickCount_Type)(*pGetProcAddress)(hModule, proc);
|
|
OutTraceD("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), extGetTickCount);
|
|
return (FARPROC)extGetTickCount;
|
|
}
|
|
if (!strcmp(proc,"GetLocalTime")){
|
|
pGetLocalTime=(GetLocalTime_Type)(*pGetProcAddress)(hModule, proc);
|
|
OutTraceD("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), extGetLocalTime);
|
|
return (FARPROC)extGetLocalTime;
|
|
}
|
|
if (!strcmp(proc,"GetSystemTime")){
|
|
pGetSystemTime=(GetSystemTime_Type)(*pGetProcAddress)(hModule, proc);
|
|
OutTraceD("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), extGetSystemTime);
|
|
return (FARPROC)extGetSystemTime;
|
|
}
|
|
if (!strcmp(proc,"GetSystemTimeAsFileTime")){
|
|
pGetSystemTimeAsFileTime=(GetSystemTimeAsFileTime_Type)(*pGetProcAddress)(hModule, proc);
|
|
OutTraceD("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), extGetSystemTimeAsFileTime);
|
|
return (FARPROC)extGetSystemTimeAsFileTime;
|
|
}
|
|
if (!strcmp(proc,"Sleep")){
|
|
pSleep=(Sleep_Type)(*pGetProcAddress)(hModule, proc);
|
|
OutTraceD("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), extSleep);
|
|
return (FARPROC)extSleep;
|
|
}
|
|
if (!strcmp(proc,"SleepEx")){
|
|
pSleepEx=(SleepEx_Type)(*pGetProcAddress)(hModule, proc);
|
|
OutTraceD("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), extSleepEx);
|
|
return (FARPROC)extSleepEx;
|
|
}
|
|
if (!strcmp(proc,"SetTimer")){
|
|
pSetTimer=(SetTimer_Type)(*pGetProcAddress)(hModule, proc);
|
|
OutTraceD("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), extSetTimer);
|
|
return (FARPROC)extSetTimer;
|
|
}
|
|
}
|
|
if(dxw.dwFlags2 & FAKEVERSION){
|
|
if (!strcmp(proc,"GetVersion")){
|
|
pGetVersion=(GetVersion_Type)(*pGetProcAddress)(hModule, proc);
|
|
OutTraceD("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), extGetVersion);
|
|
return (FARPROC)extGetVersion;
|
|
}
|
|
if (!strcmp(proc,"GetVersionEx")){
|
|
pGetVersionEx=(GetVersionEx_Type)(*pGetProcAddress)(hModule, proc);
|
|
OutTraceD("GetProcAddress: hooking proc=%s at addr=%x\n", ProcToString(proc), extGetVersionEx);
|
|
return (FARPROC)extGetVersionEx;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
int WINAPI extIsDebuggerPresent(void)
|
|
{
|
|
OutTraceD("extIsDebuggerPresent: return FALSE\n");
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL WINAPI extGetDiskFreeSpaceA(LPCSTR lpRootPathName, LPDWORD lpSectorsPerCluster, LPDWORD lpBytesPerSector, LPDWORD lpNumberOfFreeClusters, LPDWORD lpTotalNumberOfClusters)
|
|
{
|
|
BOOL ret;
|
|
OutTraceD("GetDiskFreeSpace: RootPathName=\"%s\"\n", lpRootPathName);
|
|
ret=(*pGetDiskFreeSpaceA)(lpRootPathName, lpSectorsPerCluster, lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters);
|
|
if(!ret) OutTraceE("GetDiskFreeSpace: ERROR err=%d at %d\n", GetLastError(), __LINE__);
|
|
*lpNumberOfFreeClusters = 16000;
|
|
return ret;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------------
|
|
|
|
GlobalMemoryStatus: MSDN documents that on modern PCs that have more than DWORD
|
|
memory values the GlobalMemoryStatus sets the fields to -1 (0xFFFFFFFF) and you
|
|
should use GlobalMemoryStatusEx instead.
|
|
But in some cases the value is less that DWORD max, but greater that DWORD>>1, that
|
|
is the calling application may get a big value and see it as a signed negative
|
|
value, as it happened to Nocturne on my PC. That's why it's not adviseable to write:
|
|
if(lpBuffer->dwTotalPhys== -1) ...
|
|
but this way:
|
|
if ((int)lpBuffer->dwTotalPhys < 0) ...
|
|
and also don't set
|
|
BIGENOUGH 0x80000000 // possibly negative!!!
|
|
but:
|
|
BIGENOUGH 0x20000000 // surely positive !!!
|
|
|
|
/* ---------------------------------------------------------------------------- */
|
|
#define BIGENOUGH 0x20000000
|
|
|
|
void WINAPI extGlobalMemoryStatus(LPMEMORYSTATUS lpBuffer)
|
|
{
|
|
(*pGlobalMemoryStatus)(lpBuffer);
|
|
OutTraceD("GlobalMemoryStatus: Length=%x MemoryLoad=%x "
|
|
"TotalPhys=%x AvailPhys=%x TotalPageFile=%x AvailPageFile=%x TotalVirtual=%x AvailVirtual=%x\n",
|
|
lpBuffer->dwMemoryLoad, lpBuffer->dwTotalPhys, lpBuffer->dwAvailPhys,
|
|
lpBuffer->dwTotalPageFile, lpBuffer->dwAvailPageFile, lpBuffer->dwTotalVirtual, lpBuffer->dwAvailVirtual);
|
|
if(lpBuffer->dwLength==sizeof(MEMORYSTATUS)){
|
|
if ((int)lpBuffer->dwTotalPhys < 0) lpBuffer->dwTotalPhys = BIGENOUGH;
|
|
if ((int)lpBuffer->dwAvailPhys < 0) lpBuffer->dwAvailPhys = BIGENOUGH;
|
|
if ((int)lpBuffer->dwTotalPageFile < 0) lpBuffer->dwTotalPageFile = BIGENOUGH;
|
|
if ((int)lpBuffer->dwAvailPageFile < 0) lpBuffer->dwAvailPageFile = BIGENOUGH;
|
|
if ((int)lpBuffer->dwTotalVirtual < 0) lpBuffer->dwTotalVirtual = BIGENOUGH;
|
|
if ((int)lpBuffer->dwAvailVirtual < 0) lpBuffer->dwAvailVirtual = BIGENOUGH;
|
|
}
|
|
}
|
|
|
|
/*
|
|
From MSDN:
|
|
Operating system Version number dwMajorVersion dwMinorVersion Other
|
|
Windows 8 6.2 6 2 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION
|
|
Windows Server 2012 6.2 6 2 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION
|
|
Windows 7 6.1 6 1 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION
|
|
Windows Server 2008 R2 6.1 6 1 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION
|
|
Windows Server 2008 6.0 6 0 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION
|
|
Windows Vista 6.0 6 0 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION
|
|
Windows Server 2003 R2 5.2 5 2 GetSystemMetrics(SM_SERVERR2) != 0
|
|
Windows Home Server 5.2 5 2 OSVERSIONINFOEX.wSuiteMask & VER_SUITE_WH_SERVER
|
|
Windows Server 2003 5.2 5 2 GetSystemMetrics(SM_SERVERR2) == 0
|
|
Windows XP Pro x64 Ed. 5.2 5 2 (OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION) && (SYSTEM_INFO.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
|
|
Windows XP 5.1 5 1 Not applicable
|
|
Windows 2000 5.0 5 0 Not applicable
|
|
From http://delphi.about.com/cs/adptips2000/a/bltip1100_2.htm
|
|
Windows 95 4.0 4 0
|
|
Windows 98/SE" 4.10 4 10 if osVerInfo.szCSDVersion[1] = 'A' then Windows98SE
|
|
Windows ME 4.90 4 90
|
|
*/
|
|
|
|
static struct {char bMajor; char bMinor; char *sName;} WinVersions[9]=
|
|
{
|
|
{4, 0, "Windows 95"},
|
|
{4,10, "Windows 98/SE"},
|
|
{4,90, "Windows ME"},
|
|
{5, 0, "Windows 2000"},
|
|
{5, 1, "Windows XP"},
|
|
{5, 2, "Windows Server 2003"},
|
|
{6, 0, "Windows Vista"},
|
|
{6, 1, "Windows 7"},
|
|
{6, 2, "Windows 8"}
|
|
};
|
|
|
|
BOOL WINAPI extGetVersionEx(LPOSVERSIONINFO lpVersionInfo)
|
|
{
|
|
BOOL ret;
|
|
|
|
ret=(*pGetVersionEx)(lpVersionInfo);
|
|
if(!ret) {
|
|
OutTraceE("GetVersionEx: ERROR err=%d\n", GetLastError());
|
|
return ret;
|
|
}
|
|
|
|
OutTraceD("GetVersionEx: version=%d.%d build=(%d)\n",
|
|
lpVersionInfo->dwMajorVersion, lpVersionInfo->dwMinorVersion, lpVersionInfo->dwBuildNumber);
|
|
|
|
if(dxw.dwFlags2 & FAKEVERSION) {
|
|
// fake Win XP build 0
|
|
lpVersionInfo->dwMajorVersion = WinVersions[dxw.FakeVersionId].bMajor;
|
|
lpVersionInfo->dwMinorVersion = WinVersions[dxw.FakeVersionId].bMinor;
|
|
lpVersionInfo->dwBuildNumber = 0;
|
|
OutTraceD("GetVersionEx: FIXED version=%d.%d build=(%d) os=\"%s\"\n",
|
|
lpVersionInfo->dwMajorVersion, lpVersionInfo->dwMinorVersion, lpVersionInfo->dwBuildNumber,
|
|
WinVersions[dxw.FakeVersionId].sName);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
DWORD WINAPI extGetVersion(void)
|
|
{
|
|
DWORD dwVersion;
|
|
DWORD dwMajorVersion;
|
|
DWORD dwMinorVersion;
|
|
DWORD dwBuild = 0;
|
|
|
|
dwVersion = (*pGetVersion)();
|
|
|
|
// Get the Windows version.
|
|
|
|
dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
|
|
dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
|
|
|
|
// Get the build number.
|
|
|
|
if (dwVersion < 0x80000000)
|
|
dwBuild = (DWORD)(HIWORD(dwVersion));
|
|
|
|
OutTraceD("GetVersion: version=%d.%d build=(%d)\n", dwMajorVersion, dwMinorVersion, dwBuild);
|
|
|
|
if(dxw.dwFlags2 & FAKEVERSION) {
|
|
dwVersion = WinVersions[dxw.FakeVersionId].bMajor | (WinVersions[dxw.FakeVersionId].bMinor << 8);
|
|
dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
|
|
dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
|
|
dwBuild = (DWORD)(HIWORD(dwVersion));
|
|
OutTraceD("GetVersion: FIXED version=%d.%d build=(%d) os=\"%s\"\n",
|
|
dwMajorVersion, dwMinorVersion, dwBuild, WinVersions[dxw.FakeVersionId].sName);
|
|
}
|
|
|
|
return dwVersion;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------------
|
|
|
|
time related APIs
|
|
|
|
/* ---------------------------------------------------------------------------- */
|
|
|
|
DWORD WINAPI extGetTickCount(void)
|
|
{
|
|
return dxw.GetTickCount();
|
|
}
|
|
|
|
void WINAPI extGetSystemTime(LPSYSTEMTIME lpSystemTime)
|
|
{
|
|
dxw.GetSystemTime(lpSystemTime);
|
|
if (IsDebug) OutTrace("GetSystemTime: %02d:%02d:%02d.%03d\n",
|
|
lpSystemTime->wHour, lpSystemTime->wMinute, lpSystemTime->wSecond, lpSystemTime->wMilliseconds);
|
|
}
|
|
|
|
void WINAPI extGetLocalTime(LPSYSTEMTIME lpLocalTime)
|
|
{
|
|
SYSTEMTIME SystemTime;
|
|
dxw.GetSystemTime(&SystemTime);
|
|
SystemTimeToTzSpecificLocalTime(NULL, &SystemTime, lpLocalTime);
|
|
if (IsDebug) OutTrace("GetLocalTime: %02d:%02d:%02d.%03d\n",
|
|
lpLocalTime->wHour, lpLocalTime->wMinute, lpLocalTime->wSecond, lpLocalTime->wMilliseconds);
|
|
}
|
|
|
|
UINT_PTR WINAPI extSetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc)
|
|
{
|
|
UINT uShiftedElapse;
|
|
// beware: the quicker the time flows, the more the time clicks are incremented,
|
|
// and the lesser the pauses must be lasting! Shift operations are reverted in
|
|
// GetSystemTime vs. Sleep or SetTimer
|
|
uShiftedElapse = dxw.StretchTime(uElapse);
|
|
if (IsDebug) OutTrace("SetTimer: elapse=%d->%d timeshift=%d\n", uElapse, uShiftedElapse, dxw.TimeShift);
|
|
return (*pSetTimer)(hWnd, nIDEvent, uShiftedElapse, lpTimerFunc);
|
|
}
|
|
|
|
VOID WINAPI extSleep(DWORD dwMilliseconds)
|
|
{
|
|
DWORD dwNewDelay;
|
|
dwNewDelay=dwMilliseconds;
|
|
if (dwMilliseconds!=INFINITE && dwMilliseconds!=0){
|
|
dwNewDelay = dxw.StretchTime(dwMilliseconds);
|
|
if (dwNewDelay==0){ // oh oh! troubles...
|
|
if (dxw.TimeShift > 0) dwNewDelay=1; // minimum allowed...
|
|
else dwNewDelay = INFINITE-1; // maximum allowed !!!
|
|
}
|
|
}
|
|
if (IsDebug) OutTrace("Sleep: msec=%d->%d timeshift=%d\n", dwMilliseconds, dwNewDelay, dxw.TimeShift);
|
|
(*pSleep)(dwNewDelay);
|
|
}
|
|
|
|
DWORD WINAPI extSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
|
|
{
|
|
DWORD dwNewDelay;
|
|
dwNewDelay=dwMilliseconds;
|
|
if (dwMilliseconds!=INFINITE && dwMilliseconds!=0){
|
|
dwNewDelay = dxw.StretchTime(dwMilliseconds);
|
|
if (dwNewDelay==0){ // oh oh! troubles...
|
|
if (dxw.TimeShift > 0) dwNewDelay=1; // minimum allowed...
|
|
else dwNewDelay = INFINITE-1; // maximum allowed !!!
|
|
}
|
|
}
|
|
if (IsDebug) OutTrace("SleepEx: msec=%d->%d alertable=%x, timeshift=%d\n", dwMilliseconds, dwNewDelay, bAlertable, dxw.TimeShift);
|
|
return (*pSleepEx)(dwNewDelay, bAlertable);
|
|
}
|
|
|
|
void WINAPI extGetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime)
|
|
{
|
|
if (IsDebug) OutTrace("GetSystemTimeAsFileTime\n");
|
|
dxw.GetSystemTimeAsFileTime(lpSystemTimeAsFileTime);
|
|
} |