
Опытный
 
Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев
Репутация: 1 Всего: 4
|
Доброе время суток! - Пишу программу на 'Borland C++ Builder 6.0 SP4'; - Задача: Запустить программу 1.exe из ресурсов моей программу main.exe не извлекая её на диск. - То есть, необходимо запустить программу main.exe, затем извлечь из ресурсов 1.exe заменяя память другого процесса, чтобы запустилась программа 1.exe; - Данную схему вроде частично реализовал(Без переноса таблицы импорта и релоков). # TRFR.cpp:| Код | #include "TRFR.h" #include "Main.h" //--------------------------------------------------------------------------- bool (*pNtdllFunc)(HANDLE, LPVOID); //---------------------------------------------------------------------------
TRFR::TRFR() { // ---- } //---------------------------------------------------------------------------
TRFR::~TRFR() { // ---- } //---------------------------------------------------------------------------
bool __fastcall TRFR::ZwUnmapViewOfSection(HANDLE ProcessHandle, LPVOID BaseAddress) { bool Result = false; // ----- try { HMODULE hNtdll = LoadLibrary("ntdll.dll"); if(hNtdll != NULL) { (FARPROC &)pNtdllFunc = GetProcAddress(hNtdll, "ZwUnmapViewOfSection"); pNtdllFunc(ProcessHandle, BaseAddress); FreeLibrary(hNtdll); Result = true; } } catch(...) {} // ---- return Result; } //---------------------------------------------------------------------------
ULONG __fastcall TRFR::Protect(ULONG characteristics) { const ULONG mapping[8] = {PAGE_NOACCESS, PAGE_EXECUTE, PAGE_READONLY, PAGE_EXECUTE_READ, PAGE_READWRITE, PAGE_EXECUTE_READWRITE, PAGE_READWRITE, PAGE_EXECUTE_READWRITE}; return mapping[characteristics >> 29]; } //---------------------------------------------------------------------------
bool __fastcall TRFR::GetMemoryToSection(HANDLE hProcess, LPVOID Mapping, LPVOID pRes, USHORT NumberOfSections, PIMAGE_SECTION_HEADER pSection) { bool Result = true; // ---- for (USHORT i = 0; i < NumberOfSections; i++) { Result = WriteProcessMemory(hProcess, (LPVOID)(DWORD(Mapping) + pSection[i].VirtualAddress), (LPCVOID)(DWORD(pRes) + pSection[i].PointerToRawData), pSection[i].SizeOfRawData, NULL); // ---- if(!Result) break; } // ---- return Result; } //---------------------------------------------------------------------------
DWORD __fastcall TRFR::RunFromResurs(LPTSTR ComLine, LPCTSTR ResName, LPCTSTR ResType) { bool Result = true; DWORD pPID = 0; // ---- PROCESS_INFORMATION pi; STARTUPINFO si; ZeroMemory(&pi, sizeof(pi)); ZeroMemory(&si, sizeof(si)); si.cb = sizeof(STARTUPINFO); // ---- PIMAGE_DOS_HEADER pDos = NULL; PIMAGE_NT_HEADERS pNt = NULL; PIMAGE_FILE_HEADER pFile = NULL; PIMAGE_OPTIONAL_HEADER pOptional = NULL; PIMAGE_SECTION_HEADER pSection = NULL; // ---- LPVOID x = NULL, pRes = NULL, Mapping = NULL; HANDLE hProcess = NULL; HMODULE hInst = GetModuleHandle(NULL); SIZE_T bsize = 0; // ---- pRes = LockResource(LoadResource(hInst, FindResource(hInst, ResName, ResType))); if(pRes != NULL) { pDos = PIMAGE_DOS_HEADER(pRes); if (pDos->e_magic == IMAGE_DOS_SIGNATURE) { pNt = PIMAGE_NT_HEADERS(PCHAR(pRes) + pDos->e_lfanew); if (pNt->Signature == IMAGE_NT_SIGNATURE) { pFile = &pNt->FileHeader; pOptional = &pNt->OptionalHeader; pSection = IMAGE_FIRST_SECTION(pNt); // ---- Result = CreateProcess(NULL, ComLine, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi); if(Result) { FMain->WLog("CreateProcess()"); hProcess = pi.hProcess; pPID = pi.dwProcessId; CONTEXT context; context.ContextFlags = CONTEXT_FULL; // ---- Result = GetThreadContext(pi.hThread, &context); if(Result) { FMain->WLog("GetThreadContext()"); Result = ReadProcessMemory(pi.hProcess, (LPCVOID)(context.Ebx + 8), &x, sizeof(x), &bsize); if (Result) { FMain->WLog("ReadProcessMemory()"); Result = ZwUnmapViewOfSection(pi.hProcess, x); if(Result) { FMain->WLog("ZwUnmapViewOfSection()"); Mapping = VirtualAllocEx(pi.hProcess, (LPVOID)pOptional->ImageBase, pOptional->SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); if(Mapping != NULL) { FMain->WLog("VirtualAllocEx()"); //DWORD previousProtection = 0; //Result = VirtualProtectEx(pi.hProcess, Mapping, pOptional->SizeOfHeaders, PAGE_EXECUTE_READWRITE, &previousProtection); Result = WriteProcessMemory(pi.hProcess, Mapping, (LPCVOID)pRes, pOptional->SizeOfHeaders, &bsize); if(Result) { FMain->WLog("WriteProcessMemory()"); Result = GetMemoryToSection(pi.hProcess, Mapping, pRes, pFile->NumberOfSections, pSection); if(Result) { FMain->WLog("GetMemoryToSection()"); Result = WriteProcessMemory(pi.hProcess, (LPVOID)(context.Ebx + 8), &Mapping, sizeof(Mapping), 0); if(Result) { context.Eax = (ULONG)Mapping + pOptional->AddressOfEntryPoint; // ---- SetThreadContext(pi.hThread, &context); ResumeThread(pi.hThread); } } } else FMain->WLog("[WPM1] GetLastError = '" + (String)GetLastError() + "'"); } else Result = false; } } } // ---- if(!Result && hProcess != NULL) TerminateProcess(hProcess, 0); // ---- CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } } } } // ----- FreeResource(pRes); // ---- return (Result) ? pPID : 0; } //---------------------------------------------------------------------------
|
# TRFR.h:| Код | #include <Windows.h> #include <tlhelp32.h> #include <stdio.h> //--------------------------------------------------------------------------- class TRFR { private: bool __fastcall ZwUnmapViewOfSection(HANDLE ProcessHandle, LPVOID BaseAddress); ULONG __fastcall Protect(ULONG characteristics); bool __fastcall GetMemoryToSection(HANDLE hProcess, LPVOID Mapping, LPVOID pRes, USHORT NumberOfSections, PIMAGE_SECTION_HEADER pSection); public: TRFR(); ~TRFR(); DWORD __fastcall RunFromResurs(LPTSTR AppName, LPCTSTR ResName, LPCTSTR ResType); }; //---------------------------------------------------------------------------
|
- Проблема в том, что если программу компилировать в режиме 'Debug', то всё нормально, запускается и выполняет свои функции, если скомпилировать в режиме 'Release', то на строчке 128: | Код | Result = WriteProcessMemory(pi.hProcess, Mapping, (LPCVOID)pRes, pOptional->SizeOfHeaders, &bsize); - GetLastError() выдаёт ошибку:
ERROR_PARTIAL_COPY 299 0x12B - Only part of a ReadProcessMemory or WriteProcessMemory request was completed.
|
- Вроде использую VirtualProtectEx(), вообщем что-то не могу сам допереть... # Добавлено: У Borland есть удобный класс для извлечения из ресурсов 'TResourceStream', но он мне не очень нравится. (Это так, вода...) P.S. -> Убедительно прошу, не нужно мне советовать следующее: А чем плох приём извлечения программы на диск с последующим запуском... - Задача конкретно поставлена. (Файл не должен извлекаться из ресурсов) Это сообщение отредактировал(а) MuForum - 19.12.2008, 13:18
--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
|