找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 6173|回复: 1

LoadLibrary解析(二)

[复制链接]
发表于 2015-6-14 12:17:37 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
为了实现隐藏dll,不得已出此文对LoadLibrary的解析,该函数比较庞大,尽管已经去除了很多无关代码,仍然有500行。
其中有重定位代码,值得借鉴

  1. HINSTANCE WINAPI LoadLibraryExW(LPCWSTR lpLibFileName,HANDLE hFile,DWORD dwFlags)
  2. {
  3.         UNICODE_STRING DllName;
  4.         HINSTANCE hInst;
  5.         NTSTATUS Status;
  6.         PWSTR SearchPath;
  7.         ULONG DllCharacteristics = 0;
  8.         BOOL FreeString = FALSE;

  9.         RtlInitUnicodeString(&DllName, (LPWSTR)lpLibFileName);
  10.         //比较看是否为当前exe
  11.         if (BasepExeLdrEntry && !(dwFlags & LOAD_LIBRARY_AS_DATAFILE) && DllName.Length == BasepExeLdrEntry->FullDllName.Length)
  12.         {
  13.                 if (RtlEqualUnicodeString(&DllName, &BasepExeLdrEntry->FullDllName, TRUE))
  14.                 {
  15.                         return BasepExeLdrEntry->DllBase;
  16.                 }
  17.         }
  18.         //获取系统路径 Path
  19.         SearchPath = BaseComputeProcessDllPath((dwFlags & LOAD_WITH_ALTERED_SEARCH_PATH) ?DllName.Buffer : NULL,NULL);
  20.         Status = LdrLoadDll(SearchPath,&DllCharacteristics,&DllName,(PVOID*)&hInst);
  21. }

  22. NTSTATUS NTAPI LdrLoadDll(IN PWSTR SearchPath OPTIONAL,IN PULONG DllCharacteristics OPTIONAL,
  23.         IN PUNICODE_STRING DllName, OUT PVOID *BaseAddress)
  24. {
  25.         //初始化加载器锁
  26.         LdrLockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, NULL, &Cookie);// Peb->LoaderLock = &LdrpLoaderLock;
  27.         Status = LdrpLoadDll(RedirectedDll,SearchPath,DllCharacteristics,DllName,BaseAddress,TRUE);
  28.         LdrUnlockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, Cookie);
  29. }

  30. NTSTATUS NTAPI LdrpLoadDll(IN BOOLEAN Redirected,IN PWSTR DllPath OPTIONAL,IN PULONG DllCharacteristics OPTIONAL,
  31.         IN PUNICODE_STRING DllName,OUT PVOID *BaseAddress,IN BOOLEAN CallInit)
  32. {
  33.         PPEB Peb = NtCurrentPeb();
  34.         NTSTATUS Status = STATUS_SUCCESS;
  35.         const WCHAR *p;
  36.         BOOLEAN GotExtension;
  37.         WCHAR c;
  38.         WCHAR NameBuffer[MAX_PATH + 6];
  39.         UNICODE_STRING RawDllName;
  40.         PLDR_DATA_TABLE_ENTRY LdrEntry;
  41.         BOOLEAN InInit = LdrpInLdrInit;

  42.         //处理路径及后缀。。。。。。。。。

  43.         if (!LdrpCheckForLoadedDll(DllPath,&RawDllName,FALSE,Redirected,&LdrEntry))
  44.         {//如果未加载过则映射该DLL
  45.                 Status = LdrpMapDll(DllPath,DllPath,NameBuffer,DllCharacteristics,FALSE,Redirected,&LdrEntry);
  46.                 if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++;
  47.                 LdrpUpdateLoadCount2(LdrEntry, LDRP_UPDATE_REFCOUNT);
  48.                 else if (LdrEntry->LoadCount != 0xFFFF)////如果不是dll,则只增加引用计数
  49.                 {
  50.                         LdrEntry->LoadCount++;
  51.                 }
  52.                 //插入Ldr链
  53.                 InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,&LdrEntry->InInitializationOrderModuleList);
  54.         }
  55.         else
  56.         {//检查是否为dll映像
  57.                 if ((LdrEntry->Flags & LDRP_IMAGE_DLL) && (LdrEntry->LoadCount != 0xFFFF))
  58.                 {//增加引用计数
  59.                         LdrEntry->LoadCount++;
  60.                         LdrpUpdateLoadCount2(LdrEntry, LDRP_UPDATE_REFCOUNT);
  61.                         LdrpClearLoadInProgress();
  62.                 }
  63.                 else
  64.                 {
  65.                        
  66.                         if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++;
  67.                 }
  68.         }
  69.         *BaseAddress = LdrEntry->DllBase;
  70. }

  71. BOOLEAN NTAPI LdrpCheckForLoadedDll(IN PWSTR DllPath,IN PUNICODE_STRING DllName,IN BOOLEAN Flag,IN BOOLEAN RedirectedDll,
  72.         OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
  73. {
  74.         //指定Flag则在预先生成的哈希表中查找
  75. lookinhash:
  76.         if (Flag)
  77.         {
  78.                 HashIndex = LDR_GET_HASH_ENTRY(DllName->Buffer[0]);
  79.                 //遍历对应哈希表存储的链表
  80.                 ListHead = &LdrpHashTable[HashIndex];
  81.                 ListEntry = ListHead->Flink;
  82.                 while (ListEntry != ListHead)
  83.                 {
  84.                         CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, HashLinks);
  85.                         if (RtlEqualUnicodeString(DllName, &CurEntry->BaseDllName, TRUE))
  86.                         {
  87.                                 *LdrEntry = CurEntry;
  88.                                 return TRUE;
  89.                         }
  90.                         ListEntry = ListEntry->Flink;
  91.                 }
  92.                 return FALSE;
  93.         }

  94.         //未指定Flag则查找并拼合完整路径,如果是相对路径则仍然用哈希表查找,否则用Ldr查找
  95.         if (!FullPath)//拼合过程略。。。。。。。
  96.         {
  97.                 Flag = TRUE;
  98.                 goto lookinhash;
  99.         }

  100.         ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
  101.         ListEntry = ListHead->Flink;
  102.         while (ListEntry != ListHead)
  103.         {
  104.                 CurEntry = CONTAINING_RECORD(ListEntry,LDR_DATA_TABLE_ENTRY,InLoadOrderLinks);
  105.                 ListEntry = ListEntry->Flink;
  106.                 if (!CurEntry->InMemoryOrderModuleList.Flink) continue;//如果正在被卸载
  107.                 if (RtlEqualUnicodeString(&FullDllName,&CurEntry->FullDllName,TRUE))
  108.                 {
  109.                         *LdrEntry = CurEntry;
  110.                         return TRUE;
  111.                 }
  112.         }

  113.         //如果路径名方式未能找到,则采用比对内存PE的方式决定是否加载过
  114.         if (!RtlDosPathNameToNtPathName_U(FullDllName.Buffer,&NtPathName,NULL,NULL))
  115.         {
  116.                 return FALSE;
  117.         }
  118.         //打开DLL文件并映射到虚拟内存
  119.         InitializeObjectAttributes(&ObjectAttributes,&NtPathName,OBJ_CASE_INSENSITIVE,NULL,NULL);
  120.         Status = NtOpenFile(&FileHandle,SYNCHRONIZE | FILE_EXECUTE,&ObjectAttributes,&Iosb,
  121.                 FILE_SHARE_READ | FILE_SHARE_DELETE,FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
  122.         RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
  123.         Status = NtCreateSection(&SectionHandle,SECTION_MAP_READ |SECTION_MAP_EXECUTE |SECTION_MAP_WRITE,
  124.                 NULL,NULL,PAGE_EXECUTE,SEC_COMMIT,FileHandle);
  125.         NtClose(FileHandle);
  126.         Status = ZwMapViewOfSection(SectionHandle,NtCurrentProcess(),&ViewBase,0,0,NULL,&ViewSize,ViewShare,0,PAGE_EXECUTE);
  127.         NtClose(SectionHandle);
  128.         Status = RtlImageNtHeaderEx(0, ViewBase, ViewSize, &NtHeader);//获取NT头

  129.         //重新遍历Ldr,这次采用PE头比较方式判断
  130.         //LIST_ENTRY结构很有特点,双向循环链表,链表头为空节点,所以只需要遍历除了头结点以外的节点,现在终于搞清楚这个事实了^_^
  131.         ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
  132.         ListEntry = ListHead->Flink;
  133.         while (ListEntry != ListHead)
  134.         {
  135.                 CurEntry = CONTAINING_RECORD(ListEntry,LDR_DATA_TABLE_ENTRY,InLoadOrderLinks);
  136.                 ListEntry = ListEntry->Flink;
  137.                 if (!CurEntry->InMemoryOrderModuleList.Flink) continue;
  138.                 if ((CurEntry->TimeDateStamp == NtHeader->FileHeader.TimeDateStamp) &&
  139.                         (CurEntry->SizeOfImage == NtHeader->OptionalHeader.SizeOfImage))
  140.                 {
  141.                         NtHeader2 = RtlImageNtHeader(CurEntry->DllBase);
  142.                         if (RtlCompareMemory(NtHeader2, NtHeader, sizeof(IMAGE_NT_HEADERS)))
  143.                         {
  144.                                 Status = ZwAreMappedFilesTheSame(CurEntry->DllBase, ViewBase);
  145.                                 if (NT_SUCCESS(Status))
  146.                                 {
  147.                                         *LdrEntry = CurEntry;
  148.                                         NtUnmapViewOfSection(NtCurrentProcess(), ViewBase);
  149.                                         _SEH2_YIELD(return TRUE;)
  150.                                 }
  151.                         }
  152.                 }
  153.         }
  154. }

  155. NTSTATUS NTAPI LdrpMapDll(IN PWSTR SearchPath OPTIONAL,IN PWSTR DllPath2, IN PWSTR DllName OPTIONAL, IN PULONG DllCharacteristics,
  156.       IN BOOLEAN Static,IN BOOLEAN Redirect, OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry)
  157. {
  158.         //检查是否加载过
  159. SkipCheck:
  160.     if (!SectionHandle)
  161.     {//如果未加载
  162.         if (LdrpResolveDllName(SearchPath, DllName,&FullDllName, &BaseDllName))
  163.         {
  164.             RtlDosPathNameToNtPathName_U(FullDllName.Buffer, &NtPathDllName, NULL, NULL);
  165.             Status = LdrpCreateDllSection(&NtPathDllName,DllHandle,DllCharacteristics,&SectionHandle);
  166.             RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathDllName.Buffer);
  167.         }
  168.     }
  169.     else
  170.     {
  171.         KnownDll = TRUE;
  172.     }

  173.     ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer;
  174.     Teb->NtTib.ArbitraryUserPointer = FullDllName.Buffer;
  175.         //映射dll
  176.     ViewBase = NULL;
  177.     ViewSize = 0;
  178.     Status = NtMapViewOfSection(SectionHandle,NtCurrentProcess(), &ViewBase,0,0,NULL,&ViewSize,ViewShare, 0, PAGE_READWRITE);
  179.     Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer;
  180.         NtHeaders = RtlImageNtHeader(ViewBase);//检查pe头
  181.     LdrEntry = LdrpAllocateDataTableEntry(ViewBase);//构造链表节点
  182.     LdrEntry->Flags = Static ? LDRP_STATIC_LINK : 0;
  183.     if (Redirect) LdrEntry->Flags |= LDRP_REDIRECTED;
  184.     LdrEntry->LoadCount = 0;
  185.     LdrEntry->FullDllName = FullDllName;
  186.     LdrEntry->BaseDllName = BaseDllName;
  187.     LdrEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(LdrEntry->DllBase);//获取入口点
  188.     LdrpInsertMemoryTableEntry(LdrEntry);//插入新节点到ldr
  189.     *DataTableEntry = LdrEntry;

  190.     //如果需要重定位
  191.     if (Status == STATUS_IMAGE_NOT_AT_BASE)
  192.     {
  193.         LdrEntry->Flags |= LDRP_IMAGE_NOT_AT_BASE;
  194.         ImageBase = (ULONG_PTR)NtHeaders->OptionalHeader.ImageBase;
  195.         ImageEnd = ImageBase + ViewSize;
  196.         ListHead = &Peb->Ldr->InLoadOrderModuleList;
  197.         NextEntry = ListHead->Flink;
  198.         while (NextEntry != ListHead)
  199.         {
  200.             CandidateEntry = CONTAINING_RECORD(NextEntry,LDR_DATA_TABLE_ENTRY,InLoadOrderLinks);
  201.             NextEntry = NextEntry->Flink;
  202.             CandidateBase = (ULONG_PTR)CandidateEntry->DllBase;
  203.             CandidateEnd = CandidateBase + CandidateEntry->SizeOfImage;
  204.             if (!CandidateEntry->InMemoryOrderModuleList.Flink) continue;
  205.             if ((ImageBase >= CandidateBase && ImageBase <= CandidateEnd) ||
  206.                 (ImageEnd >= CandidateBase && ImageEnd <= CandidateEnd) ||
  207.                 (CandidateBase >= ImageBase && CandidateBase <= ImageEnd))
  208.             {
  209.                 OverlapDllFound = TRUE;
  210.                 OverlapDll = CandidateEntry->FullDllName;
  211.                 break;
  212.             }
  213.         }

  214.         if (LdrEntry->Flags & LDRP_IMAGE_DLL)
  215.         {
  216.             if (!(NtHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED))
  217.             {
  218.                 RelocData = RtlImageDirectoryEntryToData(ViewBase, TRUE, IMAGE_DIRECTORY_ENTRY_BASERELOC,  &RelocDataSize);
  219.             }

  220.                         //禁止user32.dll  kernel32.dll重定位
  221.                         //更改节保护属性
  222.             Status = LdrpSetProtection(ViewBase, FALSE);
  223.             if (NT_SUCCESS(Status))
  224.             {//进行重定位
  225.                 Status = LdrRelocateImageWithBias(ViewBase, 0LL, NULL, STATUS_SUCCESS,STATUS_CONFLICTING_ADDRESSES, STATUS_INVALID_IMAGE_FORMAT);//进行重定向
  226.                 if (NT_SUCCESS(Status))
  227.                 {
  228.                     ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer;
  229.                     Teb->NtTib.ArbitraryUserPointer = FullDllName.Buffer;
  230.                     Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer;
  231.                     Status = LdrpSetProtection(ViewBase, TRUE);//还原节保护属性
  232.                 }
  233.             }
  234.         }
  235.     }
  236.     NtClose(SectionHandle);
  237.     return Status;
  238. }

  239. NTSTATUS NTAPI LdrpCreateDllSection(IN PUNICODE_STRING FullName,IN HANDLE DllHandle,IN PULONG DllCharacteristics OPTIONAL,OUT PHANDLE SectionHandle)
  240. {
  241.         if (!DllHandle)
  242.         {
  243.                 InitializeObjectAttributes(&ObjectAttributes,FullName,OBJ_CASE_INSENSITIVE,NULL,NULL);
  244.                 Status = NtOpenFile(&FileHandle,SYNCHRONIZE | FILE_EXECUTE | FILE_READ_DATA,&ObjectAttributes,&IoStatusBlock,
  245.                         FILE_SHARE_READ | FILE_SHARE_DELETE,FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
  246.                 if (!NT_SUCCESS(Status))
  247.                 {//尝试以只读方式打开
  248.                         Status = NtOpenFile(&FileHandle,SYNCHRONIZE | FILE_EXECUTE,&ObjectAttributes,&IoStatusBlock,
  249.                                 FILE_SHARE_READ | FILE_SHARE_DELETE,FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
  250.                 }
  251.         }
  252.         else
  253.         {
  254.                 FileHandle = DllHandle;
  255.         }
  256.         Status = NtCreateSection(SectionHandle,SECTION_MAP_READ | SECTION_MAP_EXECUTE |SECTION_MAP_WRITE | SECTION_QUERY,
  257.                 NULL,NULL,PAGE_EXECUTE,SEC_IMAGE,FileHandle);
  258.         NtClose(FileHandle);
  259.         return Status;
  260. }

  261. PLDR_DATA_TABLE_ENTRY NTAPI LdrpAllocateDataTableEntry(IN PVOID BaseAddress)
  262. {
  263.         PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
  264.         PIMAGE_NT_HEADERS NtHeader;

  265.         NtHeader = RtlImageNtHeader(BaseAddress);
  266.         if (NtHeader)
  267.         {
  268.                 LdrEntry = RtlAllocateHeap(RtlGetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(LDR_DATA_TABLE_ENTRY));
  269.                 if (LdrEntry)
  270.                 {
  271.                         LdrEntry->DllBase = BaseAddress;
  272.                         LdrEntry->SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
  273.                         LdrEntry->TimeDateStamp = NtHeader->FileHeader.TimeDateStamp;
  274.                         LdrEntry->PatchInformation = NULL;
  275.                 }
  276.         }
  277.         return LdrEntry;
  278. }

  279. PVOID NTAPI LdrpFetchAddressOfEntryPoint(IN PVOID ImageBase)
  280. {
  281.         PIMAGE_NT_HEADERS NtHeaders;
  282.         ULONG_PTR EntryPoint = 0;
  283.         NtHeaders = RtlImageNtHeader(ImageBase);
  284.         if (NtHeaders)
  285.         {
  286.                 EntryPoint = NtHeaders->OptionalHeader.AddressOfEntryPoint;
  287.                 if (EntryPoint) EntryPoint += (ULONG_PTR)ImageBase;
  288.         }
  289.         return (PVOID)EntryPoint;
  290. }

  291. VOID NTAPI LdrpInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
  292. {
  293.         PPEB_LDR_DATA PebData = NtCurrentPeb()->Ldr;
  294.         ULONG i;
  295.         i = LDR_GET_HASH_ENTRY(LdrEntry->BaseDllName.Buffer[0]);
  296.         InsertTailList(&LdrpHashTable[i], &LdrEntry->HashLinks);
  297.         InsertTailList(&PebData->InLoadOrderModuleList, &LdrEntry->InLoadOrderLinks);
  298.         InsertTailList(&PebData->InMemoryOrderModuleList, &LdrEntry->InMemoryOrderModuleList);
  299. }

  300. NTSTATUS NTAPI LdrpSetProtection(PVOID ViewBase,BOOLEAN Restore)
  301. {
  302.         PIMAGE_NT_HEADERS NtHeaders;
  303.         PIMAGE_SECTION_HEADER Section;
  304.         NTSTATUS Status;
  305.         PVOID SectionBase;
  306.         SIZE_T SectionSize;
  307.         ULONG NewProtection, OldProtection, i;

  308.         NtHeaders = RtlImageNtHeader(ViewBase);
  309.         if (!NtHeaders) return STATUS_INVALID_IMAGE_FORMAT;
  310.         Section = IMAGE_FIRST_SECTION(NtHeaders);
  311.         for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++)
  312.         {
  313.                 if ((Section->SizeOfRawData) && !(Section->Characteristics & IMAGE_SCN_MEM_WRITE))
  314.                 {
  315.                         if (Restore)
  316.                         {
  317.                                 if (Section->Characteristics & IMAGE_SCN_MEM_EXECUTE)
  318.                                 {
  319.                                         NewProtection = PAGE_EXECUTE;
  320.                                 }
  321.                                 else
  322.                                 {
  323.                                         NewProtection = PAGE_READONLY;
  324.                                 }

  325.                                 if (Section->Characteristics & IMAGE_SCN_MEM_NOT_CACHED)
  326.                                 {
  327.                                         NewProtection |= PAGE_NOCACHE;
  328.                                 }
  329.                         }
  330.                         else
  331.                         {
  332.                                 NewProtection = PAGE_READWRITE;
  333.                         }

  334.                         SectionBase = (PVOID)((ULONG_PTR)ViewBase + Section->VirtualAddress);
  335.                         SectionSize = Section->SizeOfRawData;
  336.                         if (SectionSize)
  337.                         {
  338.                                 Status = ZwProtectVirtualMemory(NtCurrentProcess(),&SectionBase,&SectionSize,NewProtection,&OldProtection);
  339.                                 if (!NT_SUCCESS(Status)) return Status;
  340.                         }
  341.                 }
  342.                 Section++;
  343.         }
  344.         if (Restore) ZwFlushInstructionCache(NtCurrentProcess(), NULL, 0);
  345.         return STATUS_SUCCESS;
  346. }

  347. ULONG NTAPI LdrRelocateImageWithBias(IN PVOID BaseAddress,IN LONGLONG AdditionalBias,IN PCCH  LoaderName,IN ULONG Success,IN ULONG Conflict,IN ULONG Invalid)
  348. {
  349.         PIMAGE_NT_HEADERS NtHeaders;
  350.         PIMAGE_DATA_DIRECTORY RelocationDDir;
  351.         PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
  352.         ULONG Count;
  353.         ULONG_PTR Address;
  354.         PUSHORT TypeOffset;
  355.         LONGLONG Delta;

  356.         NtHeaders = RtlImageNtHeader(BaseAddress);
  357.         if (NtHeaders == NULL)
  358.                 return Invalid;
  359.         if (SWAPW(NtHeaders->FileHeader.Characteristics) & IMAGE_FILE_RELOCS_STRIPPED)
  360.         {
  361.                 return Conflict;
  362.         }
  363.         RelocationDDir = &NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
  364.         if (SWAPD(RelocationDDir->VirtualAddress) == 0 || SWAPD(RelocationDDir->Size) == 0)
  365.         {
  366.                 return Success;
  367.         }
  368.         Delta = (ULONG_PTR)BaseAddress - SWAPD(NtHeaders->OptionalHeader.ImageBase) + AdditionalBias;
  369.         RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)BaseAddress + SWAPD(RelocationDDir->VirtualAddress));
  370.         RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + SWAPD(RelocationDDir->Size));
  371.         while (RelocationDir < RelocationEnd && SWAPW(RelocationDir->SizeOfBlock) > 0)
  372.         {
  373.                 Count = (SWAPW(RelocationDir->SizeOfBlock) - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
  374.                 Address = (ULONG_PTR)RVA(BaseAddress, SWAPD(RelocationDir->VirtualAddress));
  375.                 TypeOffset = (PUSHORT)(RelocationDir + 1);
  376.                 RelocationDir = LdrProcessRelocationBlockLongLong(Address,Count,TypeOffset,Delta);
  377.                 if (RelocationDir == NULL)
  378.                 {
  379.                         DPRINT1("Error during call to LdrProcessRelocationBlockLongLong()!\n");
  380.                         return Invalid;
  381.                 }
  382.         }
  383.         return Success;
  384. }

  385. PIMAGE_BASE_RELOCATION NTAPI LdrProcessRelocationBlockLongLong(IN ULONG_PTR Address,IN ULONG Count,IN PUSHORT TypeOffset,IN LONGLONG Delta)
  386. {
  387.     for (i = 0; i < Count; i++)
  388.     {
  389.         Offset = SWAPW(*TypeOffset) & 0xFFF;
  390.         Type = SWAPW(*TypeOffset) >> 12;
  391.         ShortPtr = (PUSHORT)(RVA(Address, Offset));
  392.         /*
  393.         if ((ULONG_PTR)ShortPtr < (ULONG_PTR)RelocationDir ||
  394.         (ULONG_PTR)ShortPtr >= (ULONG_PTR)RelocationEnd)
  395.         {*/
  396.         switch (Type)
  397.         {
  398.             /* case IMAGE_REL_BASED_SECTION : */
  399.             /* case IMAGE_REL_BASED_REL32 : */
  400.         case IMAGE_REL_BASED_ABSOLUTE:
  401.             break;
  402.         case IMAGE_REL_BASED_HIGH:
  403.             *ShortPtr = HIWORD(MAKELONG(0, *ShortPtr) + (Delta & 0xFFFFFFFF));
  404.             break;
  405.         case IMAGE_REL_BASED_LOW:
  406.             *ShortPtr = SWAPW(*ShortPtr) + LOWORD(Delta & 0xFFFF);
  407.             break;
  408.         case IMAGE_REL_BASED_HIGHLOW:
  409.             LongPtr = (PULONG)RVA(Address, Offset);
  410.             *LongPtr = SWAPD(*LongPtr) + (Delta & 0xFFFFFFFF);
  411.             break;
  412.         case IMAGE_REL_BASED_DIR64:
  413.             LongLongPtr = (PUINT64)RVA(Address, Offset);
  414.             *LongLongPtr = SWAPQ(*LongLongPtr) + Delta;
  415.             break;
  416.         case IMAGE_REL_BASED_HIGHADJ:
  417.         case IMAGE_REL_BASED_MIPS_JMPADDR:
  418.         default:
  419.             return (PIMAGE_BASE_RELOCATION)NULL;
  420.         }
  421.         TypeOffset++;
  422.     }
  423.     return (PIMAGE_BASE_RELOCATION)TypeOffset;
  424. }
复制代码
回复

使用道具 举报

 楼主| 发表于 2015-6-14 17:07:31 | 显示全部楼层
  1. BOOL WINAPI FreeLibrary(HINSTANCE hLibModule)
  2. {
  3.         NtHeaders = RtlImageNtHeader((PVOID)((ULONG_PTR)hLibModule & ~1));
  4.         Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)((ULONG_PTR)hLibModule & ~1));
  5.         Status = LdrUnloadDll((PVOID)hLibModule);
  6. }

  7. NTSTATUS NTAPI LdrUnloadDll(IN PVOID BaseAddress)
  8. {
  9.         //获取ldr记录
  10.         LdrpCheckForLoadedDllHandle(BaseAddress, &LdrEntry);
  11.         if (LdrEntry->LoadCount != 0xFFFF)
  12.         {//降低引用计数
  13.                 LdrEntry->LoadCount--;
  14.                 if (LdrEntry->Flags & LDRP_IMAGE_DLL)
  15.                 {
  16.                         LdrpUpdateLoadCount2(LdrEntry, LDRP_UPDATE_DEREFCOUNT);
  17.                 }
  18.         }
  19.         NextEntry = Peb->Ldr->InInitializationOrderModuleList.Blink;
  20.         while (NextEntry != &Peb->Ldr->InInitializationOrderModuleList)
  21.         {
  22.                 LdrEntry = CONTAINING_RECORD(NextEntry,LDR_DATA_TABLE_ENTRY,InInitializationOrderModuleList);
  23.                 NextEntry = NextEntry->Blink;
  24.                 LdrEntry->Flags &= ~LDRP_UNLOAD_IN_PROGRESS;
  25.                 if (!LdrEntry->LoadCount)
  26.                 {
  27.                         CurrentEntry = LdrEntry;
  28.                         RemoveEntryList(&CurrentEntry->InInitializationOrderModuleList);
  29.                         RemoveEntryList(&CurrentEntry->InMemoryOrderModuleList);
  30.                         RemoveEntryList(&CurrentEntry->HashLinks);
  31.                         InsertTailList(&LdrpUnloadHead, &CurrentEntry->HashLinks);
  32.                 }
  33.         }

  34.         InitializeListHead(&UnloadList);
  35.         CurrentEntry = NULL;
  36.         NextEntry = LdrpUnloadHead.Flink;
  37.         while (NextEntry != &LdrpUnloadHead)
  38.         {
  39.                 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, HashLinks);
  40.                 CurrentEntry = LdrEntry;
  41.                 LdrpLoadedDllHandleCache = NULL;
  42.                 CurrentEntry->InMemoryOrderModuleList.Flink = NULL;
  43.                 RemoveEntryList(&CurrentEntry->HashLinks);
  44.                 InsertTailList(&UnloadList, &CurrentEntry->HashLinks);
  45.                 EntryPoint = LdrEntry->EntryPoint;
  46.                 if ((EntryPoint) && (LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED))
  47.                 {
  48.                         LdrpCallInitRoutine(LdrEntry->EntryPoint,LdrEntry->DllBase,DLL_PROCESS_DETACH,NULL);
  49.                 }
  50.                 RemoveEntryList(&CurrentEntry->InLoadOrderLinks);
  51.                 CurrentEntry = NULL;
  52.                 NextEntry = LdrpUnloadHead.Flink;
  53.         }
  54.         NextEntry = UnloadList.Flink;
  55.         while (NextEntry != &UnloadList)
  56.         {
  57.                 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, HashLinks);
  58.                 NextEntry = NextEntry->Flink;
  59.                 CurrentEntry = LdrEntry;
  60.                 CorImageData = RtlImageDirectoryEntryToData(LdrEntry->DllBase,TRUE,IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR,&ComSectionSize);
  61.                 if (!(CurrentEntry->Flags & LDR_COR_OWNS_UNMAP))
  62.                 {
  63.                         Status = NtUnmapViewOfSection(NtCurrentProcess(),CurrentEntry->DllBase);
  64.                         ASSERT(NT_SUCCESS(Status));
  65.                 }
  66.                 LdrpFinalizeAndDeallocateDataTableEntry(CurrentEntry);
  67.         }
  68. Quickie:
  69.         if (!LdrpInLdrInit) RtlLeaveCriticalSection(Peb->LoaderLock);
  70. }
复制代码
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-22 14:01 , Processed in 0.030338 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表