#include <windows.h>
#include <psapi.h>
#include <tchar.h>
#include <stdio.h>
// To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS
// and compile with -DPSAPI_VERSION=1#define ARRAY_SIZE 1024
int PrintModules(DWORD processID)
{
HMODULE hMods[1024];
HANDLE hProcess;
DWORD cbNeeded;
unsigned int i;
// Print the process identifier.
printf("\nProcess ID: %u\n", processID);
// Get a handle to the process.
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID);
if (NULL == hProcess)
return 1;
// Get a list of all the modules in this process.if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
{
for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++)
{
TCHAR szModName[MAX_PATH];
// Get the full path to the module's file.if (GetModuleFileNameEx(hProcess, hMods[i], szModName,
sizeof(szModName) / sizeof(TCHAR)))
{
// Print the module name and handle value.int len = lstrlenW(szModName);
if (len > 5)
{
for (int h = 0; h < len - lstrlenW(L"user32"); h++)
{
if (memcmp(&szModName[h], L"USER32", lstrlenW(L"USER32")) == 0 || memcmp(&szModName[h], L"user32", lstrlenW(L"user32")) == 0)
{
printf("\n USER32 detect");
char *TPTP = (char*)hMods[i];
if (FreeLibrary(hMods[i]))
{
printf("\n unload complited.");
}
else
{
DWORD Err = GetLastError();
printf("\n can't unload");
}
break;
}
}
}
_tprintf(TEXT("\t%s (0x%08X)\n"), szModName, hMods[i]);
}
}
}
// Release the handle to the process.
CloseHandle(hProcess);
return 0;
}
int main(void)
{
bool ppp = LoadLibrary(L"aecache.dll");
PrintModules(GetCurrentProcessId());
printf("\n\n\n\n\n");
PrintModules(GetCurrentProcessId());
Доброго времени суток. Подскажите , почему я не могу выгрузить user32.dll из памяти процесса, хотя FreeLibrary возвращает true????
Не понимаю.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, reider, Вы писали:
PD>Ты отдаешь себе отчет, что ты пытаешься выгрузить DLL из своего процесса , а вовсе не из процесса, который ты открыл, причем с правами только чтения ?
Да, конечно.
Нашёл проблему. Совсем не учёл что другие dll также могут подключать ту dll которую я пытаюсь выгрузить.
Так что решил так: while (FreeLibrary(hMods[i]))Sleep(1);
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, reider, Вы писали:
PD>Ты отдаешь себе отчет, что ты пытаешься выгрузить DLL из своего процесса , а вовсе не из процесса, который ты открыл, причем с правами только чтения ?
Но почему то этот подход применим не ко всем dll.
Если dll не имеет процедуры обработки выгрузки, как её отключить?
Т.е. поясню свой вопрос.
Я хочу сделать процесс свободный от всех ненужных мне системных dll ,а также dll которые нагружаються извне.
Хочу защитить свою программу от внешних хуков.
Может я иду не тем путём?
Заранее благодареню
Здравствуйте, reider, Вы писали:
R>Я хочу сделать процесс свободный от всех ненужных мне системных dll ,а также dll которые нагружаються извне. R>Хочу защитить свою программу от внешних хуков. R>Может я иду не тем путём?
Я конечно 15 лет назад в последний раз под виндой что-то программировал, но от хуков ты так не защитишься, т.к. есть WriteProcessMemory.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, reider, Вы писали:
R>Я хочу сделать процесс свободный от всех ненужных мне системных dll ,а также dll которые нагружаються извне.
Тут все просто — не нужные просто не нужно подключать. Разве не?
R>Хочу защитить свою программу от внешних хуков. R>Может я иду не тем путём? R>Заранее благодареню
Думаю, что не тем: выгружать уже загруженную DLL в общем виде бесполезно — она к тому моменту уже окопалась и напакостила.
В хроме этим занимается chrome_elf, может там разглядите чего-нибудь интересного. У них есть черный список dll которые они не грузят.
PD>>Ты отдаешь себе отчет, что ты пытаешься выгрузить DLL из своего процесса , а вовсе не из процесса, который ты открыл, причем с правами только чтения ? R>Но почему то этот подход применим не ко всем dll.
Есть куча проблем которые вызовет выгрузка user32.dll. Просто говоря — это очень изощренный способ лишить себя ноги.
R>Я хочу сделать процесс свободный от всех ненужных мне системных dll ,а также dll которые нагружаються извне. R>Хочу защитить свою программу от внешних хуков. R>Может я иду не тем путём?
Я так делал: при запуске процесса, дабы избавиться от всех инжектов:
1) Запускал процесс в suspended состоянии, "удаленно" перехватывая в нем CsrClientConnectToServer — вешая на нее trampoline который LdrLoadDll'ем загружал мою длл, которая зависела только от ntdll (причем в основном только от сисколлов, Rtl* юзались очень ограниченно), и делала следующие вещи, уже в контексте дрочернего процесса (и это не опечатка ):
2) Киляла все треды своего процесса кроме текущего
3) unmap-ла все длл кроме ntdll и себя
4) вычитывала с диска секцию кода и секцию инициализированных данных ntdll и _перезаписывала_ текущий образ ntdll тем что вычитал из диска. Секцию неинициализированных данных заполняла нулями
4.1) Тоже самое проделывала с образом исполняемого файла.
5) приводила структуры связанные PEBом процесса к виду, в котором он выглядит на момент запуска
6) перезапускала загрузчик процесса вызовом LdrInitializeThunk
Разумеется код на 80% основывался на результате детального реверсинга поведения ntdll, и всех деталей я сейчас не упомню. Скажу лишь например, что параметры LdrInitializeThunk разнятся от винды к винде, как и структуры, относящиеся к PEB'у.
Вощем, это была кропотливая работа, на базе десятилетнего опыта ковыряния в кишках винды. С бухты барахты оно просто не взлетит.
НО, если не страдать перфекционизмом, то можно сделать упрощенный вариант, который поможет от сплайсинг-хуков: просто вычитываете все имеющиеся в ап длл из диска, и восстанавливаете начала экспортируемых функций в памяти согласно вычитанному с диска. Важно: нужно пропарсить таблицу релоков, и применить их к восстановленному коду.
Как много веселых ребят, и все делают велосипед...
Здравствуйте, Mystic Artifact, Вы писали:
MA> В хроме этим занимается chrome_elf, может там разглядите чего-нибудь интересного. У них есть черный список dll которые они не грузят.
Если кратко, то там хукается NtMapViewOfSection — давая ей работать, если же это то, что мы блокируем — вызывается Unmap.
Но в целом, жестко не давать загружать "чужие" DLL — идейка так себе, например, видеодрайвер может чего-то догружать, что будет разниться от версии к версии и производителя.
Здравствуйте, reider, Вы писали:
R>Но почему то этот подход применим не ко всем dll. R>Если dll не имеет процедуры обработки выгрузки, как её отключить?
Что значит не имеет ? DllMain всегда есть.
R>Т.е. поясню свой вопрос. R>Я хочу сделать процесс свободный от всех ненужных мне системных dll ,а также dll которые нагружаються извне.
По-моему, это хороший способ сделать, чтобы процесс рухнул в самом неожиданном месте в самый неожиданный момент.
R>Хочу защитить свою программу от внешних хуков.
Это не поможет, могут поставить новый
И зачем тебе понадобилась user32.dll ? В консольные приложения она не грузится (как правило), GUI приложения без нее не могут.
Здравствуйте, reider, Вы писали:
PD>>Ты отдаешь себе отчет, что ты пытаешься выгрузить DLL из своего процесса , а вовсе не из процесса, который ты открыл, причем с правами только чтения ?
R>Да, конечно.
А тогда зачем это открытие процесса и перечисление его модулей ?
Здравствуйте, ononim, Вы писали:
PD>>>Ты отдаешь себе отчет, что ты пытаешься выгрузить DLL из своего процесса , а вовсе не из процесса, который ты открыл, причем с правами только чтения ? R>>Но почему то этот подход применим не ко всем dll. O>Есть куча проблем которые вызовет выгрузка user32.dll. Просто говоря — это очень изощренный способ лишить себя ноги.
R>>Я хочу сделать процесс свободный от всех ненужных мне системных dll ,а также dll которые нагружаються извне. R>>Хочу защитить свою программу от внешних хуков. R>>Может я иду не тем путём? O>Я так делал: при запуске процесса, дабы избавиться от всех инжектов: O>1) Запускал процесс в suspended состоянии, "удаленно" перехватывая в нем CsrClientConnectToServer — вешая на нее trampoline который LdrLoadDll'ем загружал мою длл, которая зависела только от ntdll (причем в основном только от сисколлов, Rtl* юзались очень ограниченно), и делала следующие вещи, уже в контексте дрочернего процесса (и это не опечатка ): O>2) Киляла все треды своего процесса кроме текущего O>3) unmap-ла все длл кроме ntdll и себя O>4) вычитывала с диска секцию кода и секцию инициализированных данных ntdll и _перезаписывала_ текущий образ ntdll тем что вычитал из диска. Секцию неинициализированных данных заполняла нулями O>4.1) Тоже самое проделывала с образом исполняемого файла. O>5) приводила структуры связанные PEBом процесса к виду, в котором он выглядит на момент запуска O>6) перезапускала загрузчик процесса вызовом LdrInitializeThunk O>Разумеется код на 80% основывался на результате детального реверсинга поведения ntdll, и всех деталей я сейчас не упомню. Скажу лишь например, что параметры LdrInitializeThunk разнятся от винды к винде, как и структуры, относящиеся к PEB'у.
O>Вощем, это была кропотливая работа, на базе десятилетнего опыта ковыряния в кишках винды. С бухты барахты оно просто не взлетит. O>НО, если не страдать перфекционизмом, то можно сделать упрощенный вариант, который поможет от сплайсинг-хуков: просто вычитываете все имеющиеся в ап длл из диска, и восстанавливаете начала экспортируемых функций в памяти согласно вычитанному с диска. Важно: нужно пропарсить таблицу релоков, и применить их к восстановленному коду.
ИМХО LdrInitializeThunk использовать реально только для одного и того же образа винды ( Так что для меня это совсем не вариант.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, reider, Вы писали:
R>>Но почему то этот подход применим не ко всем dll. R>>Если dll не имеет процедуры обработки выгрузки, как её отключить?
PD>Что значит не имеет ? DllMain всегда есть.
R>>Т.е. поясню свой вопрос. R>>Я хочу сделать процесс свободный от всех ненужных мне системных dll ,а также dll которые нагружаються извне.
PD>По-моему, это хороший способ сделать, чтобы процесс рухнул в самом неожиданном месте в самый неожиданный момент.
R>>Хочу защитить свою программу от внешних хуков.
PD>Это не поможет, могут поставить новый
PD>И зачем тебе понадобилась user32.dll ? В консольные приложения она не грузится (как правило), GUI приложения без нее не могут.
Здравствуйте, reider, Вы писали:
R>Я хочу сделать процесс свободный от всех ненужных мне системных dll ,а также dll которые нагружаються извне. R>Хочу защитить свою программу от внешних хуков.
См. SetProcessMitigationPolicy, коды ProcessDynamicCodePolicy (запрет динамической генерации кода,
т.е. VirtualAlloc/VirtualProtect/etc с флагами PAGE_EXECUTE) и ProcessSignaturePolicy (запрет загрузки dll,
которые не подписаны Microsoft), эти API доступны на Windows 8.1 и выше.
Можно еще запускать процесс на low/untrusted integrity level (chrome так делает и некоторые другие приложения), в
песочнице AppContainer (Windows 8 и выше), под restricted-токеном (CreateRestrictedToken), внутри Job-объекта с
соответствующими ограничениями (см. CreateJobObject, SetInformationJobObject, AssignProcessToJobObject).
Это не защитит на 100% от загрузки чужих dll, но в большинстве случаев затруднит их работу.
Здравствуйте, okman, Вы писали:
O>Здравствуйте, reider, Вы писали:
R>>Я хочу сделать процесс свободный от всех ненужных мне системных dll ,а также dll которые нагружаються извне. R>>Хочу защитить свою программу от внешних хуков.
O>См. SetProcessMitigationPolicy, коды ProcessDynamicCodePolicy (запрет динамической генерации кода, O>т.е. VirtualAlloc/VirtualProtect/etc с флагами PAGE_EXECUTE) и ProcessSignaturePolicy (запрет загрузки dll, O>которые не подписаны Microsoft), эти API доступны на Windows 8.1 и выше.
O>Можно еще запускать процесс на low/untrusted integrity level (chrome так делает и некоторые другие приложения), в O>песочнице AppContainer (Windows 8 и выше), под restricted-токеном (CreateRestrictedToken), внутри Job-объекта с O>соответствующими ограничениями (см. CreateJobObject, SetInformationJobObject, AssignProcessToJobObject). O>Это не защитит на 100% от загрузки чужих dll, но в большинстве случаев затруднит их работу.