AngryPE-File Loader Bug

Posts 1–14 of 14 · Page 1 of 1
PE-File Loader Bug
Hello folks !!!!!!

I have a pe-file loader example which right now I am testing. But I face with the problem.
This piece of code does not allow me to load *.exe

Code:
// peloader.cpp : Defines the entry point for the application.
//

// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER                          // Specifies that the minimum required platform is Windows Vista.
#define WINVER 0x0600           // Change this to the appropriate value to target other versions of Windows.
#endif

#ifndef _WIN32_WINNT            // Specifies that the minimum required platform is Windows Vista.
#define _WIN32_WINNT 0x0600     // Change this to the appropriate value to target other versions of Windows.
#endif

#ifndef _WIN32_WINDOWS          // Specifies that the minimum required platform is Windows 98.
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
#endif

#ifndef _WIN32_IE                       // Specifies that the minimum required platform is Internet Explorer 7.0.
#define _WIN32_IE 0x0700        // Change this to the appropriate value to target other versions of IE.
#endif

#include <windows.h>
#include <cstdio>
#include <tchar.h>
#include <iostream>

#pragma code_seg(push,r1,".eccode")

#ifndef IMAGE_SIZEOF_BASE_RELOCATION
// Vista SDKs no longer define IMAGE_SIZEOF_BASE_RELOCATION!?
#define IMAGE_SIZEOF_BASE_RELOCATION (sizeof(IMAGE_BASE_RELOCATION))
#endif

#define SEH
#define spy_ExitProcess

#define ERR_IMAGE_IS_NOT_PE              1
#define ERR_IMAGE_NOT_VALLOC             2
#define ERR_IMAGE_NOT_HVALLOC            3
#define ERR_IMAGE_NOT_SVALLOC            4
#define ERR_IMAGE_NO_FIXUP               5
#define ERR_IMAGE_FIXUP_INVALID          6
#define ERR_IMAGE_SEC_PROTECTION_FAILED  7
#define ERR_IMAGE_NO_IMPORT              8
#define ERR_IMAGE_IMPLIB_NOT_LOADED      9

#define LDRP_RELOCATION_INCREMENT        0x1
#define LDRP_RELOCATION_FINAL            0x2

#define IMAGE_GET_DOSHEADER( lpbImage ) ((PIMAGE_DOS_HEADER)lpbImage)
#define IMAGE_GET_NTHEADER( lpbImage ) ((PIMAGE_NT_HEADERS32)((DWORD)lpbImage + IMAGE_GET_DOSHEADER(lpbImage)->e_lfanew))
#define IMAGE_IS_PE( lpbImage ) (IMAGE_GET_DOSHEADER(lpbImage)->e_magic == IMAGE_DOS_SIGNATURE ? \
    (IMAGE_GET_NTHEADER(lpbImage)->Signature == IMAGE_NT_SIGNATURE ? TRUE : FALSE) : FALSE)
#define IMAGE_GET_DIRECTORY( lpbImage, DIRECTORY_ID ) \
    (&IMAGE_GET_NTHEADER(lpbImage)->OptionalHeader.DataDirectory[DIRECTORY_ID])

// Global variable
HMODULE g_hLoadedModule = NULL;
#ifdef spy_ExitProcess
typedef VOID (WINAPI *_ExitProcess)(__in UINT uExitCode);
_ExitProcess g_ExitProcess = NULL;
LPDWORD g_ImpExitProcess = NULL;
#endif

typedef struct 
{
    WORD    wOffset:12;
    WORD    wType:4;
} IMAGE_FIXUP_ENTRY, *PIMAGE_FIXUP_ENTRY;

// Process Envorinment Block
typedef struct _PEB {
    DWORD smth[2]; // doesn't matter
    PVOID SectionBaseAddress;
} PEB, *PPEB;

// Thread Environment Block
typedef struct _TEB {
    DWORD smth[12]; // doesn't matter
    PPEB Peb;
} TEB, *PTEB;

typedef void (__cdecl *_mainCRTStartup)(void);

#ifdef _MSC_VER
#pragma function(memset)
#pragma function(memcpy)
#endif 

void * __cdecl memset (
        void *dst,
        int val,
        size_t count
        )
{
        void *start = dst;

        while (count--) {
                *(char *)dst = (char)val;
                dst = (char *)dst + 1;
        }

        return(start);
}

void * __cdecl memcpy (
        void * dst,
        const void * src,
        size_t count
        )
{
        void * ret = dst;

        while (count--) {
                *(char *)dst = *(char *)src;
                dst = (char *)dst + 1;
                src = (char *)src + 1;
        }

        return(ret);
}


VOID MessageGetLastError( HWND hWndParent, LPCTSTR szTitle )
{
  LPTSTR lpMsgBuf;
  if ( FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | 
                      FORMAT_MESSAGE_FROM_SYSTEM | 
                      FORMAT_MESSAGE_IGNORE_INSERTS,
                      NULL,
                      GetLastError(),
                      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                      (LPTSTR) &lpMsgBuf,
                      0,
                      NULL ) )
  {
    // Display the string.
    MessageBox( hWndParent, (LPCTSTR)lpMsgBuf, szTitle, MB_OK + MB_ICONERROR );
    // Free the buffer.
    LocalFree( lpMsgBuf );
  }
};

HMODULE PeLoadModule(LPBYTE lpbImage, LPDWORD lpdwError)
{
    if (lpdwError) *lpdwError = 0;
    if (IMAGE_IS_PE(lpbImage))
    {
        HMODULE lpbBase = (HMODULE) VirtualAlloc( NULL,
            //(LPVOID)IMAGE_GET_NTHEADER(lpbImage)->OptionalHeader.ImageBase,
            IMAGE_GET_NTHEADER(lpbImage)->OptionalHeader.SizeOfImage, 
            MEM_RESERVE, PAGE_EXECUTE_READWRITE );
        if (lpbBase)
        {
            // headers copy
            LPBYTE lpbHeaders = (LPBYTE) VirtualAlloc( lpbBase, 
                IMAGE_GET_NTHEADER(lpbImage)->OptionalHeader.SizeOfHeaders, 
                MEM_COMMIT, PAGE_EXECUTE_READWRITE );
            if(lpbHeaders)    
            {
                CopyMemory( lpbHeaders, lpbImage, IMAGE_GET_NTHEADER(lpbImage)->OptionalHeader.SizeOfHeaders );
                // section loading
                // macro IMAGE_FIRST_SECTION defined in WinNT.h
                PIMAGE_SECTION_HEADER pish = IMAGE_FIRST_SECTION(IMAGE_GET_NTHEADER(lpbImage)); 
                for (DWORD i=0;i<IMAGE_GET_NTHEADER(lpbImage)->FileHeader.NumberOfSections;i++,pish++)
                {
                    if (pish->VirtualAddress)
                    {
                        LPBYTE lpbSectionBase = (LPBYTE) VirtualAlloc(
                            (LPVOID)((DWORD)lpbBase+pish->VirtualAddress),
                            pish->Misc.VirtualSize,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
                        if (lpbSectionBase)
                        {
                            ZeroMemory(lpbSectionBase,pish->Misc.VirtualSize);
                            // macro min defined in WinDef.h
                            CopyMemory(lpbSectionBase, lpbImage + pish->PointerToRawData, 
                                min(pish->Misc.VirtualSize,pish->SizeOfRawData));
                        }
                        else if (lpdwError) *lpdwError = ERR_IMAGE_NOT_SVALLOC;
                    }
                }
				DWORD dwOldProtect = 0;
                VirtualProtect(lpbBase, 
                    IMAGE_GET_NTHEADER(lpbImage)->OptionalHeader.SizeOfHeaders, 
                    PAGE_EXECUTE_READWRITE, &dwOldProtect);

                return lpbBase;
            }
            else if (lpdwError) *lpdwError = ERR_IMAGE_NOT_HVALLOC;
        }
        else if (lpdwError) *lpdwError = ERR_IMAGE_NOT_VALLOC;
    }
    else if (lpdwError) *lpdwError = ERR_IMAGE_IS_NOT_PE;
    return 0;
}

DWORD PeUnloadModule()
{
    PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = 
        &IMAGE_GET_NTHEADER(g_hLoadedModule)->OptionalHeader;
    PIMAGE_DATA_DIRECTORY pDirectoryImport = 
        IMAGE_GET_DIRECTORY(g_hLoadedModule,IMAGE_DIRECTORY_ENTRY_IMPORT);
    if (pDirectoryImport->VirtualAddress)
    {
        PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)g_hLoadedModule + pDirectoryImport->VirtualAddress);
        // loop for IMAGE_IMPORT_DESCRIPTOR[]
        while (pImportDescriptor->Name)
        {
            TCHAR szModuleName[MINCHAR] = _TEXT("");
            #ifdef UNICODE
            MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, 
                (LPCSTR)((DWORD)g_hLoadedModule + pImportDescriptor->Name), -1, 
                szModuleName, MINCHAR );
            #else
            lstrcpy(szModuleName,(LPCSTR)((DWORD)hModule + pImportDescriptor->Name));
            #endif
            HMODULE hImpModule = ::GetModuleHandle(szModuleName);
//            if (hImpModule) ::FreeLibrary(hImpModule);
            // Next
            pImportDescriptor++;
        }
    }
    PIMAGE_SECTION_HEADER pish = IMAGE_FIRST_SECTION(IMAGE_GET_NTHEADER(g_hLoadedModule)); 
    for (DWORD i=0;i<IMAGE_GET_NTHEADER(g_hLoadedModule)->FileHeader.NumberOfSections;i++,pish++)
    {
        if (pish->VirtualAddress)
        {
            VirtualFree((LPVOID)((DWORD)g_hLoadedModule+pish->VirtualAddress),
                0,MEM_DECOMMIT);
        }
    }
    VirtualFree( g_hLoadedModule, 
        IMAGE_GET_NTHEADER(g_hLoadedModule)->OptionalHeader.SizeOfHeaders, 
        MEM_DECOMMIT);
    VirtualFree( g_hLoadedModule, 0, MEM_RELEASE );
    return 0;
}

#ifdef spy_ExitProcess
// spy
VOID WINAPI spyExitProcess(__in UINT uExitCode)
{
    DWORD dwOldProtection = 0;
    if (VirtualProtect((LPVOID)g_ImpExitProcess,sizeof(DWORD),
		PAGE_EXECUTE_READWRITE,&dwOldProtection))
    {
        *g_ImpExitProcess = (DWORD)g_ExitProcess;
        VirtualProtect((LPVOID)g_ImpExitProcess,sizeof(DWORD),
                dwOldProtection,&dwOldProtection);
    }
    PeUnloadModule();
    g_ExitProcess(uExitCode); // ПАДАЕТ ТУТ!!!
}
#endif

DWORD PeProcessRelocations(HMODULE hModule,LONG lImageBaseDelta)
{
    PIMAGE_FIXUP_ENTRY pFixup;
    PIMAGE_DATA_DIRECTORY pDirectoryBaseReloc = 
        IMAGE_GET_DIRECTORY(hModule,IMAGE_DIRECTORY_ENTRY_BASERELOC);
    if (pDirectoryBaseReloc->VirtualAddress)
    {
        PIMAGE_BASE_RELOCATION pRelocation = 
            (PIMAGE_BASE_RELOCATION)((DWORD)hModule + pDirectoryBaseReloc->VirtualAddress);

        DWORD dwRelocsSize = pDirectoryBaseReloc->Size;

        while (dwRelocsSize > 0)
        {
            dwRelocsSize -= pRelocation->SizeOfBlock;
            // Process current relocation block
            for (pFixup = (PIMAGE_FIXUP_ENTRY) 
                    (((LPBYTE) pRelocation) + IMAGE_SIZEOF_BASE_RELOCATION);
                (DWORD)pFixup < (DWORD)pRelocation + pRelocation->SizeOfBlock;
                pFixup++)
            {
                LPDWORD pFixupVA = NULL;
                DWORD t = 0;
                switch (pFixup->wType)
                {
                case IMAGE_REL_BASED_ABSOLUTE:
                    // no fixup required
                    break;
                case IMAGE_REL_BASED_HIGHLOW:
                    // HighLow - (32-bits) relocate the high and low half
                    // of an address.
                    pFixupVA = (LPDWORD) ((DWORD)hModule + pRelocation->VirtualAddress + 
                        pFixup->wOffset);
    
                    t = (DWORD)lImageBaseDelta;
                    *pFixupVA += t;

                    break;
                default:
                    return ERR_IMAGE_FIXUP_INVALID;
                }
            }
            pRelocation = (PIMAGE_BASE_RELOCATION)pFixup;
        }
    }
    else
        // Decided to load at different base, but no relocs present
        return ERR_IMAGE_NO_FIXUP;

    return 0;
}

DWORD PeProcessImports(HMODULE hModule)
{
#ifdef spy_ExitProcess
    WORD wEP = 0;
#endif
    PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = 
        &IMAGE_GET_NTHEADER(hModule)->OptionalHeader;
    PIMAGE_DATA_DIRECTORY pDirectoryImport = 
        IMAGE_GET_DIRECTORY(hModule,IMAGE_DIRECTORY_ENTRY_IMPORT);
    if (pDirectoryImport->VirtualAddress)
    {
        PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)hModule + pDirectoryImport->VirtualAddress);
        // loop for IMAGE_IMPORT_DESCRIPTOR[]
        while (pImportDescriptor->Name)
        {
            TCHAR szModuleName[MINCHAR] = _TEXT("");
            #ifdef UNICODE
            MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, 
                (LPCSTR)((DWORD)hModule+pImportDescriptor->Name), -1, 
                szModuleName, MINCHAR );
            #else
            lstrcpy(szModuleName,(LPCSTR)((DWORD)hModule+pImportDescriptor->Name));
            #endif
            HMODULE hImpModule = ::LoadLibrary(szModuleName);
            if (!hImpModule) 
            {
                // + message for name of dll
                return ERR_IMAGE_IMPLIB_NOT_LOADED;
            }
#ifdef spy_ExitProcess
            if (lstrcmpi(szModuleName,_TEXT("KERNEL32.DLL"))==0) wEP = 1;
            else wEP = 0;
#endif
            // Thunk[]
            PIMAGE_THUNK_DATA pitd = (PIMAGE_THUNK_DATA)
            ((DWORD)hModule + (pImportDescriptor->OriginalFirstThunk ? 
                pImportDescriptor->OriginalFirstThunk : 
                pImportDescriptor->FirstThunk));
            PIMAGE_THUNK_DATA pFirstThunk = (PIMAGE_THUNK_DATA)
                ((DWORD)hModule + pImportDescriptor->FirstThunk);

            // loop for IMAGE_THUNK_DATA
            while(pitd->u1.AddressOfData)
            {
                LPCSTR lpProcName = ((pitd->u1.Ordinal & IMAGE_ORDINAL_FLAG32) ? 
                    (LPCSTR)(IMAGE_ORDINAL32(pitd->u1.Ordinal)) :
                    (LPCSTR)((PIMAGE_IMPORT_BY_NAME)((DWORD)hModule + pitd->u1.AddressOfData))->Name);
                DWORD dwFunc = (DWORD)GetProcAddress(hImpModule,lpProcName);
#ifdef spy_ExitProcess
                if (wEP)
                {
                    if (pitd->u1.Ordinal & IMAGE_ORDINAL_FLAG32)
                    {
                        if (IMAGE_ORDINAL32(pitd->u1.Ordinal)==183) wEP |= 0x0100;
                    }
                    else
                    {
                        TCHAR szProcName[MINCHAR] = _TEXT("");
                        #ifdef UNICODE
                        MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, 
                            (LPCSTR)((PIMAGE_IMPORT_BY_NAME)((DWORD)hModule + pitd->u1.AddressOfData))->Name, -1, 
                            szProcName, MINCHAR );
                        #else
                        lstrcpy(szProcName,(LPCSTR)((PIMAGE_IMPORT_BY_NAME)((DWORD)hModule + pitd->u1.AddressOfData))->Name);
                        #endif
                        if (lstrcmpi(szProcName,_TEXT("ExitProcess"))==0)  wEP |= 0x0100;
                    }
                    if (wEP&0x0100) 
                    {
                        g_ExitProcess = (_ExitProcess)dwFunc;
                        dwFunc = (DWORD)spyExitProcess;
                        g_ImpExitProcess = &(pFirstThunk->u1.Function);
                        wEP = 0;
                    }
                }
#endif
                pFirstThunk->u1.Function = dwFunc;
                pFirstThunk++;
                pitd++;
            }
            // Next
            pImportDescriptor++;
        }
    }
    else return ERR_IMAGE_NO_IMPORT;
    return 0;
}

bool IsForwarderString(PCHAR pChar, LPVOID hExports, DWORD blockSize)
{
   bool result = pChar > hExports;
   if (result)
   {
      result = (DWORD) (pChar - hExports) < blockSize;
   }
   return result;
}

DWORD PeProcessExports(HMODULE hModule)
{
#ifdef spy_ExitProcess
   WORD wEP = 0;
#endif
   PIMAGE_OPTIONAL_HEADER32 pOptionalHeader =
      &IMAGE_GET_NTHEADER(hModule)->OptionalHeader;
   PIMAGE_DATA_DIRECTORY pDirectoryExport =
      IMAGE_GET_DIRECTORY(hModule, IMAGE_DIRECTORY_ENTRY_EXPORT);
   if (pDirectoryExport->VirtualAddress)
   {
      PIMAGE_EXPORT_DIRECTORY pExportDescriptor = (PIMAGE_EXPORT_DIRECTORY)((DWORD)hModule + pDirectoryExport->VirtualAddress);
      // loop for IMAGE_IMPORT_DESCRIPTOR[]
      for (int i = 0; i < pExportDescriptor->NumberOfNames; i++)
      {
         PCHAR PFnName = (PCHAR)(((LPDWORD)((DWORD)(pExportDescriptor->AddressOfNames) + (DWORD)(hModule)))[i]
            + (DWORD)(hModule));
         DWORD FnIndex = ((LPDWORD)((DWORD)(pExportDescriptor->AddressOfNameOrdinals) + (DWORD)(hModule)))[i];
         HMODULE PProcVar = (HMODULE)(((LPDWORD)((DWORD)(pExportDescriptor->AddressOfFunctions)
               + (DWORD)(hModule)))[FnIndex] + (DWORD)(hModule));


         TCHAR szModuleName[MINCHAR] = _TEXT("");
         #ifdef UNICODE
         MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
            PFnName, -1,
            szModuleName, MINCHAR);
         #else
         lstrcpy(szModuleName, PFnName);
         #endif
         HMODULE hImpModule = ::LoadLibrary(szModuleName);
         if (!hImpModule)
         {
            // + message for name of dll
            return ERR_IMAGE_IMPLIB_NOT_LOADED;
         }
      }
   }
}

DWORD PeGetSectionProtection(DWORD dwCharacteristics)
{
    DWORD dwProtection = 0;

    if (dwCharacteristics & IMAGE_SCN_MEM_NOT_CACHED)
        dwProtection |= PAGE_NOCACHE;

    if ((dwCharacteristics & IMAGE_SCN_MEM_EXECUTE) &&
        (dwCharacteristics & IMAGE_SCN_MEM_READ) &&
        (dwCharacteristics & IMAGE_SCN_MEM_WRITE))
        dwProtection |= PAGE_EXECUTE_READWRITE;
    else if ((dwCharacteristics & IMAGE_SCN_MEM_EXECUTE) &&
        (dwCharacteristics & IMAGE_SCN_MEM_READ))
        dwProtection |= PAGE_EXECUTE_READ;
    else if ((dwCharacteristics & IMAGE_SCN_MEM_READ) && 
        (dwCharacteristics & IMAGE_SCN_MEM_WRITE))
        dwProtection |= PAGE_READWRITE;
    else if (dwCharacteristics & IMAGE_SCN_MEM_WRITE)
        dwProtection |= PAGE_WRITECOPY;
    else if (dwCharacteristics & IMAGE_SCN_MEM_READ)
        dwProtection |= PAGE_READONLY;
    else
        dwProtection |= PAGE_EXECUTE_READWRITE;

    return dwProtection;
}

DWORD PeSetSectionProtection(HMODULE hModule)
{
    DWORD dwReturn = 0;
    PIMAGE_SECTION_HEADER pish = IMAGE_FIRST_SECTION(IMAGE_GET_NTHEADER(hModule)); 
    for (DWORD i=0;i<IMAGE_GET_NTHEADER(hModule)->FileHeader.NumberOfSections;i++,pish++)
    {
        if (pish->VirtualAddress)
        {
            DWORD dwOldProtection = 0;
            if (!VirtualProtect((LPVOID)((DWORD)hModule + pish->VirtualAddress),pish->Misc.VirtualSize,
                PeGetSectionProtection(pish->Characteristics),&dwOldProtection))
                dwReturn = ERR_IMAGE_SEC_PROTECTION_FAILED;
        }
    }
    return dwReturn;
}

void peExecute(HMODULE hModule)
{
    // PEB.ImageBaseAddress correction for resource functions
	 ((TEB*)__readfsdword(PcTeb))->Peb->SectionBaseAddress = (PVOID)hModule;
    _mainCRTStartup newmain = (_mainCRTStartup)((DWORD)hModule + IMAGE_GET_NTHEADER(hModule)->OptionalHeader.AddressOfEntryPoint);
    newmain();
}

VOID LoadExe(LPCTSTR szFileName)
{
    if (::GetFileAttributes(szFileName)!=INVALID_FILE_ATTRIBUTES)
    {
        HANDLE hFile = ::CreateFile( szFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 
            FILE_ATTRIBUTE_NORMAL, NULL );
        if(hFile!=INVALID_HANDLE_VALUE) {
            DWORD dwFileSizeHigh = 0;
            DWORD dwImageSize = ::GetFileSize(hFile,&dwFileSizeHigh);
            if (dwFileSizeHigh==0)
            {
                HANDLE hMappedFile = ::CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);
                ::CloseHandle(hFile);
                if(hMappedFile) {
                    LPVOID lpMappedFile = ::MapViewOfFile(hMappedFile,FILE_MAP_READ,0,0,0);
                    ::CloseHandle(hMappedFile);
                    if(lpMappedFile) {
                        DWORD dwError = 0;
                        g_hLoadedModule = PeLoadModule((LPBYTE)lpMappedFile,&dwError);
                        ::UnmapViewOfFile(lpMappedFile); 
                        if (g_hLoadedModule)
                        {
                            if (dwError) 
                                ::MessageBox(::GetDesktopWindow(),_TEXT("File loaded unsuccessful"),_TEXT("Peloader"),MB_OK+MB_ICONERROR),
                                std::wcout << _TEXT("file loaded unsuccessful: ")  << dwError << std::endl;
                            else
                            {
                                LONG lImageBaseDelta = (LONG)((DWORD)g_hLoadedModule - IMAGE_GET_NTHEADER(g_hLoadedModule)->OptionalHeader.ImageBase);
                                if (lImageBaseDelta)
                                {
                                    // Processing relocs
                                    dwError = PeProcessRelocations(g_hLoadedModule,lImageBaseDelta);
                                    if (dwError) std::wcout << _TEXT("can't processed relocations: ") << dwError << std::endl;
                                }
                                else std::wcout << _TEXT("relocations not processed") << std::endl;
                                // Processing import
                                dwError = PeProcessImports(g_hLoadedModule);
                                //dwError = PeProcessExports(g_hLoadedModule);
                                if (dwError) std::wcout << _TEXT("can't process import : ") << dwError << std::endl;
                                // Set protection
                                dwError = PeSetSectionProtection(g_hLoadedModule);
                                if (dwError) std::wcout << _TEXT("can't section protect : ") << dwError << std::endl;
                                peExecute(g_hLoadedModule);

                                dwError = PeUnloadModule();
                                //if (dwError) print_f(_TEXT("can't unload pe image: %u\n"),dwError);

                            }
                        }
                        else std::wcout << _TEXT("can't load pe image: ") << dwError << std::endl;
                    }
                    else MessageGetLastError(::GetDesktopWindow(),_TEXT("Can't mapview file"));
                }
                else MessageGetLastError(::GetDesktopWindow(),_TEXT("Can't mapping file"));
            }
            else
            {
                ::MessageBox(::GetDesktopWindow(),_TEXT("File is very large"),_TEXT("Peloader"),MB_OK+MB_ICONERROR);
                ::CloseHandle(hFile);
            }
        }
        else MessageGetLastError(::GetDesktopWindow(),_TEXT("Can't open file"));
    }
    else MessageGetLastError(::GetDesktopWindow(),_TEXT("Can't find file"));
}

#ifdef SEH
LONG CALLBACK TopLevelExceptionFilter( EXCEPTION_POINTERS *ExceptionInfo )
{
  if (
      ::MessageBox(
      ::GetDesktopWindow(),
      _TEXT("Unhandled exception was detected.\nClose application?"),
      _TEXT("Peloader: error"),
      MB_OKCANCEL+MB_ICONERROR
    ) == IDOK
    ) ::ExitProcess(0);
  return EXCEPTION_EXECUTE_HANDLER;
}
#endif

int main(void)
{
#ifdef SEH
    // enables an application to supersede the top-level exception handler 
    // of each thread and process
    SetUnhandledExceptionFilter( TopLevelExceptionFilter );
#endif
    //LoadExe(_TEXT("C:\\Windows\\system32\\calc.exe"));
    //LoadExe(_TEXT("D:\\Projects_Programing\\IBM_PC\\BaJi\\BaJi\\obj\\Debug\\BaJi.exe"));
    LoadExe(_TEXT("D:\\Projects_Programing\\notepad.exe"));
    ::ExitProcess(0);
    return 0;
}
#pragma code_seg(pop, r1)
I tired to find in which is this bug or mistakes. Can some body to help me or support what I did wrong ?

Regards,
Denis.
I can help you if you give people more information (what are you trying to do, what is the definitive question, when does it blocks ...)
I am trying to learn PE-file format by writing myself pe-loader.
This pe-loader can load some simple projects, but another it can't load.
Because as I have understand there is missed some blocks that describe a loading of other section of pe-file, for example: resource loading, iat table loading, export table loading.
Can you show or give a link to some correctly working pe-loader in order to understand what I am doing wrong ?

Thanks.
Parsing a PE successfully requires the following steps:

- Mapping the file to a specific base address ( And checking if the mapped address isn't the preferred address, in which case, relocations need to be performed )
- Parsing the IAT/EAT table and properly setting up the symbols for each thunk
- Parsing delay-loaded DLLs
- Setting up the exception table and calling TLS handlers
- Calling the entry point ( Determined by the type of PE, DLL gets the standard DllMainCrtStartup(), exe's get WinMainCrtStartup )

I'd recommend you look at DarthTon's BlackBone library to see how he does it as his supports EXEs as well as DLLs.
Quote Originally Posted by hkKenshin View Post
Parsing a PE successfully requires the following steps:

- Mapping the file to a specific base address ( And checking if the mapped address isn't the preferred address, in which case, relocations need to be performed )
- Parsing the IAT/EAT table and properly setting up the symbols for each thunk
- Parsing delay-loaded DLLs
- Setting up the exception table and calling TLS handlers
- Calling the entry point ( Determined by the type of PE, DLL gets the standard DllMainCrtStartup(), exe's get WinMainCrtStartup )

I'd recommend you look at DarthTon's BlackBone library to see how he does it as his supports EXEs as well as DLLs.
I have tried to use this library. This is pretty good designed.
But for one of my *.exe files that I tried to mapped, I have the next error:
Mapping failed with error 0x8000001a {No More Entries} No more entries are available from an enumeration operation.

Do you no why ? I do not understand why it happen (

- - - Updated - - -

Quote Originally Posted by redradist View Post
I have tried to use this library. This is pretty good designed.
But for one of my *.exe files that I tried to mapped, I have the next error:
Mapping failed with error 0x8000001a {No More Entries} No more entries are available from an enumeration operation.

Do you no why ? I do not understand why it happen (
I find out that is happen cause:
pe::RelocData* fixrec = reinterpret_cast<pe::RelocData*>(start);
if (fixrec == nullptr)
{
// TODO: return proper error code
BLACBONE_TRACE( L"ManualMap: Can't relocate image, no relocation data" );
LastNtStatus( STATUS_IMAGE_NOT_AT_BASE );
return false;
}
But if using this MapImageLoader I can't to download it and start into my main process, then how it do Windows OS ?
It some how did it corretly and program stated.
Can any help me ? I was tring to load the program based on Qt Library.
If it was need it, I can attach *.exe with which I have problem.
I have found that a code written in first comment is successfully work in case if I try to load the pe-file that was compiled the same compiler that my own pe-loader.
But if I try to load the pe-file that was compiled not by the same compiler, it does not start.
Can some-body propose why it happen ?
Is the program linked against a static or dynamic CRT?
I have tested BlackBone and it successfully run some my teste programs.
But on one of its occured an error:
{Image Relocated} An image file could not be mapped at the address specified in the image file. Local fixups must be performed on this image.
Can somebody explain why it's happen ? And how I can fix this by myself to load this program ?
It is possibly, because by Windows loader it started.

- - - Updated - - -

Quote Originally Posted by hkKenshin View Post
Is the program linked against a static or dynamic CRT?
The program with which I have the problem is linked static.
Quote Originally Posted by redradist View Post
I have tested BlackBone and it successfully run some my teste programs.
But on one of its occured an error:
{Image Relocated} An image file could not be mapped at the address specified in the image file. Local fixups must be performed on this image.
Can somebody explain why it's happen ? And how I can fix this by myself to load this program ?
It is possibly, because by Windows loader it started.

- - - Updated - - -



The program with which I have the problem is linked static.
I've never come across such an error message but the error message is clear. When mapping the different executable and it's required modules in place the preferred base address for the executable was not available due to a module already being placed there. Try opening up the executable in a PE Editor (e.g. CFF Explorer) and change the preferred base address to something else within possible virtual address range. But I doubt this will solve your issue.

Weird because most of the elements inside of the PE file format are relative to the base address which is calculated after the executable is mapped in. The error code seems to be ERROR_IMAGE_NOT_AT_BASE. Maybe do some searching and see what you find.
Quote Originally Posted by maktm View Post
I've never come across such an error message but the error message is clear. When mapping the different executable and it's required modules in place the preferred base address for the executable was not available due to a module already being placed there. Try opening up the executable in a PE Editor (e.g. CFF Explorer) and change the preferred base address to something else within possible virtual address range. But I doubt this will solve your issue.

Weird because most of the elements inside of the PE file format are relative to the base address which is calculated after the executable is mapped in. The error code seems to be ERROR_IMAGE_NOT_AT_BASE. Maybe do some searching and see what you find.
I have tried this one.
But it too not work. After changing address from 0x4000000 to 0x2000000, 0xF000000, 0x8000000 and etc.
But it did not help. When I try to run the program by Windows OS Loader I have got error 0xC0000005 that I have got when I use my loader.
It's seems like Windows mapped program exactly to 0x4000000 address, but when I try to map a program to this address my loader does not load a program to this address and I always have some delta (real map address and bas image).
Mind attaching the EXE for analysis?
Quote Originally Posted by hkKenshin View Post
Mind attaching the EXE for analysis?
There is an archive with files to analyze (pe-files_to_analize.rar).
ServiceManager.exe - this is my program which I try to load, but unfortunately unsuccessfully.
Mario.exe - this is file which I have successfully loaded.
pe-files_to_analize_mpgh.net.rar9.3 MB · 14 downloads Clean
"pe-files to analize mpgh.net.rar" has not been checked for malware, the files are for analyzation purposes only.

Approved.
After glancing through the file, verify these conditions are met first:

- MSVCP100D and MSVCR100D are loaded. ( Visual studio 2010 runtime CRTs -- FYI, don't use debug. Also I'd recommend static linking )
- All dependencies are met
- You might need to tamper with the TIB of the loading process and use a form of process hollowing ( Without the hollowing but rewriting the base address etc. )
- Make sure you're properly parsing relocations.
Posts 1–14 of 14 · Page 1 of 1

Post a Reply

Similar Threads

Tags for this Thread

None

Talk with us