mirror of
https://github.com/UzixLS/KernelEx.git
synced 2025-07-18 23:11:19 +03:00
import KernelEx-4.0-RC1
This commit is contained in:
19
common/is_sorted.hpp
Normal file
19
common/is_sorted.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
template<typename FI>
|
||||
inline bool is_sorted(FI begin, FI end)
|
||||
{
|
||||
return is_sorted_until(begin, end) == end;
|
||||
}
|
||||
|
||||
template<typename FI>
|
||||
FI is_sorted_until(FI begin, FI end)
|
||||
{
|
||||
if (begin == end)
|
||||
return end;
|
||||
|
||||
FI next = begin;
|
||||
for (++next ; next != end ; begin = next, ++next)
|
||||
if (*next < *begin)
|
||||
return next;
|
||||
|
||||
return end;
|
||||
}
|
196
common/kexcoresdk.h
Normal file
196
common/kexcoresdk.h
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/** KernelEx Core SDK. */
|
||||
|
||||
|
||||
#ifndef __KEXCORESDK_H
|
||||
#define __KEXCORESDK_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef KEXCORE_EXPORTS
|
||||
#define _KEXCOREIMP __declspec(dllexport)
|
||||
#else
|
||||
#define _KEXCOREIMP __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Every api library has to export the following functions:
|
||||
*
|
||||
*
|
||||
* const apilib_api_table* get_api_table()
|
||||
*
|
||||
* Function should return pointer to api tables provided by the library.
|
||||
* Function will be called when KernelEx Core builds new api
|
||||
* configuration table, but only if the library hasn't been loaded yet.
|
||||
* Named api and ordinal api tables have to be sorted in ascending order,
|
||||
* according to operator< rules below.
|
||||
* After the last api table there has to be a closing NULL entry
|
||||
* (all fields set to zeros).
|
||||
* Multiple apis with same names and ordinal numbers are allowed in single
|
||||
* api library. However only one api with given name or ordinal will be
|
||||
* included in single api configuration. It is possible to specify which
|
||||
* api should be used in core.ini configuration file.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/** Convenience macro for defining apis. */
|
||||
#define DECL_API(name_ord,func) { name_ord, (unsigned long) func }
|
||||
/** Convenience macro for defining tables. */
|
||||
#define DECL_TAB(lib,named,unnamed) { lib, named, sizeof(named) / sizeof(apilib_named_api), unnamed, sizeof(unnamed) / sizeof(apilib_unnamed_api) }
|
||||
|
||||
|
||||
/** apilib_named_api - named api structure. */
|
||||
typedef struct _apilib_named_api
|
||||
{
|
||||
const char* name; /**< Api name. */
|
||||
unsigned long addr; /**< Api address. */
|
||||
} apilib_named_api;
|
||||
|
||||
|
||||
/** apilib_unnamed_api - unnamed api structure. */
|
||||
typedef struct _apilib_unnamed_api
|
||||
{
|
||||
unsigned short ord; /**< Api ordinal number. */
|
||||
unsigned long addr; /**< Api address. */
|
||||
} apilib_unnamed_api;
|
||||
|
||||
|
||||
/** apilib_api_table - api table structure. */
|
||||
typedef struct _apilib_api_table
|
||||
{
|
||||
const char* target_library; /**< DLL library for which the apis are defined. */
|
||||
const apilib_named_api* named_apis; /**< Pointer to table of named apis. */
|
||||
int named_apis_count; /**< Number of named apis in the table. */
|
||||
const apilib_unnamed_api* ordinal_apis; /**< Pointer to table of unnamed apis. */
|
||||
int ordinal_apis_count; /**< Number of unnamed apis in the table. */
|
||||
} apilib_api_table;
|
||||
|
||||
|
||||
/** Type definition for get_api_table() function. */
|
||||
typedef const apilib_api_table* (* fgat_t)();
|
||||
|
||||
|
||||
/** kexGetKEXVersion - obtain KernelEx Core version
|
||||
*
|
||||
* Returned value is KernelEx version number encoded as follows:
|
||||
* 0xHHLLRRRR, where:
|
||||
* HH - major version number
|
||||
* LL - minor version number
|
||||
* RRRR - revision number
|
||||
*/
|
||||
_KEXCOREIMP unsigned long kexGetKEXVersion();
|
||||
|
||||
|
||||
/** kexDebugPrint - output debug information
|
||||
*
|
||||
* Parameters are compatible with printf command,
|
||||
* maximum output length is limited to 256 bytes.
|
||||
*/
|
||||
_KEXCOREIMP void kexDebugPrint(const char* format, ...);
|
||||
|
||||
|
||||
/** kexGetVersion - obtain original Windows version number.
|
||||
*
|
||||
* Refer to GetVersion API documentation for parameters and output.
|
||||
*/
|
||||
_KEXCOREIMP DWORD kexGetVersion();
|
||||
|
||||
|
||||
/** kexGetProcAddress - obtain original address of DLL library function.
|
||||
*
|
||||
* Refer to GetProcAddress API documentation for parameters and output.
|
||||
*/
|
||||
_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.
|
||||
*/
|
||||
_KEXCOREIMP void* kexPIDtoPDB(DWORD pid);
|
||||
|
||||
|
||||
/** kexTIDtoTDB - obtain pointer to thread database entry, given thread identifier.
|
||||
*
|
||||
* @param tid Thread identifier.
|
||||
* @return Pointer to thread database entry on success, NULL on failure.
|
||||
*/
|
||||
_KEXCOREIMP void* kexTIDtoTDB(DWORD tid);
|
||||
|
||||
|
||||
/** kexGetModuleSettings - Retrieve per module settings.
|
||||
*
|
||||
* @param module Module path.
|
||||
* @param conf_name Receives configuration name, has to be at least 256 bytes long.
|
||||
* @param ldr_flags Receives flags.
|
||||
*/
|
||||
_KEXCOREIMP void kexGetModuleSettings(const char* module,
|
||||
char* conf_name, BYTE* ldr_flags);
|
||||
|
||||
|
||||
/** kexSetModuleSettings - Set per module settings.
|
||||
*
|
||||
* @param module Module path.
|
||||
* @param conf_name Configuration name to be set for the module.
|
||||
* @param ldr_flags Flags to be set for the module.
|
||||
*/
|
||||
_KEXCOREIMP void kexSetModuleSettings(const char* module,
|
||||
const char* conf_name, BYTE ldr_flags);
|
||||
|
||||
|
||||
/** kexFlushAppSettings - Reloads all module settings from registy. */
|
||||
_KEXCOREIMP void kexFlushAppSettings(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}; /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
|
||||
/** Comparison operator used to order named api entries. */
|
||||
inline bool operator<(const apilib_named_api& a, const apilib_named_api& b)
|
||||
{
|
||||
return strcmp(a.name, b.name) < 0;
|
||||
}
|
||||
|
||||
|
||||
/** Comparison operator used to order unnamed api entries. */
|
||||
inline bool operator<(const apilib_unnamed_api& a, const apilib_unnamed_api& b)
|
||||
{
|
||||
return a.ord < b.ord;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
435
common/pemanip.cpp
Normal file
435
common/pemanip.cpp
Normal file
@ -0,0 +1,435 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2008-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 "pemanip.h"
|
||||
#include "debug.h"
|
||||
#include <cstring>
|
||||
|
||||
PEmanip::PEmanip()
|
||||
{
|
||||
ZeroInit();
|
||||
}
|
||||
|
||||
PEmanip::PEmanip(const char* file_path, int add_size)
|
||||
{
|
||||
ZeroInit();
|
||||
OpenFile(file_path, add_size);
|
||||
}
|
||||
|
||||
PEmanip::PEmanip(void* memory)
|
||||
{
|
||||
ZeroInit();
|
||||
OpenMemory(memory);
|
||||
}
|
||||
|
||||
PEmanip::~PEmanip()
|
||||
{
|
||||
if (file_buf)
|
||||
HeapFree(GetProcessHeap(), 0, file_buf);
|
||||
if (file_path)
|
||||
HeapFree(GetProcessHeap(), 0, file_path);
|
||||
}
|
||||
|
||||
void PEmanip::ZeroInit()
|
||||
{
|
||||
file_buf = NULL;
|
||||
file_path = NULL;
|
||||
MZh = NULL;
|
||||
PEh = NULL;
|
||||
section_hdrs = NULL;
|
||||
target_len = 0;
|
||||
max_target_len = 0;
|
||||
image_base = 0;
|
||||
has_target = false;
|
||||
}
|
||||
|
||||
bool PEmanip::HasTarget()
|
||||
{
|
||||
return has_target;
|
||||
}
|
||||
|
||||
IMAGE_NT_HEADERS* PEmanip::GetPEHeader()
|
||||
{
|
||||
return PEh;
|
||||
}
|
||||
|
||||
int PEmanip::GetFileSize(const char* file_path)
|
||||
{
|
||||
HANDLE file = CreateFile(file_path, GENERIC_READ, FILE_SHARE_READ,
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
int file_size = -1;
|
||||
if (file != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
file_size = ::GetFileSize(file, NULL);
|
||||
CloseHandle(file);
|
||||
}
|
||||
return file_size;
|
||||
}
|
||||
|
||||
bool PEmanip::LoadFile(const char* file_path, int add_size)
|
||||
{
|
||||
void* buf = NULL;
|
||||
int buf_len;
|
||||
HANDLE file;
|
||||
int bytes_read;
|
||||
bool ret = false;
|
||||
|
||||
if (!file_path || add_size < 0)
|
||||
return false;
|
||||
|
||||
buf_len = GetFileSize(file_path);
|
||||
if (buf_len > 0)
|
||||
{
|
||||
buf = HeapAlloc(GetProcessHeap(), 0, buf_len + add_size);
|
||||
if (buf)
|
||||
{
|
||||
file = CreateFile(file_path, GENERIC_READ, FILE_SHARE_READ,
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (file != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (ReadFile(file, buf, buf_len, (DWORD*) &bytes_read, NULL)
|
||||
&& bytes_read == buf_len)
|
||||
{
|
||||
this->file_path = (char*) HeapAlloc(GetProcessHeap(),
|
||||
0, strlen(file_path) + 1);
|
||||
this->target_len = buf_len;
|
||||
this->file_buf = buf;
|
||||
this->max_target_len = buf_len + add_size;
|
||||
if (this->file_path)
|
||||
{
|
||||
strcpy(this->file_path, file_path);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
CloseHandle(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret && buf)
|
||||
HeapFree(GetProcessHeap(), 0, buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool PEmanip::SaveFile(const char* file_path)
|
||||
{
|
||||
HANDLE file;
|
||||
int bytes_written;
|
||||
bool ret = false;
|
||||
|
||||
if (!file_path || !file_buf)
|
||||
return false;
|
||||
|
||||
file = CreateFile(file_path, GENERIC_WRITE, 0, NULL,
|
||||
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (WriteFile(file, file_buf, target_len, (DWORD*) &bytes_written, NULL)
|
||||
&& bytes_written == target_len)
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
CloseHandle(file);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PEmanip::Close()
|
||||
{
|
||||
if (file_buf)
|
||||
HeapFree(GetProcessHeap(), 0, file_buf);
|
||||
if (file_path)
|
||||
HeapFree(GetProcessHeap(), 0, file_path);
|
||||
|
||||
ZeroInit();
|
||||
}
|
||||
|
||||
int PEmanip::GetBufferLen()
|
||||
{
|
||||
return target_len;
|
||||
}
|
||||
|
||||
bool PEmanip::SetBufferLen(int new_size)
|
||||
{
|
||||
if (new_size >= max_target_len)
|
||||
return false;
|
||||
|
||||
if (new_size < target_len)
|
||||
return false;
|
||||
|
||||
target_len = new_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned long PEmanip::ALIGN(unsigned long x, unsigned long y)
|
||||
{
|
||||
return (x + y - 1) & (~(y - 1));
|
||||
}
|
||||
|
||||
bool PEmanip::OpenFile(const char* file_path, int add_size)
|
||||
{
|
||||
if (has_target)
|
||||
return false;
|
||||
|
||||
if (LoadFile(file_path, add_size))
|
||||
{
|
||||
MZh = (IMAGE_DOS_HEADER*) file_buf;
|
||||
|
||||
if (MZh->e_magic == IMAGE_DOS_SIGNATURE)
|
||||
{
|
||||
PEh = (IMAGE_NT_HEADERS*) ((DWORD) MZh + MZh->e_lfanew);
|
||||
if ((PEh->Signature == IMAGE_NT_SIGNATURE)
|
||||
&& (PEh->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
|
||||
&& (PEh->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR_MAGIC))
|
||||
{
|
||||
section_hdrs = (IMAGE_SECTION_HEADER*)
|
||||
((DWORD) PEh
|
||||
+ PEh->FileHeader.SizeOfOptionalHeader
|
||||
+ sizeof(IMAGE_FILE_HEADER)
|
||||
+ sizeof(DWORD));
|
||||
image_base = PEh->OptionalHeader.ImageBase;
|
||||
has_target = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PEmanip::OpenMemory(void* memory)
|
||||
{
|
||||
if (has_target)
|
||||
return false;
|
||||
|
||||
MZh = (IMAGE_DOS_HEADER*) memory;
|
||||
|
||||
if (MZh->e_magic == IMAGE_DOS_SIGNATURE)
|
||||
{
|
||||
PEh = (IMAGE_NT_HEADERS*) ((DWORD) MZh + MZh->e_lfanew);
|
||||
if ((PEh->Signature == IMAGE_NT_SIGNATURE)
|
||||
&& (PEh->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
|
||||
&& (PEh->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR_MAGIC))
|
||||
{
|
||||
section_hdrs = (IMAGE_SECTION_HEADER*)
|
||||
((DWORD) PEh
|
||||
+ PEh->FileHeader.SizeOfOptionalHeader
|
||||
+ sizeof(IMAGE_FILE_HEADER)
|
||||
+ sizeof(DWORD));
|
||||
image_base = (DWORD)memory;
|
||||
has_target = true;
|
||||
target_len = PEh->OptionalHeader.SizeOfImage;
|
||||
max_target_len = target_len;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
IMAGE_SECTION_HEADER* PEmanip::RvaToSection(DWORD Rva)
|
||||
{
|
||||
IMAGE_SECTION_HEADER* section = section_hdrs;
|
||||
|
||||
for (int i = 0 ; i < PEh->FileHeader.NumberOfSections ; i++)
|
||||
{
|
||||
if ((Rva >= section->VirtualAddress)
|
||||
&& (Rva < (section->VirtualAddress + section->Misc.VirtualSize)))
|
||||
{
|
||||
return section;
|
||||
}
|
||||
section++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* PEmanip::RvaToPointer(DWORD Rva)
|
||||
{
|
||||
if (!file_buf)
|
||||
return (void*)(Rva + image_base);
|
||||
|
||||
IMAGE_SECTION_HEADER* section = section_hdrs;
|
||||
|
||||
for (int i = 0 ; i < PEh->FileHeader.NumberOfSections ; i++)
|
||||
{
|
||||
if ((Rva >= section->VirtualAddress)
|
||||
&& (Rva < (section->VirtualAddress + section->Misc.VirtualSize)))
|
||||
{
|
||||
return (void*) (Rva - section->VirtualAddress
|
||||
+ section->PointerToRawData + (DWORD) MZh);
|
||||
}
|
||||
section++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD PEmanip::PointerToRva(void* pointer)
|
||||
{
|
||||
if (!file_buf)
|
||||
return (DWORD) pointer - image_base;
|
||||
|
||||
IMAGE_SECTION_HEADER* section = section_hdrs;
|
||||
DWORD offset;
|
||||
|
||||
if (pointer < MZh)
|
||||
return 0;
|
||||
|
||||
offset = (DWORD) pointer - (DWORD) MZh;
|
||||
|
||||
for (int i = 0 ; i < PEh->FileHeader.NumberOfSections ; i++)
|
||||
{
|
||||
if ((offset >= section->PointerToRawData)
|
||||
&& (offset < (section->PointerToRawData + section->SizeOfRawData)))
|
||||
{
|
||||
return offset - section->PointerToRawData
|
||||
+ section->VirtualAddress;
|
||||
}
|
||||
section++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
IMAGE_SECTION_HEADER* PEmanip::FindSectionByName(const char* name)
|
||||
{
|
||||
IMAGE_SECTION_HEADER* section = section_hdrs;
|
||||
|
||||
for (int i = 0 ; i < PEh->FileHeader.NumberOfSections ; i++)
|
||||
{
|
||||
if (!strnicmp((char*) section->Name, name, sizeof(section->Name)))
|
||||
return section;
|
||||
section++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* PEmanip::GetSectionByName(const char* name)
|
||||
{
|
||||
IMAGE_SECTION_HEADER* section = FindSectionByName(name);
|
||||
|
||||
if (section)
|
||||
return RvaToPointer(section->VirtualAddress);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int PEmanip::GetSectionSize(const char* name)
|
||||
{
|
||||
IMAGE_SECTION_HEADER* section = FindSectionByName(name);
|
||||
|
||||
if (section)
|
||||
if (file_buf)
|
||||
return section->SizeOfRawData;
|
||||
else
|
||||
return section->Misc.VirtualSize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool PEmanip::AllocSectionSpace(const char* name, int needed_space, void** ptr, int align)
|
||||
{
|
||||
IMAGE_SECTION_HEADER* Section = FindSectionByName(name);
|
||||
|
||||
if (!Section || align < 1 || needed_space < 0)
|
||||
return false;
|
||||
|
||||
if (!needed_space)
|
||||
return true;
|
||||
|
||||
DWORD current_size = ALIGN(Section->Misc.VirtualSize, align);
|
||||
DWORD new_size = current_size + needed_space;
|
||||
|
||||
DWORD max_size = (Section + 1)->VirtualAddress - Section->VirtualAddress;
|
||||
int available_space = max_size - current_size;
|
||||
|
||||
DBGPRINTF(("Bytes available: %d, ", available_space));
|
||||
DBGPRINTF(("Bytes needed: %d\n", needed_space));
|
||||
|
||||
if (available_space < needed_space)
|
||||
{
|
||||
DBGPRINTF(("Not enough space in section!\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (new_size > Section->SizeOfRawData)
|
||||
{
|
||||
int offset = ALIGN(new_size - Section->SizeOfRawData,
|
||||
PEh->OptionalHeader.FileAlignment);
|
||||
|
||||
DBGPRINTF(("Applying offset of %d\n", offset));
|
||||
|
||||
void* block_start = RvaToPointer((Section + 1)->VirtualAddress);
|
||||
int block_size = GetBufferLen() - (Section + 1)->PointerToRawData;
|
||||
|
||||
char* tmp = (char*)HeapAlloc(GetProcessHeap(), 0, block_size);
|
||||
memcpy(tmp, block_start, block_size);
|
||||
memcpy((void*)((int)block_start + offset), tmp, block_size);
|
||||
HeapFree(GetProcessHeap(), 0, tmp);
|
||||
memset(block_start, 0, offset);
|
||||
|
||||
// update offsets
|
||||
for (int i = 0 ; i < PEh->FileHeader.NumberOfSections ; i++)
|
||||
{
|
||||
if (§ion_hdrs[i] <= Section)
|
||||
continue;
|
||||
section_hdrs[i].PointerToRawData += offset;
|
||||
}
|
||||
Section->SizeOfRawData += offset;
|
||||
if (!SetBufferLen(GetBufferLen() + offset))
|
||||
return false;
|
||||
}
|
||||
|
||||
Section->Misc.VirtualSize = new_size;
|
||||
|
||||
if (ptr)
|
||||
*ptr = RvaToPointer(Section->VirtualAddress + current_size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD PEmanip::GetExportedAPI(const char* func)
|
||||
{
|
||||
IMAGE_EXPORT_DIRECTORY* Exports = (IMAGE_EXPORT_DIRECTORY*)
|
||||
RvaToPointer(PEh->OptionalHeader
|
||||
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
|
||||
|
||||
if (Exports)
|
||||
{
|
||||
DWORD* Names = (DWORD*) RvaToPointer(Exports->AddressOfNames);
|
||||
|
||||
for (DWORD i = 0 ; i < Exports->NumberOfNames ; i++)
|
||||
{
|
||||
if (!strcmp(func, (char*) RvaToPointer(*Names)))
|
||||
{
|
||||
WORD* OrdinalTable = (WORD*) RvaToPointer(Exports->AddressOfNameOrdinals);
|
||||
WORD Index = OrdinalTable[i];
|
||||
DWORD* FunctionTable = (DWORD*) RvaToPointer(Exports->AddressOfFunctions);
|
||||
DWORD Address = (DWORD) FunctionTable[Index];
|
||||
return Address;
|
||||
}
|
||||
Names++;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD PEmanip::GetImageBase()
|
||||
{
|
||||
return image_base;
|
||||
}
|
70
common/pemanip.h
Normal file
70
common/pemanip.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2008-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 _SETUP_PEMANIP_H
|
||||
#define _SETUP_PEMANIP_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <winnt.h>
|
||||
|
||||
class PEmanip
|
||||
{
|
||||
private:
|
||||
bool has_target;
|
||||
char* file_path;
|
||||
void* file_buf;
|
||||
int target_len;
|
||||
int max_target_len;
|
||||
IMAGE_DOS_HEADER* MZh;
|
||||
IMAGE_NT_HEADERS* PEh;
|
||||
IMAGE_SECTION_HEADER* section_hdrs;
|
||||
DWORD image_base;
|
||||
|
||||
void ZeroInit();
|
||||
int GetFileSize(const char* file_path);
|
||||
bool LoadFile(const char* file_path, int add_size);
|
||||
int GetBufferLen();
|
||||
bool SetBufferLen(int new_size);
|
||||
static unsigned long ALIGN(unsigned long x, unsigned long y);
|
||||
IMAGE_SECTION_HEADER* FindSectionByName(const char* name);
|
||||
|
||||
public:
|
||||
PEmanip();
|
||||
PEmanip(const char* file_path, int add_size = 0);
|
||||
PEmanip(void* memory);
|
||||
~PEmanip();
|
||||
bool HasTarget();
|
||||
bool OpenFile(const char* file_path, int add_size = 0);
|
||||
bool OpenMemory(void* memory);
|
||||
bool SaveFile(const char* file_path);
|
||||
void Close();
|
||||
IMAGE_NT_HEADERS* GetPEHeader();
|
||||
IMAGE_SECTION_HEADER* RvaToSection(DWORD Rva);
|
||||
void* RvaToPointer(DWORD Rva);
|
||||
DWORD PointerToRva(void* pointer);
|
||||
void* GetSectionByName(const char* name);
|
||||
int GetSectionSize(const char* name);
|
||||
bool AllocSectionSpace(const char* name, int needed_space, void** ptr, int align = 1);
|
||||
DWORD GetExportedAPI(const char* func);
|
||||
DWORD GetImageBase();
|
||||
};
|
||||
|
||||
#endif
|
78
common/sstring.hpp
Normal file
78
common/sstring.hpp
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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 __SSTRING_HPP
|
||||
#define __SSTRING_HPP
|
||||
|
||||
#include <string.h>
|
||||
|
||||
class sstring
|
||||
{
|
||||
public:
|
||||
sstring(const char* src)
|
||||
{
|
||||
len = strlen(src);
|
||||
storage = new char[len + 1];
|
||||
strcpy(storage, src);
|
||||
}
|
||||
|
||||
sstring(const sstring& src)
|
||||
{
|
||||
len = src.len;
|
||||
storage = new char[len + 1];
|
||||
strcpy(storage, src.storage);
|
||||
}
|
||||
|
||||
~sstring()
|
||||
{
|
||||
delete [] storage;
|
||||
}
|
||||
|
||||
sstring& operator=(const sstring& src)
|
||||
{
|
||||
len = src.len;
|
||||
delete [] storage;
|
||||
storage = new char[len + 1];
|
||||
strcpy(storage, src.storage);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator<(const sstring& a) const
|
||||
{
|
||||
return strcmp(storage, a.storage) < 0;
|
||||
}
|
||||
|
||||
const char* get() const
|
||||
{
|
||||
return storage;
|
||||
}
|
||||
|
||||
int length() const
|
||||
{
|
||||
return len;
|
||||
}
|
||||
|
||||
private:
|
||||
int len;
|
||||
char* storage;
|
||||
};
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user