From d6aad6c6c521a0693ae917cea70803b36ebfaf0f Mon Sep 17 00:00:00 2001 From: UzixLS Date: Sat, 3 Nov 2018 16:20:27 +0300 Subject: [PATCH] import KernelEx-4.0-Final2 --- CHANGELOG.txt | 15 +++ COMPATIBILITY.txt | 18 ++- KernelEx.nsi | 32 +++--- apilibs/kexbasen/dirlist | 1 + apilibs/kexbasen/kexbasen.dsp | 20 +++- apilibs/kexbasen/main.c | 6 +- apilibs/kexbasen/shlwapi/_shlwapi_apilist.c | 46 ++++++++ apilibs/kexbasen/shlwapi/_shlwapi_apilist.h | 34 ++++++ apilibs/kexbasen/shlwapi/string.c | 104 ++++++++++++++++++ apilibs/kexbases/Kernel32/OpenThread.c | 35 +----- apilibs/kexbases/Kernel32/_kernel32_apilist.c | 2 +- apilibs/kexbases/Kernel32/unikernel32.c | 18 +-- apilibs/kexbases/shell32/_shell32_apilist.c | 1 + apilibs/kexbases/shell32/_shell32_apilist.h | 1 + apilibs/kexbases/shell32/_shell32_stubs.c | 1 + apilibs/settings.reg | 1 + common/kexcoresdk.h | 16 ++- common/version.h | 8 +- core/DebugWindow.cpp | 86 +++++++++++---- core/DebugWindow.h | 1 + core/apilib.cpp | 2 +- core/apilog.cpp | 73 +++++++++--- core/apilog.h | 46 ++++---- core/debug.h | 2 +- core/internals.cpp | 63 +++++++---- core/internals.h | 12 +- core/kexcoresdk.cpp | 8 +- core/main.cpp | 2 +- core/resolver.cpp | 89 ++++++++++++--- core/resolver.h | 1 + core/structs.h | 6 +- kexcrt/abort.c | 6 - kexcrt/exit.c | 2 - kexcrt/kexcrt.dsp | 8 -- kexcrt/makefile | 2 +- kexcrt/makefile.msv | 2 +- kexcrt/write.c | 36 ------ setup/loadstub.h | 5 +- setup/resource.h | 2 +- setup/setup.cpp | 58 ++++++++-- setup/setup.dsp | 4 + setup/setup.h | 3 + setup/setup.rc | 2 +- 43 files changed, 624 insertions(+), 256 deletions(-) create mode 100644 apilibs/kexbasen/shlwapi/_shlwapi_apilist.c create mode 100644 apilibs/kexbasen/shlwapi/_shlwapi_apilist.h create mode 100644 apilibs/kexbasen/shlwapi/string.c delete mode 100644 kexcrt/abort.c delete mode 100644 kexcrt/write.c diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 5213d14..58898b3 100755 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,18 @@ +KernelEx v4.0 Final 2 by Xeno86 +2009-08-20 + +fixed handling of forwarded exports broken in revision 32 +fixed very rare crash which could occur at boot when module table pointer becomes invalid +added algorithm similar to KnownDLLs for auxiliary libraries to be disabled when extensions are disabled +perform stub upgrade on version mismatch, not only if it is lower than expected +added SHLWAPI.StrCmpLogicalW +added SHELL32.SHOpenFolderAndSelectItems stub +fixed KERNEL32.lstrcpynW +added kexAreExtensionsEnabled to SDK +api logging should now work correctly + +--------------------------------------- + KernelEx v4.0 Final by Xeno86 2009-07-23 diff --git a/COMPATIBILITY.txt b/COMPATIBILITY.txt index 2e2d3eb..2866703 100755 --- a/COMPATIBILITY.txt +++ b/COMPATIBILITY.txt @@ -1,3 +1,18 @@ +KernelEx v4.0 Final 2 by Xeno86 +2009-08-20 + +Major changes: +-------------- +* system won't try to load auxiliary libraries (PSAPI, MSIMG32, PDH, UXTHEME, WTSAPI32) when extensions are disabled + +Fixed regressions: +------------------ +* fixed ZoneAlarm not working properly +* Firefox 3 couldn't be uninstalled if KernelEx was installed with extensions disabled +* Foobar2000 v0.9.6.x installer was crashing + +################################################# + KernelEx v4.0 Final by Xeno86 2009-07-23 @@ -14,9 +29,10 @@ Major changes: * improved RP9 compatibility * loading MSLU altered floating point unit flags and caused certain programs to crash * MSLU (Unicows.dll) is no longer loaded right on startup and should be seen referenced less often in system +* Dependency Walker is no longer slow when profiling * startup speed improvements * stability improvements -* tons of minor changes +* tons of small changes ################################################# diff --git a/KernelEx.nsi b/KernelEx.nsi index fbf573c..d57528e 100755 --- a/KernelEx.nsi +++ b/KernelEx.nsi @@ -1,4 +1,4 @@ - !define VERSION '4.0 Final' + !define VERSION '4.0 Final 2' ;-------------------------------- ;Includes @@ -256,36 +256,36 @@ Section "Install" File /oname=$0 auxiliary\msimg32.dll Delete "$INSTDIR\msimg32.dll" Rename /REBOOTOK $0 "$INSTDIR\msimg32.dll" - WriteRegStr HKLM "System\CurrentControlSet\Control\SessionManager\KnownDLLs" \ - "MSIMG32" "..\KernelEx\msimg32.dll" + WriteRegStr HKLM "Software\KernelEx\KnownDLLs" \ + "MSIMG32" "MSIMG32.DLL" GetTempFileName $0 "$INSTDIR" File /oname=$0 auxiliary\pdh.dll Delete "$INSTDIR\pdh.dll" Rename /REBOOTOK $0 "$INSTDIR\pdh.dll" - WriteRegStr HKLM "System\CurrentControlSet\Control\SessionManager\KnownDLLs" \ - "PDH" "..\KernelEx\pdh.dll" + WriteRegStr HKLM "Software\KernelEx\KnownDLLs" \ + "PDH" "PDH.DLL" GetTempFileName $0 "$INSTDIR" File /oname=$0 auxiliary\psapi.dll Delete "$INSTDIR\psapi.dll" Rename /REBOOTOK $0 "$INSTDIR\psapi.dll" - WriteRegStr HKLM "System\CurrentControlSet\Control\SessionManager\KnownDLLs" \ - "PSAPI" "..\KernelEx\psapi.dll" + WriteRegStr HKLM "Software\KernelEx\KnownDLLs" \ + "PSAPI" "PSAPI.DLL" GetTempFileName $0 "$INSTDIR" File /oname=$0 auxiliary\uxtheme.dll Delete "$INSTDIR\uxtheme.dll" Rename /REBOOTOK $0 "$INSTDIR\uxtheme.dll" - WriteRegStr HKLM "System\CurrentControlSet\Control\SessionManager\KnownDLLs" \ - "UXTHEME" "..\KernelEx\uxtheme.dll" + WriteRegStr HKLM "Software\KernelEx\KnownDLLs" \ + "UXTHEME" "UXTHEME.DLL" GetTempFileName $0 "$INSTDIR" File /oname=$0 auxiliary\wtsapi32.dll Delete "$INSTDIR\wtsapi32.dll" Rename /REBOOTOK $0 "$INSTDIR\wtsapi32.dll" - WriteRegStr HKLM "System\CurrentControlSet\Control\SessionManager\KnownDLLs" \ - "WTSAPI32" "..\KernelEx\wtsapi32.dll" + WriteRegStr HKLM "Software\KernelEx\KnownDLLs" \ + "WTSAPI32" "WTSAPI32.DLL" SetOverwrite lastused @@ -342,15 +342,15 @@ Section "Uninstall" Delete "$INSTDIR\license.txt" Delete /REBOOTOK "$INSTDIR\msimg32.dll" - DeleteRegValue HKLM "System\CurrentControlSet\Control\SessionManager\KnownDLLs" "MSIMG32" + DeleteRegValue HKLM "Software\KernelEx\KnownDLLs" "MSIMG32" Delete /REBOOTOK "$INSTDIR\pdh.dll" - DeleteRegValue HKLM "System\CurrentControlSet\Control\SessionManager\KnownDLLs" "PDH" + DeleteRegValue HKLM "Software\KernelEx\KnownDLLs" "PDH" Delete /REBOOTOK "$INSTDIR\psapi.dll" - DeleteRegValue HKLM "System\CurrentControlSet\Control\SessionManager\KnownDLLs" "PSAPI" + DeleteRegValue HKLM "Software\KernelEx\KnownDLLs" "PSAPI" Delete /REBOOTOK "$INSTDIR\uxtheme.dll" - DeleteRegValue HKLM "System\CurrentControlSet\Control\SessionManager\KnownDLLs" "UXTHEME" + DeleteRegValue HKLM "Software\KernelEx\KnownDLLs" "UXTHEME" Delete /REBOOTOK "$INSTDIR\wtsapi32.dll" - DeleteRegValue HKLM "System\CurrentControlSet\Control\SessionManager\KnownDLLs" "WTSAPI32" + DeleteRegValue HKLM "Software\KernelEx\KnownDLLs" "WTSAPI32" Delete "$INSTDIR\verify.exe" DeleteRegValue HKLM "Software\Microsoft\Windows\CurrentVersion\Run" "KexVerify" diff --git a/apilibs/kexbasen/dirlist b/apilibs/kexbasen/dirlist index 448b513..151d792 100644 --- a/apilibs/kexbasen/dirlist +++ b/apilibs/kexbasen/dirlist @@ -6,3 +6,4 @@ comdlg32 shell32 rpcrt4 winspool +shlwapi diff --git a/apilibs/kexbasen/kexbasen.dsp b/apilibs/kexbasen/kexbasen.dsp index 9919962..f535a92 100644 --- a/apilibs/kexbasen/kexbasen.dsp +++ b/apilibs/kexbasen/kexbasen.dsp @@ -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 winspool.lib comdlg32.lib advapi32.lib shlwapi.lib shell32.lib rpcrt4.lib usp10.lib ../../common/KernelEx.lib ../../kexcrt/kexcrt.lib libc.lib delayimp.lib /nologo /dll /map /machine:I386 /nodefaultlib /OPT:NOWIN98 /DELAYLOAD:shell32.dll /DELAYLOAD:rpcrt4.dll /DELAYLOAD:usp10.dll /DELAYLOAD:comdlg32.dll /DELAYLOAD:winspool.drv +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shlwapi.lib shell32.lib rpcrt4.lib usp10.lib ../../common/KernelEx.lib ../../kexcrt/kexcrt.lib libc.lib delayimp.lib /nologo /dll /map /machine:I386 /nodefaultlib /OPT:NOWIN98 /DELAYLOAD:shell32.dll /DELAYLOAD:rpcrt4.dll /DELAYLOAD:usp10.dll /DELAYLOAD:comdlg32.dll /DELAYLOAD:winspool.drv /DELAYLOAD:shlwapi.dll # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "KernelEx Base NonShared - Win32 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 winspool.lib comdlg32.lib advapi32.lib shlwapi.lib shell32.lib rpcrt4.lib usp10.lib ../../common/KernelEx.lib ../../kexcrt/kexcrt.lib libc.lib delayimp.lib /nologo /dll /map /debug /machine:I386 /nodefaultlib /pdbtype:sept /OPT:NOWIN98 /DELAYLOAD:shell32.dll /DELAYLOAD:rpcrt4.dll /DELAYLOAD:usp10.dll /DELAYLOAD:comdlg32.dll /DELAYLOAD:winspool.drv +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shlwapi.lib shell32.lib rpcrt4.lib usp10.lib ../../common/KernelEx.lib ../../kexcrt/kexcrt.lib libc.lib delayimp.lib /nologo /dll /map /debug /machine:I386 /nodefaultlib /pdbtype:sept /OPT:NOWIN98 /DELAYLOAD:shell32.dll /DELAYLOAD:rpcrt4.dll /DELAYLOAD:usp10.dll /DELAYLOAD:comdlg32.dll /DELAYLOAD:winspool.drv /DELAYLOAD:shlwapi.dll # SUBTRACT LINK32 /pdb:none !ENDIF @@ -244,6 +244,22 @@ SOURCE=.\winspool\_winspool_apilist.h SOURCE=.\winspool\DefaultPrinter.c # End Source File # End Group +# Begin Group "shlwapi" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\shlwapi\_shlwapi_apilist.c +# End Source File +# Begin Source File + +SOURCE=.\shlwapi\_shlwapi_apilist.h +# End Source File +# Begin Source File + +SOURCE=.\shlwapi\string.c +# End Source File +# End Group # Begin Source File SOURCE=.\common.c diff --git a/apilibs/kexbasen/main.c b/apilibs/kexbasen/main.c index 2b8c5ed..b3cc881 100644 --- a/apilibs/kexbasen/main.c +++ b/apilibs/kexbasen/main.c @@ -30,9 +30,10 @@ #include "shell32/_shell32_apilist.h" #include "rpcrt4/_rpcrt4_apilist.h" #include "winspool/_winspool_apilist.h" +#include "shlwapi/_shlwapi_apilist.h" //#include "/__apilist.h" -static apilib_api_table api_table[9]; +static apilib_api_table api_table[10]; static void fill_apitable() { @@ -44,6 +45,7 @@ static void fill_apitable() api_table[5] = apitable_shell32; api_table[6] = apitable_rpcrt4; api_table[7] = apitable_winspool; + api_table[8] = apitable_shlwapi; //last entry is null terminator } @@ -57,7 +59,7 @@ const apilib_api_table* get_api_table() BOOL init() { - return common_init() && init_kernel32() && init_gdi32() && init_user32() && init_advapi32() && init_comdlg32() && init_shell32() && init_rpcrt4() && init_winspool(); + return common_init() && init_kernel32() && init_gdi32() && init_user32() && init_advapi32() && init_comdlg32() && init_shell32() && init_rpcrt4() && init_winspool() && init_shlwapi(); } BOOL APIENTRY DllMain(HINSTANCE instance, DWORD reason, BOOL load_static) diff --git a/apilibs/kexbasen/shlwapi/_shlwapi_apilist.c b/apilibs/kexbasen/shlwapi/_shlwapi_apilist.c new file mode 100644 index 0000000..27d7fe6 --- /dev/null +++ b/apilibs/kexbasen/shlwapi/_shlwapi_apilist.c @@ -0,0 +1,46 @@ +/* + * KernelEx + * Copyright (C) 2009, 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. + * + */ + +#include "common.h" +#include "kexcoresdk.h" +#include "_shlwapi_apilist.h" + +BOOL init_shlwapi() +{ + return TRUE; +} + +static const apilib_named_api shlwapi_named_apis[] = +{ +/*** AUTOGENERATED APILIST NAMED EXPORTS BEGIN ***/ + DECL_API("StrCmpLogicalW", StrCmpLogicalW_new), +/*** AUTOGENERATED APILIST NAMED EXPORTS END ***/ +}; + +#if 0 +static const apilib_unnamed_api shlwapi_ordinal_apis[] = +{ +/*** AUTOGENERATED APILIST ORDINAL EXPORTS BEGIN ***/ +/*** AUTOGENERATED APILIST ORDINAL EXPORTS END ***/ +}; +#endif + +const apilib_api_table apitable_shlwapi = DECL_TAB("SHLWAPI.DLL", shlwapi_named_apis, 0 /*shlwapi_ordinal_apis*/); diff --git a/apilibs/kexbasen/shlwapi/_shlwapi_apilist.h b/apilibs/kexbasen/shlwapi/_shlwapi_apilist.h new file mode 100644 index 0000000..68bb5f5 --- /dev/null +++ b/apilibs/kexbasen/shlwapi/_shlwapi_apilist.h @@ -0,0 +1,34 @@ +/* + * KernelEx + * Copyright (C) 2009, 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. + * + */ + +#ifndef _SHLWAPI_APILIST_H +#define _SHLWAPI_APILIST_H + +#include "kexcoresdk.h" + +BOOL init_shlwapi(); +extern const apilib_api_table apitable_shlwapi; + +/*** AUTOGENERATED APILIST DECLARATIONS BEGIN ***/ +INT WINAPI StrCmpLogicalW_new(LPCWSTR lpszStr, LPCWSTR lpszComp); +/*** AUTOGENERATED APILIST DECLARATIONS END ***/ + +#endif diff --git a/apilibs/kexbasen/shlwapi/string.c b/apilibs/kexbasen/shlwapi/string.c new file mode 100644 index 0000000..c34a6ef --- /dev/null +++ b/apilibs/kexbasen/shlwapi/string.c @@ -0,0 +1,104 @@ +/* + * Shlwapi string functions + * + * Copyright 1998 Juergen Schmied + * Copyright 2002 Jon Griffiths + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#pragma warning(disable:4002) +#define TRACE() + +EXTERN_C DECLSPEC_IMPORT BOOL WINAPI StrToIntExW(LPCWSTR lpszStr, DWORD dwFlags, LPINT lpiRet); +EXTERN_C DECLSPEC_IMPORT BOOL WINAPI ChrCmpIW(WCHAR ch1, WCHAR ch2); + +static int isdigitW(WCHAR wc) +{ + if (wc >= '0' && wc <= '9') + return 1; + return 0; +} + +/************************************************************************* + * StrCmpLogicalW [SHLWAPI.@] + * + * Compare two strings, ignoring case and comparing digits as numbers. + * + * PARAMS + * lpszStr [I] First string to compare + * lpszComp [I] Second string to compare + * iLen [I] Length to compare + * + * RETURNS + * TRUE If the strings are equal. + * FALSE Otherwise. + */ +/* MAKE_EXPORT StrCmpLogicalW_new=StrCmpLogicalW */ +INT WINAPI StrCmpLogicalW_new(LPCWSTR lpszStr, LPCWSTR lpszComp) +{ + INT iDiff; + + TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszComp)); + + if (lpszStr && lpszComp) + { + while (*lpszStr) + { + if (!*lpszComp) + return 1; + else if (isdigitW(*lpszStr)) + { + int iStr, iComp; + + if (!isdigitW(*lpszComp)) + return -1; + + /* Compare the numbers */ + StrToIntExW(lpszStr, 0, &iStr); + StrToIntExW(lpszComp, 0, &iComp); + + if (iStr < iComp) + return -1; + else if (iStr > iComp) + return 1; + + /* Skip */ + while (isdigitW(*lpszStr)) + lpszStr++; + while (isdigitW(*lpszComp)) + lpszComp++; + } + else if (isdigitW(*lpszComp)) + return 1; + else + { + iDiff = ChrCmpIW(*lpszStr,*lpszComp); + if (iDiff > 0) + return 1; + else if (iDiff < 0) + return -1; + + lpszStr++; + lpszComp++; + } + } + if (*lpszComp) + return -1; + } + return 0; +} + diff --git a/apilibs/kexbases/Kernel32/OpenThread.c b/apilibs/kexbases/Kernel32/OpenThread.c index 027435a..af00b83 100644 --- a/apilibs/kexbases/Kernel32/OpenThread.c +++ b/apilibs/kexbases/Kernel32/OpenThread.c @@ -1,6 +1,6 @@ /* * KernelEx - * Copyright (C) 2008, Xeno86 + * Copyright (C) 2009, Xeno86 * * This file is part of KernelEx source code. * @@ -22,39 +22,8 @@ #include #include "kexcoresdk.h" -typedef HANDLE (__stdcall *AllocHandle_t)(void* current_pdb, void* tdb, DWORD access); -AllocHandle_t AllocHandle = NULL; - -BOOL init_openthread() -{ - int i; - DWORD addr = (DWORD) kexGetProcAddress(GetModuleHandle("kernel32"), "OpenProcess"); - for (i = 0 ; i < 100 ; i++, addr++) - if (*(DWORD*) addr == 0xe832ff50) - { - addr += 4; - AllocHandle = (AllocHandle_t)(addr + 4 + *(DWORD*)addr); - return TRUE; - } - return FALSE; -} - /* MAKE_EXPORT OpenThread_new=OpenThread */ HANDLE WINAPI OpenThread_new(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId) { - HANDLE ret; - BYTE* tdb = (BYTE*) kexTIDtoTDB(dwThreadId); - if (!tdb || *tdb != 7) - { - SetLastError(ERROR_INVALID_PARAMETER); - return NULL; - } - - dwDesiredAccess &= THREAD_ALL_ACCESS; - if (bInheritHandle) - dwDesiredAccess |= 0x80000000; - ret = AllocHandle(kexPIDtoPDB(GetCurrentProcessId()), tdb, dwDesiredAccess); - if (ret == INVALID_HANDLE_VALUE) - return NULL; - return ret; + return kexOpenThread(dwDesiredAccess, bInheritHandle, dwThreadId); } diff --git a/apilibs/kexbases/Kernel32/_kernel32_apilist.c b/apilibs/kexbases/Kernel32/_kernel32_apilist.c index 653c5fa..f74b829 100644 --- a/apilibs/kexbases/Kernel32/_kernel32_apilist.c +++ b/apilibs/kexbases/Kernel32/_kernel32_apilist.c @@ -35,7 +35,7 @@ BOOL init_openthread(); BOOL init_kernel32() { get_cpuinfo(); - return init_tryentercritsec() && init_openthread(); + return init_tryentercritsec(); } /* diff --git a/apilibs/kexbases/Kernel32/unikernel32.c b/apilibs/kexbases/Kernel32/unikernel32.c index d27d79f..f9fa66e 100644 --- a/apilibs/kexbases/Kernel32/unikernel32.c +++ b/apilibs/kexbases/Kernel32/unikernel32.c @@ -842,17 +842,19 @@ LPWSTR WINAPI lstrcpynW_new(LPWSTR dst, LPCWSTR src, INT n) { LPWSTR ret = dst; - if (IsBadReadPtr(src, n) || IsBadWritePtr(dst, n)) + __try + { + while ((n > 1) && *src) + { + *dst++ = *src++; + n--; + } + *dst = 0; + } + __except (EXCEPTION_EXECUTE_HANDLER) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } - - while ((n > 1) && *src) - { - *dst++ = *src++; - n--; - } - *dst = 0; return ret; } diff --git a/apilibs/kexbases/shell32/_shell32_apilist.c b/apilibs/kexbases/shell32/_shell32_apilist.c index 4f3c02d..60ae682 100644 --- a/apilibs/kexbases/shell32/_shell32_apilist.c +++ b/apilibs/kexbases/shell32/_shell32_apilist.c @@ -34,6 +34,7 @@ static const apilib_named_api shell32_named_apis[] = DECL_API("CommandLineToArgvW", CommandLineToArgvW_new), DECL_API("IsUserAnAdmin", IsUserAnAdmin_new), DECL_API("SHCreateShellItem", SHCreateShellItem_stub), + DECL_API("SHOpenFolderAndSelectItems", SHOpenFolderAndSelectItems_stub), DECL_API("SHParseDisplayName", SHParseDisplayName_stub), /*** AUTOGENERATED APILIST NAMED EXPORTS END ***/ }; diff --git a/apilibs/kexbases/shell32/_shell32_apilist.h b/apilibs/kexbases/shell32/_shell32_apilist.h index 655d897..be61675 100644 --- a/apilibs/kexbases/shell32/_shell32_apilist.h +++ b/apilibs/kexbases/shell32/_shell32_apilist.h @@ -32,6 +32,7 @@ LPWSTR* WINAPI CommandLineToArgvW_new(LPCWSTR lpCmdline, int* numargs); BOOL WINAPI IsUserAnAdmin_new(void); STUB SHParseDisplayName_stub; STUB SHCreateShellItem_stub; +STUB SHOpenFolderAndSelectItems_stub; /*** AUTOGENERATED APILIST DECLARATIONS END ***/ #endif diff --git a/apilibs/kexbases/shell32/_shell32_stubs.c b/apilibs/kexbases/shell32/_shell32_stubs.c index f4dda04..0a730a6 100644 --- a/apilibs/kexbases/shell32/_shell32_stubs.c +++ b/apilibs/kexbases/shell32/_shell32_stubs.c @@ -23,3 +23,4 @@ UNIMPL_FUNC(SHParseDisplayName, 5); UNIMPL_FUNC(SHCreateShellItem, 4); +UNIMPL_FUNC(SHOpenFolderAndSelectItems, 4); diff --git a/apilibs/settings.reg b/apilibs/settings.reg index 019d109..f219457 100644 --- a/apilibs/settings.reg +++ b/apilibs/settings.reg @@ -6,6 +6,7 @@ REGEDIT4 "*\\KERNELEX\\VERIFY.EXE"="DCFG1" "*\\UNICOWS.DLL"="DCFG1" "*\\FIREFOX SETUP 3*.EXE"="WINXP" +"*FIREFOX\\UNINSTALL\\HELPER.EXE"="WINXP" "*\\FIREFOX*PRE*.INSTALLER.EXE"="WINXP" "*\\XUL.DLL"="WINXP" "*\\FIREFOX.EXE"="DCFG1" diff --git a/common/kexcoresdk.h b/common/kexcoresdk.h index 10b2fbd..6fa7624 100644 --- a/common/kexcoresdk.h +++ b/common/kexcoresdk.h @@ -135,20 +135,18 @@ _KEXCOREIMP DWORD kexGetVersion(); _KEXCOREIMP PROC kexGetProcAddress(HMODULE hModule, PCSTR lpProcName); -/** kexPIDtoPDB - obtain pointer to process database entry, given process identifier. - * - * @param pid Process identifier. - * @return Pointer to process database entry on success, NULL on failure. +/** kexOpenThread - open thread object. + * + * Refer to OpenThread API documentation for parameters and output. */ -_KEXCOREIMP void* kexPIDtoPDB(DWORD pid); +_KEXCOREIMP HANDLE kexOpenThread(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId); -/** kexTIDtoTDB - obtain pointer to thread database entry, given thread identifier. +/** kexAreExtensionsEnabled - checks if API extensions are enabled for current process. * - * @param tid Thread identifier. - * @return Pointer to thread database entry on success, NULL on failure. + * @return TRUE if extensions are enabled, FALSE otherwise. */ -_KEXCOREIMP void* kexTIDtoTDB(DWORD tid); +_KEXCOREIMP BOOL kexAreExtensionsEnabled(); /** kexGetModuleSettings - Retrieve per module settings. diff --git a/common/version.h b/common/version.h index c00e2a4..bf26015 100644 --- a/common/version.h +++ b/common/version.h @@ -22,9 +22,9 @@ #ifndef __VERSION_H #define __VERSION_H -#define VERSION_STR "4.0 Final" -#define VERSION_CODE 0x04000064 -#define RCVERSION 4, 0, 10, 0 -#define _RCVERSION_ "4, 0, 10, 0" +#define VERSION_STR "4.0 Final 2" +#define VERSION_CODE 0x04000066 +#define RCVERSION 4, 0, 10, 2 +#define _RCVERSION_ "4, 0, 10, 2" #endif diff --git a/core/DebugWindow.cpp b/core/DebugWindow.cpp index 3166296..301d8ef 100644 --- a/core/DebugWindow.cpp +++ b/core/DebugWindow.cpp @@ -40,7 +40,15 @@ DebugWindow::DebugWindow() { DWORD tid; hwnd = (HWND) -1; + + //we're interested in everything includes.push_back("*"); + //these usually aren't interesting + excludes.push_back("Tls"); + excludes.push_back("Heap"); + excludes.push_back("CriticalSection"); + excludes.push_back("Interlocked"); + InitializeCriticalSection(&cs); InitCommonControls(); hThread = CreateThread(NULL, 0, thread, (void*) this, 0, &tid); @@ -79,11 +87,21 @@ BOOL CALLBACK DebugWindow::DebugDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR break; case WM_NOTIFY: nmhdr = (NMHDR*) lParam; - if (nmhdr->idFrom == IDC_LOG && nmhdr->code == NM_RCLICK) - { - _this->HandleMenu(); - break; - } + if (nmhdr->idFrom == IDC_LOG) + if (nmhdr->code == NM_RCLICK) + { + _this->HandleMenu(); + break; + } + else if (nmhdr->code == LVN_KEYDOWN) + { + LPNMLVKEYDOWN nm = (LPNMLVKEYDOWN) lParam; + if (nm->wVKey == VK_DELETE) + { + _this->DeleteSelItems(); + break; + } + } default: return FALSE; } @@ -94,7 +112,7 @@ void DebugWindow::InitDialog(HWND hwnd) { hList = GetDlgItem(hwnd, IDC_LOG); SetClassLong(hwnd, GCL_STYLE, GetClassLong(hwnd, GCL_STYLE) | CS_NOCLOSE); - MoveWindow(hwnd, 0, 0, 320, 200, TRUE); + MoveWindow(hwnd, 0, 0, 480, 200, TRUE); SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT); @@ -102,27 +120,29 @@ void DebugWindow::InitDialog(HWND hwnd) memset(&col, 0, sizeof(col)); col.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH; - col.cx = 80; - col.pszText = "Process"; + col.cx = 20; + col.pszText = "Depth"; ListView_InsertColumn(hList, 0, &col); col.cx = 60; col.pszText = "Thread"; ListView_InsertColumn(hList, 1, &col); - col.cx = 80; + col.cx = 90; col.pszText = "Source"; ListView_InsertColumn(hList, 2, &col); - col.cx = 80; + col.cx = 90; col.pszText = "Dest"; ListView_InsertColumn(hList, 3, &col); - col.cx = 120; + col.cx = 130; col.pszText = "Function"; ListView_InsertColumn(hList, 4, &col); - col.cx = 40; + col.cx = 60; col.mask |= LVCF_FMT; col.fmt = LVCFMT_RIGHT; col.pszText = "Return"; ListView_InsertColumn(hList, 5, &col); +#define NUM_COLS 6 + menu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_LOGMENU)); menu = GetSubMenu(menu, 0); } @@ -151,6 +171,18 @@ void DebugWindow::HandleMenu() } } +void DebugWindow::DeleteSelItems() +{ + if (ListView_GetSelectedCount(hList) == 0) + return; + + for (int i = ListView_GetItemCount(hList) - 1 ; i >= 0 ; i--) + { + if (ListView_GetItemState(hList, i, LVIS_SELECTED)) + ListView_DeleteItem(hList, i); + } +} + void DebugWindow::AppendLog(char* msg) { LV_ITEM item; @@ -232,9 +264,9 @@ BOOL CALLBACK DebugWindow::FilterDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPA len1 = GetWindowTextLength(GetDlgItem(hwnd, IDC_DFINCLUDE)) + 1; len2 = GetWindowTextLength(GetDlgItem(hwnd, IDC_DFEXCLUDE)) + 1; buf = (char*) alloca(max(len1, len2)); - EnterCriticalSection(&_this->cs); GetDlgItemText(hwnd, IDC_DFINCLUDE, buf, len1); + EnterCriticalSection(&_this->cs); _this->includes.clear(); pch = strtok_r(buf, ";", &p); if (pch) @@ -243,8 +275,10 @@ BOOL CALLBACK DebugWindow::FilterDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPA while ((pch = strtok_r(NULL, ";", &p)) != NULL) _this->includes.push_back(pch); } + LeaveCriticalSection(&_this->cs); GetDlgItemText(hwnd, IDC_DFEXCLUDE, buf, len2); + EnterCriticalSection(&_this->cs); _this->excludes.clear(); pch = strtok_r(buf, ";", &p); if (pch) @@ -253,8 +287,8 @@ BOOL CALLBACK DebugWindow::FilterDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPA while ((pch = strtok_r(NULL, ";", &p)) != NULL) _this->excludes.push_back(pch); } - LeaveCriticalSection(&_this->cs); + EndDialog(hwnd, 0); break; } @@ -312,7 +346,7 @@ void DebugWindow::WriteToFile() col.pszText = buf; col.cchTextMax = sizeof(buf); DWORD wlen; - for (int j = 0 ; j < 6 ; j++) + for (int j = 0 ; j < NUM_COLS ; j++) { DWORD len; ListView_GetColumn(hList, j, &col); @@ -326,7 +360,7 @@ void DebugWindow::WriteToFile() rows = ListView_GetItemCount(hList); for (int i = 0 ; i < rows ; i++) { - for (int j = 0 ; j < 6 ; j++) + for (int j = 0 ; j < NUM_COLS ; j++) { DWORD len; DWORD wlen; ListView_GetItemText(hList, i, j, buf, sizeof(buf)); @@ -361,7 +395,6 @@ void DebugWindow::append(const char* str) { static char msg[DEBUGMSG_MAXLEN]; bool filter_out = true; - list::const_iterator it; EnterCriticalSection(&cs); @@ -370,21 +403,28 @@ void DebugWindow::append(const char* str) { if (includes.size() == 1 && strcmp(includes.front(), "*") == 0) filter_out = false; - else for (it = includes.begin() ; it != includes.end() ; it++) - if (strstr(str, *it)) - { - filter_out = false; - break; - } + else + { + list::const_iterator it; + for (it = includes.begin() ; it != includes.end() ; it++) + if (strstr(str, *it)) + { + filter_out = false; + break; + } + } } if (!filter_out) + { + list::const_iterator it; for (it = excludes.begin() ; it != excludes.end() ; it++) if (strstr(str, *it)) { filter_out = true; break; } + } if (filter_out) { diff --git a/core/DebugWindow.h b/core/DebugWindow.h index dd0b324..c21000b 100644 --- a/core/DebugWindow.h +++ b/core/DebugWindow.h @@ -55,6 +55,7 @@ private: static BOOL CALLBACK FilterDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); void InitDialog(HWND hwnd); void HandleMenu(); + void DeleteSelItems(); void AppendLog(char* msg); void WriteToFile(); static DWORD WINAPI thread(void* param); diff --git a/core/apilib.cpp b/core/apilib.cpp index 046ac3c..7c724a5 100644 --- a/core/apilib.cpp +++ b/core/apilib.cpp @@ -195,9 +195,9 @@ bool ApiLibraryManager::load_apilib(const char* apilib_name) apilib->index = apilib_cnt; //set mod_index for newly loaded api libraries - pmteModTable = *ppmteModTable; mr = MRFromHLib(apilib->mod_handle); DBGASSERT(mr); + pmteModTable = *ppmteModTable; ((IMTE_KEX*) pmteModTable[mr->mteIndex])->mod_index = 0xff00 + apilib->index; //add to table of new ApiLibraries diff --git a/core/apilog.cpp b/core/apilog.cpp index f69f8b3..a95ed99 100644 --- a/core/apilog.cpp +++ b/core/apilog.cpp @@ -27,7 +27,9 @@ #include "internals.h" #include "DebugWindow.h" -void* get_process_env_data(const char* env, void* (*c)()) +#define APILOG_TLS_INDEX 78 + +void* get_process_env_data(const char* env, void* (*creator)()) { //environment variable: ENV=ProcessID:DATA char buf[20]; @@ -41,7 +43,7 @@ void* get_process_env_data(const char* env, void* (*c)()) || ProcID != GetCurrentProcessId()) { //invalid/missing value - create new data - data = c(); + data = creator(); if (data) { sprintf(buf, "%x:%x", GetCurrentProcessId(), data); @@ -64,7 +66,11 @@ HANDLE get_process_debug_heap() void* tls_creator() { - return (void*) TlsAlloc(); + for (int i = 0 ; i < APILOG_TLS_INDEX+1 ; i++) + TlsAlloc(); + for (int i = 0 ; i < APILOG_TLS_INDEX ; i++) + TlsFree(i); + return (void*) APILOG_TLS_INDEX; } DWORD get_process_debug_tls() @@ -75,7 +81,7 @@ DWORD get_process_debug_tls() extern "C" int snprintf(char *buffer, size_t n, const char* format, ...); -DWORD __stdcall log_api(const char* source, const char* target, const char* api_name, DWORD ret) +DWORD __stdcall log_api(const char* source, const char* target, const char* api_name, DWORD depth, DWORD ret) { DebugWindow* dw = DebugWindow::get(); if (!dw) @@ -83,8 +89,20 @@ DWORD __stdcall log_api(const char* source, const char* target, const char* api_ char msg[DEBUGMSG_MAXLEN]; - const char* proc = ((*ppmteModTable)[(*pppdbCur)->pExeMODREF->mteIndex])->pszModName; - snprintf(msg, sizeof(msg), "%s|%x|%s|%s|%s|%x", proc, + //fancy call stack depth indicator + if (depth < DEBUGMSG_MAXLEN / 2) + { + for (int i = 0 ; i < depth ; i++) + msg[i] = 'l'; + } + else + { + msg[0] = 'E'; + msg[1] = 'E'; + depth = 2; + } + + snprintf(msg + depth, sizeof(msg) - depth, "|%x|%s|%s|%s|%x", GetCurrentThreadId(), source, target, api_name, ret); dw->append(msg); @@ -97,31 +115,56 @@ ThreadAddrStack::ThreadAddrStack() pos = 0; } -void __stdcall ThreadAddrStack::push_ret_addr(DWORD tls, DWORD addr) +void __stdcall ThreadAddrStack::push_ret_addr(DWORD addr) { - ThreadAddrStack* tas = (ThreadAddrStack*) TlsGetValue(tls); + //TlsGetValue clears last error value so remember & restore it + DWORD lasterr = GetLastError(); + ThreadAddrStack* tas = (ThreadAddrStack*) TlsGetValue(APILOG_TLS_INDEX); + SetLastError(lasterr); if (!tas) { void* mem = HeapAlloc(get_process_debug_heap(), 0, sizeof(ThreadAddrStack)); tas = new (mem) ThreadAddrStack; - TlsSetValue(tls, mem); + TlsSetValue(APILOG_TLS_INDEX, mem); } tas->stack[tas->pos++] = addr; + DBGASSERT(tas->pos < sizeof(tas->stack) / sizeof(tas->stack[0])); } -DWORD __stdcall ThreadAddrStack::pop_ret_addr(DWORD tls) +DWORD __stdcall ThreadAddrStack::pop_ret_addr() { - ThreadAddrStack* tas = (ThreadAddrStack*) TlsGetValue(tls); - if (!tas || !tas->pos) - return 0; + //TlsGetValue clears last error value so remember & restore it + DWORD lasterr = GetLastError(); + ThreadAddrStack* tas = (ThreadAddrStack*) TlsGetValue(APILOG_TLS_INDEX); + SetLastError(lasterr); + DBGASSERT(tas->pos > 0); return tas->stack[--tas->pos]; } +DWORD __stdcall ThreadAddrStack::get_level() +{ + //TlsGetValue clears last error value so remember & restore it + DWORD lasterr = GetLastError(); + ThreadAddrStack* tas = (ThreadAddrStack*) TlsGetValue(APILOG_TLS_INDEX); + SetLastError(lasterr); + return tas->pos; +} + PROC create_log_stub(const char* caller, const char* target, const char* api, PROC orig) { HANDLE heap = get_process_debug_heap(); + char* new_api = (char*) HeapAlloc(heap, 0, strlen(api) + 1); + strcpy(new_api, api); + get_process_debug_tls(); void* mem = HeapAlloc(heap, 0, sizeof(log_stub)); return (PROC) new (mem) log_stub(caller, - target, api, (unsigned long) orig, - (unsigned long) log_api, get_process_debug_tls()); + target, new_api, (unsigned long) orig, + (unsigned long) log_api); +} + +PROC create_log_stub(const char* caller, const char* target, WORD ord, PROC orig) +{ + char ord_name[16]; + snprintf(ord_name, sizeof(ord_name), "Ordinal:%d", ord); + return create_log_stub(caller, target, ord_name, orig); } diff --git a/core/apilog.h b/core/apilog.h index 53a76e8..24a746b 100644 --- a/core/apilog.h +++ b/core/apilog.h @@ -29,12 +29,13 @@ class ThreadAddrStack { public: ThreadAddrStack(); - static void __stdcall push_ret_addr(DWORD tls, DWORD addr); - static DWORD __stdcall pop_ret_addr(DWORD tls); + static void __stdcall push_ret_addr(DWORD addr); + static DWORD __stdcall pop_ret_addr(); + static DWORD __stdcall get_level(); private: int pos; - DWORD stack[31]; + DWORD stack[1023]; }; #pragma pack(push,1) @@ -44,41 +45,46 @@ class log_stub { public: log_stub(const char* source, const char* target, const char* name, - unsigned long proc, unsigned long log_fun, DWORD tls) + unsigned long proc, unsigned long log_fun) : call_orig(proc, true), jmp_logfun(log_fun), tas_store((unsigned long) ThreadAddrStack::push_ret_addr, true), - tas_restore((unsigned long) ThreadAddrStack::pop_ret_addr, true) + tas_restore((unsigned long) ThreadAddrStack::pop_ret_addr, true), + tas_depth((unsigned long) ThreadAddrStack::get_level, true) { - c_push1 = c_push2 = c_push3 = c_push4 = c_push5 = 0x68; - tls1 = tls2 = tls; + c_push2 = c_push3 = c_push4 = 0x68; v_source = source; v_target = target; v_name = name; - c_pusheax1 = c_pusheax2 = 0x50; + c_pusheax1 = c_pusheax2 = c_pusheax3 = c_pusheax4 = 0x50; + c_popeax4 = 0x58; + c_pushecx = 0x51; + c_popecx = 0x59; } private: - unsigned char c_push1; - DWORD tls1; - redir_stub tas_store; //arg1=tls, arg2=caller ret + unsigned char c_popeax4; //caller ret + unsigned char c_pushecx; + unsigned char c_pusheax4; //caller ret + redir_stub tas_store; + unsigned char c_popecx; redir_stub call_orig; unsigned char c_pusheax1; //orig ret - unsigned char c_push2; + redir_stub tas_depth; + unsigned char c_pusheax3; //call stack depth + unsigned char c_push2; //api name const char* v_name; - unsigned char c_push3; + unsigned char c_push3; //target module const char* v_target; - unsigned char c_push4; + unsigned char c_push4; //calling module const char* v_source; - unsigned char c_push5; - DWORD tls2; - redir_stub tas_restore; //restore caller ret - unsigned char c_pusheax2; - redir_stub jmp_logfun; //jmp to log_fun + redir_stub tas_restore; + unsigned char c_pusheax2; //caller return address + redir_stub jmp_logfun; //jump to log_fun }; #pragma pack(pop) PROC create_log_stub(const char* caller, const char* target, const char* api, PROC orig); - +PROC create_log_stub(const char* caller, const char* target, WORD ord, PROC orig); #endif diff --git a/core/debug.h b/core/debug.h index 75c12d0..3789d34 100644 --- a/core/debug.h +++ b/core/debug.h @@ -46,7 +46,7 @@ void dbgvprintf(const char* format, void* _argp); void dbgprintf(const char* format, ...); -PROC create_log_stub(const char* caller, const char* target, const char* api, PROC orig); +#include "apilog.h" #endif diff --git a/core/internals.cpp b/core/internals.cpp index c17fc20..abd782f 100644 --- a/core/internals.cpp +++ b/core/internals.cpp @@ -29,7 +29,7 @@ static bool is_winme; HINSTANCE hInstance; -IMTE*** ppmteModTable = NULL; +IMTE*** volatile ppmteModTable = NULL; HMODULE h_kernel32; CRITICAL_SECTION* krnl32lock = NULL; PDB98** pppdbCur = NULL; @@ -37,11 +37,11 @@ WORD* pimteMax = NULL; MRFromHLib_t MRFromHLib = NULL; TIDtoTDB_t TIDtoTDB = NULL; -PIDtoPDB_t PIDtoPDB = NULL; MRLoadTree_t MRLoadTree = NULL; FreeLibTree_t FreeLibTree = NULL; FLoadTreeNotify_t FLoadTreeNotify = NULL; FreeLibRemove_t FreeLibRemove = NULL; +AllocHandle_t AllocHandle = NULL; sstring kernelex_dir(""); sstring own_path(""); @@ -162,6 +162,25 @@ MODREF* MRfromCallerAddr(DWORD addr) return NULL; } +HANDLE _OpenThread(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId) +{ + HANDLE ret; + TDB98* tdb = TIDtoTDB(dwThreadId); + if (!tdb || tdb->Type != WIN98_K32OBJ_THREAD) + { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + dwDesiredAccess &= THREAD_ALL_ACCESS; + if (bInheritHandle) + dwDesiredAccess |= 0x80000000; + ret = AllocHandle(*pppdbCur, tdb, dwDesiredAccess); + if (ret == INVALID_HANDLE_VALUE) + return NULL; + return ret; +} + /* find win32 mutex */ static CRITICAL_SECTION* find_krnl32lock() { @@ -273,23 +292,6 @@ static TIDtoTDB_t find_TIDtoTDB() return ret; } -static PIDtoPDB_t find_PIDtoPDB() -{ - PIDtoPDB_t ret; - - const char* pat_name = "PIDtoPDB"; - short pat[] = {0xFF,0x74,0x24,0x0C,0xE8,-2,-2,-2,-2}; - int pat_len = sizeof(pat) / sizeof(short); - - DWORD* res = find_unique_pattern((void*) iGetProcAddress(h_kernel32, "OpenProcess"), pat_len, pat, pat_len, pat_name); - if (!res) - return NULL; - - ret = (PIDtoPDB_t)decode_calljmp(res); - DBGPRINTF(("%s @ 0x%08x\n", pat_name, ret)); - return ret; -} - static MRLoadTree_t find_MRLoadTree() { MRLoadTree_t ret; @@ -370,6 +372,23 @@ static FreeLibRemove_t find_FreeLibRemove() return ret; } +static AllocHandle_t find_AllocHandle() +{ + AllocHandle_t ret; + + const char* pat_name = "AllocHandle"; + short pat[] = {0x83,0xD1,0xFF,0x81,0xE2,0xFF,0x0F,0x1F,0x00,0x81,0xE1,0x00,0x00,0x00,0x80,0x0B,0xCA,0x8B,0x15,-1,-1,-1,-1,0x51,0x50,0xFF,0x32,0xE8,-2,-2,-2,-2}; + int pat_len = sizeof(pat) / sizeof(short); + + DWORD* res = find_unique_pattern((void*) iGetProcAddress(h_kernel32, "OpenProcess"), 0x80, pat, pat_len, pat_name); + if (!res) + return NULL; + + ret = (AllocHandle_t)decode_calljmp(res); + DBGPRINTF(("%s @ 0x%08x\n", pat_name, ret)); + return ret; +} + static bool find_kernelex_install_dir() { //registry value InstallDir is written by the installer @@ -424,17 +443,17 @@ int internals_init() MRFromHLib = find_MRFromHLib(); pimteMax = find_pimteMax(); TIDtoTDB = find_TIDtoTDB(); - PIDtoPDB = find_PIDtoPDB(); MRLoadTree = find_MRLoadTree(); FreeLibTree = find_FreeLibTree(); FLoadTreeNotify = find_FLoadTreeNotify(); FreeLibRemove = find_FreeLibRemove(); + AllocHandle = find_AllocHandle(); bool instdir_rslt = find_kernelex_install_dir(); is_winme = (GetVersion() == 0xc0005a04); if (!h_kernel32 || !ppmteModTable || !krnl32lock || !pppdbCur || !MRFromHLib - || !pimteMax || !TIDtoTDB || !PIDtoPDB || !MRLoadTree || !FreeLibTree - || !FLoadTreeNotify || !FreeLibRemove || !instdir_rslt) + || !pimteMax || !TIDtoTDB || !MRLoadTree || !FreeLibTree + || !FLoadTreeNotify || !FreeLibRemove || !AllocHandle || !instdir_rslt) return 0; return 1; } diff --git a/core/internals.h b/core/internals.h index 9fd6423..3734533 100644 --- a/core/internals.h +++ b/core/internals.h @@ -39,7 +39,7 @@ extern HINSTANCE hInstance; -extern IMTE*** ppmteModTable; +extern IMTE*** volatile ppmteModTable; extern HMODULE h_kernel32; extern CRITICAL_SECTION* krnl32lock; extern PDB98** pppdbCur; @@ -53,11 +53,11 @@ bool isWinMe(); typedef MODREF* (__stdcall *MRFromHLib_t)(HMODULE); typedef TDB98* (__stdcall *TIDtoTDB_t)(DWORD); -typedef PDB98* (__stdcall *PIDtoPDB_t)(DWORD); typedef MODREF* (__stdcall * MRLoadTree_t)(LPCSTR); typedef BOOL (__stdcall * FreeLibTree_t)(MODREF*); typedef BOOL (__stdcall * FLoadTreeNotify_t)(MODREF*, BOOL); typedef VOID (__stdcall * FreeLibRemove_t)(VOID); +typedef HANDLE (__stdcall *AllocHandle_t)(PDB98*, TDB98*, DWORD); extern MRFromHLib_t MRFromHLib; @@ -67,17 +67,13 @@ extern MRFromHLib_t MRFromHLib; */ extern TIDtoTDB_t TIDtoTDB; -/** Convert Process ID into pointer to Process Database. - * @param pid Process ID. - * @return Pointer to Process Database. - */ -extern PIDtoPDB_t PIDtoPDB; - extern MRLoadTree_t MRLoadTree; extern FreeLibTree_t FreeLibTree; extern FLoadTreeNotify_t FLoadTreeNotify; extern FreeLibRemove_t FreeLibRemove; +extern AllocHandle_t AllocHandle; MODREF* MRfromCallerAddr(DWORD addr); +HANDLE _OpenThread(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId); #endif diff --git a/core/kexcoresdk.cpp b/core/kexcoresdk.cpp index fd6daf1..eb562ee 100644 --- a/core/kexcoresdk.cpp +++ b/core/kexcoresdk.cpp @@ -62,14 +62,14 @@ PROC kexGetProcAddress(HMODULE hModule, PCSTR lpProcName) return iGetProcAddress(hModule, lpProcName); } -void* kexPIDtoPDB(DWORD pid) +HANDLE kexOpenThread(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId) { - return PIDtoPDB(pid); + return _OpenThread(dwDesiredAccess, bInheritHandle, dwThreadId); } -void* kexTIDtoTDB(DWORD tid) +BOOL kexAreExtensionsEnabled() { - return TIDtoTDB(tid); + return are_extensions_enabled(); } void kexGetModuleSettings(const char* module, diff --git a/core/main.cpp b/core/main.cpp index 8c9e646..18de143 100644 --- a/core/main.cpp +++ b/core/main.cpp @@ -119,7 +119,7 @@ void load_MPRServices() RegOpenKey(hk_serv, subkey, &hk_this); size = sizeof(dllname); if (RegQueryValueEx(hk_this, "DllName", NULL, NULL, (BYTE*)dllname, &size) - == ERROR_SUCCESS && strcmpi(dllname, own_path) != 0) + == ERROR_SUCCESS) { LoadLibrary(dllname); } diff --git a/core/resolver.cpp b/core/resolver.cpp index 2b1fe39..4e3b452 100644 --- a/core/resolver.cpp +++ b/core/resolver.cpp @@ -37,8 +37,8 @@ char system_path[MAX_PATH]; int system_path_len; static PLONG jtab; -static LONG old_jtab[4]; - +static LONG old_jtab[JTAB_SIZE]; +static HKEY known_dlls_key; /** Get API configuration for selected module. @@ -101,6 +101,7 @@ static bool get_config(MODREF* moduleMR, config_params& cp) if (ppdbParent && !(ppdbParent->Flags & (fTerminated | fTerminating | fNearlyTerminating | fDosProcess | fWin16Process))) { + pmteModTable = *ppmteModTable; IMTE_KEX* parent = (IMTE_KEX*) pmteModTable[ppdbParent->pExeMODREF->mteIndex]; conf = parent->config; flags = parent->flags; @@ -128,7 +129,7 @@ static bool get_config(MODREF* moduleMR, config_params& cp) DBGASSERT(conf != NULL); cp.apiconf = conf; #ifdef _DEBUG - cp.log_apis = (flags & LDR_LOG_APIS) != 0; + cp.log_apis = (process->flags & LDR_LOG_APIS) != 0; #endif return true; } @@ -234,7 +235,7 @@ static PROC resolve_nonshared_addr(DWORD addr, MODREF* caller, PMODREF** refmod) } DBGPRINTF(("Implicit load: replacing tree %s => %s [PID=%08x]\n", - pmteModTable[caller->ImplicitImports[*refmod - buffer].pMR->mteIndex] + (*ppmteModTable)[caller->ImplicitImports[*refmod - buffer].pMR->mteIndex] ->pszModName, apilib->apilib_name, GetCurrentProcessId())); @@ -261,6 +262,7 @@ static PROC resolve_nonshared_addr(DWORD addr, MODREF* caller, PMODREF** refmod) } } + pmteModTable = *ppmteModTable; IMTE_KEX* imte = (IMTE_KEX*) pmteModTable[mr->mteIndex]; img_base = imte->pNTHdr->OptionalHeader.ImageBase; @@ -462,7 +464,9 @@ DWORD encode_address(DWORD addr, const ApiLibrary* apilib) //STD apilib if (index == 0) { - if (addr < 0xc0000000) + //normal address (shared or nonshared library) + //or ordinal number for export forwarding + if (addr < 0xc0000000 || addr >= 0xffff0000) return addr; //extremely rare scenario: driver hijacked apis so the address is now @@ -526,6 +530,15 @@ PROC WINAPI ExportFromOrdinal(IMTE_KEX* target, MODREF* caller, PMODREF** refmod target->pNTHdr, caller, refmod); else ret = OriExportFromOrdinal(target->pNTHdr, ordinal); +#ifdef _DEBUG + if (ret && cp.log_apis) + { + IMTE_KEX* icaller = (IMTE_KEX*)((*ppmteModTable)[caller->mteIndex]); + if (DWORD(ret) < target->pNTHdr->OptionalHeader.ImageBase + + target->pNTHdr->OptionalHeader.BaseOfData) + ret = create_log_stub(icaller->pszModName, target->pszModName, ordinal, ret); + } +#endif } else ret = OriExportFromOrdinal(target->pNTHdr, ordinal); @@ -568,7 +581,9 @@ PROC WINAPI ExportFromName(IMTE_KEX* target, MODREF* caller, PMODREF** refmod, W if (ret && cp.log_apis) { IMTE_KEX* icaller = (IMTE_KEX*)((*ppmteModTable)[caller->mteIndex]); - ret = create_log_stub(icaller->pszModName, target->pszModName, name, ret); + if (DWORD(ret) < target->pNTHdr->OptionalHeader.ImageBase + + target->pNTHdr->OptionalHeader.BaseOfData) + ret = create_log_stub(icaller->pszModName, target->pszModName, name, ret); } #endif } @@ -585,6 +600,50 @@ PROC WINAPI ExportFromName(IMTE_KEX* target, MODREF* caller, PMODREF** refmod, W return ret; } +bool are_extensions_enabled() +{ + config_params cp; + MODREF* exe = (*pppdbCur)->pExeMODREF; + return get_config(exe, cp); +} + +typedef BOOL (__stdcall *IsKnownDLL_t)(char*, const char*); + +static BOOL WINAPI IsKnownKexDLL(char* name, const char* ext) +{ + LONG res; + DWORD type; + char path[MAX_PATH]; + DWORD size = sizeof(path); + + if (ext && strcmp(ext, "DLL") != 0) + return FALSE; + + if (are_extensions_enabled()) + { + //workaround windows bug + int pos = strlen(name) - 4; + if (pos > 0 && name[pos] == '.') + name[pos] = '\0'; + + res = RegQueryValueEx(known_dlls_key, name, NULL, &type, (BYTE*) path, &size); + } + else + res = ERROR_INVALID_FUNCTION; + + if (res == ERROR_SUCCESS && type == REG_SZ) + { + memcpy(name, (const char*) kernelex_dir, kernelex_dir.length()); + memcpy(name + kernelex_dir.length(), path, size); + return TRUE; + } + else + { + IsKnownDLL_t IsKnownDLL = (IsKnownDLL_t) old_jtab[JTAB_KNO_DLL]; + return IsKnownDLL(name, NULL); + } +} + PROC WINAPI iGetProcAddress(HMODULE hModule, LPCSTR lpProcName) { IMAGE_DOS_HEADER* dos_hdr; @@ -708,6 +767,7 @@ int resolver_init() jtab = (PLONG) dseg->jtab; system_path_len = GetSystemDirectory(system_path, sizeof(system_path)); + RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\KernelEx\\KnownDLLs", &known_dlls_key); SettingsDB::instance.flush_all(); @@ -716,6 +776,8 @@ int resolver_init() void resolver_uninit() { + DBGPRINTF(("resolver_uninit()\n")); + RegCloseKey(known_dlls_key); SettingsDB::instance.clear(); reset_imtes(); } @@ -723,17 +785,16 @@ void resolver_uninit() void resolver_hook() { DBGPRINTF(("resolver_hook()\n")); - old_jtab[0] = InterlockedExchange(jtab + JTAB_EFO_DYN, (LONG) ExportFromOrdinalDynamic_thunk); - old_jtab[1] = InterlockedExchange(jtab + JTAB_EFO_STA, (LONG) ExportFromOrdinalStatic_thunk); - old_jtab[2] = InterlockedExchange(jtab + JTAB_EFN_DYN, (LONG) ExportFromNameDynamic_thunk); - old_jtab[3] = InterlockedExchange(jtab + JTAB_EFN_STA, (LONG) ExportFromNameStatic_thunk); + old_jtab[JTAB_EFO_DYN] = InterlockedExchange(jtab + JTAB_EFO_DYN, (LONG) ExportFromOrdinalDynamic_thunk); + old_jtab[JTAB_EFO_STA] = InterlockedExchange(jtab + JTAB_EFO_STA, (LONG) ExportFromOrdinalStatic_thunk); + old_jtab[JTAB_EFN_DYN] = InterlockedExchange(jtab + JTAB_EFN_DYN, (LONG) ExportFromNameDynamic_thunk); + 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); } void resolver_unhook() { DBGPRINTF(("resolver_unhook()\n")); - InterlockedExchange(jtab + JTAB_EFO_DYN, old_jtab[0]); - InterlockedExchange(jtab + JTAB_EFO_STA, old_jtab[1]); - InterlockedExchange(jtab + JTAB_EFN_DYN, old_jtab[2]); - InterlockedExchange(jtab + JTAB_EFN_STA, old_jtab[3]); + for (int i = 0 ; i < JTAB_SIZE ; i++) + InterlockedExchange(jtab + i, old_jtab[i]); } diff --git a/core/resolver.h b/core/resolver.h index 19b9121..cf6a6b6 100644 --- a/core/resolver.h +++ b/core/resolver.h @@ -70,6 +70,7 @@ struct config_params #pragma pack(pop) +bool are_extensions_enabled(); DWORD encode_address(DWORD addr, const ApiLibrary* apilib); PROC WINAPI iGetProcAddress(HMODULE hModule, LPCSTR lpProcName); PROC WINAPI ExportFromOrdinal(IMTE_KEX* target, MODREF* caller, PMODREF** refmod, WORD ordinal); diff --git a/core/structs.h b/core/structs.h index e40b482..4b9265a 100644 --- a/core/structs.h +++ b/core/structs.h @@ -249,7 +249,8 @@ typedef struct _TDBX98 TDBX98; // Thread database (FS:[0x18] - 0x8) typedef struct _TDB98 { // Size = 0x228 (from Kernel32) - WORD Type; // 00 K32 object type + BYTE Type; // 00 K32 object type + BYTE Unknown_A; // 01 WORD cReference; // 02 Reference count DWORD pSomeEvent; // 04 K32 event object used when someone waits on the thread object TIB98 tib; // 08 Thread information block (TIB) @@ -266,7 +267,8 @@ typedef struct _TDB98 { // Size = 0x228 (from Kernel32) } TDB98, *PTDB98; typedef struct _TDBME { // Size = 0x228 (from Kernel32) - WORD Type; // 00 K32 object type + BYTE Type; // 00 K32 object type + BYTE Unknown_A; // 01 WORD cReference; // 02 Reference count DWORD pSomeEvent; // 04 K32 event object used when someone waits on the thread object TIB98 tib; // 08 Thread information block (TIB) diff --git a/kexcrt/abort.c b/kexcrt/abort.c deleted file mode 100644 index e3c43cc..0000000 --- a/kexcrt/abort.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -void __cdecl abort(void) -{ - RaiseException(0xdeafcafe, EXCEPTION_NONCONTINUABLE, 0, NULL); -} diff --git a/kexcrt/exit.c b/kexcrt/exit.c index d606c58..f54b1c4 100644 --- a/kexcrt/exit.c +++ b/kexcrt/exit.c @@ -1,5 +1,3 @@ -#include - void __exit(void); void exit(int v) diff --git a/kexcrt/kexcrt.dsp b/kexcrt/kexcrt.dsp index 908b717..199ed17 100644 --- a/kexcrt/kexcrt.dsp +++ b/kexcrt/kexcrt.dsp @@ -58,10 +58,6 @@ SOURCE=.\_vsnprintf.c # End Source File # Begin Source File -SOURCE=.\abort.c -# End Source File -# Begin Source File - SOURCE=.\msvc\argcargv.c # End Source File # Begin Source File @@ -324,10 +320,6 @@ SOURCE=.\vsscanf.c SOURCE=.\msvc\wincrt0.c # End Source File -# Begin Source File - -SOURCE=.\write.c -# End Source File # End Group # Begin Group "Header Files" diff --git a/kexcrt/makefile b/kexcrt/makefile index 17f755a..5dbab34 100644 --- a/kexcrt/makefile +++ b/kexcrt/makefile @@ -1,4 +1,4 @@ -OBJ = abort.o atoi.o atol.o atoll.o ctypes.o memccpy.o memchr.o memcmp.o memcpy.o memmem.o memmove.o memrchr.o memset.o memswap.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 = atoi.o atol.o atoll.o ctypes.o memccpy.o memchr.o memcmp.o memcpy.o memmem.o memmove.o memrchr.o memset.o memswap.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 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 diff --git a/kexcrt/makefile.msv b/kexcrt/makefile.msv index aee1783..38df778 100644 --- a/kexcrt/makefile.msv +++ b/kexcrt/makefile.msv @@ -1,4 +1,4 @@ -OBJ = abort.obj atoi.obj atol.obj atoll.obj ctypes.obj memccpy.obj memchr.obj memcmp.obj memcpy.obj memmem.obj memmove.obj memrchr.obj memset.obj memswap.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 = atoi.obj atol.obj atoll.obj ctypes.obj memccpy.obj memchr.obj memcmp.obj memcpy.obj memmem.obj memmove.obj memrchr.obj memset.obj memswap.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 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 diff --git a/kexcrt/write.c b/kexcrt/write.c deleted file mode 100644 index 0e51ab0..0000000 --- a/kexcrt/write.c +++ /dev/null @@ -1,36 +0,0 @@ -#include - -#define STDIN_FILENO 0 -#define STDOUT_FILENO 1 -#define STDERR_FILENO 2 - -int __cdecl write(int fd, const void* buf, unsigned int size) -{ - DWORD written; - HANDLE hFile; - - switch (fd) - { - case STDIN_FILENO: - hFile = GetStdHandle(STD_INPUT_HANDLE); - break; - case STDOUT_FILENO: - hFile = GetStdHandle(STD_OUTPUT_HANDLE); - break; - case STDERR_FILENO: - hFile = GetStdHandle(STD_ERROR_HANDLE); - break; - default: - hFile = (HANDLE) fd; - } - - if (!WriteFile(hFile, buf, size, &written, NULL)) - return -1; - return written; - -} - -int __cdecl _write(int fd, const void* buf, unsigned int size) -{ - return write(fd, buf, size); -} diff --git a/setup/loadstub.h b/setup/loadstub.h index 38ecd26..b5ddf18 100644 --- a/setup/loadstub.h +++ b/setup/loadstub.h @@ -23,13 +23,14 @@ #define __LOADSTUB_H #define KEX_SIGNATURE "KrnlEx" -#define KEX_STUB_VER 0 +#define KEX_STUB_VER 1 -#define JTAB_SIZE 4 +#define JTAB_SIZE 5 #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 #include typedef struct diff --git a/setup/resource.h b/setup/resource.h index 25ebef5..b74b4ab 100644 --- a/setup/resource.h +++ b/setup/resource.h @@ -9,7 +9,7 @@ #define IDS_FAILSEC 5 #define IDS_FAILBAK 6 #define IDS_ERRCHECK 7 -#define IDS_INVSTUB 8 +#define IDS_FAILOPENBACKUP 8 #define IDS_WINVER 9 // Next default values for new objects diff --git a/setup/setup.cpp b/setup/setup.cpp index 3e8de29..952b265 100644 --- a/setup/setup.cpp +++ b/setup/setup.cpp @@ -38,13 +38,16 @@ Setup::Setup(const char* backup_file) { this->backup_file = backup_file; - h_kernel32 = GetModuleHandle("kernel32"); + for (string::iterator it = this->backup_file.begin() ; it != this->backup_file.end() ; it++) + *it = toupper(*it); + + h_kernel32 = GetModuleHandle("KERNEL32"); detect_old_version(); pemem.OpenMemory(h_kernel32); if (!pemem.HasTarget()) - ShowError(IDS_FAILOPEN, "k32mem"); + ShowError(IDS_FAILOPEN, "KERNEL32 memory image"); version = get_signature_ver(); @@ -291,6 +294,30 @@ void Setup::find_ExportFromX() EFN_EFO_call = a; } +void Setup::find_IsKnownDLL() +{ + static const short pattern[] = { + 0xFF,0x75,0xFC,0x8D,0x8D,0xF0,0xFE,0xFF,0xFF,0x51,0xE8,-2,-2,-2,-2, + 0x85,0xC0,0x75,0x1E,0x8D,0x85,0xE8,0xFD,0xFF,0xFF, + 0x8D,0x8D,0xF0,0xFE,0xFF,0xFF,0x50,0x51 + }; + + 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, "IsKnownDLL"); + else ShowError(IDS_MULPAT, "IsKnownDLL"); + } + DBGPRINTF(("%s: pattern found @ 0x%08x\n", "IsKnownDLL", + pefile.PointerToRva((void*) found_loc) + pefile.GetImageBase())); + IsKnownDLL_call = found_loc + 10; + _IsKnownDLL = decode_call(IsKnownDLL_call, 5); +} + void Setup::kill_process(const char* name) { PROCESSENTRY32 pe32; @@ -400,8 +427,8 @@ void Setup::install() if (version >= 0) { - if (version > KEX_STUB_VER) - ShowError(IDS_INVSTUB, version); + if (version == KEX_STUB_VER) + return; else upgrade = true; } @@ -412,12 +439,14 @@ void Setup::install() pefile.OpenFile(upgrade ? backup_file.c_str() : kernel32path, 0x10000); if (!pefile.HasTarget()) { - if (version == KEX_STUB_VER) - return; - ShowError(IDS_FAILOPEN, upgrade ? backup_file.c_str() : kernel32path); + if (upgrade) + ShowError(IDS_FAILOPENBACKUP, backup_file.c_str(), kernel32path); + else + ShowError(IDS_FAILOPEN, kernel32path); } find_ExportFromX(); + find_IsKnownDLL(); disable_platform_check(); disable_resource_check(); mod_imte_alloc(); @@ -444,11 +473,13 @@ void Setup::install() memcpy(dseg->signature, "KrnlEx", 6); dseg->version = KEX_STUB_VER; - dseg->jtab[0] = _ExportFromOrdinal + pefile.GetImageBase(); - dseg->jtab[1] = _ExportFromOrdinal + pefile.GetImageBase(); - dseg->jtab[2] = _ExportFromName + pefile.GetImageBase(); - dseg->jtab[3] = _ExportFromName + pefile.GetImageBase(); + dseg->jtab[JTAB_EFO_DYN] = _ExportFromOrdinal + pefile.GetImageBase(); + dseg->jtab[JTAB_EFO_STA] = _ExportFromOrdinal + pefile.GetImageBase(); + dseg->jtab[JTAB_EFN_DYN] = _ExportFromName + pefile.GetImageBase(); + dseg->jtab[JTAB_EFN_STA] = _ExportFromName + pefile.GetImageBase(); + dseg->jtab[JTAB_KNO_DLL] = _IsKnownDLL + pefile.GetImageBase(); + //exportfromx patch DWORD code = (DWORD) pefile.GetSectionByName(CODE_SEG); int code_size = pefile.GetSectionSize(CODE_SEG); @@ -488,6 +519,11 @@ void Setup::install() if (efo_cnt != 2 || efn_cnt != 2) ShowError(IDS_ERRCHECK); + //isknowndll patch + set_call_ref(IsKnownDLL_call, (DWORD) &cseg->jmp_stub[JTAB_KNO_DLL]); + DBGPRINTF(("KNO_DLL: address %08x\n", pefile.PointerToRva((void*) a) + + pefile.GetImageBase())); + // backup original file if (!upgrade) { diff --git a/setup/setup.dsp b/setup/setup.dsp index 848aae4..39c9dae 100644 --- a/setup/setup.dsp +++ b/setup/setup.dsp @@ -113,6 +113,10 @@ SOURCE=..\common\pemanip.h # End Source File # Begin Source File +SOURCE=.\resource.h +# End Source File +# Begin Source File + SOURCE=.\setup.h # End Source File # Begin Source File diff --git a/setup/setup.h b/setup/setup.h index 43143d8..51777db 100644 --- a/setup/setup.h +++ b/setup/setup.h @@ -38,12 +38,14 @@ private: string backup_file; DWORD _ExportFromOrdinal; DWORD _ExportFromName; + DWORD _IsKnownDLL; HMODULE h_kernel32; PEmanip pemem; PEmanip pefile; DWORD gpa_ExportFromOrdinal_call; DWORD gpa_ExportFromName_call; DWORD EFN_EFO_call; + DWORD IsKnownDLL_call; int version; bool is_winme; bool upgrade; @@ -56,6 +58,7 @@ private: void mod_imte_alloc(); void mod_pdb_alloc(); void find_ExportFromX(); + void find_IsKnownDLL(); DWORD find_ExportFromOrdinal(); DWORD find_ExportFromName(); void kill_process(const char* name); diff --git a/setup/setup.rc b/setup/setup.rc index 9afb89c..96a76fc 100644 --- a/setup/setup.rc +++ b/setup/setup.rc @@ -35,7 +35,7 @@ BEGIN IDS_FAILSEC "ERROR: Failed to allocate %s section memory" IDS_FAILBAK "ERROR: Failed to create backup in %s" IDS_ERRCHECK "ERROR: Checksum error" - IDS_INVSTUB "ERROR: Invalid stub version found: %d. Possibly newer KernelEx. Aborting." + IDS_FAILOPENBACKUP "ERROR: Failed to open backup file %s.\nPossible causes: previous version not uninstalled correctly or file has been deleted.\nRestore %s manually from install media." IDS_WINVER "Incompatible Windows version" END