Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: [BC++] Запуск .exe из ресурсов  (Прочитано 15718 раз)
0 Пользователей и 1 Гость смотрят эту тему.
MuForum
Гость
« : 18-12-2008 21:57 » 

Доброе время суток!
- Пишу программу на '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);
    // ----
    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), 0);
                        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()");
                                    SIZE_T bsize = 0;
                                    DWORD previousProtection = 0;
                                    Result = VirtualProtectEx(pi.hProcess, Mapping, pOptional->SizeOfHeaders, PAGE_EXECUTE_READWRITE, &previousProtection);
                                    //FMain->WLog("VirtualProtectEx = '" + (String)(int)Result + "'");
                                    Result = WriteProcessMemory(pi.hProcess, Mapping, (LPCVOID)pRes, pOptional->SizeOfHeaders, &bsize);
                                    FMain->WLog("bsize = '" + (String)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:
Код: (Text)
#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() выдаёт ошибку 0x05:

ERROR_ACCESS_DENIED
5
0x5
- Вроде использую VirtualProtectEx(), в общем что-то не могу сам допереть...


# Добавлено: У Borland есть удобный класс для извлечения из ресурсов 'TResourceStream', но он мне не очень нравится. (Это так, вода...)


P.S. -> Убедительно прошу, не нужно мне советовать следующее: А чем плох приём извлечения программы на диск с последующим запуском...
- Задача конкретно поставлена. (Файл не должен извлекаться из ресурсов)
Записан
sss
Специалист

ru
Offline Offline

« Ответ #1 : 19-12-2008 01:39 » 

MuForum, попробуй добавить процессу привилегию SeDebugPrivilege.
Записан

while (8==8)
MuForum
Гость
« Ответ #2 : 19-12-2008 07:21 » 

#2, sss - К сожалению не помогло =)
- Вот код функции:
Код:
void TFMain::EnableDebugPriv(void)
{
        String Text = "";
        HANDLE hToken;
        LUID sedebugnameValue;
        TOKEN_PRIVILEGES tkp;
        // enable the SeDebugPrivilege;
        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
        {
                Text = "OpenProcessToken() failed, Error = %d SeDebugPrivilege is not available. " + (String)GetLastError();
                //wprintf( L"OpenProcessToken() failed, Error = %d SeDebugPrivilege is not available.\n", GetLastError());
                WLog(Text);
                return;
        }
        // ----
        if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue))
        {
                Text = "LookupPrivilegeValue() failed, Error = %d SeDebugPrivilege is not available. " + (String)GetLastError();
                //wprintf( L"LookupPrivilegeValue() failed, Error = %d SeDebugPrivilege is not available.\n", GetLastError());
                WLog(Text);
                CloseHandle(hToken);
                return;
        }
        // ----
        tkp.PrivilegeCount = 1;
        tkp.Privileges[0].Luid = sedebugnameValue;
        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        // ----
         if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL))
         {
                Text = "AdjustTokenPrivileges() failed, Error = %d SeDebugPrivilege is not available. " + (String)GetLastError();
                //wprintf( L"AdjustTokenPrivileges() failed, Error = %d SeDebugPrivilege is not available.\n", GetLastError());
                WLog(Text);
         }
         // ----
         CloseHandle(hToken);
}
Записан
sss
Специалист

ru
Offline Offline

« Ответ #3 : 19-12-2008 07:33 » 

Ну я не знаю. А как открываешь pi.hProcess? Может из другого потока (ImpersonateSelf)?
Записан

while (8==8)
MuForum
Гость
« Ответ #4 : 19-12-2008 07:49 » 

Ну я не знаю. А как открываешь pi.hProcess? Может из другого потока (ImpersonateSelf)?
- Не понимаю вопроса.
- Я создаю процесс при помощи WinApi функции CreateProcess();]
- Или я чего-то не понял, или ты не так оформил вопрос.
Записан
sss
Специалист

ru
Offline Offline

« Ответ #5 : 19-12-2008 08:05 » 

MuForum, ты добавляешь привилегию процессу. Не все потоки процесса наследуют его привилегии . Вот не понял, какие параметры у CreateProcess()? Там же имя образа на диске?
Записан

while (8==8)
MuForum
Гость
« Ответ #6 : 19-12-2008 09:58 » 

MuForum, ты добавляешь привилегию процессу. Не все потоки процесса наследуют его привилегии . Вот не понял, какие параметры у CreateProcess()? Там же имя образа на диске?
RunFromResurs(LPTSTR ComLine, LPCTSTR ResName, LPCTSTR ResType)
- ComLine: Полный путь к программе вместе с командной строкой.
- ResName: Имя загруженного файла в ресурсах программы.
- ResType: Тип загруженного файла в ресурсах программы.

- Запускаю отдельно файл через CreateProcess, атрибуты процесса по умолчанию(FALSE).
Записан
sss
Специалист

ru
Offline Offline

« Ответ #7 : 22-12-2008 02:01 » 

MuForum, я не знаю что такое RunFromResurs. Давай разберемся... Есть exe1 в котором есть exe2.  exe1 запускает процесс - какой? Еще один exe1? Вообще что за задача - обход файловых фильтров антивирусов?
Записан

while (8==8)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines