这是我的问题。
我正在打包一个包装工。这个打包器可以从内存中运行程序。实际上,这部分有效。但有时VirtualAllocEx会返回无效地址,因为程序没有足够的连续空间(程序是可执行的PE x86文件。
它作为打包者的资源嵌入)。所以我需要重新分配/重新分配/ Fixeup /无论你使用的名称是什么:)。但它不起作用。 PerformeRebase方法失败。
这里我得到偏移它没关系:0x16000(就像我在pe资源管理器程序中打开我的pe文件一样)
DWORD dwVa = pPE-> OptionalHeader.DataDirectory [IMAGE_DIRECTORY_ENTRY_BASERELOC] .VirtualAddress;
这里我有一个尺寸:3564没关系
DWORD dwCb = pPE-> OptionalHeader.DataDirectory [IMAGE_DIRECTORY_ENTRY_BASERELOC] .Size;
但是在pBR中,VirtualAddress = 0和SizeOfBlock = 0所以有一个问题,因为有一个.reloc部分,我在pe explorer程序中看到它。
PIMAGE_BASE_RELOCATION pBR = MakePtr(PIMAGE_BASE_RELOCATION,lpAddress,dwVa);
所以我想知道为什么它不起作用,是因为我在调用此方法后复制了该部分?如果是这样的话,我不明白我必须按什么顺序这样做,我对所有地址都有点混淆。
以下是代码:
rebase:
#define MakePtr( cast, ptr, addValue ) (cast)( (DWORD)(ptr) + (addValue) )
BOOL PerformRebase(LPVOID lpAddress, DWORD dwNewBase)
{
PIMAGE_DOS_HEADER pDH = (PIMAGE_DOS_HEADER)lpAddress;
if (pDH->e_magic != IMAGE_DOS_SIGNATURE)
return FALSE;
PIMAGE_NT_HEADERS pPE = (PIMAGE_NT_HEADERS)((char *)pDH + pDH->e_lfanew);
if (pPE->Signature != IMAGE_NT_SIGNATURE)
return FALSE;
DWORD dwDelta = dwNewBase - pPE->OptionalHeader.ImageBase;
DWORD dwVa = pPE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
DWORD dwCb = pPE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
PIMAGE_BASE_RELOCATION pBR = MakePtr(PIMAGE_BASE_RELOCATION, lpAddress, dwVa);
UINT c = 0;
while (c < dwCb)
{
c += pBR->SizeOfBlock;
int RelocCount = (pBR->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
LPVOID lpvBase = MakePtr(LPVOID, lpAddress, pBR->VirtualAddress);
WORD *areloc = MakePtr(LPWORD, pBR, sizeof(IMAGE_BASE_RELOCATION));
for (int i = 0; i < RelocCount; i++)
{
int type = areloc[i] >> 12;
if (type == IMAGE_REL_BASED_ABSOLUTE)
continue;
if (type != IMAGE_REL_BASED_HIGHLOW)
{
return FALSE;
}
int ofs = areloc[i] & 0x0fff;
DWORD *pReloc = MakePtr(DWORD *, lpvBase, ofs);
if (*pReloc - pPE->OptionalHeader.ImageBase > pPE->OptionalHeader.SizeOfImage)
{
return FALSE;
}
*pReloc += dwDelta;
}
pBR = MakePtr(PIMAGE_BASE_RELOCATION, pBR, pBR->SizeOfBlock);
}
pPE->OptionalHeader.ImageBase = dwNewBase;
return TRUE;
}
运行方法:
BOOL WINAPI Run(LPVOID pImage, char* pPath)
{
PIMAGE_NT_HEADERS pim;
IMAGE_NT_HEADERS INH;
IMAGE_DOS_HEADER IDH;
IMAGE_SECTION_HEADER section;
SECURITY_ATTRIBUTES secAttrib;
PROCESS_INFORMATION peProcessInformation;
STARTUPINFO peStartUpInformation;
CONTEXT pContext;
DWORD dwSectionCount;
DWORD dwImageSize;
memcpy(&IDH, pImage, sizeof(IDH));
memcpy(&INH, (void*)((DWORD)pImage + IDH.e_lfanew), sizeof(INH));
/* Sanity check : see if MZ */
if (IDH.e_magic != IMAGE_DOS_SIGNATURE)
{
return FALSE;
}
if (INH.Signature != IMAGE_NT_SIGNATURE)
{
return FALSE;
}
memset(&peStartUpInformation, 0, sizeof(STARTUPINFO));
memset(&peProcessInformation, 0, sizeof(PROCESS_INFORMATION));
memset(&pContext, 0, sizeof(CONTEXT));
HMODULE hModule = LoadLibrary("C:\\Windows\\System32\\ntdll.dll");
PGNSI pGNSI;
WVM pWVM;
int re;
pGNSI = (PGNSI) GetProcAddress(hModule, "NtUnmapViewOfSection");
pWVM = (WVM) GetProcAddress(hModule, "NtWriteVirtualMemory");
void* newImageBase;
if (CreateProcess(NULL, pPath, NULL, NULL, false, CREATE_SUSPENDED, NULL, NULL,
&peStartUpInformation, &peProcessInformation))
{
//re = pGNSI(peProcessInformation.hProcess, (DWORD*)INH.OptionalHeader.ImageBase);
if ((newImageBase = VirtualAllocEx(peProcessInformation.hProcess, (DWORD*)INH.OptionalHeader.ImageBase, INH.OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)) == 0)
{
if ((newImageBase = VirtualAllocEx(peProcessInformation.hProcess, NULL, INH.OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)) == 0)
{
FreeLibrary(hModule);
TerminateProcess(peProcessInformation.hProcess, 1);
int i = GetLastError();
printf("GLE : %d", i);
Sleep(5000);
Run(pImage, pPath);
return FALSE;
}
else
{
//pim = (PIMAGE_NT_HEADERS)((DWORD)pImage + IDH.e_lfanew);
//pe_perform_base_reloc((char*)pImage, pim, (unsigned long)((char*)newImageBase - INH.OptionalHeader.ImageBase));
PerformRebase(pImage, (DWORD)newImageBase);
}
}
re = pWVM(peProcessInformation.hProcess, (DWORD*)INH.OptionalHeader.ImageBase
, pImage, INH.OptionalHeader.SizeOfHeaders, 0);
for (dwSectionCount = 0; dwSectionCount < INH.FileHeader.NumberOfSections; dwSectionCount++)
{
memcpy(§ion
, (void*)((DWORD)pImage + IDH.e_lfanew + sizeof(IMAGE_NT_HEADERS) + (sizeof(IMAGE_SECTION_HEADER) * dwSectionCount))
, sizeof(section));
re = pWVM(peProcessInformation.hProcess
, (DWORD*)(INH.OptionalHeader.ImageBase + section.VirtualAddress)
,(char*)pImage + section.PointerToRawData, section.SizeOfRawData,0);
}
pContext.ContextFlags = CONTEXT_FULL;
GetThreadContext(peProcessInformation.hThread, &pContext);
BOOL res = WriteProcessMemory(peProcessInformation.hProcess,
(void*)(pContext.Ebx + 8), &(INH.OptionalHeader.ImageBase), 4, 0);
pContext.Eax = INH.OptionalHeader.ImageBase + INH.OptionalHeader.AddressOfEntryPoint;
SetThreadContext(peProcessInformation.hThread, &pContext);
ResumeThread(peProcessInformation.hThread);
WaitForSingleObject(peProcessInformation.hProcess, INFINITE);
CloseHandle(peProcessInformation.hProcess);
CloseHandle(peProcessInformation.hThread);
}
return TRUE;
}
我知道代码不正确,我在这里是沙箱模式^^
提前感谢您的挚爱。