Results 1 to 1 of 1
  1. #1
    Grooguz
    Grooguz is offline
    BanHammer Holder
    Grooguz's Avatar
    Join Date
    2010 May
    Posts
    678
    Thanks Thanks Given 
    152
    Thanks Thanks Received 
    537
    Thanked in
    167 Posts
    Rep Power
    14

    Easiest way to Hide Injected DLL in Windows

    Hiding your injected DLL may be unnecessary when you inject DLL into your own process (e.g. for debugging purposes), but what if you are a tough malware researcher trying to trace the activity of some bad executable? In such case, the less you inform the malware you deal with about your presence - the better.

    In this article I will cover the easiest way to hide your injected library from the "victim" process. Intentionally or not, but we will have to dive a bit into Windows internals starting with the TIB (Thread Information Block) and ending with good old UNICODE_STRING data structure.


    TIB - Thread Information Block (aka TEB)
    You may remember the [FS: 0x00000000] cell. There are thousands of resources mentioning this memory location (and this blog is not an exception) mainly as a location which contains the address of the latest EXCEPTION_REGISTRATION structure added. It is also the first cell of the Thread Information Block (TIB), which is a Win32 structure containing information about the running thread.

    I am not going to provide the full declaration of this structure here, as we have almost no interest in it. Those interested may read this. What we do need, is the data located at offset 0x30 in the TIB - the address of the Process Environment Block (PEB).

    Depending on the programming language you are using, you need to do the following in order to get the PEB address:

    for Assemby:
    Code:
       mov eax, [fs:0x30]  ;FASM syntax
        or
       movl %fs:0, %eax   ;AT&T syntax (if you use mingw32, for instance)
    for C:
    Code:
    /* Microsoft C */
    __asm 
    {
       mov eax, fs:[0x30]
       mov [addr], eax
    }
    
    /* mingw32 */
    __asm__("movl %%fs:0, %0":"=r"(addr));
    in both cases addr is the name of the variable where you want to store the address of the PEB.


    PEB - Process Environment Block
    Alright, now we have the PEB address. But how should we store it? All is clear in case of Assembly - just store it as double word, but what about C? There are several options. Given that we are not going to do much with it, you can store it as an unsigned int or void*. In either case, I believe it will be interesting to see what lies beneath the name. Therefore, let's declare the _PEB structure and PEB type (you may take the declaration from here). There are several things that you have to keep in mind if you are writing in Assembly:
    • BOOL should be defined as db (sizeof(BOOL) equals to sizeof(char));
    • BYTE speaks for itself and is equal to db;
    • HANDLE, ULONG, PVOID, PPVOID and other pointers are all double words and should be defined as dd.


    Field at offset 0x02 (BeingDebugged) may be used for debugger detection, however, this method may be unreliable and should be backed up by additional checks. But the field of interest for us is the LoaderData, located at offset 0x0C. This field contains the address of the PEB_LDR_DATA structure which will lead us to the list of loaded modules (the main executable that started the process and all the loaded DLLs).


    PEB_LDR_DATA

    There is not much to say about it. The structure itself is described below:

    Code:
    typedef struct _PEB_LDR_DATA
    {
       ULONG      Length;
       BOOL       Initialized;
       PVOID      SsHandle;
       LIST_ENTRY InLoadOrderModuleList;
       LIST_ENTRY InMemoryOrderModuleList;
       LIST_ENTRY InInitializationOrderModuleList;
    }PEB_LDR_DATA, *PPEB_LDR_DATA;

    The LIST_ENTRY structure is declared as follows:

    Code:
    typedef struct _LIST_ENTRY
    {
       struct _LIST_ENTRY  *Flink;
       struct _LIST_ENTRY  *Blink;
    }LIST_ENTRY, *PLIST_ENTRY;
    Each LIST_ENTRY structure in PEB_LDR_DATA represents a head of chain of structures, which in turn are parts of the LDR_MODULE structure (we will see that in a minute).
    InLoadOrderModuleList represents the linked list of loaded modules ordered by the load order (first loaded module is the main executable).
    InMemoryOrderModuleList represents the linked list of loaded modules ordered by their memory location (by their module handles).
    InInitializationOrderModuleList represents the linked list of loaded modules in the order they were initialized. However, it is important to remember, that the Flink and Blink point to the LIST_ENTRY structures, not to the LDR_MODULE structures. Let me explain it in the next section.


    LDR_MODULE
    We finally have reached the structure that we've been looking for. Each LDR_MODULE structure has all the basic information about one of the modules present in memory and the list of these structures is used by several Windows API functions (for example GetModuleHandle).

    Let us inspect the declaration of the LDR_MODULE structure before we start looking for one related to our injected DLL:

    Code:
    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;
    It may be a good suggestion to use the InLoadOrderModuleList for going through the linked list of LDR_MODULE as its Blink and Flink pointers also point to the beginning of the LDR_MODULE structure, whereas, if you decide to use InMemoryOrderModuleList, you would have to subtract the size of LIST_ENTRY structure from either Flink or Blink in order to get the address of the LDR_MODULE structure. If you are masochistic enough to use InInitializationOrderModuleList, then you would have to subtract sizeof(LIST_ENTRY) * 2. I said masochistic, but it is not really that painful if you keep in mind that you are dealing with pointers and cast your variables properly.

    Lets see what we have here. The first is the LIST_ENTRY structure used to link modules in the order they were loaded, the second - in the order they are positioned in virtual memory and the third - in the order they (modules) have been initialized.

    BaseAddress is the actual address where the module is loaded at. In ideal case, it is equal to the ImageBase specified in the Optional Header of a PE file, but it may differ.

    EntryPoint is the address of the entry point of that specific module or NULL if the module has not entry point (which is allowable for DLLs).

    SizeOfImage - the size of the image in memory.

    FullDllName - full name of the module, including full path to the file. Important to mention that it is stored in the form of UNICODE_STRING which has the following format:

    Code:
    typedef struct _LSA_UNICODE_STRING
    {
       USHORT Length;
       USHORT MaximumLength;
       PWSTR  Buffer;
    } LSA_UNICODE_STRING, *PLSA_UNICODE_STRNIG, UNICODE_STRING, *PUNICODE_STRING;
    BaseDllName - the name of the file itself. Represented as a UNICODE_STRING as well. Most likely, this is the field that you would use in order to find the entry related to your injected DLL.


    Last Step
    The last step to take in order to hide your injected DLL is to simply remove it from the linked list of the LDR_MODULE structures. My assumption is that if you dare to mess with Windows internals, you probably know how to mess with linked lists and, therefore, are able to perform that operation.
    written by Alexey Lyashko

  2. The Following User Says Thank You to Grooguz For This Useful Post:


Similar Threads

  1. Replies: 8
    Last Post: 2020-11-09, 11:05 AM
  2. [Question] Injected Dll creating controls
    By codeprada in forum C/C++
    Replies: 1
    Last Post: 2010-12-14, 02:48 PM
  3. Replies: 0
    Last Post: 2010-11-29, 04:08 PM
  4. [Sources] Hiding injected dll
    By ADACH in forum Anti-Cheat Systems
    Replies: 3
    Last Post: 2010-11-29, 03:42 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •