I have been having trouble loading and executing a PE executable. I load the PE into memory, check the magic numbers and signature. When I try to jump to the entry point, I get an invalid OPCODE error. I have stripped the code down to the bare essentials, commenting out relocations (and loading the PE to preferred PE address) and loading to a set address instead of using my heap. I have include the function below (without the relocation method since it is commented out and without the checking method since that works fine (all values are valid).
Code: Select all
bool PE::RunExecutable(char* path)
{
//Data
PE::Private::DOSHeader* dos;
PE::Private::NTHeaders* nt;
dword ImageBase;
dword OldImageBase;
dword EntryPoint;
dword RelocationTable;
//Code
File::FILE* hos = File::Open(path);
if (hos->Flags != 1)
{
if (hos->Flags != 0)
{
Heap::Free(hos);
return false;
}
return false;
}
void* hosPE = (void*)0x500000;
if (hosPE == 0)
return false;
ImageBase = (dword)hosPE;
File::Read(hos, hosPE);
File::Close(hos);
dos = (PE::Private::DOSHeader*)hosPE;
nt = (PE::Private::NTHeaders*)(dos->EXEHeader + ImageBase);
OldImageBase = nt->OptionalHeader.ImageBase;
if (!PE::Private::CheckPE(nt, hosPE))
return false;
EntryPoint = nt->OptionalHeader.AddrOfEntry + ImageBase;
RelocationTable = nt->DataDirs[5].RVA + ImageBase;
//Relocate
//if (!PE::Private::RelocatePE(ImageBase, OldImageBase, RelocationTable, nt->DataDirs[5].Size))
//{
// Heap::Free(hosPE);
// return false;
//}
Video::NewLine();Video::NewLine();
Video::PrintNumber(ImageBase, 16);
Video::Print("\nd\n");
Video::PrintNumber(OldImageBase, 16);
Keyboard::WaitForKeyDown();
_asm
{
push ss;
push esp;
pushfd;
push cs;
push [EntryPoint];
iretd;
}
Heap::Free(hosPE);
return true;
}
Code: Select all
typedef unsigned char byte;
void HosMain()
{
byte* VidMem = (byte*)0xB8000;
*VidMem = '~';
VidMem++;
*VidMem = '45';
VidMem++;
*VidMem = '>';
VidMem++;
for (;;);
}