PE文件rebase失败

时间:2016-08-16 09:32:54

标签: c windows winapi portable-executable

这是我的问题。

我正在打包一个包装工。这个打包器可以从内存中运行程序。实际上,这部分有效。但有时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(&section
                , (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;
}

我知道代码不正确,我在这里是沙箱模式^^

提前感谢您的挚爱。

0 个答案:

没有答案