- UID
- 2
- 精华
- 积分
- 7736
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
为了实现隐藏dll,不得已出此文对LoadLibrary的解析,该函数比较庞大,尽管已经去除了很多无关代码,仍然有500行。
其中有重定位代码,值得借鉴
- HINSTANCE WINAPI LoadLibraryExW(LPCWSTR lpLibFileName,HANDLE hFile,DWORD dwFlags)
- {
- UNICODE_STRING DllName;
- HINSTANCE hInst;
- NTSTATUS Status;
- PWSTR SearchPath;
- ULONG DllCharacteristics = 0;
- BOOL FreeString = FALSE;
- RtlInitUnicodeString(&DllName, (LPWSTR)lpLibFileName);
- //比较看是否为当前exe
- if (BasepExeLdrEntry && !(dwFlags & LOAD_LIBRARY_AS_DATAFILE) && DllName.Length == BasepExeLdrEntry->FullDllName.Length)
- {
- if (RtlEqualUnicodeString(&DllName, &BasepExeLdrEntry->FullDllName, TRUE))
- {
- return BasepExeLdrEntry->DllBase;
- }
- }
- //获取系统路径 Path
- SearchPath = BaseComputeProcessDllPath((dwFlags & LOAD_WITH_ALTERED_SEARCH_PATH) ?DllName.Buffer : NULL,NULL);
- Status = LdrLoadDll(SearchPath,&DllCharacteristics,&DllName,(PVOID*)&hInst);
- }
- NTSTATUS NTAPI LdrLoadDll(IN PWSTR SearchPath OPTIONAL,IN PULONG DllCharacteristics OPTIONAL,
- IN PUNICODE_STRING DllName, OUT PVOID *BaseAddress)
- {
- //初始化加载器锁
- LdrLockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, NULL, &Cookie);// Peb->LoaderLock = &LdrpLoaderLock;
- Status = LdrpLoadDll(RedirectedDll,SearchPath,DllCharacteristics,DllName,BaseAddress,TRUE);
- LdrUnlockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, Cookie);
- }
- NTSTATUS NTAPI LdrpLoadDll(IN BOOLEAN Redirected,IN PWSTR DllPath OPTIONAL,IN PULONG DllCharacteristics OPTIONAL,
- IN PUNICODE_STRING DllName,OUT PVOID *BaseAddress,IN BOOLEAN CallInit)
- {
- PPEB Peb = NtCurrentPeb();
- NTSTATUS Status = STATUS_SUCCESS;
- const WCHAR *p;
- BOOLEAN GotExtension;
- WCHAR c;
- WCHAR NameBuffer[MAX_PATH + 6];
- UNICODE_STRING RawDllName;
- PLDR_DATA_TABLE_ENTRY LdrEntry;
- BOOLEAN InInit = LdrpInLdrInit;
- //处理路径及后缀。。。。。。。。。
- if (!LdrpCheckForLoadedDll(DllPath,&RawDllName,FALSE,Redirected,&LdrEntry))
- {//如果未加载过则映射该DLL
- Status = LdrpMapDll(DllPath,DllPath,NameBuffer,DllCharacteristics,FALSE,Redirected,&LdrEntry);
- if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++;
- LdrpUpdateLoadCount2(LdrEntry, LDRP_UPDATE_REFCOUNT);
- else if (LdrEntry->LoadCount != 0xFFFF)////如果不是dll,则只增加引用计数
- {
- LdrEntry->LoadCount++;
- }
- //插入Ldr链
- InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,&LdrEntry->InInitializationOrderModuleList);
- }
- else
- {//检查是否为dll映像
- if ((LdrEntry->Flags & LDRP_IMAGE_DLL) && (LdrEntry->LoadCount != 0xFFFF))
- {//增加引用计数
- LdrEntry->LoadCount++;
- LdrpUpdateLoadCount2(LdrEntry, LDRP_UPDATE_REFCOUNT);
- LdrpClearLoadInProgress();
- }
- else
- {
-
- if (LdrEntry->LoadCount != 0xFFFF) LdrEntry->LoadCount++;
- }
- }
- *BaseAddress = LdrEntry->DllBase;
- }
- BOOLEAN NTAPI LdrpCheckForLoadedDll(IN PWSTR DllPath,IN PUNICODE_STRING DllName,IN BOOLEAN Flag,IN BOOLEAN RedirectedDll,
- OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
- {
- //指定Flag则在预先生成的哈希表中查找
- lookinhash:
- if (Flag)
- {
- HashIndex = LDR_GET_HASH_ENTRY(DllName->Buffer[0]);
- //遍历对应哈希表存储的链表
- ListHead = &LdrpHashTable[HashIndex];
- ListEntry = ListHead->Flink;
- while (ListEntry != ListHead)
- {
- CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, HashLinks);
- if (RtlEqualUnicodeString(DllName, &CurEntry->BaseDllName, TRUE))
- {
- *LdrEntry = CurEntry;
- return TRUE;
- }
- ListEntry = ListEntry->Flink;
- }
- return FALSE;
- }
- //未指定Flag则查找并拼合完整路径,如果是相对路径则仍然用哈希表查找,否则用Ldr查找
- if (!FullPath)//拼合过程略。。。。。。。
- {
- Flag = TRUE;
- goto lookinhash;
- }
- ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
- ListEntry = ListHead->Flink;
- while (ListEntry != ListHead)
- {
- CurEntry = CONTAINING_RECORD(ListEntry,LDR_DATA_TABLE_ENTRY,InLoadOrderLinks);
- ListEntry = ListEntry->Flink;
- if (!CurEntry->InMemoryOrderModuleList.Flink) continue;//如果正在被卸载
- if (RtlEqualUnicodeString(&FullDllName,&CurEntry->FullDllName,TRUE))
- {
- *LdrEntry = CurEntry;
- return TRUE;
- }
- }
- //如果路径名方式未能找到,则采用比对内存PE的方式决定是否加载过
- if (!RtlDosPathNameToNtPathName_U(FullDllName.Buffer,&NtPathName,NULL,NULL))
- {
- return FALSE;
- }
- //打开DLL文件并映射到虚拟内存
- InitializeObjectAttributes(&ObjectAttributes,&NtPathName,OBJ_CASE_INSENSITIVE,NULL,NULL);
- Status = NtOpenFile(&FileHandle,SYNCHRONIZE | FILE_EXECUTE,&ObjectAttributes,&Iosb,
- FILE_SHARE_READ | FILE_SHARE_DELETE,FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
- RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
- Status = NtCreateSection(&SectionHandle,SECTION_MAP_READ |SECTION_MAP_EXECUTE |SECTION_MAP_WRITE,
- NULL,NULL,PAGE_EXECUTE,SEC_COMMIT,FileHandle);
- NtClose(FileHandle);
- Status = ZwMapViewOfSection(SectionHandle,NtCurrentProcess(),&ViewBase,0,0,NULL,&ViewSize,ViewShare,0,PAGE_EXECUTE);
- NtClose(SectionHandle);
- Status = RtlImageNtHeaderEx(0, ViewBase, ViewSize, &NtHeader);//获取NT头
- //重新遍历Ldr,这次采用PE头比较方式判断
- //LIST_ENTRY结构很有特点,双向循环链表,链表头为空节点,所以只需要遍历除了头结点以外的节点,现在终于搞清楚这个事实了^_^
- ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
- ListEntry = ListHead->Flink;
- while (ListEntry != ListHead)
- {
- CurEntry = CONTAINING_RECORD(ListEntry,LDR_DATA_TABLE_ENTRY,InLoadOrderLinks);
- ListEntry = ListEntry->Flink;
- if (!CurEntry->InMemoryOrderModuleList.Flink) continue;
- if ((CurEntry->TimeDateStamp == NtHeader->FileHeader.TimeDateStamp) &&
- (CurEntry->SizeOfImage == NtHeader->OptionalHeader.SizeOfImage))
- {
- NtHeader2 = RtlImageNtHeader(CurEntry->DllBase);
- if (RtlCompareMemory(NtHeader2, NtHeader, sizeof(IMAGE_NT_HEADERS)))
- {
- Status = ZwAreMappedFilesTheSame(CurEntry->DllBase, ViewBase);
- if (NT_SUCCESS(Status))
- {
- *LdrEntry = CurEntry;
- NtUnmapViewOfSection(NtCurrentProcess(), ViewBase);
- _SEH2_YIELD(return TRUE;)
- }
- }
- }
- }
- }
- NTSTATUS NTAPI LdrpMapDll(IN PWSTR SearchPath OPTIONAL,IN PWSTR DllPath2, IN PWSTR DllName OPTIONAL, IN PULONG DllCharacteristics,
- IN BOOLEAN Static,IN BOOLEAN Redirect, OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry)
- {
- //检查是否加载过
- SkipCheck:
- if (!SectionHandle)
- {//如果未加载
- if (LdrpResolveDllName(SearchPath, DllName,&FullDllName, &BaseDllName))
- {
- RtlDosPathNameToNtPathName_U(FullDllName.Buffer, &NtPathDllName, NULL, NULL);
- Status = LdrpCreateDllSection(&NtPathDllName,DllHandle,DllCharacteristics,&SectionHandle);
- RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathDllName.Buffer);
- }
- }
- else
- {
- KnownDll = TRUE;
- }
- ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer;
- Teb->NtTib.ArbitraryUserPointer = FullDllName.Buffer;
- //映射dll
- ViewBase = NULL;
- ViewSize = 0;
- Status = NtMapViewOfSection(SectionHandle,NtCurrentProcess(), &ViewBase,0,0,NULL,&ViewSize,ViewShare, 0, PAGE_READWRITE);
- Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer;
- NtHeaders = RtlImageNtHeader(ViewBase);//检查pe头
- LdrEntry = LdrpAllocateDataTableEntry(ViewBase);//构造链表节点
- LdrEntry->Flags = Static ? LDRP_STATIC_LINK : 0;
- if (Redirect) LdrEntry->Flags |= LDRP_REDIRECTED;
- LdrEntry->LoadCount = 0;
- LdrEntry->FullDllName = FullDllName;
- LdrEntry->BaseDllName = BaseDllName;
- LdrEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(LdrEntry->DllBase);//获取入口点
- LdrpInsertMemoryTableEntry(LdrEntry);//插入新节点到ldr
- *DataTableEntry = LdrEntry;
- //如果需要重定位
- if (Status == STATUS_IMAGE_NOT_AT_BASE)
- {
- LdrEntry->Flags |= LDRP_IMAGE_NOT_AT_BASE;
- ImageBase = (ULONG_PTR)NtHeaders->OptionalHeader.ImageBase;
- ImageEnd = ImageBase + ViewSize;
- ListHead = &Peb->Ldr->InLoadOrderModuleList;
- NextEntry = ListHead->Flink;
- while (NextEntry != ListHead)
- {
- CandidateEntry = CONTAINING_RECORD(NextEntry,LDR_DATA_TABLE_ENTRY,InLoadOrderLinks);
- NextEntry = NextEntry->Flink;
- CandidateBase = (ULONG_PTR)CandidateEntry->DllBase;
- CandidateEnd = CandidateBase + CandidateEntry->SizeOfImage;
- if (!CandidateEntry->InMemoryOrderModuleList.Flink) continue;
- if ((ImageBase >= CandidateBase && ImageBase <= CandidateEnd) ||
- (ImageEnd >= CandidateBase && ImageEnd <= CandidateEnd) ||
- (CandidateBase >= ImageBase && CandidateBase <= ImageEnd))
- {
- OverlapDllFound = TRUE;
- OverlapDll = CandidateEntry->FullDllName;
- break;
- }
- }
- if (LdrEntry->Flags & LDRP_IMAGE_DLL)
- {
- if (!(NtHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED))
- {
- RelocData = RtlImageDirectoryEntryToData(ViewBase, TRUE, IMAGE_DIRECTORY_ENTRY_BASERELOC, &RelocDataSize);
- }
- //禁止user32.dll kernel32.dll重定位
- //更改节保护属性
- Status = LdrpSetProtection(ViewBase, FALSE);
- if (NT_SUCCESS(Status))
- {//进行重定位
- Status = LdrRelocateImageWithBias(ViewBase, 0LL, NULL, STATUS_SUCCESS,STATUS_CONFLICTING_ADDRESSES, STATUS_INVALID_IMAGE_FORMAT);//进行重定向
- if (NT_SUCCESS(Status))
- {
- ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer;
- Teb->NtTib.ArbitraryUserPointer = FullDllName.Buffer;
- Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer;
- Status = LdrpSetProtection(ViewBase, TRUE);//还原节保护属性
- }
- }
- }
- }
- NtClose(SectionHandle);
- return Status;
- }
- NTSTATUS NTAPI LdrpCreateDllSection(IN PUNICODE_STRING FullName,IN HANDLE DllHandle,IN PULONG DllCharacteristics OPTIONAL,OUT PHANDLE SectionHandle)
- {
- if (!DllHandle)
- {
- InitializeObjectAttributes(&ObjectAttributes,FullName,OBJ_CASE_INSENSITIVE,NULL,NULL);
- Status = NtOpenFile(&FileHandle,SYNCHRONIZE | FILE_EXECUTE | FILE_READ_DATA,&ObjectAttributes,&IoStatusBlock,
- FILE_SHARE_READ | FILE_SHARE_DELETE,FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
- if (!NT_SUCCESS(Status))
- {//尝试以只读方式打开
- Status = NtOpenFile(&FileHandle,SYNCHRONIZE | FILE_EXECUTE,&ObjectAttributes,&IoStatusBlock,
- FILE_SHARE_READ | FILE_SHARE_DELETE,FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
- }
- }
- else
- {
- FileHandle = DllHandle;
- }
- Status = NtCreateSection(SectionHandle,SECTION_MAP_READ | SECTION_MAP_EXECUTE |SECTION_MAP_WRITE | SECTION_QUERY,
- NULL,NULL,PAGE_EXECUTE,SEC_IMAGE,FileHandle);
- NtClose(FileHandle);
- return Status;
- }
- PLDR_DATA_TABLE_ENTRY NTAPI LdrpAllocateDataTableEntry(IN PVOID BaseAddress)
- {
- PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
- PIMAGE_NT_HEADERS NtHeader;
- NtHeader = RtlImageNtHeader(BaseAddress);
- if (NtHeader)
- {
- LdrEntry = RtlAllocateHeap(RtlGetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(LDR_DATA_TABLE_ENTRY));
- if (LdrEntry)
- {
- LdrEntry->DllBase = BaseAddress;
- LdrEntry->SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
- LdrEntry->TimeDateStamp = NtHeader->FileHeader.TimeDateStamp;
- LdrEntry->PatchInformation = NULL;
- }
- }
- return LdrEntry;
- }
- PVOID NTAPI LdrpFetchAddressOfEntryPoint(IN PVOID ImageBase)
- {
- PIMAGE_NT_HEADERS NtHeaders;
- ULONG_PTR EntryPoint = 0;
- NtHeaders = RtlImageNtHeader(ImageBase);
- if (NtHeaders)
- {
- EntryPoint = NtHeaders->OptionalHeader.AddressOfEntryPoint;
- if (EntryPoint) EntryPoint += (ULONG_PTR)ImageBase;
- }
- return (PVOID)EntryPoint;
- }
- VOID NTAPI LdrpInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
- {
- PPEB_LDR_DATA PebData = NtCurrentPeb()->Ldr;
- ULONG i;
- i = LDR_GET_HASH_ENTRY(LdrEntry->BaseDllName.Buffer[0]);
- InsertTailList(&LdrpHashTable[i], &LdrEntry->HashLinks);
- InsertTailList(&PebData->InLoadOrderModuleList, &LdrEntry->InLoadOrderLinks);
- InsertTailList(&PebData->InMemoryOrderModuleList, &LdrEntry->InMemoryOrderModuleList);
- }
- NTSTATUS NTAPI LdrpSetProtection(PVOID ViewBase,BOOLEAN Restore)
- {
- PIMAGE_NT_HEADERS NtHeaders;
- PIMAGE_SECTION_HEADER Section;
- NTSTATUS Status;
- PVOID SectionBase;
- SIZE_T SectionSize;
- ULONG NewProtection, OldProtection, i;
- NtHeaders = RtlImageNtHeader(ViewBase);
- if (!NtHeaders) return STATUS_INVALID_IMAGE_FORMAT;
- Section = IMAGE_FIRST_SECTION(NtHeaders);
- for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++)
- {
- if ((Section->SizeOfRawData) && !(Section->Characteristics & IMAGE_SCN_MEM_WRITE))
- {
- if (Restore)
- {
- if (Section->Characteristics & IMAGE_SCN_MEM_EXECUTE)
- {
- NewProtection = PAGE_EXECUTE;
- }
- else
- {
- NewProtection = PAGE_READONLY;
- }
- if (Section->Characteristics & IMAGE_SCN_MEM_NOT_CACHED)
- {
- NewProtection |= PAGE_NOCACHE;
- }
- }
- else
- {
- NewProtection = PAGE_READWRITE;
- }
- SectionBase = (PVOID)((ULONG_PTR)ViewBase + Section->VirtualAddress);
- SectionSize = Section->SizeOfRawData;
- if (SectionSize)
- {
- Status = ZwProtectVirtualMemory(NtCurrentProcess(),&SectionBase,&SectionSize,NewProtection,&OldProtection);
- if (!NT_SUCCESS(Status)) return Status;
- }
- }
- Section++;
- }
- if (Restore) ZwFlushInstructionCache(NtCurrentProcess(), NULL, 0);
- return STATUS_SUCCESS;
- }
- ULONG NTAPI LdrRelocateImageWithBias(IN PVOID BaseAddress,IN LONGLONG AdditionalBias,IN PCCH LoaderName,IN ULONG Success,IN ULONG Conflict,IN ULONG Invalid)
- {
- PIMAGE_NT_HEADERS NtHeaders;
- PIMAGE_DATA_DIRECTORY RelocationDDir;
- PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
- ULONG Count;
- ULONG_PTR Address;
- PUSHORT TypeOffset;
- LONGLONG Delta;
- NtHeaders = RtlImageNtHeader(BaseAddress);
- if (NtHeaders == NULL)
- return Invalid;
- if (SWAPW(NtHeaders->FileHeader.Characteristics) & IMAGE_FILE_RELOCS_STRIPPED)
- {
- return Conflict;
- }
- RelocationDDir = &NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
- if (SWAPD(RelocationDDir->VirtualAddress) == 0 || SWAPD(RelocationDDir->Size) == 0)
- {
- return Success;
- }
- Delta = (ULONG_PTR)BaseAddress - SWAPD(NtHeaders->OptionalHeader.ImageBase) + AdditionalBias;
- RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)BaseAddress + SWAPD(RelocationDDir->VirtualAddress));
- RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + SWAPD(RelocationDDir->Size));
- while (RelocationDir < RelocationEnd && SWAPW(RelocationDir->SizeOfBlock) > 0)
- {
- Count = (SWAPW(RelocationDir->SizeOfBlock) - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
- Address = (ULONG_PTR)RVA(BaseAddress, SWAPD(RelocationDir->VirtualAddress));
- TypeOffset = (PUSHORT)(RelocationDir + 1);
- RelocationDir = LdrProcessRelocationBlockLongLong(Address,Count,TypeOffset,Delta);
- if (RelocationDir == NULL)
- {
- DPRINT1("Error during call to LdrProcessRelocationBlockLongLong()!\n");
- return Invalid;
- }
- }
- return Success;
- }
- PIMAGE_BASE_RELOCATION NTAPI LdrProcessRelocationBlockLongLong(IN ULONG_PTR Address,IN ULONG Count,IN PUSHORT TypeOffset,IN LONGLONG Delta)
- {
- for (i = 0; i < Count; i++)
- {
- Offset = SWAPW(*TypeOffset) & 0xFFF;
- Type = SWAPW(*TypeOffset) >> 12;
- ShortPtr = (PUSHORT)(RVA(Address, Offset));
- /*
- if ((ULONG_PTR)ShortPtr < (ULONG_PTR)RelocationDir ||
- (ULONG_PTR)ShortPtr >= (ULONG_PTR)RelocationEnd)
- {*/
- switch (Type)
- {
- /* case IMAGE_REL_BASED_SECTION : */
- /* case IMAGE_REL_BASED_REL32 : */
- case IMAGE_REL_BASED_ABSOLUTE:
- break;
- case IMAGE_REL_BASED_HIGH:
- *ShortPtr = HIWORD(MAKELONG(0, *ShortPtr) + (Delta & 0xFFFFFFFF));
- break;
- case IMAGE_REL_BASED_LOW:
- *ShortPtr = SWAPW(*ShortPtr) + LOWORD(Delta & 0xFFFF);
- break;
- case IMAGE_REL_BASED_HIGHLOW:
- LongPtr = (PULONG)RVA(Address, Offset);
- *LongPtr = SWAPD(*LongPtr) + (Delta & 0xFFFFFFFF);
- break;
- case IMAGE_REL_BASED_DIR64:
- LongLongPtr = (PUINT64)RVA(Address, Offset);
- *LongLongPtr = SWAPQ(*LongLongPtr) + Delta;
- break;
- case IMAGE_REL_BASED_HIGHADJ:
- case IMAGE_REL_BASED_MIPS_JMPADDR:
- default:
- return (PIMAGE_BASE_RELOCATION)NULL;
- }
- TypeOffset++;
- }
- return (PIMAGE_BASE_RELOCATION)TypeOffset;
- }
复制代码 |
|