1
0
mirror of https://github.com/UzixLS/KernelEx.git synced 2025-07-18 23:11:19 +03:00
Files
KernelEx/vxd/pemanip.cpp
2018-11-03 16:24:01 +03:00

201 lines
4.7 KiB
C++
Executable File

/*
* KernelEx
* Copyright (C) 2008-2009, 2011, 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>
extern "C" {
#define WANTVXDWRAPS
#include <vmm.h>
#include <vxdwraps.h>
};
PEmanip::PEmanip()
{
ZeroInit();
}
PEmanip::PEmanip(void* memory)
{
ZeroInit();
OpenMemory(memory);
}
void PEmanip::ZeroInit()
{
MZh = NULL;
PEh = NULL;
section_hdrs = NULL;
target_len = 0;
image_base = 0;
has_target = false;
}
void PEmanip::Close()
{
ZeroInit();
}
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;
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;
}
IMAGE_SECTION_HEADER* PEmanip::FindSectionByName(const char* name)
{
IMAGE_SECTION_HEADER* section = section_hdrs;
for (int i = 0 ; i < PEh->FileHeader.NumberOfSections ; i++)
{
if (!strncmp((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;
}
DWORD PEmanip::GetSectionSize(const char* name)
{
IMAGE_SECTION_HEADER* section = FindSectionByName(name);
if (section)
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(("Allocating space in section '%s' avail: %d needed: %d",
name, available_space, needed_space));
if (available_space < needed_space)
{
DBGPRINTF(("Not enough space in section!"));
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;
}
void* PEmanip::CreateBackup()
{
if (!has_target)
return NULL;
void* mem = _HeapAllocate(target_len, HEAPSWAP);
memcpy(mem, MZh, target_len);
return mem;
}