Показать сообщение отдельно

Загрузка dll из памяти
  #16  
Старый 24.02.2010, 14:38
Gar|k
Постоянный
Регистрация: 20.03.2009
Сообщений: 564
Провел на форуме:
991929

Репутация: 395


По умолчанию Загрузка dll из памяти

Понадобилось загружать dll из памяти сразу вот переделал несколько функцию


Код:
// непосредственно функция загрузки DLL из памяти by Gar|k
HMODULE __stdcall HideLoadLibraryFromMemory(unsigned char * pMemory)
{
	ULONG retadr = 0;
	DWORD rb = 0;
	IMAGE_DOS_HEADER *DosHeader;
	IMAGE_NT_HEADERS *PeHeader;
	IMAGE_SECTION_HEADER * Section[MAX_SECTIONS];

	if (pMemory != NULL)
	{
		// считаем DOS заголовок
		DosHeader=(IMAGE_DOS_HEADER *)&pMemory[0];
		if (DosHeader->e_magic == IMAGE_DOS_SIGNATURE) // проверим сигнатуру
		{
			// установим указатель на PE заголовок
			rb=DosHeader->e_lfanew;

			// считаем заголовок
			PeHeader=(IMAGE_NT_HEADERS *)&pMemory[rb]; rb+=sizeof(IMAGE_NT_HEADERS);
			if (PeHeader->Signature == IMAGE_NT_SIGNATURE) // проверим сигнатуру
			{
				// выделим память столько, сколько указано в SIZE OF BASE
				retadr = (ULONG)VirtualAlloc(0, PeHeader->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE);
				
				if (retadr) // если память выделилась
				{
					// скопируем туда DOS заголовок
					memcpy((void*) retadr, DosHeader, sizeof(IMAGE_DOS_HEADER));
					// скопируем туда PE заголовок
					memcpy((void*)(retadr + DosHeader->e_lfanew), PeHeader, sizeof(IMAGE_NT_HEADERS));
					// скопируем туда таблицу секций
					memcpy((void*)(retadr + DosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS)),&pMemory[rb], sizeof(IMAGE_SECTION_HEADER) * PeHeader->FileHeader.NumberOfSections);

					// если есть Rich данные то и их тоже скопируем
					if (sizeof(IMAGE_DOS_HEADER) < DosHeader->e_lfanew) 
					{
						memcpy((void*)(retadr + sizeof(IMAGE_DOS_HEADER)), &pMemory[sizeof(IMAGE_DOS_HEADER)], DosHeader->e_lfanew - sizeof(IMAGE_DOS_HEADER));
					}
					// обработаем каждую секцию
					for (int i = 0; i < PeHeader->FileHeader.NumberOfSections; i++)
					{
						Section[i]=(IMAGE_SECTION_HEADER *)&pMemory[rb]; rb+=sizeof(IMAGE_SECTION_HEADER);
						// считаем всё секцию
						memcpy((void*)(retadr + Section[i]->VirtualAddress),&pMemory[Section[i]->PointerToRawData],Section[i]->SizeOfRawData);
					}
					// Обработаем релоки
					if (!ProgressReloc(retadr)) // если ошибка
					{
						VirtualFree((void*)retadr, 0, MEM_RELEASE); // освободим память
						retadr = 0;
					}
					else if (!ProgressImport(retadr))// обработаем импорт
					{
						VirtualFree((void*)retadr, 0, MEM_RELEASE);// если ошибка освободим память
						retadr = 0;
					}
					else
					{
						rb=PeHeader->OptionalHeader.AddressOfEntryPoint;
						__asm
						{
							mov eax, rb
							add eax, retadr // EAX = ENTRY POINT
							push 0
							push DLL_PROCESS_ATTACH // ставим флаг что подгрузили DLL
							push retadr
							call eax // передадим управление на точку входа в DLL 
						}
					}
				}
			}
		}
		 // закрываем файл

	}

	return (HMODULE)retadr; // возвращаем адрес загруженного модуля в памяти
}
Спасибо SLESH-у за то что терпеливо выслушивал меня и отвечал в аське