Модератор форума
-
Автор темы
- #1
Привет, опять я хуйней маюсь, да
Сегодня у нас гайд как запустить свою функцию в другом процессе без дополнительного выделения памяти под нее
Мини-алгоритм:
Структуры, которые нам понадобятся:
Сама фунция, которая будет вызвана:
Найдем процесс, откроем его, найдем адрес и размер интересующего нас модуля (откуда мы будем выполнять наш поток), создадим структуру аргумента и заполним ее
Функция, с помощью которой мы найдем пустое пространство:
Этой функцией найдем пустые пространства под функцию и аргумент, сменим протект, запишем функцию, аргумент
Запустим сам поток, дождемся его завершения и закроем дескриптор
Так как размер моей функции я нашел, я могу обнулить ее саму в своем процессе и записать уже обнуленные байты в удаленный процесс
Размер своей функции ищите сами, а лучше ставьте размер 0х1000 и для обнуления создавайте массив из 0х1000 байт, обнуляйте его и пишите уже относительно его
Я использую фиксированный размер, т.к. моя функция маленькая и по пизде вряд-ли что-то пойдет
Так вот, снимем протект у себя в процессе со своей функции, обнулим, поставим протект обратно, обнулим аргумент, запишем аргумент и функцию в удаленный процесс так, как мы это делали до этого, после чего установим исходный протект и закроем процесс
Запустим empty.exe и наш процесс:
Исходный код всего проекта -
Сегодня у нас гайд как запустить свою функцию в другом процессе без дополнительного выделения памяти под нее
Мини-алгоритм:
- Находим пустое пространство в модуле под функцию
- Находим пустое пространство под аргумент
- Меняем защиту на этих адресных пространствах
- Записываем в память функцию и аргумент
- Выполняем
- Обнуляем
- Ставим протект обратно
Структуры, которые нам понадобятся:
C++:
struct ModInfo
{
DWORD Base;
DWORD Size;
};
struct Arg
{
fnLoadLibraryA pLoadLibraryA; // адрес LoadLibraryA для загрузки модулей, откуда мы возьмем импорт MessageBoxA
fnMessageBoxA pMessageBoxA; // сам MessageBoxA
char msg[255];
char title[255];
char user32[255];
};
C++:
void Function(Arg* arg)
{
arg->pLoadLibraryA(arg->user32);
arg->pMessageBoxA(0, arg->msg, arg->title, 0);
}
C++:
DWORD ProcessId = FindProcessId("empty.exe");
if (!ProcessId)
{
cout << "Counldn't find process\n";
Quit(1);
}
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
if (hProc == INVALID_HANDLE_VALUE || !hProc)
{
cout << "Failed to open process\n";
Quit(1);
}
LPCSTR Module = "ntdll.dll"; // модуль, из которого мы будем запускать поток (выбрать можете любой, но учтите, что он должен существовать в процессе)
ModInfo Info = GetModInfo(Module, ProcessId);
Arg arg;
arg.pLoadLibraryA = LoadLibraryA;
arg.pMessageBoxA = MessageBoxA;
strcpy(arg.msg, "message");
strcpy(arg.title, "title");
strcpy(arg.user32, "user32.dll");
C++:
DWORD FreeSpaceInModule(const HANDLE& hProc, const ModInfo& Info, const DWORD& Size)
{
// скопируем модуль себе
BYTE* Bytes = new BYTE[Info.Size];
ReadProcessMemory(hProc, (LPCVOID)(Info.Base), Bytes, Info.Size, nullptr);
int Matches = 0;
// найдем адрес, начиная с которого в модуле будет 00 Size раз
for (int i = 0; i < Info.Size - 1; i++)
{
if (Bytes[i] == 0)
Matches++;
else
Matches = 0;
if (Matches == Size)
{
delete[] Bytes;
return Info.Base + i;
}
}
delete[] Bytes;
return 0;
}
C++:
PVOID pFunc = (PVOID)FreeSpaceInModule(hProc, Info, FunctionLength);
PVOID pArg = (PVOID)FreeSpaceInModule(hProc, Info, sizeof(arg));
DWORD OldProtect_Function = 0;
DWORD OldProtect_Arg = 0;
if (!pFunc || !pArg)
{
cout << "Couldn't find free memory in " << Module << endl;
CloseHandle(hProc);
Quit(1);
}
cout << "Found free memory for function at 0x" << pFunc << endl;
cout << "Found free memory for argument at 0x" << pArg << endl;
if (!VirtualProtectEx(hProc, pFunc, FunctionLength, PAGE_EXECUTE_READWRITE, &OldProtect_Function))
{
cout << "VirtualProtectEx (1) failed with status: " << GetLastError() << endl;
CloseHandle(hProc);
Quit(1);
}
if (!VirtualProtectEx(hProc, pArg, sizeof(arg), PAGE_EXECUTE_READWRITE, &OldProtect_Arg))
{
cout << "VirtualProtectEx (2) failed with status: " << GetLastError() << endl;
VirtualProtectEx(hProc, pFunc, FunctionLength, OldProtect_Function, &OldProtect_Function);
CloseHandle(hProc);
Quit(1);
}
if (!WriteProcessMemory(hProc, pFunc, Function, FunctionLength, nullptr))
{
cout << "WriteProcessMemory (1) failed with status: " << GetLastError() << endl;
VirtualProtectEx(hProc, pFunc, FunctionLength, OldProtect_Function, &OldProtect_Function);
VirtualProtectEx(hProc, pFunc, sizeof(arg), OldProtect_Arg, &OldProtect_Arg);
CloseHandle(hProc);
Quit(1);
}
if (!WriteProcessMemory(hProc, pArg, &arg, sizeof(arg), nullptr))
{
cout << "WriteProcessMemory (2) failed with status: " << GetLastError() << endl;
VirtualProtectEx(hProc, pFunc, FunctionLength, OldProtect_Function, &OldProtect_Function);
VirtualProtectEx(hProc, pFunc, sizeof(arg), OldProtect_Arg, &OldProtect_Arg);
CloseHandle(hProc);
Quit(1);
}
C++:
HANDLE hThread = CreateRemoteThread(hProc, nullptr, 0, (LPTHREAD_START_ROUTINE)pFunc, pArg, 0, nullptr);
if (hThread == INVALID_HANDLE_VALUE || !hThread)
{
cout << "Failed to create remote thread\n";
Quit(1);
}
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
Размер своей функции ищите сами, а лучше ставьте размер 0х1000 и для обнуления создавайте массив из 0х1000 байт, обнуляйте его и пишите уже относительно его
Я использую фиксированный размер, т.к. моя функция маленькая и по пизде вряд-ли что-то пойдет
Так вот, снимем протект у себя в процессе со своей функции, обнулим, поставим протект обратно, обнулим аргумент, запишем аргумент и функцию в удаленный процесс так, как мы это делали до этого, после чего установим исходный протект и закроем процесс
C++:
DWORD OldFunctionProtect1 = 0;
VirtualProtect(Function, FunctionLength, PAGE_EXECUTE_READWRITE, &OldFunctionProtect1);
ZeroMemory(&arg, sizeof(arg));
ZeroMemory(Function, FunctionLength);
VirtualProtect(Function, FunctionLength, OldFunctionProtect1, &OldFunctionProtect1);
WriteProcessMemory(hProc, pFunc, Function, FunctionLength, nullptr);
WriteProcessMemory(hProc, pArg, &arg, sizeof(arg), nullptr);
VirtualProtectEx(hProc, pFunc, FunctionLength, OldProtect_Function, &OldProtect_Function);
VirtualProtectEx(hProc, pFunc, sizeof(arg), OldProtect_Arg, &OldProtect_Arg);
CloseHandle(hProc);
Исходный код всего проекта -
Пожалуйста, авторизуйтесь для просмотра ссылки.