Пятница, 19.10.2018, 23:37
Приветствую Вас Гость

LabSoft

Меню сайта
Категории каталога
Статьи по кодингу [24]
Материалы по кодингу
КреатиFF [144]
Рассказы, истории, анекдоты...
Разное [8]
Советы, трюки, полезные рекомендации, статьи о новом и забытом старом...
Наш опрос
Оцените сайт:
Всего ответов: 19
Главная » Статьи » Статьи по кодингу

Запускаем программу из памяти.
Здесь я приведу пример как можно запустить программу не с диска, а из памяти. Конечно, строго говоря, программа запускается в контексте другого приложения, но не суть важно, поставленной цели мы добъемся. Мы поместим тестовую программу mem.exe, которую надо запустить, в ресурс нашего приложения, а затем при запуске нашего приложения загрузим ресурс и запустим программу mem.exe из памяти.

В общем вот код Delphi:

res.rc:
[code]
EXE RCDATA "mem.exe"
[/code]

project1.dpr:
[code]
program project1;

uses
Windows,
rxtypes;

{$R res.res}

Var
nb, i: Cardinal;

function ZwUnmapViewOfSection(SectionHandle: THandle;
p: Pointer): DWord; stdcall; external 'ntdll.dll';

function protect(characteristics: ULONG): ULONG;
const mapping: array [0..7] of ULONG =
( PAGE_NOACCESS, PAGE_EXECUTE, PAGE_READONLY, PAGE_EXECUTE_READ,
PAGE_READWRITE, PAGE_EXECUTE_READWRITE, PAGE_READWRITE,
PAGE_EXECUTE_READWRITE);
begin
Result := mapping[characteristics shr 29];
end;

var
pi: TProcessInformation;
si: TStartupInfo;
x, p, q: Pointer;
nt: PIMAGE_NT_HEADERS;
context: TContext;
sect: PIMAGE_SECTION_HEADER;

begin
si.cb := SizeOf(si);
CreateProcess(nil, 'cmd.exe', nil, nil, FALSE, CREATE_SUSPENDED, nil, nil, si, pi);
context.ContextFlags := CONTEXT_INTEGER;
GetThreadContext(pi.hThread, context);
ReadProcessMemory(pi.hProcess,
PCHAR(context.ebx) + 8,
@x, sizeof (x),
nb
);
ZwUnmapViewOfSection(pi.hProcess, x);
p := LockResource(LoadResource(Hinstance, FindResource(Hinstance, 'EXE', RT_RCDATA)));
if p = nil then exit;
nt := PIMAGE_NT_HEADERS(PCHAR(p) + PIMAGE_DOS_HEADER(p).e_lfanew);
q := VirtualAllocEx( pi.hProcess,
Pointer(nt.OptionalHeader.ImageBase),
nt.OptionalHeader.SizeOfImage,
MEM_RESERVE or MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(pi.hProcess, q, p, nt.OptionalHeader.SizeOfHeaders, nb);
sect := PIMAGE_SECTION_HEADER(nt);
Inc(PIMAGE_NT_HEADERS(sect));
for I := 0 to nt.FileHeader.NumberOfSections - 1 do
begin
WriteProcessMemory(pi.hProcess,
PCHAR(q) + sect.VirtualAddress,
PCHAR(p) + sect.PointerToRawData,
sect.SizeOfRawData, nb);
VirtualProtectEx( pi.hProcess,
PCHAR(q) + sect.VirtualAddress,
sect.SizeOfRawData,
protect(sect.Characteristics),
@x);
Inc(sect);
end;
WriteProcessMemory(pi.hProcess, PCHAR(context.Ebx) + 8, @q, sizeof(q), nb);
context.Eax := ULONG(q) + nt.OptionalHeader.AddressOfEntryPoint;
SetThreadContext(pi.hThread, context);
ResumeThread(pi.hThread);
end.
[/code]

Модуль rxtypes и исходники вместе с примером находятся в аттаче.

А вот исходный пример, делающий тоже самое на C (который и был переведен на Delphi):
[code]
#include

extern "C" NTSYSAPI LONG NTAPI ZwUnmapViewOfSection(HANDLE, PVOID);

ULONG protect(ULONG characteristics)
{
static const ULONG mapping[]
= {PAGE_NOACCESS, PAGE_EXECUTE, PAGE_READONLY, PAGE_EXECUTE_READ,
PAGE_READWRITE, PAGE_EXECUTE_READWRITE, PAGE_READWRITE,
PAGE_EXECUTE_READWRITE};

return mapping[characteristics >> 29];
}

int main(int argc, char *argv[])
{
PROCESS_INFORMATION pi;
STARTUPINFO si = {sizeof si};

CreateProcess(0, "cmd", 0, 0, FALSE, CREATE_SUSPENDED, 0, 0, &si, &pi);

CONTEXT context = {CONTEXT_INTEGER};

GetThreadContext(pi.hThread, &context);

PVOID x; ReadProcessMemory(pi.hProcess, PCHAR(context.Ebx) + 8, &x,
sizeof x, 0);

ZwUnmapViewOfSection(pi.hProcess, x);

PVOID p = LockResource(LoadResource(0, FindResource(0, "Image",
"EXE")));

PIMAGE_NT_HEADERS nt = PIMAGE_NT_HEADERS(PCHAR(p) +
PIMAGE_DOS_HEADER(p)->e_lfanew);

PVOID q = VirtualAllocEx(pi.hProcess,
PVOID(nt->OptionalHeader.ImageBase),
nt->OptionalHeader.SizeOfImage,
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

WriteProcessMemory(pi.hProcess, q, p, nt->OptionalHeader.SizeOfHeaders,
0);

PIMAGE_SECTION_HEADER sect = IMAGE_FIRST_SECTION(nt);

for (ULONG i = 0; i < nt->FileHeader.NumberOfSections; i++) {

WriteProcessMemory(pi.hProcess,
PCHAR(q) + sect[i].VirtualAddress,
PCHAR(p) + sect[i].PointerToRawData,
sect[i].SizeOfRawData, 0);

ULONG x;

VirtualProtectEx(pi.hProcess, PCHAR(q) + sect[i].VirtualAddress,
sect[i].Misc.VirtualSize,
protect(sect[i].Characteristics), &x);
}

WriteProcessMemory(pi.hProcess, PCHAR(context.Ebx) + 8, &q, sizeof q,
0);

context.Eax = ULONG(q) + nt->OptionalHeader.AddressOfEntryPoint;

SetThreadContext(pi.hThread, &context);

ResumeThread(pi.hThread);

return 0;
}
[/code]

Категория: Статьи по кодингу | Добавил: Jimmy (18.02.2008) | Автор: Voyager
Просмотров: 1100 | Комментарии: 2 | Рейтинг: 5.0/1 |
Всего комментариев: 0
Имя *:
Email *:
Код *:
Форма входа
Поиск
Друзья сайта
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0