UID 2 精华 积分 7982 威望  点 
宅币  个 
贡献  次 
宅之契约  份 
最后登录 1970-1-1 
在线时间  小时 
 
 
 
 
 
 
 本帖最后由 元始天尊 于 2015-6-13 15:06 编辑  FARPROC WINAPI GetProcAddress(HMODULE hModule, LPCSTR lpProcName) {     if (HIWORD(lpProcName) != 0)     {//按名称查找         RtlInitAnsiString(&ProcedureName, (LPSTR)lpProcName);         ProcNamePtr = &ProcedureName;     }     else     { //按序号查找         Ordinal = (ULONG)lpProcName;     }     hMapped = BasepMapModuleHandle(hModule, FALSE);//如果没提供hModule则取得当前模块hModule     Status = LdrGetProcedureAddress(hMapped,ProcNamePtr, Ordinal,(PVOID*)&fnExp); } PVOID WINAPI BasepMapModuleHandle(HMODULE hModule, BOOLEAN AsDataFile) {         if (!hModule) return NtCurrentPeb()->ImageBaseAddress;         if (LDR_IS_DATAFILE(hModule) && !AsDataFile)//如果为资源DLL                 return NULL;         return hModule; } NTSTATUS NTAPI LdrpGetProcedureAddress(IN PVOID BaseAddress,IN PANSI_STRING Name,IN ULONG Ordinal,OUT PVOID *ProcedureAddress,IN BOOLEAN ExecuteInit) {     NTSTATUS Status = STATUS_SUCCESS;     UCHAR ImportBuffer[64];     PLDR_DATA_TABLE_ENTRY LdrEntry;     IMAGE_THUNK_DATA Thunk;     PVOID ImageBase;     PIMAGE_IMPORT_BY_NAME ImportName = NULL;     PIMAGE_EXPORT_DIRECTORY ExportDir;     ULONG ExportDirSize, Length;     PLIST_ENTRY Entry;     if (Name)//若按名称查找     {         Length = Name->Length +sizeof(CHAR) + FIELD_OFFSET(IMAGE_IMPORT_BY_NAME, Name);         ImportName->Hint = 0;         RtlCopyMemory(ImportName->Name, Name->Buffer, Name->Length);         ImportName->Name[Name->Length] = ANSI_NULL;         ImageBase = ImportName;         Thunk.u1.AddressOfData = 0;     }     else//若按序号查找     {         ImageBase = NULL;         Thunk.u1.Ordinal = Ordinal | IMAGE_ORDINAL_FLAG;     }     LdrpCheckForLoadedDllHandle(BaseAddress, &LdrEntry); //查找已加载dll     ExportDir = RtlImageDirectoryEntryToData(LdrEntry->DllBase,TRUE,IMAGE_DIRECTORY_ENTRY_EXPORT, &ExportDirSize);//查找导出表     Status = LdrpSnapThunk(LdrEntry->DllBase,ImageBase,&Thunk, &Thunk,ExportDir,ExportDirSize,FALSE,NULL);//获取导出表Thunk结构         *ProcedureAddress = (PVOID)Thunk.u1.Function; } BOOLEAN NTAPI LdrpCheckForLoadedDllHandle(IN PVOID Base,OUT PLDR_DATA_TABLE_ENTRY *LdrEntry) {         PLDR_DATA_TABLE_ENTRY Current;         PLIST_ENTRY ListHead, Next;         if ((LdrpLoadedDllHandleCache) && (LdrpLoadedDllHandleCache->DllBase == Base))//查找缓存         {                 *LdrEntry = LdrpLoadedDllHandleCache;                 return TRUE;         }         ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;//线性查找ldr         Next = ListHead->Flink;         while (Next != ListHead)         {                 Current = CONTAINING_RECORD(Next,LDR_DATA_TABLE_ENTRY,InLoadOrderLinks);                 if ((Current->InMemoryOrderModuleList.Flink) && (Base == Current->DllBase))                 {                         LdrpLoadedDllHandleCache = Current;                         *LdrEntry = Current;                         return TRUE;                 }                 Next = Next->Flink;         }         return FALSE; } PVOID NTAPI RtlImageDirectoryEntryToData(PVOID BaseAddress,BOOLEAN MappedAsImage,USHORT Directory,PULONG Size) {         PIMAGE_NT_HEADERS NtHeader;         ULONG Va;         NtHeader = RtlImageNtHeader(BaseAddress);         if (NtHeader == NULL)                 return NULL;         if(NtHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)                 return RtlpImageDirectoryEntryToData32(BaseAddress,MappedAsImage,Directory,Size,NtHeader);         else if(NtHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)                 return RtlpImageDirectoryEntryToData64(BaseAddress,MappedAsImage,Directory,Size,NtHeader);         return NULL; } PIMAGE_NT_HEADERS NTAPI RtlImageNtHeader(IN PVOID Base) {         PIMAGE_NT_HEADERS NtHeaders = NULL;         PIMAGE_DOS_HEADER DosHeader;         if ((Base != NULL) && (Base == (PVOID)-1) && (DosHeader->e_magic == IMAGE_DOS_SIGNATURE))         {                 if (DosHeader->e_lfanew < 0x10000000)                 {                         NtHeaders = (BYTE*)Base + DosHeader->e_lfanew;                         if(NtHeaders->Signature != IMAGE_NT_SIGNATURE)                                 NtHeaders = NULL;                 }         }         return NtHeaders; } PVOID NTAPI RtlpImageDirectoryEntryToData32(PVOID BaseAddress, BOOLEAN MappedAsImage, USHORT Directory, PULONG Size, PIMAGE_NT_HEADERS32 NtHeader)  {         if(Directory >= NtHeader->OptionalHeader.NumberOfRvaAndSizes)                 return NULL;         DWORD vaaddr = NtHeader->OptionalHeader.DataDirectory[Directory].VirtualAddress;         if(vaaddr == 0)                 return NULL;         *Size = NtHeader->OptionalHeader.DataDirectory[Directory].Size;         if(MappedAsImage || vaaddr < NtHeader->OptionalHeader.SizeOfHeaders)                 return (PVOID)((BYTE*)BaseAddress + vaaddr); } PVOID NTAPI RtlpImageDirectoryEntryToData64(PVOID BaseAddress, BOOLEAN MappedAsImage, USHORT Directory, PULONG Size, PIMAGE_NT_HEADERS64 NtHeader)  {         if(Directory >= NtHeader->OptionalHeader.NumberOfRvaAndSizes)                 return NULL;         DWORD vaaddr = NtHeader->OptionalHeader.DataDirectory[Directory].VirtualAddress;         if(vaaddr == 0)                 return NULL;         *Size = NtHeader->OptionalHeader.DataDirectory[Directory].Size;         if(MappedAsImage || vaaddr < NtHeader->OptionalHeader.SizeOfHeaders)                 return (PVOID)((BYTE*)BaseAddress + vaaddr); } NTSTATUS NTAPI LdrpSnapThunk(IN PVOID ExportBase,IN PVOID ImportBase,IN PIMAGE_THUNK_DATA OriginalThunk,IN OUT PIMAGE_THUNK_DATA Thunk,         IN PIMAGE_EXPORT_DIRECTORY ExportEntry,IN ULONG ExportSize,IN BOOLEAN Static,IN LPSTR DllName) {         BOOLEAN IsOrdinal;         USHORT Ordinal;         ULONG OriginalOrdinal = 0;         PIMAGE_IMPORT_BY_NAME AddressOfData;         PULONG NameTable;         PUSHORT OrdinalTable;         LPSTR ImportName = NULL;         USHORT Hint;         NTSTATUS Status;         ULONG_PTR HardErrorParameters[3];         UNICODE_STRING HardErrorDllName, HardErrorEntryPointName;         ANSI_STRING TempString;         ULONG Mask;         ULONG Response;         PULONG AddressOfFunctions;         UNICODE_STRING TempUString;         ANSI_STRING ForwarderName;         PANSI_STRING ForwardName;         PVOID ForwarderHandle;         ULONG ForwardOrdinal;         if ((IsOrdinal = IMAGE_SNAP_BY_ORDINAL(OriginalThunk->u1.Ordinal)))//按序号         {                 OriginalOrdinal = IMAGE_ORDINAL(OriginalThunk->u1.Ordinal);                 Ordinal = (USHORT)(OriginalOrdinal - ExportEntry->Base);         }         else         {                 AddressOfData = (PIMAGE_IMPORT_BY_NAME)((ULONG_PTR)ImportBase +((ULONG_PTR)OriginalThunk->u1.AddressOfData & 0xffffffff));                 ImportName = (LPSTR)AddressOfData->Name;                 NameTable = (PULONG)((ULONG_PTR)ExportBase + (ULONG_PTR)ExportEntry->AddressOfNames);                 OrdinalTable = (PUSHORT)((ULONG_PTR)ExportBase + (ULONG_PTR)ExportEntry->AddressOfNameOrdinals);                 Hint = AddressOfData->Hint;                 Ordinal = LdrpNameToOrdinal(ImportName,ExportEntry->NumberOfNames,ExportBase,NameTable,OrdinalTable);//根据名称找到序号         }         if ((ULONG)Ordinal >= ExportEntry->NumberOfFunctions)         {         }         else         {                 AddressOfFunctions = (PULONG)((ULONG_PTR)ExportBase + (ULONG_PTR)ExportEntry->AddressOfFunctions);                 Thunk->u1.Function = (ULONG_PTR)ExportBase + AddressOfFunctions[Ordinal];                 if ((Thunk->u1.Function > (ULONG_PTR)ExportEntry) && (Thunk->u1.Function < ((ULONG_PTR)ExportEntry + ExportSize)))                 {//对于前向索引的动态链  Function指向字符串  "dll.func"                         ImportName = (LPSTR)Thunk->u1.Function;                         ForwarderName.Buffer = ImportName;                         ForwarderName.Length = (USHORT)(strchr(ImportName, '.') - ImportName);//取得dll名称                         ForwarderName.MaximumLength = ForwarderName.Length;                         Status = RtlAnsiStringToUnicodeString(&TempUString,&ForwarderName,TRUE);                         if (NT_SUCCESS(Status))                         {                                 Status = LdrpLoadDll(FALSE,NULL,NULL,&TempUString,&ForwarderHandle,FALSE);                                 RtlFreeUnicodeString(&TempUString);                         }                         RtlInitAnsiString(&ForwarderName,ImportName + ForwarderName.Length + sizeof(CHAR));//取得函数名                         if ((ForwarderName.Length > 1) && (*ForwarderName.Buffer == '#'))                         {//按序号                                 ForwardName = NULL;                                 Status = RtlCharToInteger(ForwarderName.Buffer + sizeof(CHAR),0,&ForwardOrdinal);                         }                         else                         {//按名称                                 ForwardName = &ForwarderName;                         }                         Status = LdrpGetProcedureAddress(ForwarderHandle,ForwardName,ForwardOrdinal,(PVOID*)&Thunk->u1.Function,FALSE);//重新获取地址                 } } USHORT NTAPI LdrpNameToOrdinal(IN LPSTR ImportName,                   IN ULONG NumberOfNames,                   IN PVOID ExportBase,                   IN PULONG NameTable,                   IN PUSHORT OrdinalTable) {     LONG Start, End, Next, CmpResult;     /* Use classical binary search to find the ordinal */     Start = Next = 0;     End = NumberOfNames - 1;     while (End >= Start)     {         /* Next will be exactly between Start and End */         Next = (Start + End) >> 1;         /* Compare this name with the one we need to find */         CmpResult = strcmp(ImportName, (PCHAR)((ULONG_PTR)ExportBase + NameTable[Next]));         /* We found our entry if result is 0 */         if (!CmpResult) break;         /* We didn't find, update our range then */         if (CmpResult < 0)         {             End = Next - 1;         }         else if (CmpResult > 0)         {             Start = Next + 1;         }     }     /* If end is before start, then the search failed */     if (End < Start) return -1;     /* Return found name */     return OrdinalTable[Next]; } 复制代码