Сейчас на форуме: vsv1, johnniewalker, Magister Yoda, Kybyx, r0lka (+5 невидимых)

 eXeL@B —› Крэки, обсуждения —› MemPatcher sources
Посл.ответ Сообщение

Ранг: 253.9 (наставник)
Активность: 0.130
Статус: Участник

Создано: 26 декабря 2005 00:13
· Личное сообщение · #1

Доброго времени суток, уважаемая аудитория!

Понадобилось мне как-то сделать лоадер, да не простой, а такой, чтобы пропатчить память определенной DLL запускаемого процесса. Везде обыскался, ничего не нашел. Поэтому написал свой, довольно универсальный лоадер. Можно патчить хоть сам EXE'шник, хоть любую его DLL.

Лоадер написан на Borland C++ 5.0 с использованием VCL. На выхлопе получается ~100 кб., сжимается до ~45 кб.

Держите и пользуйтесь, кому надо.


/*

MemPatcher
A process memory patcher

Written by Tim
E-mail: timqwerty@yandex.ru

12/26/2005 1.00 Первая версия

*/

#include <vcl.h>
#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>

long filesize(FILE *stream);
long MyGetFileSize(AnsiString FileName);
int MyMessageBox(AnsiString Text);

WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{

// Создаваемый процесс. Внимание! Это не тот процесс, который будем патчить!
AnsiString RunApplication = "FL.exe";

// Модуль создаваемого процесса, который будем патчить. Это может быть как
// загружаемая DLL, так и сам EXE файл (читай, создаваемый процесс).
AnsiString VictimModule = "FLEngine.dll";

// Размер модуля на жестком диске.
long VictimSize = 1178112;

// Ждем пока протектор/упаковщик распакует данные. Если вы собираетесь
// патчить сам EXE файл, то можете поставить здесь даже 0, а вот если
// будете патчить DLL, то это зависит от ее типа загрузки. Т.е., если она
// находится в таблице импорта создаваемого процесса, то функция CreateProcess
// не вернет управление лоадеру, пока не загрузит все DLL. Значит можно
// поставить даже 0. А вот если тип загрузки DLL - динамический, то возникает
// проблема. Вам нужно будет подобрать такое значение, чтобы создаваемый
// процесс успел загрузить эту DLL (т.е., чтобы она появилась при перечислении
// модулей процесса). Обычно хватает 200-300 мс.
// Еще раз оговорюсь. Это значение имеет очень важную роль, если вы хотите
// патчить DLL, которая подгружается динамически.
unsigned int Delay = 555;

// Количество попыток пропатчить данные. Если вы хотите, чтобы лоадер
// пропатчил процесс до того, как он начнет выполняться с OEP, вам нужно
// проконтролировать количество сделанных попыток. Если лоадер пропатчил все
// с первого раза (0) - значит он не успел сделать это до OEP. Если же попыток
// было несколько (5 и больше) - то есть гарантия, что процесс был пропатчен
// до OEP.
// Внизу по коду есть закоментированный MessageBox. Используйте его для
// контроля попыток.
// Важное замечание. Если вы делаете лоадер на ASProtect, то количество
// попыток может быть равно 0, иначе он выдаст "Error: 45" (ошибка CRC).
unsigned int Retries = 1000;

// Задержка между попытками. Retries * RetryDelay = максимальное время работы
// лоадера. Например, если количество попыток равно 1000, а задержка равна
// 5 мс, то лоадер будет 5 секунд пытаться пропатчить данные.
unsigned int RetryDelay = 0;

// Количество байт в патче (смотрите ниже).
unsigned long DataSize = 24;

// Адрес по которому патчить (смотреть в дампе, без Image Base).
DWORD Address = 0x1C27B4;

// Оригинальные байты.
static const unsigned char OriginalData[] = {
0x33, 0xD2, 0x83, 0x78, 0x18, 0x02, 0x75, 0x0D,
0x8B, 0x40, 0x14, 0x8B, 0x40, 0x08, 0xF6, 0x40,
0x0D, 0x80, 0x0F, 0x95, 0xC2, 0x8B, 0xC2, 0xC3 };

// Измененные байты.
static const unsigned char ModifiedData[] = {
0x33, 0xD2, 0x83, 0x78, 0x18, 0x02, 0x75, 0x0D,
0x8B, 0x40, 0x14, 0x8B, 0x40, 0x08, 0xF6, 0x40,
0x0D, 0x80, 0x0F, 0x95, 0xC2, 0x33, 0xC0, 0xC3 };

// -----

if(!FileExists(RunApplication))
{
MyMessageBox("File doesn't exist:\n" + RunApplication);
exit(1);
}

if(!FileExists(VictimModule))
{
MyMessageBox("File doesn't exist:\n" + VictimModule);
exit(1);
}

if(MyGetFileSize(VictimModule) != VictimSize)
{
MyMessageBox("File is wrong size:\n" + VictimModule);
exit(1);
}

STARTUPINFO si;
PROCESS_INFORMATION pi;

memset(&si, 0, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);

if(CreateProcess(NULL,
AnsiString(RunApplication + " " + lpCmdLine).c_str(),
NULL, NULL,
false,
0,
NULL, NULL,
&si, &pi))
{
Sleep(Delay);

MODULEENTRY32 me;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pi.dwProcessId);

memset(&me, 0, sizeof(MODULEENTRY32));
me.dwSize = sizeof(MODULEENTRY32);

if(!hSnapshot)
{
MyMessageBox("Can't take a snapshot of the module:\n" + RunApplication);
exit(1);
}

bool Status = false;

if(Module32First(hSnapshot, &me))
do
{
if(AnsiString(me.szModule).LowerCase() == VictimModule.LowerCase())
{
// -----

bool DataDiffers;
unsigned long BytesRead;
unsigned long BytesWrote;
unsigned char *Data = new unsigned char[DataSize];
unsigned int RetriesCount = 0;

while(RetriesCount < Retries)
{
if(!ReadProcessMemory(pi.hProcess,
(LPVOID)(Address + (DWORD)me.modBaseAddr),
(LPVOID)Data,
DataSize,
&BytesRead))
{
MyMessageBox("Can't read process memory:\n" + VictimModule);
exit(1);
}

if(BytesRead != DataSize)
{
MyMessageBox("Read the wrong number of bytes:\n" + VictimModule);
exit(1);
}

DataDiffers = false;

for(unsigned long i = 0; i < DataSize; i++)
if(Data[i] != OriginalData[i])
{
DataDiffers = true;
break;
}

if(!DataDiffers)
break;

Sleep(RetryDelay);

RetriesCount++;
}

if(DataDiffers)
{
MyMessageBox("File is wrong version:\n" + VictimModule);
exit(1);
}

SuspendThread(pi.hThread);

if(!WriteProcessMemory(pi.hProcess,
(LPVOID)(Address + (DWORD)me.modBaseAddr),
(LPVOID)ModifiedData,
DataSize,
&BytesWrote))
{
MyMessageBox("Can't write process memory:\n" + VictimModule);
exit(1);
}

ResumeThread(pi.hThread);
CloseHandle (pi.hThread);

if(BytesWrote != DataSize)
MyMessageBox("Wrote the wrong number of bytes:\n" + VictimModule);

Status = true;

// Контроль попыток.
/*
MessageBox(NULL,
AnsiString("Number of retries: " + IntToStr(RetriesCount)).c_str(),
"Information",
MB_ICONINFORMATION);
*/
// -----

break;
}
}
while(Module32Next(hSnapshot, &me));

if(!Status)
MyMessageBox("Module not found in the snapshot:\n" + VictimModule);

CloseHandle(hSnapshot);
}
else
{
MyMessageBox("Can't execute:\n" + RunApplication);
exit(1);
}

return 0;
}

long filesize(FILE *stream)
{
long curpos;
long length;
curpos = ftell(stream);
fseek(stream, 0L, SEEK_END);
length = ftell(stream);
fseek(stream, curpos, SEEK_SET);
return length;
}

long MyGetFileSize(AnsiString FileName)
{
long length;
FILE *in = fopen(FileName.c_str(), "rb");

if(in)
{
length = filesize(in);
fclose(in);
return length;
}

return -1;
}

int MyMessageBox(AnsiString Text)
{
return MessageBox(NULL, Text.c_str(), "Error", MB_ICONERROR);
}


-----
MicroSoft? Is it some kind of a toilet paper?




Ранг: 253.9 (наставник)
Активность: 0.130
Статус: Участник

Создано: 26 декабря 2005 00:18
· Личное сообщение · #2

Нда... А где же старые рамки у кода? И почему выравнивание по левому краю? =(

-----
MicroSoft? Is it some kind of a toilet paper?




Ранг: 253.9 (наставник)
Активность: 0.130
Статус: Участник

Создано: 26 декабря 2005 00:23
· Личное сообщение · #3

Вот исходник в ZIP'е. Сохранено оформление.

c404_MemPatcher.zip.zip

-----
MicroSoft? Is it some kind of a toilet paper?




Ранг: 3.9 (гость)
Активность: 0.010
Статус: Участник

Создано: 02 августа 2010 18:19
· Личное сообщение · #4

http://www.exelab.ru/f/files/c404_MemPatcher.zip.zip

Уважаемый Тим, а ЕХЕника нету?




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 02 августа 2010 18:37
· Личное сообщение · #5

Только не говори, что через 5 лет ты реально рассчитываешь от него ответ. Учитывая, что он сам тут был 5 месяцев назад.




Ранг: 355.4 (мудрец), 55thx
Активность: 0.320
Статус: Uploader
5KRT

Создано: 02 августа 2010 19:35
· Личное сообщение · #6

Зачем нужен экзе, если код под нужды затачивается?

-----
Gutta cavat lapidem. Feci, quod potui. Faciant meliora potentes




Ранг: 3.9 (гость)
Активность: 0.010
Статус: Участник

Создано: 03 августа 2010 05:57
· Личное сообщение · #7

Coderess пишет:
Зачем нужен экзе, если код под нужды затачивается?


Он же сам написал.

Tim пишет:
Поэтому написал свой, довольно универсальный лоадер. Можно патчить хоть сам EXE'шник, хоть любую его DLL.


А я писать программы не умею.

Archer пишет:
Только не говори, что через 5 лет ты реально рассчитываешь от него ответ. Учитывая, что он сам тут был 5 месяцев назад.


Ну так заглядывает же иногда.




Ранг: 324.3 (мудрец), 221thx
Активность: 0.480.37
Статус: Участник

Создано: 03 августа 2010 05:59
· Личное сообщение · #8

alt, взял бы и скомпилил.

-----
IZ.RU




Ранг: 3.9 (гость)
Активность: 0.010
Статус: Участник

Создано: 03 августа 2010 06:28
· Личное сообщение · #9

DenCoder пишет:
alt, взял бы и скомпилил.


Не умею.
Но если не найду подходящий, видимо, придется учиться.




Ранг: 355.4 (мудрец), 55thx
Активность: 0.320
Статус: Uploader
5KRT

Создано: 03 августа 2010 13:45
· Личное сообщение · #10

alt
Не умею.
Пора начинать, как раз есть пример, мотивация разобраться, скачай справочник по Си смотри в MSDN - разбирайся, firststeps.ru - очень хороший сайт

-----
Gutta cavat lapidem. Feci, quod potui. Faciant meliora potentes



 eXeL@B —› Крэки, обсуждения —› MemPatcher sources
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати