mirror of
https://github.com/UzixLS/KernelEx.git
synced 2025-07-19 07:21:20 +03:00
import KernelEx-4.5-RC5
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2010, Tihiy
|
||||
* Copyright (C) 2008, Xeno86
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
@ -20,6 +21,73 @@
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include "kexcoresdk.h"
|
||||
#include "kstructs.h"
|
||||
#include "k32ord.h"
|
||||
|
||||
#define RELTOABS(x) ( (DWORD)(x) + *(DWORD*)(x) + 4 )
|
||||
#define MAPHANDLE_MAPPED 0x1000
|
||||
|
||||
/*
|
||||
* A bit of mapping file 9x rules:
|
||||
* copy-on-write access is possible to file mappings created with
|
||||
* PAGE_WRITECOPY. Note that it makes sense only to real files.
|
||||
* If you CreateFileMapping on INVALID_HANDLE_VALUE with PAGE_WRITECOPY
|
||||
* you will get mapping handle which can be only mapped with FILE_MAP_READ
|
||||
* PAGE_READONLY can be mapped only with FILE_MAP_READ, end of story
|
||||
* PAGE_READWRITE can be mapped with any FILE_MAP_READ or FILE_MAP_WRITE
|
||||
* but not FILE_MAP_COPY; however FILE_MAP_ALL_ACCESS is fine
|
||||
* kernel checks exactly for it, other masks with FILE_MAP_COPY will fail.
|
||||
*
|
||||
* Office 2003 workaround is hack for specific access mask which breaks
|
||||
* that FILE_MAP_COPY rule
|
||||
*/
|
||||
|
||||
#define FILE_MAP_OFFICE2003 (SECTION_QUERY | SECTION_MAP_WRITE | \
|
||||
SECTION_MAP_READ | SECTION_MAP_EXECUTE | \
|
||||
SECTION_EXTEND_SIZE | READ_CONTROL)
|
||||
|
||||
//MapHandle: maps kernel handle to object
|
||||
static PVOID MapHandle(HANDLE hObject, DWORD dwFlags, DWORD dwReserved)
|
||||
{
|
||||
typedef PDWORD (WINAPI *MapHandle_t)(HANDLE,DWORD,DWORD);
|
||||
static MapHandle_t KernelMapHandle;
|
||||
if (!KernelMapHandle)
|
||||
KernelMapHandle = (MapHandle_t)RELTOABS((DWORD)kexGetProcAddress(
|
||||
GetModuleHandle("KERNEL32.DLL"),"OpenVxDHandle")+0xC);
|
||||
return KernelMapHandle(hObject,dwFlags,dwReserved);
|
||||
}
|
||||
|
||||
static LPVOID GetMapViewAddress(HANDLE hFileMapping)
|
||||
{
|
||||
PVOID ret = (PVOID)-1;
|
||||
PFILEMAPPING mapobj;
|
||||
static CRITICAL_SECTION* k32lock;
|
||||
if (!k32lock)
|
||||
k32lock = (CRITICAL_SECTION*) kexGetK32Lock();
|
||||
_EnterSysLevel(k32lock);
|
||||
mapobj = (PFILEMAPPING)MapHandle(hFileMapping,MAPHANDLE_MAPPED,0);
|
||||
if (mapobj && mapobj->type == WIN98_K32OBJ_MEM_MAPPED_FILE)
|
||||
ret = mapobj->mapaddr;
|
||||
_LeaveSysLevel(k32lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD FindSharedMem64K(DWORD StartAddress)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
DWORD TryAddress = StartAddress;
|
||||
while (true)
|
||||
{
|
||||
if (TryAddress & 0x0FFFF) //64K align
|
||||
TryAddress = (TryAddress & 0xFFFF0000) + 0x10000;
|
||||
if ( !VirtualQuery((PVOID)TryAddress,&mbi,sizeof(mbi)) ) return NULL;
|
||||
if (mbi.State == MEM_FREE)
|
||||
return TryAddress;
|
||||
TryAddress = (DWORD)mbi.BaseAddress + (DWORD)mbi.RegionSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* MAKE_EXPORT MapViewOfFileEx_new=MapViewOfFileEx */
|
||||
LPVOID WINAPI MapViewOfFileEx_new(
|
||||
@ -39,6 +107,57 @@ LPVOID WINAPI MapViewOfFileEx_new(
|
||||
{
|
||||
lpBaseAddress = 0;
|
||||
}
|
||||
return MapViewOfFileEx(hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh,
|
||||
dwFileOffsetLow, dwNumberOfBytesToMap, lpBaseAddress);
|
||||
|
||||
LPVOID ret = NULL;
|
||||
if ( dwDesiredAccess == FILE_MAP_OFFICE2003 )
|
||||
{
|
||||
DBGPRINTF(("KEX: Using 64K align workaround on memmap handle %p\n",
|
||||
hFileMappingObject));
|
||||
//was it already mapped?
|
||||
LPVOID oldmapaddr = GetMapViewAddress(hFileMappingObject);
|
||||
if (oldmapaddr == (LPVOID)-1)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return NULL;
|
||||
}
|
||||
if (oldmapaddr) //if it was, try that address first
|
||||
ret = MapViewOfFileEx(hFileMappingObject,FILE_MAP_ALL_ACCESS,
|
||||
dwFileOffsetHigh,dwFileOffsetLow,dwNumberOfBytesToMap,oldmapaddr);
|
||||
//search shared memory piece, skipping 64K to not deadloop
|
||||
DWORD mem64K = 0x81000000;
|
||||
while (!ret)
|
||||
{
|
||||
mem64K = FindSharedMem64K(mem64K + 0x10000);
|
||||
if (!mem64K)
|
||||
{
|
||||
DBGPRINTF(("KEX: Failed to find memory for mapping handle %p!",
|
||||
hFileMappingObject));
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
DWORD gle = GetLastError();
|
||||
SetLastError(0);
|
||||
ret = MapViewOfFileEx(hFileMappingObject,FILE_MAP_ALL_ACCESS,dwFileOffsetHigh,
|
||||
dwFileOffsetLow,dwNumberOfBytesToMap,(LPVOID)mem64K);
|
||||
if ( GetLastError() == ERROR_INVALID_PARAMETER ) //not according to plan
|
||||
return NULL;
|
||||
else
|
||||
SetLastError(gle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = MapViewOfFileEx(hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh,
|
||||
dwFileOffsetLow, dwNumberOfBytesToMap, lpBaseAddress);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT MapViewOfFile_new=MapViewOfFile */
|
||||
LPVOID WINAPI MapViewOfFile_new( HANDLE hFileMappingObject, DWORD dwDesiredAccess,
|
||||
DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap )
|
||||
{
|
||||
return MapViewOfFileEx_new(hFileMappingObject, dwDesiredAccess,
|
||||
dwFileOffsetHigh, dwFileOffsetLow, dwNumberOfBytesToMap, NULL);
|
||||
}
|
||||
|
Reference in New Issue
Block a user