Results 1 to 14 of 14
  1. #1
    redradist's Avatar
    Join Date
    Dec 2015
    Gender
    male
    Posts
    7
    Reputation
    10
    Thanks
    0

    Angry 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.

  2. #2
    maestro1994's Avatar
    Join Date
    Sep 2015
    Gender
    male
    Posts
    95
    Reputation
    10
    Thanks
    13
    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 ...)



  3. #3
    redradist's Avatar
    Join Date
    Dec 2015
    Gender
    male
    Posts
    7
    Reputation
    10
    Thanks
    0
    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.

  4. #4
    hkKenshin's Avatar
    Join Date
    Oct 2013
    Gender
    male
    Posts
    301
    Reputation
    28
    Thanks
    340
    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.

  5. #5
    redradist's Avatar
    Join Date
    Dec 2015
    Gender
    male
    Posts
    7
    Reputation
    10
    Thanks
    0
    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.

  6. #6
    redradist's Avatar
    Join Date
    Dec 2015
    Gender
    male
    Posts
    7
    Reputation
    10
    Thanks
    0
    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 ?

  7. #7
    hkKenshin's Avatar
    Join Date
    Oct 2013
    Gender
    male
    Posts
    301
    Reputation
    28
    Thanks
    340
    Is the program linked against a static or dynamic CRT?

  8. #8
    redradist's Avatar
    Join Date
    Dec 2015
    Gender
    male
    Posts
    7
    Reputation
    10
    Thanks
    0
    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.

  9. #9
    hkKenshin's Avatar
    Join Date
    Oct 2013
    Gender
    male
    Posts
    301
    Reputation
    28
    Thanks
    340
    Mind attaching the EXE for analysis?

  10. #10
    redradist's Avatar
    Join Date
    Dec 2015
    Gender
    male
    Posts
    7
    Reputation
    10
    Thanks
    0
    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.
    <b>Downloadable Files</b> Downloadable Files

  11. #11
    Yemiez's Avatar
    Join Date
    Jun 2012
    Gender
    male
    Location
    Sweden
    Posts
    2,566
    Reputation
    731
    Thanks
    16,280
    My Mood
    Devilish
    "pe-files to analize mpgh.net.rar" has not been checked for malware, the files are for analyzation purposes only.

    Approved.

  12. #12
    maktm's Avatar
    Join Date
    Sep 2015
    Gender
    male
    Posts
    10
    Reputation
    10
    Thanks
    1
    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.
    Last edited by maktm; 01-05-2016 at 06:18 AM.

  13. #13
    redradist's Avatar
    Join Date
    Dec 2015
    Gender
    male
    Posts
    7
    Reputation
    10
    Thanks
    0
    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).

  14. #14
    hkKenshin's Avatar
    Join Date
    Oct 2013
    Gender
    male
    Posts
    301
    Reputation
    28
    Thanks
    340
    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.

Similar Threads

  1. [Request] How to Fix the Infinity Files Exp Bug
    By Trololol Fist in forum Adventure Quest Worlds (AQW) Private Servers
    Replies: 0
    Last Post: 06-07-2015, 10:34 AM
  2. [Release] Smaller RF017.rez file (no bug + easy to upload) with all original gp weapons!!!
    By rlenskens in forum CrossFire Mods & Rez Modding
    Replies: 27
    Last Post: 04-14-2012, 07:39 PM
  3. Replies: 8
    Last Post: 04-30-2011, 06:30 PM
  4. [Solved] Loader bug
    By Gab in forum CrossFire Help
    Replies: 2
    Last Post: 03-04-2011, 09:02 PM
  5. "Corrupted File Memory"-Bug-how to solve
    By poncho007 in forum WarRock - International Hacks
    Replies: 17
    Last Post: 07-18-2008, 08:43 PM