diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 5db352d..e7c63bc 100755 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,33 @@ +KernelEx v4.5 RC 1 by Xeno86 +2010-07-30 + +implemented kernel32.RtlCaptureContext for Firefox 4.0 Beta 2 +reworked compatibility tab to allow resetting compatibility settings to default values +compatibility tab is visible on all PE modules thus allowing to change compatibility options on per-module basis +disallow resources with high ID (>32767) when KernelEx is disabled +perform platform check when KernelEx is disabled +added kernel32.GetComputerNameEx stubs which supposedly make Artweaver run +simulate TrueType MS Sans Serif for VLC +use ASCII table instead of ISO8859-1 for character conversion (fixes problem with national characters in paths) +added ADVAPI32.FileEncryptionStatus stubs +added get-post I/O completion ports functionality for Firefox 3.6.4 +added a bunch of new user32 stubs allowing to run newer MPC-HC, includes: DefRawInputProc, GetRawInputBuffer, GetRawInputData, GetRawInputDeviceList, GetRawInputDeviceInfoA, GetRawInputDeviceInfoW, GetRegisteredRawInputDevices, RegisterRawInputDevices, PrintWindow +more accurate object owner check in DeleteObject +fixed missing ScriptCache unlock in case of error +fixed crash on displaying of error message in KernelEx Setup program +added a simple protection against footer corruption in jemalloc heap +excluded jemalloc from handling limited size heaps +added "Disable custom heap" configuration +added "Default mode" configuration +fixed GTA:SA crash on game load +fixed Rally Championship '99 crash +removed shell32.SHGetDiskFreeSpaceW as there is no such function in WIN32 api +implemented missing SHELL32.SHGetDiskFreeSpaceEx on Windows 98 +implemented SHELL32.SHGetDiskFreeSpaceW for Adobe Flash 10 +removed positive PIDs patch as it causes incompatibility with MSYS and propably other apps too + +--------------------------------------- + KernelEx v4.5 Beta 2 by Xeno86 2010-02-14 diff --git a/KernelEx.nsi b/KernelEx.nsi index 18fcec2..44661ca 100755 --- a/KernelEx.nsi +++ b/KernelEx.nsi @@ -1,4 +1,4 @@ - !define _VERSION '4.5 Beta 2' + !define _VERSION '4.5 RC 1' !ifndef _DEBUG !define FLAVOUR 'Release' diff --git a/NEWS.txt b/NEWS.txt index a12a90a..c7cca1c 100755 --- a/NEWS.txt +++ b/NEWS.txt @@ -1,3 +1,29 @@ +KernelEx v4.5 RC 1 by Xeno86 +2010-07-30 + +What's new: +---------------------------------- +* Reworked 'Compatibility' tab to allow resetting compatibility settings to default values +* Resources with high ID are disallowed when KernelEx is disabled +* Platform check is now re-enabled when KernelEx is disabled +* Fixed settings not applied for applications with international characters in path +* Implemented get-post I/O completion ports functionality + +Apps fixed / now working: +------------------------- +* Fixed: MSYS (broken) +* Fixed: Microsoft Access XP (crashing) +* Fixed: Rally Championship '99 (crashing) +* Fixed: GTA San Andreas (crashing) +* Fixed: VLC 1.0+ (UI) +* Fixed: Firefox 3.6.4+ (high cpu usage) +* Now working: Adobe Flash 10.1 plugin +* Now working: Mozilla Firefox 4.0 Beta 1 +* Now working: Artweaver 1.0 +* Now working: MPC-HC (newer builds, svn build 1391+) + +################################################# + KernelEx v4.5 Beta 2 by Xeno86 2010-02-14 @@ -6,7 +32,7 @@ What's new: * Implemented Uniscribe font caching (improves Firefox 3 performance). * New thread pool implementation (fixes IE6 problems). * Fixed rare font related Firefox 3 crash. -* Implemted timer queue APIs. +* Implemented timer queue APIs. * Implemented SHParseDisplayName and restricted to XP+ configs to fix Firefox mailto issues. * Fixed premature kexCOM unloading crashing Photoshop 5 and other buggy apps. * Updated jemalloc to version from FF3.6. diff --git a/apilibs/CORE.INI b/apilibs/CORE.INI index 5b06874..3de8a91 100755 --- a/apilibs/CORE.INI +++ b/apilibs/CORE.INI @@ -10,10 +10,11 @@ default=0 7=WIN2K3 8=VISTA 9=WIN2K8 +10=NOHEAP [DCFG1] contents=std,kexbases,kexbasen -noshow=1 +desc=Default mode [DCFG1.names.98] KERNEL32.GetVersion=std @@ -145,3 +146,15 @@ KERNEL32.GetVersionExA=kexbases.9 KERNEL32.GetVersionExW=kexbases.9 KERNEL32.VerifyVersionInfoA=kexbases.4 KERNEL32.VerifyVersionInfoW=kexbases.4 + +[NOHEAP] +inherit=DCFG1 +desc=Disable custom heap + +[NOHEAP.names] +KERNEL32.HeapCreate=std +KERNEL32.HeapDestroy=std +KERNEL32.HeapAlloc=std +KERNEL32.HeapFree=std +KERNEL32.HeapSize=std +KERNEL32.HeapReAlloc=std diff --git a/apilibs/kexbasen/gdi32/UberGDI.c b/apilibs/kexbasen/gdi32/UberGDI.c index b5c82b3..2c9e9f2 100755 --- a/apilibs/kexbasen/gdi32/UberGDI.c +++ b/apilibs/kexbasen/gdi32/UberGDI.c @@ -4,10 +4,6 @@ * Copyright (C) 2008, 2010, Tihiy * This file is part of KernelEx source code. * - * Copyright 1993 Alexandre Julliard - * 1997 Alex Korobka - * Copyright 2002,2003 Shachar Shemesh - * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla) * * KernelEx is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published @@ -30,7 +26,6 @@ #include #include "ScriptCache.h" - #ifdef __cplusplus extern "C" #endif @@ -66,7 +61,11 @@ int WINAPI GetGlyphIndicesW_new( int i; SCRIPT_FONTPROPERTIES fpr; fpr.cBytes = sizeof(SCRIPT_FONTPROPERTIES); - if (FAILED(ScriptGetFontProperties(hdc,&cache,&fpr))) return GDI_ERROR; + if (FAILED(ScriptGetFontProperties(hdc,&cache,&fpr))) + { + ScriptCache::instance.Unlock(); + return GDI_ERROR; + } for (i = 0; i < c; i++) { if (*checkglyph == fpr.wgDefault) *checkglyph = 0xFFFF; @@ -80,26 +79,22 @@ int WINAPI GetGlyphIndicesW_new( static int WINAPI GdiGetCodePage( HDC hdc ) { - UINT cp = CP_ACP; - CHARSETINFO csi; - int charset = GetTextCharset(hdc); + int charset = GetTextCharset(hdc); - /* Hmm, nicely designed api this one! */ - if(TranslateCharsetInfo((DWORD*)charset, &csi, TCI_SRCCHARSET)) - cp = csi.ciACP; - else - { - switch(charset) - { - case OEM_CHARSET: - cp = GetOEMCP(); - break; - case DEFAULT_CHARSET: - cp = GetACP(); - break; - } - } - return cp; + switch(charset) { + case DEFAULT_CHARSET: + return GetACP(); + case OEM_CHARSET: + return GetOEMCP(); + default: + { + CHARSETINFO csi; + if(TranslateCharsetInfo((DWORD*)charset, &csi, TCI_SRCCHARSET)) + return csi.ciACP; + else + return CP_ACP; + } + } } /* MAKE_EXPORT GetGlyphIndicesA_new=GetGlyphIndicesA */ @@ -296,8 +291,38 @@ DWORD WINAPI GetGlyphOutlineW_new( memcpy( &matr, lpmat2, sizeof(MAT2) ); lpmat2 = &matr; } - if (uFormat & GGO_GLYPH_INDEX) + + + if ( uFormat & GGO_GLYPH_INDEX ) return GetGlyphOutlineA( hdc, uChar, uFormat, lpgm, cbBuffer, lpvBuffer, lpmat2 ); - GetGlyphIndicesW_new( hdc, (LPWSTR)&uChar, 1, (LPWORD)&glyph, 0 ); - return GetGlyphOutlineA( hdc, glyph, uFormat | GGO_GLYPH_INDEX, lpgm, cbBuffer, lpvBuffer, lpmat2 ); + else + { + DWORD ret = GetGlyphIndicesW_new( hdc, (LPWSTR)&uChar, 1, (LPWORD)&glyph, 0 ); + if (ret != GDI_ERROR) + ret = GetGlyphOutlineA( hdc, glyph, uFormat | GGO_GLYPH_INDEX, lpgm, cbBuffer, lpvBuffer, lpmat2 ); + + //someone assumed MS Shell Dlg is TrueType? + if (ret == GDI_ERROR && uFormat == GGO_METRICS && lpmat2 && lpgm) + { + char fontface[100]; + GetTextFaceA(hdc,100,fontface); + if (strcmp(fontface,"MS Sans Serif") == 0) + { + //well let's fake it then + SIZE sz; + if (GetTextExtentPointW(hdc,(LPWSTR)&uChar,1,&sz)) + { + lpgm->gmBlackBoxX = sz.cx; + lpgm->gmBlackBoxY = sz.cy; + lpgm->gmptGlyphOrigin.x = 0; + lpgm->gmptGlyphOrigin.y = sz.cy; + lpgm->gmCellIncX = sz.cx; + lpgm->gmCellIncY = 0; + ret = 1; + } + } + } + + return ret; + } } diff --git a/apilibs/kexbasen/kernel32/allocator.c b/apilibs/kexbasen/kernel32/allocator.c index 3aa8294..2807799 100755 --- a/apilibs/kexbasen/kernel32/allocator.c +++ b/apilibs/kexbasen/kernel32/allocator.c @@ -117,16 +117,20 @@ int footer_size_for_usable_size(size_t usable) static inline DWORD read_footer(const void* ptr, size_t usable, int fs) { + DWORD ret; UFooter* footer; if (!ptr) return 0; footer = (UFooter*) ((DWORD) ptr + usable - fs); if (fs == sizeof(BYTE)) - return footer->db; + ret = footer->db; else if (fs == sizeof(WORD)) - return footer->dw; + ret = footer->dw; else - return footer->dd; + ret = footer->dd; + if (ret > usable - fs) //heap corruption detected + ret = usable - fs; + return ret; } static inline @@ -144,7 +148,7 @@ void write_footer(void* ptr, size_t usable, int fs, DWORD value) /* MAKE_EXPORT HeapCreate_new=HeapCreate */ HANDLE WINAPI HeapCreate_new(DWORD flOptions, DWORD dwInitialSize, DWORD dwMaximumSize) { - if (flOptions & HEAP_SHARED) + if (flOptions & HEAP_SHARED || dwMaximumSize != 0) return HeapCreate(flOptions, dwInitialSize, dwMaximumSize); if (flOptions & HEAP_GENERATE_EXCEPTIONS) return JM_HEAP_EXCP; diff --git a/apilibs/kexbases/Advapi32/_advapi32_apilist.c b/apilibs/kexbases/Advapi32/_advapi32_apilist.c index 96c0d46..9b1b9a5 100755 --- a/apilibs/kexbases/Advapi32/_advapi32_apilist.c +++ b/apilibs/kexbases/Advapi32/_advapi32_apilist.c @@ -63,6 +63,8 @@ static const apilib_named_api advapi32_named_apis[] = DECL_API("EnumServicesStatusExW", EnumServicesStatusExW_stub), DECL_API("EqualPrefixSid", EqualPrefixSid_new), DECL_API("EqualSid", EqualSid_new), + DECL_API("FileEncryptionStatusA", FileEncryptionStatusA_stub), + DECL_API("FileEncryptionStatusW", FileEncryptionStatusW_stub), DECL_API("FreeSid", FreeSid_new), DECL_API("GetAce", GetAce_new), DECL_API("GetFileSecurityA", GetFileSecurityA_new), diff --git a/apilibs/kexbases/Advapi32/_advapi32_apilist.h b/apilibs/kexbases/Advapi32/_advapi32_apilist.h index 308413f..e6001ca 100755 --- a/apilibs/kexbases/Advapi32/_advapi32_apilist.h +++ b/apilibs/kexbases/Advapi32/_advapi32_apilist.h @@ -61,6 +61,8 @@ STUB EnumServicesStatusExW_stub; STUB CreateProcessWithLogonW_stub; STUB InitiateSystemShutdownExA_stub; STUB InitiateSystemShutdownExW_stub; +STUB FileEncryptionStatusA_stub; +STUB FileEncryptionStatusW_stub; BOOL WINAPI OpenProcessToken_new(HANDLE ProcessHandle, DWORD DesiredAccess, HANDLE *TokenHandle); BOOL WINAPI OpenThreadToken_new(HANDLE ThreadHandle, DWORD DesiredAccess, BOOL OpenAsSelf, HANDLE *TokenHandle); BOOL WINAPI DuplicateTokenEx_new(HANDLE ExistingTokenHandle, DWORD dwDesiredAccess, LPSECURITY_ATTRIBUTES lpTokenAttributes, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, TOKEN_TYPE TokenType, PHANDLE DuplicateTokenHandle); diff --git a/apilibs/kexbases/Advapi32/_advapi32_stubs.c b/apilibs/kexbases/Advapi32/_advapi32_stubs.c index e02145d..c46cf4d 100755 --- a/apilibs/kexbases/Advapi32/_advapi32_stubs.c +++ b/apilibs/kexbases/Advapi32/_advapi32_stubs.c @@ -55,3 +55,7 @@ UNIMPL_FUNC(EnumServicesStatusExW, 10); UNIMPL_FUNC(CreateProcessWithLogonW, 11); UNIMPL_FUNC(InitiateSystemShutdownExA, 6); UNIMPL_FUNC(InitiateSystemShutdownExW, 6); + + +UNIMPL_FUNC(FileEncryptionStatusA, 2); +UNIMPL_FUNC(FileEncryptionStatusW, 2); diff --git a/apilibs/kexbases/Gdi32/GdiObjects.c b/apilibs/kexbases/Gdi32/GdiObjects.c index 1a8cf85..0f28aec 100755 --- a/apilibs/kexbases/Gdi32/GdiObjects.c +++ b/apilibs/kexbases/Gdi32/GdiObjects.c @@ -152,6 +152,17 @@ DWORD WINAPI GetObjectType_fix( HGDIOBJ hgdiobj ) return result; } +__declspec(naked) +WORD GetCurrentTDB() +{ + __asm + { + mov ax, fs:[0Ch] + movzx eax, ax + ret + } +} + /* MAKE_EXPORT DeleteObject_fix=DeleteObject */ BOOL WINAPI DeleteObject_fix( HGDIOBJ hObject ) { @@ -159,7 +170,7 @@ BOOL WINAPI DeleteObject_fix( HGDIOBJ hObject ) PGDIOBJ16 obj = GetGDIObjectPtr( hObject ); if ( !obj || !SwitchGDIObjectType(obj) ) return FALSE; DWORD violated = 0; - if ( obj->wOwner ) //not system objects + if ( obj->wOwner == GetCurrentTDB() ) //not system or foreign objects { if (obj->wType == GDI_TYPE_FONT) { diff --git a/apilibs/kexbases/Kernel32/CompletionPorts.c b/apilibs/kexbases/Kernel32/CompletionPorts.c new file mode 100755 index 0000000..e5162fa --- /dev/null +++ b/apilibs/kexbases/Kernel32/CompletionPorts.c @@ -0,0 +1,153 @@ +/* + * KernelEx + * Copyright (C) 2010, Tihiy + * + * This file is part of KernelEx source code. + * + * KernelEx is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 of the License. + * + * KernelEx is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include "kexcoresdk.h" + +/* + * Note that only get-post functionality is rougly simulated; + * no actual I/O completion notification can be done. + * + * Also handles don't get proper cleanup! + */ + +#define PORT_SIGNATURE 0xABADC0FE +#define MAX_QUEUES 200 + +typedef struct +{ + DWORD dwBytes; + ULONG_PTR dwKey; + LPOVERLAPPED lpOverlapped; +} COMPLET_PACKET; + +typedef struct +{ + DWORD signature; + HANDLE hEvent; + CRITICAL_SECTION cs; + DWORD count; + COMPLET_PACKET packets[MAX_QUEUES]; +} COMPLET_PORT, *PCOMPLET_PORT; + + +/* MAKE_EXPORT CreateIoCompletionPort_new=CreateIoCompletionPort */ +HANDLE WINAPI CreateIoCompletionPort_new( + HANDLE FileHandle, // handle to file + HANDLE ExistingCompletionPort, // handle to I/O completion port + ULONG_PTR CompletionKey, // completion key + DWORD NumberOfConcurrentThreads // number of threads to execute concurrently +) +{ + //kexDebugPrint("CreateIoCompletionPort FileHandle %p Port %p Key %p Threads %d",FileHandle,ExistingCompletionPort,CompletionKey,NumberOfConcurrentThreads); + if (FileHandle != INVALID_HANDLE_VALUE) + { + DBGPRINTF(("CreateIoCompletionPort is used for real (file handle %p), not supported.\n",FileHandle)); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return NULL; + } + //go create a handle we will hack on + HANDLE hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,sizeof(COMPLET_PORT),NULL); + if (hFileMap) + { + PCOMPLET_PORT port = (PCOMPLET_PORT)MapViewOfFile(hFileMap,FILE_MAP_ALL_ACCESS,0,0,0); + port->signature = PORT_SIGNATURE; + port->count = 0; + port->hEvent = CreateEvent(NULL,FALSE,FALSE,NULL); + InitializeCriticalSection( &port->cs ); + UnmapViewOfFile(port); + } + return hFileMap; +} + + +/* MAKE_EXPORT GetQueuedCompletionStatus_new=GetQueuedCompletionStatus */ +BOOL WINAPI GetQueuedCompletionStatus_new( + HANDLE CompletionPort, // handle to completion port + LPDWORD lpNumberOfBytes, // bytes transferred + PULONG_PTR lpCompletionKey, // file completion key + LPOVERLAPPED *lpOverlapped, // buffer + DWORD dwMilliseconds // optional timeout value +) +{ + PCOMPLET_PORT port = (PCOMPLET_PORT)MapViewOfFile(CompletionPort,FILE_MAP_ALL_ACCESS,0,0,0); + if (!port || port->signature != PORT_SIGNATURE || !lpOverlapped || !lpNumberOfBytes || !lpCompletionKey) + { + UnmapViewOfFile(port); + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + //kexDebugPrint("GetQueuedCompletionStatus waiting port %p for %d ms",port,dwMilliseconds); + DWORD status = WaitForSingleObject(port->hEvent,dwMilliseconds); + if (status != WAIT_OBJECT_0) + { + //kexDebugPrint("GetQueuedCompletionStatus waiting port %p timed up!",port); + UnmapViewOfFile(port); + *lpOverlapped = NULL; + SetLastError(WAIT_TIMEOUT); + return FALSE; + } + EnterCriticalSection(&port->cs); + *lpNumberOfBytes = port->packets[0].dwBytes; + *lpCompletionKey = port->packets[0].dwKey; + *lpOverlapped = port->packets[0].lpOverlapped; + port->count--; + memmove(&port->packets[0],&port->packets[1],sizeof(COMPLET_PACKET)*port->count); + if (port->count > 0) SetEvent(port->hEvent); + LeaveCriticalSection(&port->cs); + UnmapViewOfFile(port); + //kexDebugPrint("GetQueuedCompletionStatus dequeued from port %p: %p %p %p",port,*lpNumberOfBytes,*lpCompletionKey,*lpOverlapped); + return TRUE; +} + +/* MAKE_EXPORT PostQueuedCompletionStatus_new=PostQueuedCompletionStatus */ +BOOL WINAPI PostQueuedCompletionStatus_new( + HANDLE CompletionPort, // handle to an I/O completion port + DWORD dwNumberOfBytesTransferred, // bytes transferred + ULONG_PTR dwCompletionKey, // completion key + LPOVERLAPPED lpOverlapped // overlapped buffer +) +{ + PCOMPLET_PORT port = (PCOMPLET_PORT)MapViewOfFile(CompletionPort,FILE_MAP_ALL_ACCESS,0,0,0); + //kexDebugPrint("PostQueuedCompletionStatus queued from port %p: %p %p %p",port,dwNumberOfBytesTransferred,dwCompletionKey,lpOverlapped); + if (!port || port->signature != PORT_SIGNATURE || !lpOverlapped) + { + UnmapViewOfFile(port); + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + BOOL ret = FALSE; + EnterCriticalSection(&port->cs); + if (port->count < MAX_QUEUES) + { + DWORD last = port->count; + port->packets[last].dwBytes = dwNumberOfBytesTransferred; + port->packets[last].dwKey = dwCompletionKey; + port->packets[last].lpOverlapped = lpOverlapped; + port->count++; + SetEvent(port->hEvent); + ret = TRUE; + } + LeaveCriticalSection(&port->cs); + UnmapViewOfFile(port); + return ret; +} + diff --git a/apilibs/kexbases/Kernel32/RtlCaptureContext.c b/apilibs/kexbases/Kernel32/RtlCaptureContext.c new file mode 100755 index 0000000..5d501be --- /dev/null +++ b/apilibs/kexbases/Kernel32/RtlCaptureContext.c @@ -0,0 +1,76 @@ +/* + * KernelEx + * Copyright (C) 2010, Xeno86 + * + * This file is part of KernelEx source code. + * + * KernelEx is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 of the License. + * + * KernelEx is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#define CONTEXT_CONTEXTFLAGS 0x00 +#define CONTEXT_SEGGS 0x8C +#define CONTEXT_SEGFS 0x90 +#define CONTEXT_SEGES 0x94 +#define CONTEXT_SEGDS 0x98 +#define CONTEXT_EDI 0x9C +#define CONTEXT_ESI 0xA0 +#define CONTEXT_EBX 0xA4 +#define CONTEXT_EDX 0xA8 +#define CONTEXT_ECX 0xAC +#define CONTEXT_EAX 0xB0 +#define CONTEXT_EBP 0xB4 +#define CONTEXT_EIP 0xB8 +#define CONTEXT_SEGCS 0xBC +#define CONTEXT_EFLAGS 0xC0 +#define CONTEXT_ESP 0xC4 +#define CONTEXT_SEGSS 0xC8 + +#define CONTEXT_FULL 0x10007 + +#define WINAPI __stdcall + +/* MAKE_EXPORT RtlCaptureContext_new=RtlCaptureContext */ +__declspec(naked) +void WINAPI RtlCaptureContext_new(void* cr) +{ +__asm { + push ebx + mov ebx, [esp+8] + mov [ebx+CONTEXT_EAX], eax + mov eax, [esp] + mov [ebx+CONTEXT_EBX], eax + mov [ebx+CONTEXT_ECX], ecx + mov [ebx+CONTEXT_EDX], edx + mov [ebx+CONTEXT_ESI], esi + mov [ebx+CONTEXT_EDI], edi + mov [ebx+CONTEXT_SEGCS], cs + mov [ebx+CONTEXT_SEGDS], ds + mov [ebx+CONTEXT_SEGES], es + mov [ebx+CONTEXT_SEGFS], fs + mov [ebx+CONTEXT_SEGGS], gs + mov [ebx+CONTEXT_SEGSS], ss + pushf + pop [ebx+CONTEXT_EFLAGS] + mov eax, [ebp] + mov [ebx+CONTEXT_EBP], eax + mov eax, [ebp+4] + mov [ebx+CONTEXT_EIP], eax + lea eax, [ebp+8] + mov [ebx+CONTEXT_ESP], eax + mov [ebx+CONTEXT_CONTEXTFLAGS], CONTEXT_FULL + pop ebx + ret 4 + } +} diff --git a/apilibs/kexbases/Kernel32/_kernel32_apilist.c b/apilibs/kexbases/Kernel32/_kernel32_apilist.c index 82b4ba1..09a9d64 100755 --- a/apilibs/kexbases/Kernel32/_kernel32_apilist.c +++ b/apilibs/kexbases/Kernel32/_kernel32_apilist.c @@ -59,6 +59,7 @@ static const apilib_named_api kernel32_named_apis[] = DECL_API("CreateFileW", CreateFileW_new), DECL_API("CreateHardLinkA", CreateHardLinkA_stub), DECL_API("CreateHardLinkW", CreateHardLinkW_stub), + DECL_API("CreateIoCompletionPort", CreateIoCompletionPort_new), DECL_API("CreateJobObjectA", CreateJobObjectA_new), DECL_API("CreateJobObjectW", CreateJobObjectW_new), DECL_API("CreateThread", CreateThread_fix), @@ -78,6 +79,8 @@ static const apilib_named_api kernel32_named_apis[] = DECL_API("FoldStringW", FoldStringW_new), DECL_API("FreeEnvironmentStringsW", FreeEnvironmentStringsW_new), DECL_API("GetAtomNameW", GetAtomNameW_new), + DECL_API("GetComputerNameExA", GetComputerNameExA_stub), + DECL_API("GetComputerNameExW", GetComputerNameExW_stub), DECL_API("GetConsoleWindow", GetConsoleWindow_new), DECL_API("GetCurrentDirectoryW", GetCurrentDirectoryW_new), DECL_API("GetDefaultCommConfigW", GetDefaultCommConfigW_new), @@ -97,6 +100,7 @@ static const apilib_named_api kernel32_named_apis[] = DECL_API("GetModuleHandleW", GetModuleHandleW_new), DECL_API("GetNativeSystemInfo", GetSystemInfo), DECL_API("GetProcessIoCounters", GetProcessIoCounters_stub), + DECL_API("GetQueuedCompletionStatus", GetQueuedCompletionStatus_new), DECL_API("GetShortPathNameW", GetShortPathNameW_new), DECL_API("GetStartupInfoW", GetStartupInfoW_new), DECL_API("GetStringTypeExW", GetStringTypeExW_new), @@ -173,6 +177,7 @@ static const apilib_named_api kernel32_named_apis[] = DECL_API("OpenJobObjectW", OpenJobObjectW_new), DECL_API("OpenThread", OpenThread_new), DECL_API("OutputDebugStringW", OutputDebugStringW_new), + DECL_API("PostQueuedCompletionStatus", PostQueuedCompletionStatus_new), DECL_API("Process32FirstW", Process32FirstW_new), DECL_API("Process32NextW", Process32NextW_new), DECL_API("ProcessIdToSessionId", ProcessIdToSessionId_new), @@ -182,6 +187,7 @@ static const apilib_named_api kernel32_named_apis[] = DECL_API("ReplaceFileA", ReplaceFileA_stub), DECL_API("ReplaceFileW", ReplaceFileW_stub), DECL_API("RestoreLastError", SetLastError), + DECL_API("RtlCaptureContext", RtlCaptureContext_new), DECL_API("RtlCaptureStackBackTrace", RtlCaptureStackBackTrace_stub), DECL_API("SearchPathW", SearchPathW_new), DECL_API("SetConsoleTitleW", SetConsoleTitleW_new), diff --git a/apilibs/kexbases/Kernel32/_kernel32_apilist.h b/apilibs/kexbases/Kernel32/_kernel32_apilist.h index 16295dc..18cf50a 100755 --- a/apilibs/kexbases/Kernel32/_kernel32_apilist.h +++ b/apilibs/kexbases/Kernel32/_kernel32_apilist.h @@ -29,6 +29,9 @@ BOOL init_kernel32(); extern const apilib_api_table apitable_kernel32; /*** AUTOGENERATED APILIST DECLARATIONS BEGIN ***/ +HANDLE WINAPI CreateIoCompletionPort_new(HANDLE FileHandle, HANDLE ExistingCompletionPort, ULONG_PTR CompletionKey, DWORD NumberOfConcurrentThreads); +BOOL WINAPI GetQueuedCompletionStatus_new(HANDLE CompletionPort, LPDWORD lpNumberOfBytes, PULONG_PTR lpCompletionKey, LPOVERLAPPED *lpOverlapped, DWORD dwMilliseconds); +BOOL WINAPI PostQueuedCompletionStatus_new(HANDLE CompletionPort, DWORD dwNumberOfBytesTransferred, ULONG_PTR dwCompletionKey, LPOVERLAPPED lpOverlapped); BOOL WINAPI CopyFileExA_new(LPCSTR lpExistingFileNameA, LPCSTR lpNewFileNameA, LPPROGRESS_ROUTINE lpProgressRoutine, LPVOID lpData, LPBOOL pbCancel, DWORD dwCopyFlags); HANDLE WINAPI CreateThread_fix(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId); void WINAPI DeleteCriticalSection_new(PCRITICAL_SECTION lpCriticalSection); @@ -67,6 +70,7 @@ BOOL WINAPI MoveFileWithProgressA_new(LPCSTR lpExistingFileName, LPCSTR lpNewFil HANDLE WINAPI OpenThread_new(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId); BOOL WINAPI ProcessIdToSessionId_new(DWORD dwProcessId, DWORD *pSessionId); DWORD WINAPI WTSGetActiveConsoleSessionId_new(void); +void WINAPI RtlCaptureContext_new(void* cr); BOOL WINAPI SetFilePointerEx_new(HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod); BOOL WINAPI TryEnterCriticalSection_new(CRITICAL_SECTION* cs); LPVOID WINAPI VirtualAllocEx_new(HANDLE hProcess, LPVOID lpAddress, DWORD dwSize, DWORD flAllocationType, DWORD flProtect); @@ -80,6 +84,8 @@ STUB FindFirstFileExW_stub; STUB HeapSetInformation_stub; STUB GetProcessIoCounters_stub; STUB RtlCaptureStackBackTrace_stub; +STUB GetComputerNameExA_stub; +STUB GetComputerNameExW_stub; INT WINAPI CompareStringW_new(LCID lcid, DWORD style, LPCWSTR str1, INT len1, LPCWSTR str2, INT len2); BOOL WINAPI GetStringTypeW_new(DWORD type, LPCWSTR src, INT count, LPWORD chartype); BOOL WINAPI GetStringTypeExW_new(LCID locale, DWORD type, LPCWSTR src, INT count, LPWORD chartype); diff --git a/apilibs/kexbases/Kernel32/_kernel32_stubs.c b/apilibs/kexbases/Kernel32/_kernel32_stubs.c index 8f5a267..580f701 100755 --- a/apilibs/kexbases/Kernel32/_kernel32_stubs.c +++ b/apilibs/kexbases/Kernel32/_kernel32_stubs.c @@ -30,3 +30,5 @@ UNIMPL_FUNC(FindFirstFileExW, 6); UNIMPL_FUNC(HeapSetInformation, 4); UNIMPL_FUNC(GetProcessIoCounters, 2); UNIMPL_FUNC(RtlCaptureStackBackTrace, 4); +UNIMPL_FUNC(GetComputerNameExA, 3); +UNIMPL_FUNC(GetComputerNameExW, 3); diff --git a/apilibs/kexbases/User32/_user32_apilist.c b/apilibs/kexbases/User32/_user32_apilist.c index 234e689..6590c5a 100755 --- a/apilibs/kexbases/User32/_user32_apilist.c +++ b/apilibs/kexbases/User32/_user32_apilist.c @@ -84,6 +84,7 @@ static const apilib_named_api user32_named_apis[] = DECL_API("DefDlgProcW", DefDlgProcW_NEW), DECL_API("DefFrameProcW", DefFrameProcW_NEW), DECL_API("DefMDIChildProcW", DefMDIChildProcW_NEW), + DECL_API("DefRawInputProc", DefRawInputProc_stub), DECL_API("DefWindowProcW", DefWindowProcW_NEW), DECL_API("DeregisterShellHookWindow", IsWindow), DECL_API("DialogBoxIndirectParamW", DialogBoxIndirectParamW_NEW), @@ -103,6 +104,12 @@ static const apilib_named_api user32_named_apis[] = DECL_API("GetMessageW", GetMessageW_NEW), DECL_API("GetMouseMovePointsEx", GetMouseMovePointsEx_98), DECL_API("GetNextDlgTabItem", GetNextDlgTabItem_fix), + DECL_API("GetRawInputBuffer", GetRawInputBuffer_stub), + DECL_API("GetRawInputData", GetRawInputData_stub), + DECL_API("GetRawInputDeviceInfoA", GetRawInputDeviceInfoA_stub), + DECL_API("GetRawInputDeviceInfoW", GetRawInputDeviceInfoW_stub), + DECL_API("GetRawInputDeviceList", GetRawInputDeviceList_stub), + DECL_API("GetRegisteredRawInputDevices", GetRegisteredRawInputDevices_stub), DECL_API("GetWindowLongA", GetWindowLongA_NEW), DECL_API("GetWindowLongW", GetWindowLongW_NEW), DECL_API("GetWindowTextLengthW", GetWindowTextLengthW_NEW), @@ -125,10 +132,12 @@ static const apilib_named_api user32_named_apis[] = DECL_API("PeekMessageW", PeekMessageW_NEW), DECL_API("PostMessageW", PostMessageW_NEW), DECL_API("PostThreadMessageW", PostThreadMessageW_NEW), + DECL_API("PrintWindow", PrintWindow_stub), DECL_API("RealGetWindowClassA", RealGetWindowClass), DECL_API("RealGetWindowClassW", RealGetWindowClassW_new), DECL_API("RegisterClassExW", RegisterClassExW_NEW), DECL_API("RegisterClassW", RegisterClassW_NEW), + DECL_API("RegisterRawInputDevices", RegisterRawInputDevices_stub), DECL_API("RegisterShellHookWindow", IsWindow), DECL_API("SendDlgItemMessageW", SendDlgItemMessageW_NEW), DECL_API("SendMessageA", SendMessageA_fix), diff --git a/apilibs/kexbases/User32/_user32_apilist.h b/apilibs/kexbases/User32/_user32_apilist.h index 55a62b3..1d931e5 100755 --- a/apilibs/kexbases/User32/_user32_apilist.h +++ b/apilibs/kexbases/User32/_user32_apilist.h @@ -60,6 +60,15 @@ UINT WINAPI MapVirtualKeyExA_new(UINT uCode, UINT uMapType, HKL dwhkl); LRESULT WINAPI SendMessageA_fix(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); BOOL WINAPI UpdateLayeredWindow_new(HWND hwnd, HDC hdcDst, POINT *pptDst, SIZE *psize, HDC hdcSrc, POINT *pptSrc, COLORREF crKey, BLENDFUNCTION *pblend, DWORD dwFlags); STUB SetLayeredWindowAttributes_stub; +STUB DefRawInputProc_stub; +STUB GetRawInputBuffer_stub; +STUB GetRawInputData_stub; +STUB GetRawInputDeviceList_stub; +STUB GetRawInputDeviceInfoA_stub; +STUB GetRawInputDeviceInfoW_stub; +STUB GetRegisteredRawInputDevices_stub; +STUB RegisterRawInputDevices_stub; +STUB PrintWindow_stub; LPWSTR WINAPI CharNextExW_new(WORD codepage, LPCWSTR ptr, DWORD flags); LPWSTR WINAPI CharNextW_new(LPCWSTR x); LPSTR WINAPI CharPrevExW_new(WORD codepage, LPCWSTR start, LPCWSTR ptr, DWORD flags); diff --git a/apilibs/kexbases/User32/_user32_stubs.c b/apilibs/kexbases/User32/_user32_stubs.c index f1cff14..6b4065b 100755 --- a/apilibs/kexbases/User32/_user32_stubs.c +++ b/apilibs/kexbases/User32/_user32_stubs.c @@ -1,6 +1,6 @@ /* * KernelEx - * Copyright (C) 2008, Xeno86 + * Copyright (C) 2008-2010, Xeno86, Tihiy * * This file is part of KernelEx source code. * @@ -22,3 +22,14 @@ #include "common.h" UNIMPL_FUNC(SetLayeredWindowAttributes, 4); +//raw input APIs +UNIMPL_FUNC(DefRawInputProc, 3); +UNIMPL_FUNC(GetRawInputBuffer, 3); +UNIMPL_FUNC(GetRawInputData, 5); +UNIMPL_FUNC(GetRawInputDeviceList, 3); +UNIMPL_FUNC(GetRawInputDeviceInfoA, 4); +UNIMPL_FUNC(GetRawInputDeviceInfoW, 4); +UNIMPL_FUNC(GetRegisteredRawInputDevices, 3); +UNIMPL_FUNC(RegisterRawInputDevices, 3); +// +UNIMPL_FUNC(PrintWindow, 3); \ No newline at end of file diff --git a/apilibs/kexbases/kexbases.dsp b/apilibs/kexbases/kexbases.dsp index a4e4f34..b8e60b7 100755 --- a/apilibs/kexbases/kexbases.dsp +++ b/apilibs/kexbases/kexbases.dsp @@ -109,6 +109,10 @@ SOURCE=.\Kernel32\_kernel32_stubs.c # End Source File # Begin Source File +SOURCE=.\Kernel32\CompletionPorts.c +# End Source File +# Begin Source File + SOURCE=.\Kernel32\CopyFileEx.c # End Source File # Begin Source File @@ -578,6 +582,10 @@ InputPath=.\kexbases.def SOURCE=.\main.c # End Source File +# Begin Source File + +SOURCE=.\Kernel32\RtlCaptureContext.c +# End Source File # End Group # Begin Group "Header Files" diff --git a/apilibs/kexbases/shell32/_shell32_apilist.c b/apilibs/kexbases/shell32/_shell32_apilist.c index 674a6c5..eca400e 100755 --- a/apilibs/kexbases/shell32/_shell32_apilist.c +++ b/apilibs/kexbases/shell32/_shell32_apilist.c @@ -22,18 +22,28 @@ #include "common.h" #include "kexcoresdk.h" #include "_shell32_apilist.h" +#include "../kernel32/_kernel32_apilist.h" BOOL init_shell32() { return TRUE; } +/* + * MAKE_EXPORT GetDiskFreeSpaceExA_fix=SHGetDiskFreeSpaceA + * MAKE_EXPORT GetDiskFreeSpaceExA_fix=SHGetDiskFreeSpaceExA + * MAKE_EXPORT GetDiskFreeSpaceExW_new=SHGetDiskFreeSpaceExW + */ + static const apilib_named_api shell32_named_apis[] = { /*** AUTOGENERATED APILIST NAMED EXPORTS BEGIN ***/ DECL_API("CommandLineToArgvW", CommandLineToArgvW_new), DECL_API("IsUserAnAdmin", IsUserAnAdmin_new), DECL_API("SHCreateShellItem", SHCreateShellItem_stub), + DECL_API("SHGetDiskFreeSpaceA", GetDiskFreeSpaceExA_fix), + DECL_API("SHGetDiskFreeSpaceExA", GetDiskFreeSpaceExA_fix), + DECL_API("SHGetDiskFreeSpaceExW", GetDiskFreeSpaceExW_new), DECL_API("SHOpenFolderAndSelectItems", SHOpenFolderAndSelectItems_stub), /*** AUTOGENERATED APILIST NAMED EXPORTS END ***/ }; diff --git a/apilibs/quirks.txt b/apilibs/quirks.txt new file mode 100755 index 0000000..b417ef5 --- /dev/null +++ b/apilibs/quirks.txt @@ -0,0 +1,3 @@ +GTA: San Andreas +---------------- +It can't use jemalloc heap. It depends on undocumented Windows heap feature and expects HeapReAlloc to always shrink allocation blocks in place, thus leading to fragmentation, which jemalloc can't guarantee. diff --git a/apilibs/settings.reg b/apilibs/settings.reg index 8663f55..2c862cf 100755 --- a/apilibs/settings.reg +++ b/apilibs/settings.reg @@ -8,6 +8,7 @@ REGEDIT4 "*\\MFC*U.DLL"="WINXP" ;-Firefox "*\\FIREFOX SETUP 3*.EXE"="WINXP" +"*\\FIREFOX SETUP 4*.EXE"="WINXP" "*FIREFOX\\UNINSTALL\\HELPER.EXE"="WINXP" "*\\FIREFOX*PRE*.INSTALLER.EXE"="WINXP" "*\\XUL.DLL"="NT2K" @@ -23,6 +24,15 @@ REGEDIT4 "*\\QTWEBKIT4.DLL"="WINXP" ;-AbiWord "*\\BIN\\ABIWORD.EXE"="VISTA" +;-Flash Player +"*\\NPSWF32.DLL"="WINXP" +"%WINDIR%\\SYSTEM\\MACROMED\\FLASH\\FLASH10*.OCX"="WINXP" +;-GTA:SA +"*\\GTA_SA.EXE"="NOHEAP" +;-Rally Championship '99 +"*\\RAL.EXE"="NOHEAP" +;-MPC Home Cinema Setup +"*\\MPC-HOMECINEMA.1.*.EXE"="WINXP" [HKEY_LOCAL_MACHINE\Software\KernelEx\AppSettings\Flags] ;DISABLE KERNELEX FOR: diff --git a/common/kexcoresdk.h b/common/kexcoresdk.h index 656e44e..6b41be2 100755 --- a/common/kexcoresdk.h +++ b/common/kexcoresdk.h @@ -190,6 +190,13 @@ _KEXCOREIMP void kexSetModuleSettings(const char* module, const char* conf_name, DWORD mod_flags); +/** kexResetModuleSettings - Reset per module settings to defaults. + * + * @param module Module path. + */ +_KEXCOREIMP void kexResetModuleSettings(const char* module); + + /** kexFlushAppSettings - Reloads all module settings from registy. */ _KEXCOREIMP void kexFlushAppSettings(void); diff --git a/common/version.h b/common/version.h index 9f2e595..4075e97 100755 --- a/common/version.h +++ b/common/version.h @@ -22,9 +22,9 @@ #ifndef __VERSION_H #define __VERSION_H -#define VERSION_STR "4.5 Beta 2" -#define VERSION_CODE 0x04050002 -#define RCVERSION 4, 5, 0, 2 -#define _RCVERSION_ "4, 5, 0, 2" +#define VERSION_STR "4.5 RC 1" +#define VERSION_CODE 0x0405000B +#define RCVERSION 4, 5, 1, 1 +#define _RCVERSION_ "4, 5, 1, 1" #endif diff --git a/core/SettingsDB.cpp b/core/SettingsDB.cpp index 17176e5..b998376 100755 --- a/core/SettingsDB.cpp +++ b/core/SettingsDB.cpp @@ -224,6 +224,7 @@ void SettingsDB::write_single(const char* path, const char* conf_name, BYTE flag char path2[MAX_PATH]; strncpy(path2, path, sizeof(path2)); strupr(path2); + path = path2; //check if configuration name is valid as.conf = apiconfmgr.get_api_configuration(conf_name); @@ -253,8 +254,43 @@ void SettingsDB::write_single(const char* path, const char* conf_name, BYTE flag //add to DB EnterCriticalSection(&cs); - db.erase(path2); - db.insert(pair(path2, as)); + db.erase(path); + db.insert(pair(path, as)); + LeaveCriticalSection(&cs); +} + +void SettingsDB::reset_single(const char* path) +{ + LONG result; + HKEY key; + + //convert path to uppercase + char path2[MAX_PATH]; + strncpy(path2, path, sizeof(path2)); + strupr(path2); + path = path2; + + //erase config + result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, + "Software\\KernelEx\\AppSettings\\Configs", 0, KEY_WRITE, &key); + if (result == ERROR_SUCCESS) + { + RegDeleteValue(key, path); + RegCloseKey(key); + } + + //erase flags + result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, + "Software\\KernelEx\\AppSettings\\Flags", 0, KEY_WRITE, &key); + if (result == ERROR_SUCCESS) + { + RegDeleteValue(key, path); + RegCloseKey(key); + } + + //erase from DB + EnterCriticalSection(&cs); + db.erase(path); LeaveCriticalSection(&cs); } diff --git a/core/SettingsDB.h b/core/SettingsDB.h index a748ed1..bda6c5b 100755 --- a/core/SettingsDB.h +++ b/core/SettingsDB.h @@ -39,6 +39,7 @@ public: void flush_all(); appsetting get_appsetting(const char* path); void write_single(const char* path, const char* conf_name, BYTE flags); + void reset_single(const char* path); #ifdef _DEBUG void dump_db(); #endif diff --git a/core/kexcoresdk.cpp b/core/kexcoresdk.cpp index cf0b988..5338815 100755 --- a/core/kexcoresdk.cpp +++ b/core/kexcoresdk.cpp @@ -108,6 +108,11 @@ void kexSetModuleSettings(const char* module, SettingsDB::instance.write_single(module, conf_name, flags); } +void kexResetModuleSettings(const char* module) +{ + SettingsDB::instance.reset_single(module); +} + void kexFlushAppSettings(void) { SettingsDB::instance.flush_all(); diff --git a/core/resolver.cpp b/core/resolver.cpp index b3e0a88..2eb1b22 100755 --- a/core/resolver.cpp +++ b/core/resolver.cpp @@ -40,7 +40,7 @@ char system_path[MAX_PATH]; int system_path_len; static PLONG jtab; -static LONG old_jtab[JTAB_SIZE]; +LONG old_jtab[JTAB_SIZE]; static HKEY known_dlls_key; FLoadTreeNotify_t FLoadTreeNotify; @@ -56,6 +56,7 @@ static bool get_config(MODREF* moduleMR, config_params& cp) IMTE** pmteModTable = *ppmteModTable; PDB98* ppdbCur = *pppdbCur; volatile MODREF_KEX module(moduleMR); + DBGASSERT(ppdbCur->pExeMODREF != NULL); MODREF_KEX process(ppdbCur->pExeMODREF); //shared modules should use standard api @@ -599,6 +600,59 @@ bool are_extensions_enabled() return get_config(exe, cp); } +/** Determines whether module has API extensions enabled. + * Use this function when there is no access to MODREF. + * @param path Full path of the module (uppercase). + */ +bool are_extensions_enabled_module(const char* path) +{ + //find entry for given module... + appsetting as = SettingsDB::instance.get_appsetting(path); + + if (!(as.flags & LDR_VALID_FLAG)) + { + //...no entry? try process exe settings... + PDB98* ppdbCur = *pppdbCur; + MODREF* exe = ppdbCur->pExeMODREF; + + if (exe != NULL) + { + config_params cp; + + as.flags = LDR_VALID_FLAG; + if (!get_config(exe, cp)) + as.flags |= LDR_KEX_DISABLE; + } + else + { + //...so there is NO PROCESS exe yet? try with parent process exe... + PDB98* ppdbParent = ppdbCur->ParentPDB; + + if (ppdbParent && !(ppdbParent->Flags & (fTerminated | fTerminating | + fNearlyTerminating | fDosProcess | fWin16Process))) + { + MODREF_KEX parent(ppdbParent->pExeMODREF); + + //...unless parent disallows us to inherit + if ((parent.as.flags & LDR_VALID_FLAG) && !(parent.as.flags & LDR_NO_INHERIT)) + as = parent.as; + } + } + } + + //...so everything else failed eh? - take defaults then... + if (!(as.flags & LDR_VALID_FLAG)) + { + as.flags = LDR_VALID_FLAG; + if (apiconfmgr.are_extensions_disabled()) + as.flags |= LDR_KEX_DISABLE; + } + + if (as.flags & LDR_KEX_DISABLE) + return false; + return true; +} + typedef BOOL (__stdcall *IsKnownDLL_t)(char*, const char*); static BOOL WINAPI IsKnownKexDLL(char* name, const char* ext) @@ -648,6 +702,29 @@ static BOOL WINAPI KexLoadTreeNotify(MODREF* mr, BOOL is_static) return FLoadTreeNotify(mr, is_static); } +typedef BOOL (WINAPI * GetOrdinal_t)(DWORD, DWORD, DWORD, DWORD*, WORD*, DWORD); + +static BOOL WINAPI KexResourceCheck(DWORD un0, DWORD un1, DWORD un2, DWORD* pNameOrId, WORD* pResult, DWORD un3) +{ + DWORD NameOrId = *pNameOrId; //parameter from IMAGE_RESOURCE_DIRECTORY_ENTRY + + //not a named resource and index > 32767 allowed by 9x ? + if (!(NameOrId & 0x80000000) && NameOrId >= 0x8000 && NameOrId < 0x10000) + { + //we need to check if module has extensions enabled + if (mod_ext_ena) + { + NameOrId |= 0x8000; //?? + *pResult = NameOrId; + return TRUE; + } + } + + //fall back + GetOrdinal_t GetOrdinal = (GetOrdinal_t) old_jtab[JTAB_RES_CHK]; + return GetOrdinal(un0, un1, un2, pNameOrId, pResult, un3); +} + PROC WINAPI iGetProcAddress(HMODULE hModule, LPCSTR lpProcName) { IMAGE_DOS_HEADER* dos_hdr; @@ -805,6 +882,8 @@ void resolver_hook() old_jtab[JTAB_EFN_STA] = InterlockedExchange(jtab + JTAB_EFN_STA, (LONG) ExportFromNameStatic_thunk); old_jtab[JTAB_KNO_DLL] = InterlockedExchange(jtab + JTAB_KNO_DLL, (LONG) IsKnownKexDLL); old_jtab[JTAB_FLD_TRN] = InterlockedExchange(jtab + JTAB_FLD_TRN, (LONG) KexLoadTreeNotify); + old_jtab[JTAB_SYS_CHK] = InterlockedExchange(jtab + JTAB_SYS_CHK, (LONG) SubSysCheck); + old_jtab[JTAB_RES_CHK] = InterlockedExchange(jtab + JTAB_RES_CHK, (LONG) KexResourceCheck); } void resolver_unhook() diff --git a/core/resolver.h b/core/resolver.h index 0b97f75..47cfb4b 100755 --- a/core/resolver.h +++ b/core/resolver.h @@ -85,7 +85,10 @@ struct config_params #pragma pack(pop) +extern LONG old_jtab[]; + bool are_extensions_enabled(); +bool are_extensions_enabled_module(const char* path); DWORD encode_address(DWORD addr, const ApiLibrary* apilib); PROC WINAPI iGetProcAddress(HMODULE hModule, LPCSTR lpProcName); PROC WINAPI ExportFromOrdinal(IMTE_KEX* target, MODREF* caller, BOOL is_static, WORD ordinal); diff --git a/core/thunks.cpp b/core/thunks.cpp index 820a62f..81ec762 100755 --- a/core/thunks.cpp +++ b/core/thunks.cpp @@ -1,6 +1,6 @@ /* * KernelEx - * Copyright (C) 2008-2009, Xeno86 + * Copyright (C) 2008-2010, Xeno86 * * This file is part of KernelEx source code. * @@ -23,6 +23,7 @@ #include "thunks.h" #include "internals.h" #include "resolver.h" +#include "../setup/loadstub.h" __declspec(naked) PROC ExportFromOrdinalStatic_thunk(IMAGE_NT_HEADERS* PEh, WORD ordinal) @@ -102,3 +103,27 @@ __asm { jmp ExportFromName } } + +BYTE mod_ext_ena; + +__declspec(naked) +void SubSysCheck() +{ +__asm { + seta al /* is subsystem value above supported by OS? */ + push eax + + push [ebp+8] + call are_extensions_enabled_module + add esp, 4 + mov mod_ext_ena, al + cmp al, 1 + clc + + pop ecx + jz __done + cmp cl, 0 +__done: + jmp [old_jtab+4*JTAB_SYS_CHK] + } +} diff --git a/core/thunks.h b/core/thunks.h index 6f52043..f18c696 100755 --- a/core/thunks.h +++ b/core/thunks.h @@ -1,6 +1,6 @@ /* * KernelEx - * Copyright (C) 2008-2009, Xeno86 + * Copyright (C) 2008-2010, Xeno86 * * This file is part of KernelEx source code. * @@ -26,5 +26,7 @@ PROC ExportFromOrdinalStatic_thunk(IMAGE_NT_HEADERS* PEh, WORD ordinal); PROC ExportFromNameStatic_thunk(IMAGE_NT_HEADERS* PEh, WORD hint, LPCSTR name); PROC ExportFromOrdinalDynamic_thunk(IMAGE_NT_HEADERS* PEh, WORD ordinal); PROC ExportFromNameDynamic_thunk(IMAGE_NT_HEADERS* PEh, WORD hint, LPCSTR name); +void SubSysCheck(); +extern BYTE mod_ext_ena; #endif diff --git a/kexcrt/ctypes.c b/kexcrt/ctypes.c index 1106418..4788003 100755 --- a/kexcrt/ctypes.c +++ b/kexcrt/ctypes.c @@ -2,7 +2,7 @@ * ctypes.c * * This is the array that defines classes. - * This assumes ISO 8859-1. + * This assumes ASCII. */ #include "ctypes.h" @@ -145,140 +145,4 @@ const unsigned char __ctypes[257] = { __ctype_print | __ctype_punct, /* punctuation */ __ctype_print | __ctype_punct, /* punctuation */ __ctype_cntrl, /* control character */ - - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - - __ctype_print | __ctype_space, /* NBSP */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_punct, /* punctuation */ - - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_upper, /* upper accented */ - __ctype_print | __ctype_lower, /* lower accented */ - - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_punct, /* punctuation */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ - __ctype_print | __ctype_lower, /* lower accented */ }; diff --git a/kexcrt/kexcrt.dsp b/kexcrt/kexcrt.dsp index 3acf6cd..d930ab5 100755 --- a/kexcrt/kexcrt.dsp +++ b/kexcrt/kexcrt.dsp @@ -238,6 +238,10 @@ SOURCE=.\strcpy.c # End Source File # Begin Source File +SOURCE=.\strdup.c +# End Source File +# Begin Source File + SOURCE=.\strlen.c # End Source File # Begin Source File diff --git a/kexcrt/makefile b/kexcrt/makefile index 8c2dc82..60e3c26 100755 --- a/kexcrt/makefile +++ b/kexcrt/makefile @@ -1,4 +1,4 @@ -OBJ = abort.o assert.o atoi.o atol.o atoll.o ctypes.o memccpy.o memchr.o memcmp.o memcpy.o memmem.o memmove.o memory.o memory-cpp.o memrchr.o memset.o memswap.o printf.o snprintf.o sprintf.o sscanf.o strcat.o strchr.o strcmp.o strcmpi.o strcpy.o strlen.o strncat.o strncmp.o strncpy.o strnicmp.o strnlen.o strntoimax.o strntoumax.o strpbrk.o strrchr.o strsep.o strstr.o strtok.o strtok_r.o strtol.o strtoll.o strtoul.o strtoull.o strtoumax.o strupr.o strxspn.o vsnprintf.o vsprintf.o vsscanf.o _vsnprintf.o write.o exit.o \ +OBJ = abort.o assert.o atoi.o atol.o atoll.o ctypes.o memccpy.o memchr.o memcmp.o memcpy.o memmem.o memmove.o memory.o memory-cpp.o memrchr.o memset.o memswap.o printf.o snprintf.o sprintf.o sscanf.o strcat.o strchr.o strcmp.o strcmpi.o strcpy.o strdup.o strlen.o strncat.o strncmp.o strncpy.o strnicmp.o strnlen.o strntoimax.o strntoumax.o strpbrk.o strrchr.o strsep.o strstr.o strtok.o strtok_r.o strtol.o strtoll.o strtoul.o strtoull.o strtoumax.o strupr.o strxspn.o vsnprintf.o vsprintf.o vsscanf.o _vsnprintf.o write.o exit.o \ ctype/isalnum.o ctype/isalpha.o ctype/isascii.o ctype/isblank.o ctype/iscntrl.o ctype/isdigit.o ctype/isgraph.o ctype/islower.o ctype/isprint.o ctype/ispunct.o ctype/isspace.o ctype/isupper.o ctype/isxdigit.o ctype/tolower.o ctype/toupper.o \ gcc/init.o gcc/dllcrt0.o gcc/pseudo-reloc.o gcc/pseudo-reloc-list.o gcc/purecall.o diff --git a/kexcrt/makefile.msv b/kexcrt/makefile.msv index 2fecdf4..a9596be 100755 --- a/kexcrt/makefile.msv +++ b/kexcrt/makefile.msv @@ -1,4 +1,4 @@ -OBJ = abort.obj assert.obj atoi.obj atol.obj atoll.obj ctypes.obj memccpy.obj memchr.obj memcmp.obj memcpy.obj memmem.obj memmove.obj memory.obj memory-cpp.obj memrchr.obj memset.obj memswap.obj printf.obj snprintf.obj sprintf.obj sscanf.obj strcat.obj strchr.obj strcmp.obj strcmpi.obj strcpy.obj strlen.obj strncat.obj strncmp.obj strncpy.obj strnicmp.obj strnlen.obj strntoimax.obj strntoumax.obj strpbrk.obj strrchr.obj strsep.obj strstr.obj strtok.obj strtok_r.obj strtol.obj strtoll.obj strtoul.obj strtoull.obj strtoumax.obj strupr.obj strxspn.obj vsnprintf.obj vsprintf.obj vsscanf.obj _vsnprintf.obj write.obj exit.obj \ +OBJ = abort.obj assert.obj atoi.obj atol.obj atoll.obj ctypes.obj memccpy.obj memchr.obj memcmp.obj memcpy.obj memmem.obj memmove.obj memory.obj memory-cpp.obj memrchr.obj memset.obj memswap.obj printf.obj snprintf.obj sprintf.obj sscanf.obj strcat.obj strchr.obj strcmp.obj strcmpi.obj strcpy.obj strdup.obj strlen.obj strncat.obj strncmp.obj strncpy.obj strnicmp.obj strnlen.obj strntoimax.obj strntoumax.obj strpbrk.obj strrchr.obj strsep.obj strstr.obj strtok.obj strtok_r.obj strtol.obj strtoll.obj strtoul.obj strtoull.obj strtoumax.obj strupr.obj strxspn.obj vsnprintf.obj vsprintf.obj vsscanf.obj _vsnprintf.obj write.obj exit.obj \ ctype/isalnum.obj ctype/isalpha.obj ctype/isascii.obj ctype/isblank.obj ctype/iscntrl.obj ctype/isdigit.obj ctype/isgraph.obj ctype/islower.obj ctype/isprint.obj ctype/ispunct.obj ctype/isspace.obj ctype/isupper.obj ctype/isxdigit.obj ctype/tolower.obj ctype/toupper.obj \ msvc/init.obj msvc/dllcrt0.obj msvc/argcargv.obj msvc/concrt0.obj msvc/wincrt0.obj msvc/purecall.obj diff --git a/kexcrt/strdup.c b/kexcrt/strdup.c new file mode 100755 index 0000000..40830d9 --- /dev/null +++ b/kexcrt/strdup.c @@ -0,0 +1,16 @@ +#include +#include + +char *strdup(const char *str) +{ + char *newstr; + + if (!str) + return NULL; + + newstr = (char *) malloc(strlen(str) + 1); + if (newstr) + strcpy(newstr, str); + + return newstr; +} diff --git a/setup/loadstub.h b/setup/loadstub.h index 9f8b736..68fe6bf 100755 --- a/setup/loadstub.h +++ b/setup/loadstub.h @@ -24,15 +24,17 @@ #define KEX_SIGNATURE "KrnlEx" /* Update this whenever patching functions are changed. */ -#define KEX_STUB_VER 6 +#define KEX_STUB_VER 9 -#define JTAB_SIZE 6 +#define JTAB_SIZE 8 #define JTAB_EFO_DYN 0 #define JTAB_EFO_STA 1 #define JTAB_EFN_DYN 2 #define JTAB_EFN_STA 3 #define JTAB_KNO_DLL 4 #define JTAB_FLD_TRN 5 +#define JTAB_SYS_CHK 6 +#define JTAB_RES_CHK 7 #include typedef struct diff --git a/setup/setup.cpp b/setup/setup.cpp index 12df334..0af94a4 100755 --- a/setup/setup.cpp +++ b/setup/setup.cpp @@ -182,7 +182,7 @@ int Setup::get_signature_ver() return dseg->version; } -void Setup::disable_platform_check() +void Setup::prepare_subsystem_check() { static const short pattern[] = { 0x66,0x8b,0x46,0x48,0x66,0x3d,0x04,0x00,0x0f,0x87,0x9c,0x01,0x00,0x00, @@ -190,8 +190,8 @@ void Setup::disable_platform_check() 0x81,0x7e,0x04,0x4c,0x01, }; static const short after[] = { - 0xeb,0x19,0x46,0x48,0x66,0x3d,0x04,0x00,0x0f,0x87,0x9c,0x01,0x00,0x00, - 0x75,0x0b,0x66,0x83,0x7e,0x4a,0x0a,0x0f,0x87,0x8f,0x01,0x00,0x00,0x66, + 0x66,0x83,0x7E,0x48,0x04,0x75,0x05,0x66,0x83,0x7E,0x4A,0x0A,0xE9,0x00, + 0x00,0x00,0x00,0x0F,0x87,0x93,0x01,0x00,0x00,0x90,0x90,0x90,0x90,0x66, 0x81,0x7e,0x04,0x4c,0x01, }; @@ -202,36 +202,61 @@ void Setup::disable_platform_check() int found = find_pattern(offset, size, pattern, length, &found_loc); if (found != 1) { - if (!found) ShowError(IDS_NOPAT, "disable_platform_check"); - else ShowError(IDS_MULPAT, "disable_platform_check"); + if (!found) ShowError(IDS_NOPAT, "subsystem_check"); + else ShowError(IDS_MULPAT, "subsystem_check"); } - DBGPRINTF(("%s: pattern found @ 0x%08x\n", "disable_platform_check", + DBGPRINTF(("%s: pattern found @ 0x%08x\n", "subsystem_check", pefile.PointerToRva((void*) found_loc) + pefile.GetImageBase())); set_pattern(found_loc, after, length); + + SubsysCheck_jmp = found_loc + 12; + _SubsysCheckPerform = decode_jmp(SubsysCheck_jmp, 5); } -void Setup::disable_resource_check() +void Setup::find_resource_check1() { static const short pattern[] = { - 0x3d,0x00,0x80,0x00,0x00,0x72, - }; - static const short after[] = { - 0x3d,0x00,0x80,0x00,0x00,0xeb, + 0x6A,0x00,0x8D,0x45,0xE0,0x50,0xFF,0x75,0xA4,0xFF,0x75,0xD0,0x8D,0x45, + 0xCC,0x50,0xFF,0x75,0x08,0xE8,-2,-2,-2,-2,0x85,0xC0 }; DWORD offset = (DWORD) pefile.GetSectionByName(CODE_SEG); int size = pefile.GetSectionSize(CODE_SEG); int length = sizeof(pattern) / sizeof(short); DWORD found_loc; - int found = find_pattern(offset, size, pattern, length, &found_loc); + int found = find_pattern(offset, size,pattern, length, &found_loc); if (found != 1) { - if (!found) ShowError(IDS_NOPAT, "disable_resource_check"); - else ShowError(IDS_MULPAT, "disable_resource_check"); + if (!found) ShowError(IDS_NOPAT, "resource_check1"); + else ShowError(IDS_MULPAT, "resource_check1"); } - DBGPRINTF(("%s: pattern found @ 0x%08x\n", "disable_resource_check", + DBGPRINTF(("%s: pattern found @ 0x%08x\n", "resource_check1", pefile.PointerToRva((void*) found_loc) + pefile.GetImageBase())); - set_pattern(found_loc, after, length); + GetOrdinal_call1 = found_loc + 19; + _GetOrdinal = decode_call(GetOrdinal_call1, 5); +} + +void Setup::find_resource_check2() +{ + static const short pattern[] = { + 0x66,0x8B,0x45,0xE0,0x66,0x2D,0x06,0x80,0x66,0x3D,0x01,0x00,0x1B,0xC0, + 0xF7,0xD8,0x50,0x8D,0x45,0xDE,0x50,0xFF,0x75, -1,0xFF,0x75,0xD0,0x8D, + 0x45,0xCC,0x50,0xFF,0x75,0x08,0xE8, -2, -2, -2, -2,0x85,0xC0 + }; + + DWORD offset = (DWORD) pefile.GetSectionByName(CODE_SEG); + int size = pefile.GetSectionSize(CODE_SEG); + int length = sizeof(pattern) / sizeof(short); + DWORD found_loc; + int found = find_pattern(offset, size,pattern, length, &found_loc); + if (found != 1) + { + if (!found) ShowError(IDS_NOPAT, "resource_check2"); + else ShowError(IDS_MULPAT, "resource_check2"); + } + DBGPRINTF(("%s: pattern found @ 0x%08x\n", "resource_check2", + pefile.PointerToRva((void*) found_loc) + pefile.GetImageBase())); + GetOrdinal_call2 = found_loc + 34; } //no named/rcdata resource types mirroring @@ -265,31 +290,6 @@ void Setup::disable_named_and_rcdata_resources_mirroring() set_pattern(found_loc, after, length); } -//change obfuscator to non-negative IDs -void Setup::positive_pids_patch() -{ - static const short pattern[] = { - 0xB9,0x01,0x00,0xFF,0xFF,-1,0x23,0xD1,0x33,0xD1 - }; - static const short after[] = { - 0xB9,0x01,0x00,0xFF,0x4F,-1,0x23,0xD1,0x2B,0xD1 - }; - - DWORD offset = (DWORD) pefile.GetSectionByName(INIT_SEG); - int size = pefile.GetSectionSize(INIT_SEG); - int length = sizeof(pattern) / sizeof(short); - DWORD found_loc; - int found = find_pattern(offset, size, pattern, length, &found_loc); - if (found != 1) - { - if (!found) ShowError(IDS_NOPAT, "positive_pids_patch"); - else ShowError(IDS_MULPAT, "positive_pids_patch"); - } - DBGPRINTF(("%s: pattern found @ 0x%08x\n", "positive_pids_patch", - pefile.PointerToRva((void*) found_loc) + pefile.GetImageBase())); - set_pattern(found_loc, after, length); -} - void Setup::mod_imte_alloc() { //VA BFF8745C, RVA 1745C, file 15A5C, sec E45C @@ -503,16 +503,58 @@ DWORD Setup::decode_call(DWORD addr, int len) { unsigned char* code = (unsigned char*)addr; - if (len == 5 && *code == 0xe8) /* call rel32 */ + /* CALL rel32 */ + if (code[0] == 0xe8) { - return (DWORD)(pefile.PointerToRva(code) + 5 + *(DWORD*)(code + 1)); + if (len && len == 5 || !len) + return (DWORD)(pefile.PointerToRva(code) + 5 + *(INT32*)(code + 1)); } - else if (len == 6 && code[0] == 0xff - && code[1] == 0x15) /* call m32 */ + /* CALL imm32 */ + else if (code[0] == 0xff && code[1] == 0x15) { + if (len && len == 6 || !len) return *(DWORD*)(code + 2); } - else return 0; + /* unmatched */ + return 0; +} + +DWORD Setup::decode_jmp(DWORD addr, int len) +{ + unsigned char* code = (unsigned char*)addr; + + /* JMP rel8 */ + if (code[0] == 0xeb) + { + if (len && len == 2 || !len) + return (DWORD)(pefile.PointerToRva(code) + 2 + *(INT8*)(code + 1)); + } + /* JMP rel32 */ + else if (code[0] == 0xe9) + { + if (len && len == 5 || !len) + return (DWORD)(pefile.PointerToRva(code) + 5 + *(INT32*)(code + 1)); + } + /* JMP imm32 */ + else if (code[0] == 0xff && code[1] == 0x25) + { + if (len && len == 6 || !len) + return *(DWORD*)(code + 2); + } + /* Jxx rel8 */ + else if (code[0] >= 0x70 && code[0] < 0x7f || code[0] == 0xe3) + { + if (len && len == 2 || !len) + return (DWORD)(pefile.PointerToRva(code) + 2 + *(INT8*)(code + 1)); + } + /* Jxx rel32 */ + else if (code[0] == 0x0f && code[1] >= 0x80 && code[1] <= 0x8f) + { + if (len && len == 6 || !len) + return (DWORD)(pefile.PointerToRva(code) + 6 + *(INT32*)(code + 2)); + } + /* unmatched */ + return 0; } bool Setup::is_call_ref(DWORD loc, DWORD target) @@ -534,6 +576,25 @@ void Setup::set_call_ref(DWORD loc, DWORD target) *(DWORD*)(loc + 1) = rel; } +// Both addresses have to be from the same section! +void Setup::set_jmp_ref(DWORD loc, DWORD target) +{ + DWORD rel; + unsigned char* code = (unsigned char*)loc; + + if (code[0] == 0xe9) + { + rel = target - (loc + 5); + *(DWORD*)(loc + 1) = rel; + } + else if (code[0] == 0x0f && code[1] >= 0x80 && code[1] <= 0x8f) + { + rel = target - (loc + 6); + *(DWORD*)(loc + 2) = rel; + } + else assert(false); +} + bool Setup::is_fixupc(DWORD addr) { if (*(DWORD*)(addr - 5) == 0xDAC) @@ -593,7 +654,7 @@ void Setup::install() if (!pefile.HasTarget()) { if (upgrade) - ShowError(IDS_FAILOPENBACKUP, backup_file, kernel32path); + ShowError(IDS_FAILOPENBACKUP, (const char*) backup_file, kernel32path); else ShowError(IDS_FAILOPEN, kernel32path); } @@ -602,10 +663,10 @@ void Setup::install() find_IsKnownDLL(); find_FLoadTreeNotify1(); find_FLoadTreeNotify2(); - disable_platform_check(); - disable_resource_check(); + prepare_subsystem_check(); + find_resource_check1(); + find_resource_check2(); disable_named_and_rcdata_resources_mirroring(); - positive_pids_patch(); mod_imte_alloc(); mod_mr_alloc(); mod_pdb_alloc(); @@ -637,6 +698,8 @@ void Setup::install() dseg->jtab[JTAB_EFN_STA] = _ExportFromName + pefile.GetImageBase(); dseg->jtab[JTAB_KNO_DLL] = _IsKnownDLL + pefile.GetImageBase(); dseg->jtab[JTAB_FLD_TRN] = _FLoadTreeNotify + pefile.GetImageBase(); + dseg->jtab[JTAB_SYS_CHK] = _SubsysCheckPerform + pefile.GetImageBase(); + dseg->jtab[JTAB_RES_CHK] = _GetOrdinal + pefile.GetImageBase(); //exportfromx patch DWORD code = (DWORD) pefile.GetSectionByName(CODE_SEG); @@ -656,7 +719,7 @@ void Setup::install() set_call_ref(file_loc, (DWORD) &cseg->jmp_stub[JTAB_EFO_DYN]); else set_call_ref(file_loc, (DWORD) &cseg->jmp_stub[JTAB_EFO_STA]); - DBGPRINTF(("EFO: address %08x\n", pefile.PointerToRva((void*) a) + DBGPRINTF(("%s: address 0x%08x\n", "EFO", pefile.PointerToRva((void*) a) + pefile.GetImageBase())); efo_cnt++; } @@ -669,7 +732,7 @@ void Setup::install() set_call_ref(file_loc, (DWORD) &cseg->jmp_stub[JTAB_EFN_DYN]); else set_call_ref(file_loc, (DWORD) &cseg->jmp_stub[JTAB_EFN_STA]); - DBGPRINTF(("EFN: address %08x\n", pefile.PointerToRva((void*) a) + DBGPRINTF(("%s: address 0x%08x\n", "EFN", pefile.PointerToRva((void*) a) + pefile.GetImageBase())); efn_cnt++; } @@ -680,22 +743,35 @@ void Setup::install() //isknowndll patch set_call_ref(IsKnownDLL_call, (DWORD) &cseg->jmp_stub[JTAB_KNO_DLL]); - DBGPRINTF(("KNO_DLL: address %08x\n", pefile.PointerToRva((void*) IsKnownDLL_call) + DBGPRINTF(("%s: address 0x%08x\n", "KNO_DLL", pefile.PointerToRva((void*) IsKnownDLL_call) + pefile.GetImageBase())); //FLoadTreeNotify patch set_call_ref(FLoadTreeNotify_call1, (DWORD) &cseg->jmp_stub[JTAB_FLD_TRN]); - DBGPRINTF(("FLD_TRN: address %08x\n", pefile.PointerToRva((void*) FLoadTreeNotify_call1) + DBGPRINTF(("%s: address 0x%08x\n", "FLD_TRN1", pefile.PointerToRva((void*) FLoadTreeNotify_call1) + pefile.GetImageBase())); set_call_ref(FLoadTreeNotify_call2, (DWORD) &cseg->jmp_stub[JTAB_FLD_TRN]); - DBGPRINTF(("FLD_TRN: address %08x\n", pefile.PointerToRva((void*) FLoadTreeNotify_call2) + DBGPRINTF(("%s: address 0x%08x\n", "FLD_TRN2", pefile.PointerToRva((void*) FLoadTreeNotify_call2) + + pefile.GetImageBase())); + + //subsys check patch + set_jmp_ref(SubsysCheck_jmp, (DWORD) &cseg->jmp_stub[JTAB_SYS_CHK]); + DBGPRINTF(("%s: address 0x%08x\n", "SYS_CHK", pefile.PointerToRva((void*) SubsysCheck_jmp) + + pefile.GetImageBase())); + + //resource check patch + set_call_ref(GetOrdinal_call1, (DWORD) &cseg->jmp_stub[JTAB_RES_CHK]); + DBGPRINTF(("%s: address 0x%08x\n", "RES_CHK1", pefile.PointerToRva((void*) GetOrdinal_call1) + + pefile.GetImageBase())); + set_call_ref(GetOrdinal_call2, (DWORD) &cseg->jmp_stub[JTAB_RES_CHK]); + DBGPRINTF(("%s: address 0x%08x\n", "RES_CHK2", pefile.PointerToRva((void*) GetOrdinal_call2) + pefile.GetImageBase())); // backup original file if (!upgrade) { if (!CopyFile(kernel32path, backup_file, FALSE)) - ShowError(IDS_FAILBAK, backup_file); + ShowError(IDS_FAILBAK, (const char*) backup_file); } // save patched file diff --git a/setup/setup.h b/setup/setup.h index f017eb6..758ceb4 100755 --- a/setup/setup.h +++ b/setup/setup.h @@ -34,19 +34,24 @@ public: protected: private: sstring backup_file; + DWORD _GetOrdinal; DWORD _ExportFromOrdinal; DWORD _ExportFromName; DWORD _IsKnownDLL; DWORD _FLoadTreeNotify; + DWORD _SubsysCheckPerform; HMODULE h_kernel32; PEmanip pemem; PEmanip pefile; + DWORD GetOrdinal_call1; + DWORD GetOrdinal_call2; DWORD gpa_ExportFromOrdinal_call; DWORD gpa_ExportFromName_call; DWORD EFN_EFO_call; DWORD IsKnownDLL_call; DWORD FLoadTreeNotify_call1; DWORD FLoadTreeNotify_call2; + DWORD SubsysCheck_jmp; int version; bool is_winme; bool upgrade; @@ -55,10 +60,10 @@ private: void detect_downgrade(); int find_pattern(DWORD offset, int size, const short* pattern, int pat_len, DWORD* found_loc); void set_pattern(DWORD loc, const short* new_pattern, int pat_len); - void disable_platform_check(); - void disable_resource_check(); + void prepare_subsystem_check(); + void find_resource_check1(); + void find_resource_check2(); void disable_named_and_rcdata_resources_mirroring(); - void positive_pids_patch(); void mod_imte_alloc(); void mod_mr_alloc(); void mod_pdb_alloc(); @@ -67,9 +72,11 @@ private: void find_FLoadTreeNotify1(); void find_FLoadTreeNotify2(); void kill_process(const char* name); - DWORD decode_call(DWORD addr, int len); + DWORD decode_call(DWORD addr, int len = 0); + DWORD decode_jmp(DWORD addr, int len = 0); bool is_call_ref(DWORD loc, DWORD target); void set_call_ref(DWORD loc, DWORD target); + void set_jmp_ref(DWORD loc, DWORD target); bool is_fixupc(DWORD addr); sstring get_temp_file_name(); void ShowError(UINT id, ...); diff --git a/sheet/KexLinkage.cpp b/sheet/KexLinkage.cpp index c4c07f8..e4dd9e2 100755 --- a/sheet/KexLinkage.cpp +++ b/sheet/KexLinkage.cpp @@ -56,12 +56,15 @@ bool KexLinkage::Prepare() "kexGetModuleSettings"); m_kexSetModuleSettings = (kexSetModuleSettings_t) GetProcAddress(hKernelEx, "kexSetModuleSettings"); + m_kexResetModuleSettings = (kexResetModuleSettings_t) GetProcAddress(hKernelEx, + "kexResetModuleSettings"); m_kexGetKEXVersion = (kexGetKEXVersion_t) GetProcAddress(hKernelEx, "kexGetKEXVersion"); m_kexIsDebugCore = (kexIsDebugCore_t) GetProcAddress(hKernelEx, "kexIsDebugCore"); if (!m_kexGetModuleSettings || !m_kexSetModuleSettings + || !m_kexResetModuleSettings || !m_kexGetKEXVersion || !m_kexIsDebugCore) return false; diff --git a/sheet/KexLinkage.h b/sheet/KexLinkage.h index aebdcc9..5f8bae1 100755 --- a/sheet/KexLinkage.h +++ b/sheet/KexLinkage.h @@ -36,6 +36,7 @@ class KexLinkage char* conf_name, DWORD* mod_flags); typedef void (*kexSetModuleSettings_t)(const char* module, const char* conf_name, DWORD mod_flags); + typedef void (*kexResetModuleSettings_t)(const char* module); typedef unsigned long (*kexGetKEXVersion_t)(void); typedef int (*kexIsDebugCore_t)(void); @@ -57,6 +58,7 @@ public: bool disable_extensions; kexGetModuleSettings_t m_kexGetModuleSettings; kexSetModuleSettings_t m_kexSetModuleSettings; + kexResetModuleSettings_t m_kexResetModuleSettings; kexGetKEXVersion_t m_kexGetKEXVersion; kexIsDebugCore_t m_kexIsDebugCore; diff --git a/sheet/resource.h b/sheet/resource.h index 9e28984..a839ae0 100755 --- a/sheet/resource.h +++ b/sheet/resource.h @@ -2,12 +2,15 @@ // Microsoft Developer Studio generated include file. // Used by sheet.rc // -#define TIP_DISABLE 1 -#define TIP_COMPAT 2 -#define TIP_SYSTEM 3 -#define TIP_NOINHERIT 4 -#define TIP_OVERRIDE 5 -#define TIP_LOG 6 +#define TIP_DEFAULT 1 +#define TIP_DISABLE 2 +#define TIP_COMPAT 3 +#define TIP_SYSTEM 4 +#define TIP_NOINHERIT 5 +#define TIP_OVERRIDE 6 +#define TIP_LOG 7 +#define IDS_ENABLED 8 +#define IDS_DISABLED 9 #define IDD_PROPPAGE 102 #define IDC_CHECK 1000 #define IDC_COMPAT 1000 @@ -22,6 +25,7 @@ #define IDC_GADVAN 1010 #define IDC_CHECK1 1011 #define IDC_OVERRIDE 1011 +#define IDC_DEFAULT 1012 // Next default values for new objects // @@ -29,7 +33,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 102 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1012 +#define _APS_NEXT_CONTROL_VALUE 1013 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/sheet/server.cpp b/sheet/server.cpp index c5d10af..c1f5870 100755 --- a/sheet/server.cpp +++ b/sheet/server.cpp @@ -81,36 +81,18 @@ STDAPI DllRegisterServer() RegCloseKey(keyCLSID); } - if (RegCreateKey(HKEY_CLASSES_ROOT, "exefile\\shellex\\PropertySheetHandlers", + if (RegCreateKey(HKEY_CLASSES_ROOT, "*\\shellex\\PropertySheetHandlers", &hkey) != ERROR_SUCCESS) result = false; if (result) { - if (RegCreateKey(hkey, sCLSID_KexShlExt, &hkey2) != ERROR_SUCCESS) + if (RegCreateKey(hkey, "KernelEx", &hkey2) != ERROR_SUCCESS) result = false; if (result) { - RegSetValueEx(hkey2, NULL, 0, REG_SZ, (LPBYTE)"", sizeof("")); - RegCloseKey(hkey2); - } - - RegCloseKey(hkey); - } - - if (RegCreateKey(HKEY_CLASSES_ROOT, "lnkfile\\shellex\\PropertySheetHandlers", - &hkey) != ERROR_SUCCESS) - result = false; - - if (result) - { - if (RegCreateKey(hkey, sCLSID_KexShlExt, &hkey2) != ERROR_SUCCESS) - result = false; - - if (result) - { - RegSetValueEx(hkey2, NULL, 0, REG_SZ, (LPBYTE)"", sizeof("")); + RegSetValueEx(hkey2, NULL, 0, REG_SZ, (LPBYTE)sCLSID_KexShlExt, sizeof(sCLSID_KexShlExt)); RegCloseKey(hkey2); } @@ -145,26 +127,16 @@ STDAPI DllUnregisterServer() RegCloseKey(keyCLSID); } - if (RegOpenKey(HKEY_CLASSES_ROOT, "exefile\\shellex\\PropertySheetHandlers", + if (RegOpenKey(HKEY_CLASSES_ROOT, "*\\shellex\\PropertySheetHandlers", &hkey) != ERROR_SUCCESS) result = false; if (result) { - RegDeleteKey(hkey, sCLSID_KexShlExt); + RegDeleteKey(hkey, "KernelEx"); RegCloseKey(hkey); } - if (RegOpenKey(HKEY_CLASSES_ROOT, "lnkfile\\shellex\\PropertySheetHandlers", - &hkey) != ERROR_SUCCESS) - result = false; - - if (result) - { - RegDeleteKey(hkey, sCLSID_KexShlExt); - RegCloseKey(hkey); - } - return S_OK; } diff --git a/sheet/sheet.cpp b/sheet/sheet.cpp index 43f6fd6..71478d1 100755 --- a/sheet/sheet.cpp +++ b/sheet/sheet.cpp @@ -20,15 +20,17 @@ */ #include -#include #include #include "sheet.h" #include "server.h" #include "resource.h" #include "KexLinkage.h" +extern "C" int snprintf(char*, size_t, const char*, ...); + struct CTips { + char* _TIP_DEFAULT; char* _TIP_DISABLE; char* _TIP_COMPAT; char* _TIP_SYSTEM; @@ -38,8 +40,8 @@ struct CTips CTips() { - _TIP_DISABLE = _TIP_COMPAT = _TIP_SYSTEM = _TIP_NOINHERIT - = _TIP_OVERRIDE = _TIP_LOG = NULL; + _TIP_DEFAULT = _TIP_DISABLE = _TIP_COMPAT = _TIP_SYSTEM + = _TIP_NOINHERIT = _TIP_OVERRIDE = _TIP_LOG = NULL; loaded = false; } @@ -47,6 +49,7 @@ struct CTips { if (loaded) { + free(_TIP_DEFAULT); free(_TIP_DISABLE); free(_TIP_COMPAT); free(_TIP_SYSTEM); @@ -61,6 +64,7 @@ struct CTips if (loaded) return; loaded = true; + _TIP_DEFAULT = load_string(TIP_DEFAULT); _TIP_DISABLE = load_string(TIP_DISABLE); _TIP_COMPAT = load_string(TIP_COMPAT); _TIP_SYSTEM = load_string(TIP_SYSTEM); @@ -136,23 +140,24 @@ bool KexShlExt::IsPEModule(const char* path) { IMAGE_DOS_HEADER MZh; IMAGE_NT_HEADERS PEh; - FILE* f; + HANDLE f; bool result = false; + DWORD bytes_read; - f = fopen(path, "rb"); - if (!f) + f = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (f == INVALID_HANDLE_VALUE) return false; - if (fread(&MZh, sizeof(MZh), 1, f) != 1) + if (!ReadFile(f, &MZh, sizeof(MZh), &bytes_read, NULL) || bytes_read != sizeof(MZh)) goto __end; - + if (MZh.e_magic != IMAGE_DOS_SIGNATURE) goto __end; - if (fseek(f, MZh.e_lfanew, SEEK_SET)) + if (SetFilePointer(f, MZh.e_lfanew, NULL, FILE_BEGIN) == 0xffffffff) goto __end; - if (fread(&PEh, sizeof(PEh), 1, f) != 1) + if (!ReadFile(f, &PEh, sizeof(PEh), &bytes_read, NULL) || bytes_read != sizeof(PEh)) goto __end; if ((PEh.Signature != IMAGE_NT_SIGNATURE) @@ -163,8 +168,8 @@ bool KexShlExt::IsPEModule(const char* path) result = true; __end: - fclose(f); - + CloseHandle(f); + return result; } @@ -364,27 +369,28 @@ BOOL CALLBACK KexShlExt::DlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPa { switch (LOWORD(wParam)) { + case IDC_DEFAULT: + if (!IsDlgButtonChecked(hwnd, IDC_DEFAULT)) break; + EnableWindow(GetDlgItem(hwnd, IDC_SYSTEM), FALSE); + EnableWindow(GetDlgItem(hwnd, IDC_LOG), FALSE); + EnableWindow(GetDlgItem(hwnd, IDC_NOINHERIT), FALSE); + EnableWindow(GetDlgItem(hwnd, IDC_OVERRIDE), FALSE); + PropSheet_Changed(GetParent(hwnd), hwnd); + break; case IDC_DISABLE: - if (IsDlgButtonChecked(hwnd, IDC_DISABLE)) - { - EnableWindow(GetDlgItem(hwnd, IDC_COMPAT), FALSE); - EnableWindow(GetDlgItem(hwnd, IDC_SYSTEM), FALSE); - EnableWindow(GetDlgItem(hwnd, IDC_LOG), FALSE); - EnableWindow(GetDlgItem(hwnd, IDC_NOINHERIT), FALSE); - } - else - { - EnableWindow(GetDlgItem(hwnd, IDC_COMPAT), TRUE); - EnableWindow(GetDlgItem(hwnd, IDC_SYSTEM), - IsDlgButtonChecked(hwnd, IDC_COMPAT)); - EnableWindow(GetDlgItem(hwnd, IDC_LOG), TRUE); - EnableWindow(GetDlgItem(hwnd, IDC_NOINHERIT), TRUE); - } + if (!IsDlgButtonChecked(hwnd, IDC_DISABLE)) break; + EnableWindow(GetDlgItem(hwnd, IDC_SYSTEM), FALSE); + EnableWindow(GetDlgItem(hwnd, IDC_LOG), FALSE); + EnableWindow(GetDlgItem(hwnd, IDC_NOINHERIT), TRUE); + EnableWindow(GetDlgItem(hwnd, IDC_OVERRIDE), TRUE); PropSheet_Changed(GetParent(hwnd), hwnd); break; case IDC_COMPAT: - EnableWindow(GetDlgItem(hwnd, IDC_SYSTEM), - IsDlgButtonChecked(hwnd, IDC_COMPAT)); + if (!IsDlgButtonChecked(hwnd, IDC_COMPAT)) break; + EnableWindow(GetDlgItem(hwnd, IDC_SYSTEM), TRUE); + EnableWindow(GetDlgItem(hwnd, IDC_LOG), TRUE); + EnableWindow(GetDlgItem(hwnd, IDC_NOINHERIT), TRUE); + EnableWindow(GetDlgItem(hwnd, IDC_OVERRIDE), TRUE); PropSheet_Changed(GetParent(hwnd), hwnd); break; case IDC_SYSTEM: @@ -428,15 +434,19 @@ void KexShlExt::OnInitDialog(HWND hwnd, ModuleSetting* ms) SendMessage(GetDlgItem(hwnd, IDC_SYSTEM), CB_SETCURSEL, i, 0); break; } - if (!(ms->flags & KRF_VALID_FLAG) && (KexLinkage::instance.disable_extensions || !default_index_valid)) - ms->flags |= KRF_KEX_DISABLE; - if (ms->flags & KRF_KEX_DISABLE) + if (!(ms->flags & KRF_VALID_FLAG)) { - CheckDlgButton(hwnd, IDC_DISABLE, BST_CHECKED); - EnableWindow(GetDlgItem(hwnd, IDC_COMPAT), FALSE); + CheckDlgButton(hwnd, IDC_DEFAULT, BST_CHECKED); EnableWindow(GetDlgItem(hwnd, IDC_SYSTEM), FALSE); EnableWindow(GetDlgItem(hwnd, IDC_LOG), FALSE); EnableWindow(GetDlgItem(hwnd, IDC_NOINHERIT), FALSE); + EnableWindow(GetDlgItem(hwnd, IDC_OVERRIDE), FALSE); + } + if (ms->flags & KRF_KEX_DISABLE) + { + CheckDlgButton(hwnd, IDC_DISABLE, BST_CHECKED); + EnableWindow(GetDlgItem(hwnd, IDC_SYSTEM), FALSE); + EnableWindow(GetDlgItem(hwnd, IDC_LOG), FALSE); } if (ms->flags & KRF_LOG_APIS) CheckDlgButton(hwnd, IDC_LOG, BST_CHECKED); @@ -445,13 +455,31 @@ void KexShlExt::OnInitDialog(HWND hwnd, ModuleSetting* ms) if (ms->flags & KRF_OVERRIDE_PROC_MOD) CheckDlgButton(hwnd, IDC_OVERRIDE, BST_CHECKED); - //set KernelEx version - unsigned long ver = KexLinkage::instance.m_kexGetKEXVersion(); + { + //show what are the default compatibility settings + char bufi[512]; + char bufo[512]; + char bufs[512]; + + SendMessage(GetDlgItem(hwnd, IDC_DEFAULT), WM_GETTEXT, + (WPARAM) sizeof(bufi), (LPARAM) bufi); + LoadString(g_hModule, KexLinkage::instance.disable_extensions ? + IDS_DISABLED : IDS_ENABLED, bufs, sizeof(bufs)); + snprintf(bufo, sizeof(bufo), bufi, bufs); + SendMessage(GetDlgItem(hwnd, IDC_DEFAULT), WM_SETTEXT, + (WPARAM) 0, (LPARAM) bufo); + } + + int debug = KexLinkage::instance.m_kexIsDebugCore(); - char ver_s[32]; - sprintf(ver_s, "KernelEx Core v%d.%d.%d %s", - ver>>24, (ver>>16) & 0xff, ver & 0xffff, debug ? "DEBUG" : ""); - SendMessage(GetDlgItem(hwnd, IDC_KEXVER), WM_SETTEXT, 0, (LPARAM) ver_s); + { + //set KernelEx version + unsigned long ver = KexLinkage::instance.m_kexGetKEXVersion(); + char ver_s[32]; + snprintf(ver_s, sizeof(ver_s), "KernelEx Core v%d.%d.%d %s", + ver>>24, (ver>>16) & 0xff, ver & 0xffff, debug ? "DEBUG" : ""); + SendMessage(GetDlgItem(hwnd, IDC_KEXVER), WM_SETTEXT, 0, (LPARAM) ver_s); + } ShowWindow(GetDlgItem(hwnd, IDC_OVERRIDE), debug ? SW_SHOW : SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_LOG), debug ? SW_SHOW : SW_HIDE); @@ -467,6 +495,7 @@ void KexShlExt::OnInitDialog(HWND hwnd, ModuleSetting* ms) tips.load_tips(); HWND hwndTip = CreateTooltipWindow(hwnd); + CreateTooltip(hwndTip, hwnd, IDC_DEFAULT, tips._TIP_DEFAULT); CreateTooltip(hwndTip, hwnd, IDC_DISABLE, tips._TIP_DISABLE); CreateTooltip(hwndTip, hwnd, IDC_COMPAT, tips._TIP_COMPAT); CreateTooltip(hwndTip, hwnd, IDC_SYSTEM, tips._TIP_SYSTEM); @@ -481,6 +510,8 @@ void KexShlExt::OnApply(HWND hwnd) ModuleSetting* ms = (ModuleSetting*) GetWindowLong(hwnd, GWL_USERDATA); DWORD flags = 0; const char* conf = ""; + if (!IsDlgButtonChecked(hwnd, IDC_DEFAULT)) + flags |= KRF_VALID_FLAG; if (IsDlgButtonChecked(hwnd, IDC_DISABLE)) flags |= KRF_KEX_DISABLE; if (IsDlgButtonChecked(hwnd, IDC_COMPAT)) @@ -494,7 +525,12 @@ void KexShlExt::OnApply(HWND hwnd) flags |= KRF_OVERRIDE_PROC_MOD; if (flags != ms->flags || strcmp(conf, ms->conf) != 0) - KexLinkage::instance.m_kexSetModuleSettings(ms->file, conf, flags); + { + if (flags & KRF_VALID_FLAG) + KexLinkage::instance.m_kexSetModuleSettings(ms->file, conf, flags); + else + KexLinkage::instance.m_kexResetModuleSettings(ms->file); + } } diff --git a/sheet/sheet.dsp b/sheet/sheet.dsp index fdaf4ea..cd2a757 100755 --- a/sheet/sheet.dsp +++ b/sheet/sheet.dsp @@ -43,7 +43,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SHEET_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /O2 /I "../common" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SHEET_EXPORTS" /YX /FD /GF /c +# ADD CPP /nologo /W3 /O2 /I "../common" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SHEET_EXPORTS" /YX /FD /GF /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x415 /d "NDEBUG" @@ -53,7 +53,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib comctl32.lib advapi32.lib shell32.lib shlwapi.lib ole32.lib /nologo /dll /machine:I386 /OPT:NOWIN98 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib comctl32.lib advapi32.lib shell32.lib shlwapi.lib ole32.lib uuid.lib ..\kexcrt\kexcrt.lib libc.lib /nologo /dll /map /machine:I386 /nodefaultlib /OPT:NOWIN98 # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "sheet - Win32 Debug" @@ -70,7 +70,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SHEET_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MD /W3 /Gm /ZI /Od /I "../common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SHEET_EXPORTS" /YX /FD /GZ /GF /c +# ADD CPP /nologo /ML /W3 /Gm /ZI /Od /I "../common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SHEET_EXPORTS" /YX /FD /GZ /GF /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x415 /d "_DEBUG" @@ -80,7 +80,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib comctl32.lib advapi32.lib shell32.lib shlwapi.lib ole32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /OPT:NOWIN98 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib comctl32.lib advapi32.lib shell32.lib shlwapi.lib ole32.lib uuid.lib ..\kexcrt\kexcrt.lib libc.lib /nologo /dll /map /debug /machine:I386 /nodefaultlib /pdbtype:sept /OPT:NOWIN98 # SUBTRACT LINK32 /pdb:none !ENDIF diff --git a/sheet/sheet.rc b/sheet/sheet.rc index 67ed434..3a35c2e 100755 --- a/sheet/sheet.rc +++ b/sheet/sheet.rc @@ -54,8 +54,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,4 - PRODUCTVERSION 1,0,0,4 + FILEVERSION 1,0,0,5 + PRODUCTVERSION 1,0,0,5 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -80,7 +80,7 @@ BEGIN VALUE "OriginalFilename", "sheet.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "KernelEx\0" - VALUE "ProductVersion", "1, 0, 0, 4\0" + VALUE "ProductVersion", "1, 0, 0, 5\0" VALUE "SpecialBuild", "\0" END END @@ -110,31 +110,34 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // Dialog // -IDD_PROPPAGE DIALOG DISCARDABLE 0, 0, 190, 177 +IDD_PROPPAGE DIALOG DISCARDABLE 0, 0, 232, 191 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Compatibility" FONT 8, "MS Sans Serif" BEGIN - GROUPBOX "Compatibility options",IDC_GCOMPAT,7,30,176,64 + GROUPBOX "Basic options",IDC_GCOMPAT,7,30,218,78 + CONTROL "Use default compatibility options [%s]",IDC_DEFAULT, + "Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,15, + 43,208,10 CONTROL "Disable KernelEx extensions",IDC_DISABLE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,15,43,165,10 + BS_AUTORADIOBUTTON | WS_TABSTOP,15,57,208,10 CONTROL "Use specific compatibility mode:",IDC_COMPAT,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,15,57,164,10 - COMBOBOX IDC_SYSTEM,15,70,157,60,CBS_DROPDOWNLIST | WS_DISABLED | + BS_AUTORADIOBUTTON | WS_TABSTOP,15,71,208,10 + COMBOBOX IDC_SYSTEM,15,84,157,60,CBS_DROPDOWNLIST | WS_DISABLED | WS_VSCROLL | WS_TABSTOP - LTEXT "kexver here",IDC_KEXVER,7,161,71,9,WS_DISABLED - LTEXT "Try changing compatibility options if you have problems\nwith running this program.", - IDC_TCOMPAT,7,7,175,22 - CONTROL "",IDC_HORIZ1,"Static",SS_BLACKFRAME | SS_SUNKEN,7,160, - 176,1 - GROUPBOX "Advanced options",IDC_GADVAN,7,100,176,57 + LTEXT "kexver here",IDC_KEXVER,7,175,71,9,WS_DISABLED + LTEXT "Try changing compatibility options if you have problems\nrunning the program.", + IDC_TCOMPAT,7,7,218,22 + CONTROL "",IDC_HORIZ1,"Static",SS_BLACKFRAME | SS_SUNKEN,7,174, + 218,1 + GROUPBOX "Advanced options",IDC_GADVAN,7,114,218,57 CONTROL "Don't use these settings in child processes", IDC_NOINHERIT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15, - 113,164,10 + 127,208,10 CONTROL "Override settings of invidual modules",IDC_OVERRIDE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,127,164,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,141,208,10 CONTROL "Enable api logging",IDC_LOG,"Button",BS_AUTOCHECKBOX | - NOT WS_VISIBLE | WS_TABSTOP,15,141,164,10 + NOT WS_VISIBLE | WS_TABSTOP,15,155,208,10 END @@ -149,9 +152,9 @@ BEGIN IDD_PROPPAGE, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 183 + RIGHTMARGIN, 225 TOPMARGIN, 7 - BOTTOMMARGIN, 170 + BOTTOMMARGIN, 184 END END #endif // APSTUDIO_INVOKED @@ -164,12 +167,15 @@ END STRINGTABLE DISCARDABLE BEGIN - TIP_DISABLE "Use this option to run this program as if KernelEx wasn't installed." - TIP_COMPAT "Changes operating system identification and emulates different operating system behavior. Choose operating system which is required to run this program." - TIP_SYSTEM "Select operating system to emulate from the list." + TIP_DEFAULT "Use default settings for this module as specified during installation (brackets). This option allows overriding by main executable or parent process executable settings." + TIP_DISABLE "Select this option to execute module as if KernelEx wasn't installed." + TIP_COMPAT "Choose desired compatibility mode as required by the application. This option allows changing operating system identification and emulation of different operating system behavior." + TIP_SYSTEM "Select desired compatibility mode from the list." TIP_NOINHERIT "Disables inheritance of these settings. Normally programs started by this application use settings from this tab as their default settings. Use this option to disable such behaviour." TIP_OVERRIDE "Disables usage of per module settings. Use this option to use same settings for all modules in the application." TIP_LOG "Use this option to enable api spying debugging feature." + IDS_ENABLED "KernelEx is enabled" + IDS_DISABLED "KernelEx is disabled" END #endif // English (U.S.) resources diff --git a/util/prep/prep.cpp b/util/prep/prep.cpp index 49f21f9..4b731c5 100755 --- a/util/prep/prep.cpp +++ b/util/prep/prep.cpp @@ -40,6 +40,7 @@ using namespace std; vector all_exports_named; vector all_exports_ordinal; stringstream all_declarations; +time_t timestamp; ////////////////////////////////////////////////////////////////////////// @@ -489,21 +490,12 @@ bool is_uptodate_dir(const string& path) string file; FileFinder ff; struct _stat st; - time_t mintime; - ff.search_for(path + "_*_apilist.c"); - file = ff.get_next_file(); - if (file.empty()) - throw Exception("Couldn't find output def file"); - - _stat((path + file).c_str(), &st); - mintime = st.st_mtime; - ff.search_for(path + "*.c"); while (!(file = ff.get_next_file()).empty()) { _stat((path + file).c_str(), &st); - if (st.st_mtime > mintime) + if (st.st_mtime > timestamp) return false; } @@ -516,6 +508,14 @@ void work() if (!dirlist) throw Exception("Couldn't open dirlist"); + { + struct _stat st; + if (_stat(".timestamp", &st) < 0) + timestamp = 0; + else + timestamp = st.st_mtime; + } + while (!dirlist.eof()) { fstream out_file; @@ -680,6 +680,8 @@ void work() out_file.close(); replace(file, file + ".tmp"); + + ofstream timestamp(".timestamp", ios::out | ios::trunc); } }