Добавление записи в PEB

Тема в разделе "WASM.BEGINNERS", создана пользователем sideX, 23 июн 2010.

  1. sideX

    sideX New Member

    Публикаций:
    0
    Регистрация:
    9 июн 2009
    Сообщения:
    57
    Приветствую вас, уважаемые.
    Имеется ситуация - в процесс загружается DLL, внутри DllMain происходит удаление записи об ее имени из списков InLoadOrderModuleList и InMemoryOrderModuleList.
    вот код:
    Код (Text):
    1. hModule - хэндл DLL
    2.  
    3. HideDllFromPEB  proc uses esi edi ebx hModule : DWORD
    4.         LOCAL   lpBuffer : DWORD
    5.         LOCAL   lpName   : DWORD
    6.        
    7.         invoke  LocalAlloc, LPTR, 256
    8.         mov lpBuffer, eax
    9.        
    10.         invoke  LocalAlloc, LPTR, 64
    11.         mov lpName, eax
    12.  
    13.         invoke  GetModuleFileNameA, hModule, lpBuffer, 256
    14.         test    eax, eax
    15.         jz  _return
    16.        
    17.         mov esi, lpBuffer
    18.         mov ecx, eax
    19.         dec eax
    20. @@:
    21.         cmp byte ptr [esi + eax], '\'
    22.         jz  @F
    23.         dec eax
    24.         jmp @B
    25. @@:
    26.         inc eax
    27.         add esi, eax
    28.         sub ecx, eax
    29.        
    30.         xor eax, eax
    31.         mov edi, lpName
    32. @@:
    33.         lodsb
    34.         stosw
    35.         loop    @B
    36.  
    37.         assume  fs : nothing
    38.         mov     eax, fs :[30h]
    39.         mov     eax, [eax + 0Ch]
    40.         mov     eax, [eax + 0Ch]
    41.         mov ebx, eax
    42. @@:
    43.         mov ecx, [eax + 30h]
    44.         push    eax
    45.         invoke  lstrcmpiW, ecx, lpName
    46.         test    eax, eax
    47.         pop eax
    48.         jz  _found
    49.         mov     eax, [eax]
    50.         test    eax, ebx
    51.         jnz @B
    52.         jmp _return
    53. _found:
    54.         call    _del_peb_entry
    55.         add     eax, 8
    56.         call    _del_peb_entry
    57.  
    58. _return:
    59.         invoke  LocalFree, lpName
    60.         invoke  LocalFree, lpBuffer
    61.         ret
    62.  
    63. _del_peb_entry:
    64.         push    eax
    65.         mov eax, [eax + 4]
    66.         mov     ebx, [eax]
    67.         mov     ebx, [ebx]
    68.         mov     dword ptr [eax], ebx
    69.         mov     ebx, [eax + 4]
    70.         mov     ebx, [ebx + 4]
    71.         mov     dword ptr [eax + 4], ebx
    72.         pop eax
    73.         retn       
    74. HideDllFromPEB  endp
    после того как DLL отработала мне необходимо удалить ее, но выгрузить само собой не получается.
    Подскажите пожалуйста каким образом реализовать данную задачу. Понимаю что нужно вернуть запись в PEB. Буду рад любым примерам.
    Благодарю за внимание
     
  2. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    каким образом пробовал удалять?
     
  3. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Попробуй UnmapViewOfFile() на базовый адрес ДЛЛ. Всех проблем не решит, но блокировку с файла снимет
     
  4. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    На случай, если потребуется когда-нибудь работа со списками загрузчика.

    Код (Text):
    1. #include <ntdll.h>
    2. #include <stdio.h>
    3.  
    4. //////////////////////////////////////////////////////////////////////////
    5. // Some loader stuff
    6.  
    7. #define LDRP_HASH_TABLE_SIZE 32
    8. #define LDRP_HASH_MASK       (LDRP_HASH_TABLE_SIZE-1)
    9. #define LDRP_COMPUTE_HASH_INDEX(wch) ( (RtlUpcaseUnicodeChar((wch)) - (WCHAR)'A') & LDRP_HASH_MASK )
    10.  
    11. // Loader hash table.
    12. // This table contains 32 list heads to double-linked lists for each hash index (0..31).
    13. // Indexes are computed from uppercased first character of base dll name (see LDRP_COMPUTE_HASH_INDEX)
    14. // Real prototype in ntdll:   LIST_ENTRY LdrpHashTable[LDRP_HASH_TABLE_SIZE];
    15. PLIST_ENTRY LdrpHashTable;
    16.  
    17. // Global loader heap
    18. HANDLE LdrHeap;
    19.  
    20. // Find loader heap
    21. BOOL FindLoaderHeap ()
    22. {
    23.     PPEB_LDR_DATA Ldr = NtCurrentPeb()->Ldr;
    24.     MEMORY_BASIC_INFORMATION mbi;
    25.     PLDR_DATA_TABLE_ENTRY NtdllEntry;
    26.    
    27.     // Get any pointer within this heap.
    28.     NtdllEntry = CONTAINING_RECORD (Ldr->InInitializationOrderModuleList.Flink, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
    29.  
    30.     // Query VM information (base address)
    31.     if (VirtualQuery (NtdllEntry, &mbi, sizeof(mbi)))
    32.     {
    33.         LdrHeap = (HANDLE) mbi.AllocationBase;
    34.         return TRUE;
    35.     }
    36.     return FALSE;
    37. }
    38.  
    39. // Find LdrpHashTable[] table with list heads
    40. BOOL FindLdrpHashTable ()
    41. {
    42.     PPEB_LDR_DATA Ldr = NtCurrentPeb()->Ldr;
    43.  
    44.     // get ntdll entry
    45.     PLDR_DATA_TABLE_ENTRY Ntdll = CONTAINING_RECORD (Ldr->InInitializationOrderModuleList.Flink, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
    46.     UCHAR NtdllHashIndex = LDRP_COMPUTE_HASH_INDEX (Ntdll->BaseDllName.Buffer[0]);
    47.  
    48.     // get ntdll.dll module bounds
    49.     ULONG_PTR NtdllBase = (ULONG_PTR) Ntdll->DllBase;
    50.     ULONG_PTR NtdllEndAddress = NtdllBase + Ntdll->SizeOfImage - 1;
    51.  
    52.     // scan hash list to the head (head is located within ntdll)
    53.     BOOL bHeadFound = FALSE;
    54.     PLIST_ENTRY pNtdllHashHead = NULL;
    55.  
    56.     for (PLIST_ENTRY e = Ntdll->HashLinks.Flink; e != &Ntdll->HashLinks; e = e->Flink)
    57.     {
    58.         if ((ULONG_PTR)e >= NtdllBase && (ULONG_PTR)e < NtdllEndAddress)
    59.         {
    60.             bHeadFound = TRUE;
    61.             pNtdllHashHead = e;
    62.             break;
    63.         }
    64.     }
    65.  
    66.     if (bHeadFound)
    67.     {
    68.         LdrpHashTable = pNtdllHashHead - NtdllHashIndex;
    69.     }
    70.  
    71.     return bHeadFound;
    72. }
    73.  
    74. // Allocate LDR_DATA_TABLE_ENTRY from loader heap
    75. __inline PLDR_DATA_TABLE_ENTRY LdrpAllocateEntry ()
    76. {
    77.     return (PLDR_DATA_TABLE_ENTRY) HeapAlloc (LdrHeap, HEAP_ZERO_MEMORY, sizeof(LDR_DATA_TABLE_ENTRY));
    78. }
    79.  
    80. // Perform generic search in loader lists for the specified dll.
    81. PVOID LdrpSlowFindDllHandle (PWSTR BaseDllName)
    82. {
    83.     UNICODE_STRING usBaseDllName;
    84.     PLIST_ENTRY pLoadOrderHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
    85.  
    86.     RtlInitUnicodeString (&usBaseDllName, BaseDllName);
    87.  
    88.     for (PLIST_ENTRY e = pLoadOrderHead->Flink; e != pLoadOrderHead; e = e->Flink)
    89.     {
    90.         PLDR_DATA_TABLE_ENTRY LoaderEntry = CONTAINING_RECORD (e, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
    91.  
    92.         if (!RtlCompareUnicodeString (&LoaderEntry->BaseDllName, &usBaseDllName, TRUE))
    93.         {
    94.             return LoaderEntry->DllBase;
    95.         }
    96.     }
    97.  
    98.     return NULL;
    99. }
    100.  
    101. // Perform fast search for the specified dll by hash
    102. PVOID LdrpFastFindDllHandle (PWSTR BaseDllName)
    103. {
    104.     UNICODE_STRING usBaseDllName;
    105.     PLIST_ENTRY pHashTableHead = &LdrpHashTable[LDRP_COMPUTE_HASH_INDEX(BaseDllName[0])];
    106.  
    107.     RtlInitUnicodeString (&usBaseDllName, BaseDllName);
    108.  
    109.     for (PLIST_ENTRY e = pHashTableHead->Flink; e != pHashTableHead; e = e->Flink)
    110.     {
    111.         PLDR_DATA_TABLE_ENTRY LoaderEntry = CONTAINING_RECORD (e, LDR_DATA_TABLE_ENTRY, HashLinks);
    112.  
    113.         if (!RtlCompareUnicodeString (&LoaderEntry->BaseDllName, &usBaseDllName, TRUE))
    114.         {
    115.             return LoaderEntry->DllBase;
    116.         }
    117.     }
    118.  
    119.     //return LdrpSlowFindDllHandle (BaseDllName);
    120.     return NULL;
    121. }
    122.  
    123. PLDR_DATA_TABLE_ENTRY LdrpFastGetCachedEntry (PWSTR BaseDllName)
    124. {
    125.     UNICODE_STRING usBaseDllName;
    126.     PLIST_ENTRY pHashTableHead = &LdrpHashTable[LDRP_COMPUTE_HASH_INDEX(BaseDllName[0])];
    127.  
    128.     RtlInitUnicodeString (&usBaseDllName, BaseDllName);
    129.  
    130.     for (PLIST_ENTRY e = pHashTableHead->Flink; e != pHashTableHead; e = e->Flink)
    131.     {
    132.         PLDR_DATA_TABLE_ENTRY LoaderEntry = CONTAINING_RECORD (e, LDR_DATA_TABLE_ENTRY, HashLinks);
    133.  
    134.         if (!RtlCompareUnicodeString (&LoaderEntry->BaseDllName, &usBaseDllName, TRUE))
    135.         {
    136.             return LoaderEntry;
    137.         }
    138.     }
    139.  
    140.     return NULL;
    141. }
    142.  
    143. BOOL LdrAddModuleToLdrLists (PVOID hModule, PWSTR FullDllName)
    144. {
    145.     PPEB_LDR_DATA Ldr = NtCurrentPeb()->Ldr;
    146.     PLDR_DATA_TABLE_ENTRY e;
    147.     PIMAGE_NT_HEADERS NtHeaders;
    148.  
    149.     if (!(e = LdrpAllocateEntry ()))
    150.         return FALSE; // insufficient resources?
    151.  
    152.     NtHeaders = (PIMAGE_NT_HEADERS) RtlImageNtHeader (hModule);
    153.  
    154.     e->DllBase = hModule;
    155.     e->EntryPoint = (PUCHAR)hModule + NtHeaders->OptionalHeader.AddressOfEntryPoint;
    156.     e->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
    157.  
    158.     SIZE_T cchCount = wcslen(FullDllName);
    159.     PWSTR wszDllNameCopy = (PWSTR) HeapAlloc (LdrHeap, HEAP_ZERO_MEMORY, cchCount*2+2);
    160.     if (wszDllNameCopy == NULL)
    161.     {
    162.         HeapFree (LdrHeap, 0, e);
    163.         return FALSE;
    164.     }
    165.  
    166.     wcscpy (wszDllNameCopy, FullDllName);
    167.  
    168.     RtlInitUnicodeString (&e->FullDllName, wszDllNameCopy);
    169.  
    170.     PWCHAR pSlash = (PWCHAR) wcsrchr (wszDllNameCopy, L'\\');
    171.     if (pSlash)
    172.     {
    173.         RtlInitUnicodeString (&e->BaseDllName, pSlash+1);
    174.         e->BaseDllName.MaximumLength = (USHORT)((cchCount - (pSlash - wszDllNameCopy))*2);
    175.     }
    176.  
    177.     e->Flags =
    178.         LDRP_IMAGE_DLL |                  // this entry describes a DLL
    179.         LDRP_ENTRY_PROCESSED |            // entry point has been already called
    180.         LDRP_PROCESS_ATTACH_CALLED |      // DLL_PROCESS_ATTACH called, don't call again
    181.         LDRP_DONT_CALL_FOR_THREADS;       // don't call DLL_THREAD_ATTACH/DLL_THREAD_DETACH
    182.  
    183.     e->LoadCount = 1;
    184.     e->TlsIndex = 0;
    185.     e->TimeDateStamp = NtHeaders->FileHeader.TimeDateStamp;
    186.     e->EntryPointActivationContext = NULL; // no activation context (wtf is actx?!)
    187.     e->PatchInformation; // no patch information, for kernel images only.
    188.  
    189.     //
    190.     // LDR_DATA_TABLE_ENTRY allocated & initialized.
    191.     // Insert in the appropriate lists.
    192.     //
    193.  
    194.     UCHAR HashIndex = LDRP_COMPUTE_HASH_INDEX (e->BaseDllName.Buffer[0]);
    195.  
    196.     InsertTailList (&LdrpHashTable[HashIndex], &e->HashLinks);
    197.     InsertTailList (&Ldr->InInitializationOrderModuleList, &e->InInitializationOrderLinks);
    198.     InsertTailList (&Ldr->InLoadOrderModuleList, &e->InLoadOrderLinks);
    199.  
    200.     //bugbug
    201.     InsertTailList (&Ldr->InMemoryOrderModuleList, &e->InMemoryOrderLinks);
    202.    
    203.     return TRUE;   
    204. }
    205.  
    206. VOID LdrRemoveModuleFromLdrLists (PVOID BaseAddress)
    207. {
    208.     PLDR_DATA_TABLE_ENTRY Entry = NULL;
    209.     PPEB_LDR_DATA Ldr = NtCurrentPeb()->Ldr;
    210.     BOOL bEntryFound = FALSE;
    211.  
    212.     for (PLIST_ENTRY e = Ldr->InLoadOrderModuleList.Flink; e != &Ldr->InLoadOrderModuleList; e = e->Flink)
    213.     {
    214.         Entry = CONTAINING_RECORD (e, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
    215.  
    216.         if (Entry->DllBase == BaseAddress)
    217.         {
    218.             bEntryFound = TRUE;
    219.             break;
    220.         }
    221.     }
    222.  
    223.     if (!bEntryFound) return;
    224.  
    225.     RemoveEntryList (&Entry->InLoadOrderLinks);
    226.     RemoveEntryList (&Entry->InInitializationOrderLinks);
    227.     RemoveEntryList (&Entry->InMemoryOrderLinks);
    228.     RemoveEntryList (&Entry->HashLinks);
    229.  
    230.     HeapFree (LdrHeap, 0, Entry->FullDllName.Buffer);
    231.     HeapFree (LdrHeap, 0, Entry);
    232. }
    233.  
    234. void xxLdrDumpFlags (ULONG f)
    235. {
    236. #define DUMP_FLAG(VALUE) if(f & VALUE) printf(#VALUE " ");
    237.     DUMP_FLAG (LDRP_STATIC_LINK);
    238.     DUMP_FLAG (LDRP_IMAGE_DLL);
    239.     DUMP_FLAG (LDRP_LOAD_IN_PROGRESS);
    240.     DUMP_FLAG (LDRP_UNLOAD_IN_PROGRESS);
    241.     DUMP_FLAG (LDRP_ENTRY_PROCESSED);
    242.     DUMP_FLAG (LDRP_ENTRY_INSERTED);
    243.     DUMP_FLAG (LDRP_CURRENT_LOAD);
    244.     DUMP_FLAG (LDRP_FAILED_BUILTIN_LOAD);
    245.     DUMP_FLAG (LDRP_DONT_CALL_FOR_THREADS);
    246.     DUMP_FLAG (LDRP_PROCESS_ATTACH_CALLED);
    247.     DUMP_FLAG (LDRP_DEBUG_SYMBOLS_LOADED);
    248.     DUMP_FLAG (LDRP_IMAGE_NOT_AT_BASE);
    249.     DUMP_FLAG (LDRP_COR_IMAGE);
    250.     DUMP_FLAG (LDRP_COR_OWNS_UNMAP);
    251.     DUMP_FLAG (LDRP_SYSTEM_MAPPED);
    252.     DUMP_FLAG (LDRP_IMAGE_VERIFYING);
    253.     DUMP_FLAG (LDRP_DRIVER_DEPENDENT_DLL);
    254.     DUMP_FLAG (LDRP_ENTRY_NATIVE);
    255.     DUMP_FLAG (LDRP_REDIRECTED);
    256.     DUMP_FLAG (LDRP_NON_PAGED_DEBUG_INFO);
    257.     DUMP_FLAG (LDRP_MM_LOADED);
    258.     DUMP_FLAG (LDRP_COMPAT_DATABASE_PROCESSED);
    259.     printf("\n");
    260. }
    261.  
    262. void LdrpDumpEntry (PLDR_DATA_TABLE_ENTRY e)
    263. {
    264.     printf("LDR_DATA_TABLE_ENTRY at %p\n", e);
    265.     printf(" load links: [%p %p]\n", e->InLoadOrderLinks.Blink, e->InLoadOrderLinks.Flink);
    266.     printf(" memory links: [%p %p]\n", e->InMemoryOrderLinks.Blink, e->InMemoryOrderLinks.Flink);
    267.     printf(" init links: [%p %p]\n", e->InInitializationOrderLinks.Blink, e->InInitializationOrderLinks.Flink);
    268.     printf(" DllBase: %p\n", e->DllBase);
    269.     printf(" EntryPoint: %p\n", e->EntryPoint);
    270.     printf(" SizeOfImage: %p\n", e->SizeOfImage);
    271.     printf(" FullDllName: '%wZ'\n", &e->FullDllName);
    272.     printf(" BaseDllName: '%wZ'\n", &e->BaseDllName);
    273.     printf(" Flags: %08x\n", e->Flags);
    274.     xxLdrDumpFlags (e->Flags);
    275.     printf(" LoadCount: %04x\n", e->LoadCount);
    276.     printf(" TlsIndex: %04x\n", e->TlsIndex);
    277.     printf("  HashLinks: [%p %p]\n", e->HashLinks.Blink, e->HashLinks.Flink);
    278.     printf("  SectionPointer: %p\n", e->SectionPointer);
    279.     printf("  CheckSum: %p\n", e->CheckSum);
    280.     printf("  TimeDateStamp: %p\n", e->TimeDateStamp);
    281.     printf("  LoadedImports: %p\n", e->LoadedImports);
    282.     printf(" EntryPointActivationContext: %p\n", e->EntryPointActivationContext);
    283.     printf(" PatchInformation: %p\n", e->PatchInformation);
    284.     printf("\n");
    285. }
    286.  
    287. void* memdup (void* source, size_t length)
    288. {
    289.     void* dst = VirtualAlloc (0, length, MEM_COMMIT, PAGE_READWRITE);
    290.     if (dst)
    291.     {
    292.         memcpy (dst, source, length);
    293.     }
    294.     return dst;
    295. }
    296.  
    297. void swap_dwords (DWORD* a, DWORD *b)
    298. {
    299.     DWORD t = *a;
    300.     *a = *b;
    301.     *b = t;
    302. }
    303.  
    304. int main()
    305. {
    306.     if (!FindLoaderHeap ())
    307.         return printf ("Could not find loader heap\n");
    308.     printf("Loader heap handle: %p\n", LdrHeap);
    309.  
    310.     if (!FindLdrpHashTable ())
    311.         return printf ("Could not find LdrpHashTable[] array address\n");
    312.     printf("LdrpHashTable[] is %p\n", LdrpHashTable);
    313.  
    314.     //
    315.     // Try to add my own fake entry to loader lists.
    316.     //
    317.  
    318.     WCHAR path[MAX_PATH];
    319.  
    320.     HMODULE hDll = LoadLibrary ("smalldll.dll");
    321.     PIMAGE_NT_HEADERS NtHeaders = (PIMAGE_NT_HEADERS) RtlImageNtHeader (hDll);
    322.     SIZE_T ImageSize = NtHeaders->OptionalHeader.SizeOfImage;
    323.  
    324.     printf ("library loaded at %p, image size %lx\n", hDll, ImageSize);
    325.  
    326.     PVOID pDuplicate = memdup (hDll, ImageSize);
    327.     FreeLibrary (hDll);
    328.  
    329.     printf ("duplicated rgn at %p\n", pDuplicate);
    330.  
    331.     GetCurrentDirectoryW (sizeof(path)/2, path);
    332.     wcscat (path, L"\\smalldll.dll");
    333.  
    334.     PVOID BaseAddress = (PVOID) hDll;
    335.     SIZE_T RegionSize = ImageSize;
    336.     NTSTATUS Status;
    337.  
    338. #if 0
    339.     Status = ZwAllocateVirtualMemory (
    340.         NtCurrentProcess(),
    341.         &BaseAddress,
    342.         0,
    343.         &RegionSize,
    344.         MEM_COMMIT,
    345.         PAGE_EXECUTE_READWRITE
    346.         );
    347.  
    348.     printf ("ZwAllocateVirtualMemory: %lx (allocated at %p)\n", Status, BaseAddress);
    349. #else
    350.     HANDLE hTempSection = CreateFileMapping (INVALID_HANDLE_VALUE, 0, PAGE_EXECUTE_READWRITE, 0, ImageSize, 0);
    351.     printf("hTempSection %lx\n", hTempSection);
    352.  
    353.     Status = ZwMapViewOfSection (
    354.         hTempSection,
    355.         NtCurrentProcess(),
    356.         &BaseAddress,
    357.         0,
    358.         0,
    359.         0,
    360.         &RegionSize,
    361.         ViewUnmap,
    362.         MEM_DOS_LIM,
    363.         PAGE_EXECUTE_READWRITE
    364.         );
    365.  
    366.     printf ("ZwMapViewOfSection: %lx (mapped at %p)\n", Status, BaseAddress);
    367. #endif
    368.  
    369.     if (NT_SUCCESS(Status))
    370.     {
    371.         memcpy (BaseAddress, pDuplicate, ImageSize);
    372.         VirtualFree (pDuplicate, 0, MEM_RELEASE);
    373.  
    374.         printf ("copied duplicated rgn %p to re-allocated memory %p\n", pDuplicate, BaseAddress);
    375.  
    376.         if (LdrAddModuleToLdrLists (BaseAddress, path))
    377.         {
    378.             printf ("added %S (%p) to module lists\n", path, pDuplicate);
    379.  
    380.             PLDR_DATA_TABLE_ENTRY NtdllEntry = LdrpFastGetCachedEntry (L"ntdll.dll");
    381.  
    382.             RemoveEntryList (&NtdllEntry->InLoadOrderLinks);
    383.             RemoveEntryList (&NtdllEntry->InMemoryOrderLinks);
    384.             RemoveEntryList (&NtdllEntry->InInitializationOrderLinks);
    385.             RemoveEntryList (&NtdllEntry->HashLinks);
    386.  
    387. //          PLDR_DATA_TABLE_ENTRY Kernel32Entry = LdrpFastGetCachedEntry (L"kernel32.dll");
    388. //          swap_dwords ((DWORD*)&NtdllEntry->DllBase, (DWORD*)&Kernel32Entry->DllBase);
    389. //          swap_dwords ((DWORD*)&NtdllEntry->SizeOfImage, (DWORD*)&Kernel32Entry->SizeOfImage);
    390. //          swap_dwords ((DWORD*)&NtdllEntry->EntryPoint, (DWORD*)&Kernel32Entry->EntryPoint);
    391.  
    392. //          PLIST_ENTRY Head = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
    393. //          for (PLIST_ENTRY e = Head->Flink; e != Head; e = e->Flink)
    394. //          {
    395. //              PLDR_DATA_TABLE_ENTRY Ldr = (PLDR_DATA_TABLE_ENTRY) e;
    396. //              Ldr->DllBase = (PVOID) 0x7c800000;
    397. //              Ldr->SizeOfImage = 0x10000;
    398. //          }
    399.  
    400.             __asm int 3;
    401.         }
    402.     }
    403.  
    404.  
    405. //  GetSystemDirectoryW (path, sizeof(path)-1);
    406. //  wcscat (path, L"\\csrsrv.dll");
    407. //
    408. //  HANDLE hFile = CreateFileW (path, GENERIC_READ | GENERIC_EXECUTE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
    409. //  printf("CreateFile for '%S' returned handle %lx\n", path, hFile);
    410. //
    411. //  if (hFile != INVALID_HANDLE_VALUE)
    412. //  {
    413. //      NTSTATUS Status;
    414. //      HANDLE hSection;
    415. //      OBJECT_ATTRIBUTES Oa;
    416. //
    417. //      InitializeObjectAttributes (&Oa, 0, 0, 0, 0);
    418. //      Status = ZwCreateSection (
    419. //          &hSection,
    420. //          SECTION_MAP_READ | SECTION_MAP_EXECUTE,
    421. //          &Oa,
    422. //          NULL,
    423. //          PAGE_EXECUTE,
    424. //          SEC_IMAGE,
    425. //          hFile
    426. //          );
    427. //
    428. //      printf("ZwCreateSection returned status %lx, handle %lx\n", Status, hSection);
    429. //       
    430. //      if (NT_SUCCESS (Status))
    431. //      {
    432. //          PVOID BaseAddress = 0;
    433. //          SIZE_T ViewSize = 0;
    434. //
    435. //          Status = ZwMapViewOfSection (
    436. //              hSection,
    437. //              NtCurrentProcess(),
    438. //              &BaseAddress,
    439. //              0,
    440. //              0,
    441. //              NULL,
    442. //              &ViewSize,
    443. //              ViewUnmap,
    444. //              MEM_TOP_DOWN,
    445. //              PAGE_EXECUTE);
    446. //         
    447. //          printf("ZwMapViewOfSection returned status %lx, base address %p, view size 0x%lx\n", Status, BaseAddress, ViewSize);
    448. //
    449. //          if (NT_SUCCESS(Status))
    450. //          {
    451. //              HMODULE hm;
    452. //
    453. //              hm = GetModuleHandle ("csrsrv.dll");
    454. //              printf("GetModuleHandle(csrsrv.dll) before inserting LDR_DATA_TABLE_ENTRY returned  %p\n", hm);
    455. //
    456. //              if (LdrAddModuleToLdrLists (BaseAddress, path))
    457. //              {
    458. //                  printf("Module has been added to module lists\n");
    459. //
    460. //                  hm = GetModuleHandle ("csrsrv.dll");
    461. //                  printf("GetModuleHandle(csrsrv.dll) after inserting LDR_DATA_TABLE_ENTRY returned  %p\n", hm);
    462. //
    463. //                  LdrRemoveModuleFromLdrLists (BaseAddress);
    464. //              }
    465. //             
    466. //              UnmapViewOfFile (BaseAddress);
    467. //          }
    468. //
    469. //          CloseHandle (hSection);
    470. //      }
    471. //
    472. //      CloseHandle (hFile);
    473. //  }
    474.  
    475. //////////////////////////////////////////////////////////////////////////
    476.  
    477. //  //
    478. //  // Perform fast search in loader hash lists.
    479. //  //
    480. //
    481. //  PVOID hKernel32 = LdrpFastFindDllHandle (L"kernel32.dll");
    482. //  printf("LdrpFastFindDllHandle(L\"kernel32.dll\") returned %p\n", hKernel32);
    483.  
    484. //////////////////////////////////////////////////////////////////////////
    485.  
    486. //  //
    487. //  // Try to find ntdll.dll in hash entries for 'N' (to check if LdrpHashTable[] address is valid)
    488. //  //
    489. //
    490. //  PLIST_ENTRY pHashTableForN = &LdrpHashTable[LDRP_COMPUTE_HASH_INDEX('n')];
    491. //  printf("hash list head for 'N'(ntdll) is: %p\n", pHashTableForN);
    492. //
    493. //  printf("\nDumping dlls for 'N':\n");
    494. //
    495. //  for (PLIST_ENTRY e = pHashTableForN->Flink; e != pHashTableForN; e = e->Flink)
    496. //  {
    497. //      PLDR_DATA_TABLE_ENTRY Entry = CONTAINING_RECORD (e, LDR_DATA_TABLE_ENTRY, HashLinks);
    498. //      LdrpDumpEntry (Entry);
    499. //  }
    500.  
    501. //////////////////////////////////////////////////////////////////////////
    502.  
    503. //  //
    504. //  // Dump entries
    505. //  //
    506. //
    507. //  LoadLibrary("csrsrv.dll");
    508. //
    509. //  PPEB_LDR_DATA Ldr = NtCurrentPeb()->Ldr;
    510. //
    511. //  for (PLIST_ENTRY e = Ldr->InLoadOrderModuleList.Flink; e != &Ldr->InLoadOrderModuleList; e = e->Flink)
    512. //  {
    513. //      PLDR_DATA_TABLE_ENTRY loaderEntry = (PLDR_DATA_TABLE_ENTRY) e;
    514. //      LdrpDumpEntry (loaderEntry);
    515. //  }
    516.  
    517. //////////////////////////////////////////////////////////////////////////
    518.  
    519.     return 0;
    520. }
    Пример хорошо откомментирован и в пояснении не нуждается.

    Заголовочный ntdll.h (сам составлял) со структурами everfall.com

    Вероятно, тебя заинтересуют LdrAddModuleToLdrLists и LdrRemoveModuleFromLdrLists.
    Обращаю внимание на то, что существуют кроме трех основных списков (in memory order, in init order, in load order) еще 32 списка по хешам первой буквы имени (upcase(name[0]) % 32), про которые никто не помнит, как обычно. А GetModuleHandle/LoadLibrary смотрят их в первую очередь, потому что так быстрее искать, чем полным перебором (см. LdrpSlowFindDllHandle, LdrpFastFindDllHandle, LdrpFastGetCachedEntry)
     
  5. Rustem

    Rustem New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2004
    Сообщения:
    429
    Адрес:
    Russia
    sideX Если из DllMain вернуть 0, то загрузчик сам должен удалить запись об длл
     
  6. s_d_f

    s_d_f New Member

    Публикаций:
    0
    Регистрация:
    15 май 2008
    Сообщения:
    342
    Для безопасного добавления/удаления существует ещё критическая секция.
    Вход в критическую секцию:

    NTSYSAPI
    NTSTATUS
    NTAPI
    LdrLockLoaderLock(
    IN DWORD dwFlags,
    OUT PULONG LockTry OPTIONAL,
    OUT PULONG ThreadLocks);

    Для dwFlags
    #define LOCK_GENERATE_EXEPTIONS 1 //исключение если один из параметвов не правильный
    #define LOCK_MUST_BE_TRY 2 //не входить если секция занята, LockTry тогда обязательный
    остальные биты должны быть сброшены.

    LockTry
    0 - занято
    1 - была свободной
    2 - не была свободной, но вход выполнен

    ThreadLocks - переменная значение которой нужно сохранить для выхода из секции.

    NTSYSAPI
    NTSTATUS
    NTAPI
    LdrUnlockLoaderLock(
    IN DWORD dwFlags,
    IN ULONG ThreadLocks);
     
  7. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    s_d_f
    да, про нее чето забыл совсем)
     
  8. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    Тоже с этим сталкивался.
    Нужно сделать ZwUnmapViewOfSection c адресом загрузки DLL (который получен в DllMain).
    После загрузки DLL надо сделать DisableThreadLibraryCalls, чтобы после выгрузки не вызвалась уже не существующая DllMain.
     
  9. dign

    dign Дмитрий Игнатьев

    Публикаций:
    0
    Регистрация:
    29 мар 2010
    Сообщения:
    3
    Адрес:
    Херсон
    В Win2000 этой функции нет, но в PEB есть критическая секция, которую должна использовать эта функция.
    Поэтому надо еще версию системы учитывать.
     
  10. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    не спасет от DLL_PROCESS_DETACH
    да, и оффсет вроде фиксирован. там же есть и указатели, чтото типа FastLoaderLockRoutine, FastLoaderUnlockRoutine.
     
  11. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    Great
    спасает
     
  12. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    K10
    UPD: действительно)
     
  13. sideX

    sideX New Member

    Публикаций:
    0
    Регистрация:
    9 июн 2009
    Сообщения:
    57
    Всем огромное спасибо. Проблема решена.
     
  14. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
  15. СFF

    СFF PP

    Публикаций:
    0
    Регистрация:
    16 янв 2009
    Сообщения:
    233
    Очень помогли сорсы Great'a, но начиная с win7 там другая хеш функция. На радостях выкладываю сорсы
    Код (Text):
    1. LdrpGetHashIndex proc uses ebx esi edi pString:PUNICODE_STRING
    2.     xor eax,eax
    3.     cmp pString,0
    4.     je _exit
    5.    
    6.     mov eax,dword ptr ds:[7FFE026Ch]
    7.     mov ecx,dword ptr ds:[7FFE0270h]
    8.     shl eax,8
    9.     mov al,cl
    10.        
    11.     .if eax>=OS_WIN7
    12.         xor ebx,ebx
    13.         mov esi,pString
    14.         assume esi:PUNICODE_STRING
    15.         mov esi,[esi].Buffer
    16.         mov edi,esi
    17.         mov eax,pString
    18.         assume eax:PUNICODE_STRING
    19.         movsx eax,[eax]._Length
    20.         add esi,eax
    21.         sub esi,2
    22.     @@:
    23.         cmp edi,esi
    24.         jg @F
    25.                    
    26.         movsx eax,word ptr [esi]
    27.         invoke RtlUpcaseUnicodeChar,eax
    28.         imul eax,1003Fh
    29.         add ebx,eax
    30.                    
    31.         dec esi
    32.         dec esi
    33.         jmp @B
    34.     @@:
    35.         xchg eax,ebx
    36.     .else
    37.         mov eax,pString
    38.         assume eax:PUNICODE_STRING
    39.         mov eax,[eax].Buffer
    40.         movsx eax,word ptr [eax]
    41.         or eax,20h
    42.         sub eax,'A'
    43.     .endif
    44.    
    45.     and eax,31
    46. _exit:
    47.     ret
    48. LdrpGetHashIndex endp
     
  16. gloomyraven

    gloomyraven Руслан

    Публикаций:
    0
    Регистрация:
    16 апр 2006
    Сообщения:
    288
    Адрес:
    Москва
    Что-то у меня не работает добавление модуля в Windows 7 x64 (не срабатывает GetModuleHandle на загруженной из памяти dll)...
    В winXP все нормально.
    Можете помочь? (Конкретно проблема в том, что в загруженной dll не обрабатываются исключения)
     
  17. gloomyraven

    gloomyraven Руслан

    Публикаций:
    0
    Регистрация:
    16 апр 2006
    Сообщения:
    288
    Адрес:
    Москва
    Похоже, что обработка исключений не связана с присутствием dll в списке модулей. Я загрузил dll обычным способом (LoadLibrary) и удалил ее из PEB => исключения ловились правильно...