Решил поэкспериментировать с PE форматом и для начала просто попытаться файл с диска отобразить в память и запустить.
в качестве жертвы запуска — обычное Win32 GUI-приложение (MS Visual Studio сама генерит).
Вроде бы все хорошо, отлавливаю ExitProcess, пытаюсь освободить зарезервированную память, и пытаюсь вызвать оригинальную ExitProcess... И тут лажа происходит типа Access violation at 0xC0000005 и DEP под Vistой срабатывает, цуко...
Короче не пойму как это юзать нужно...
см. в коде коммент: ПАДАЕТ ТУТ!!!
впрочем если закоментарить строчку с VirtualFree( g_hLoadedModule, 0, MEM_RELEASE ); тогда все работает
может у кого-нить придет умная мысль в голову насчет этого, поделитесь, плиз
// 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 <tchar.h>
#pragma code_seg(push,r1,".eccode")
#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 Blocktypedef struct _PEB {
DWORD smth[2]; // doesn't matter
PVOID SectionBaseAddress;
} PEB, *PPEB;
// Thread Environment Blocktypedef 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_NOACCESS );
if (lpbBase)
{
// headers copy
LPBYTE lpbHeaders = (LPBYTE) VirtualAlloc( lpbBase,
IMAGE_GET_NTHEADER(lpbImage)->OptionalHeader.SizeOfHeaders,
MEM_COMMIT, PAGE_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_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_READONLY, &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_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 blockfor (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 requiredbreak;
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 presentreturn 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 dllreturn 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_DATAwhile(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;
}
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);
// print_f(_TEXT("file loaded unsuccessful: %u\n"),dwError);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) print_f(_TEXT("can't processed relocations: %u\n"),dwError);
}
// else print_f(_TEXT("relocations not processed\n"));
// Processing import
dwError = PeProcessImports(g_hLoadedModule);
// if (dwError) print_f(_TEXT("can't process import : %u\n"),dwError);
// Set protection
dwError = PeSetSectionProtection(g_hLoadedModule);
// if (dwError) print_f(_TEXT("can't section protect : %u\n"),dwError);
peExecute(g_hLoadedModule);
/*
dwError = PeUnloadModule();
if (dwError) print_f(_TEXT("can't unload pe image: %u\n"),dwError);
*/
}
}
// else print_f(_TEXT("can't load pe image: %08X\n"),dwError);
}
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 WinMainCRTStartup(void)
{
#ifdef SEH
// enables an application to supersede the top-level exception handler
// of each thread and process
SetUnhandledExceptionFilter( TopLevelExceptionFilter );
#endif
LoadExe(_TEXT("Test.exe"));
::ExitProcess(0);
return 0;
}
#pragma code_seg(pop, r1)
И не нужно флудить вопросами типа: а нафига оно тебе?...
Здравствуйте, explorus, Вы писали:
E>разобрался, теперь и под вистой работает
А в чём проблема, разобрался? Я сначала подумал, что возникает гонка подобная FreeLibrary & ExitThread, но в коде её не увидел. А про отладчик ты и сам должен знать
Что не понравилось — VirtualAlloc на каждую секцию PE, на каких-то образах это сработает, на каких-то нет, из-за разной гранулярности VirtualAlloc и выравнивания секций. Ну это, как оказывалось, наследие статьи
. И выгрузка в статье сделана (почти) как в последнем твоем варианте.
И так есть файл на диске, и так есть MapViewOfFile — можно добавить SEC_IMAGE, и выкинуть половину кода Или можно вычитывать файл сразу в образ в памяти, как сделано здесь в load_image.
E>решение простое: VirtualFree( g_hLoadedModule, 0, MEM_DECOMMIT | MEM_RELEASE ); E>я сперва перемудрил немного
MSDN о MEM_RELEASE -
Do not use this value with MEM_DECOMMIT
Возвращаемые API значения не проверяются, поэтому исправление вероятно аналогично
если закоментарить строчку с VirtualFree( g_hLoadedModule, 0, MEM_RELEASE ); тогда все работает
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, gear nuke, Вы писали:
GN>А в чём проблема, разобрался? Я сначала подумал, что возникает гонка подобная FreeLibrary & ExitThread, но в коде её не увидел. А про отладчик ты и сам должен знать
ExitProcess не должен возвращаться в тело вызывающего, иначе на висте все падает. Почему до конца не понятно, буду в исходниках Винды ковырять, наверное.
гонка подобная FreeLibrary & ExitThread
— речь про critical section или чего? непонятно, да и потоки я не создаю, и про отладчик... ???
GN>Что не понравилось — VirtualAlloc на каждую секцию PE, на каких-то образах это сработает, на каких-то нет, из-за разной гранулярности VirtualAlloc и выравнивания секций. Ну это, как оказывалось, наследие статьи
. И выгрузка в статье сделана (почти) как в последнем твоем варианте.
Конструктивная критика всегда принимается!!!
Это тестовое приложение, файл не диска будет грузиться, а по частям в виртуальную память, сперва заголовок, потом все остальное... Про гранулярность не совсем понятно, это что за выравнивание такое должно быть, чтоб VirtualAllloc не сработал, можно примерчик?
GN>И так есть файл на диске, и так есть MapViewOfFile — можно добавить SEC_IMAGE, и выкинуть половину кода
Добавить что, что это? Пля, моя жена щас прочитала весь этот пост, покрутила у виска и поперлась дальше тупить у телика...
GN>Или можно вычитывать файл сразу в образ в памяти, как сделано здесь в load_image.
E>>решение простое: VirtualFree( g_hLoadedModule, 0, MEM_DECOMMIT | MEM_RELEASE ); E>>я сперва перемудрил немного
GN>MSDN о MEM_RELEASE -
Do not use this value with MEM_DECOMMIT
GN>Возвращаемые API значения не проверяются, поэтому исправление вероятно аналогично
если закоментарить строчку с VirtualFree( g_hLoadedModule, 0, MEM_RELEASE ); тогда все работает
Про MEM_DECOMMIT | MEM_RELEASE согласен — тут лажа. Мне нужно обязательно ресурсы высвобождать, поскольку загружаться в памяти должно несколько мелких утилит, и после их работы высвобождать ресурсы.
сырцы обязательно гляну, спасиб
В ближайшее время попробую переделать...
Re[3]: запуск PE (exe) в памяти
От:
Аноним
Дата:
02.09.09 22:51
Оценка:
GN>А в чём проблема, разобрался? Я сначала подумал, что возникает гонка подобная FreeLibrary & ExitThread, но в коде её не увидел. А про отладчик ты и сам должен знать GN>Что не понравилось — VirtualAlloc на каждую секцию PE, на каких-то образах это сработает, на каких-то нет, из-за разной гранулярности VirtualAlloc и выравнивания секций.
Кроме гранулярности есть еще маленький нередко используемый trick в виде получения базы модуля вызовом VirtualQuery на адрес гдето в его середине. Такими фокусами например даэе занимается делфевая VCL сама по себе.
Здравствуйте, Аноним, Вы писали:
GN>>А в чём проблема, разобрался? Я сначала подумал, что возникает гонка подобная FreeLibrary & ExitThread, но в коде её не увидел. А про отладчик ты и сам должен знать GN>>Что не понравилось — VirtualAlloc на каждую секцию PE, на каких-то образах это сработает, на каких-то нет, из-за разной гранулярности VirtualAlloc и выравнивания секций. А>Кроме гранулярности есть еще маленький нередко используемый trick в виде получения базы модуля вызовом VirtualQuery на адрес гдето в его середине. Такими фокусами например даэе занимается делфевая VCL сама по себе.
Это чуть ли не официальный способ, в MSDN отражён
---
С уважением,
Сергей Мухин
Re[4]: запуск PE (exe) в памяти
От:
Аноним
Дата:
04.09.09 20:13
Оценка:
Здравствуйте, explorus, Вы писали:
E>В ближайшее время попробую переделать...