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

QQ登录

只需一步,快速开始

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

实现自己的LoadLibrary

[复制链接]
发表于 2015-6-15 00:05:41 | 显示全部楼层 |阅读模式

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

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

×
决定实现自己的loadlibrary,已经实现大部分,然而在模拟执行dllmain时却发生异常,查找发现加载的dll导入表没有初始化。
不明白这段代码在哪里实现的,正在研究中,功亏一篑啊
该代码完全独立于ldr结构,并用map结构一次映射所有函数,不需要getproc一个个进行查找,LoadLibary只需要传入完整dll路径
GetProcAddress只需要dll路径以及函数名即可获得函数地址,这部分功能测试正常,500行代码

而输出表部分,很奇怪,懂得高人指点一下:
  1. #include <windows.h>
  2. #include <winternl.h>
  3. #include <map>
  4. #include <string>
  5. using namespace std;

  6. #if defined(WIN64) || defined(_WIN64)
  7. #pragma comment(lib,"ntdll64.lib")
  8. #else
  9. #pragma comment(lib,"ntdll.lib")
  10. #endif

  11. #if defined(UNICODE) || defined(_UNICODE)
  12. #define GetProcAddressT GetProcAddressTW
  13. #define LoadLibraryT LoadLibraryTW
  14. #define FreeLibraryT FreeLibraryTW
  15. #else
  16. #define GetProcAddressT GetProcAddressTA
  17. #define LoadLibraryT LoadLibraryTA
  18. #define FreeLibraryT FreeLibraryTA
  19. #endif

  20. extern "C"
  21. {
  22.         BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(PCWSTR,PUNICODE_STRING,PCWSTR*,PVOID*);
  23.         NTSTATUS WINAPI NtMapViewOfSection(HANDLE,HANDLE,PVOID*,ULONG,SIZE_T,const LARGE_INTEGER*,SIZE_T*,ULONG,ULONG,ULONG);
  24.         BOOLEAN WINAPI RtlFreeHeap(PVOID,ULONG,PVOID);
  25.         NTSTATUS WINAPI NtCreateSection(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PLARGE_INTEGER,ULONG,ULONG,HANDLE);
  26.         NTSTATUS WINAPI NtUnmapViewOfSection(HANDLE,PVOID);
  27.         NTSTATUS WINAPI NtProtectVirtualMemory(HANDLE,PVOID,PSIZE_T,ULONG,PULONG);
  28.         NTSTATUS WINAPI NtFlushInstructionCache(HANDLE,PVOID,ULONG);
  29. };



  30. ULONG NTAPI LdrRelocateImageWithBias(PVOID,PIMAGE_NT_HEADERS,LONGLONG ,PCCH,ULONG,ULONG,ULONG);
  31. NTSTATUS NTAPI LdrpSetProtection(PVOID,PIMAGE_NT_HEADERS,BOOLEAN);


  32. #define STATUS_IMAGE_NOT_AT_BASE ((NTSTATUS)0x40000003L)
  33. #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
  34. #define STATUS_CONFLICTING_ADDRESSES ((NTSTATUS)0xC0000018L)
  35. #define STATUS_INVALID_IMAGE_FORMAT ((NTSTATUS)0xC000007BL)

  36. typedef struct _CLIENT_ID
  37. {
  38.         HANDLE UniqueProcess;
  39.         HANDLE UniqueThread;
  40. } CLIENT_ID;

  41. typedef struct _MTEB
  42. {
  43.         _NT_TIB NtTib;
  44.         PVOID EnvironmentPointer;
  45.         CLIENT_ID ClientId;
  46.         PVOID ActiveRpcHandle;
  47.         PVOID ThreadLocalStoragePointer;
  48.         PPEB Peb;
  49. }MTEB,*PMTEB;

  50. typedef struct _MPEB
  51. {
  52.         DWORD flags;
  53.         PVOID Mutant;
  54.         PVOID ImageBaseAddress;
  55.         PPEB_LDR_DATA Ldr;
  56.         PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
  57.         PVOID SubSystemData;
  58.         PVOID ProcessHeap;
  59. }MPEB,*PMPEB;

  60. struct DllStruct
  61. {
  62.         PVOID EntryPoint;
  63.         PVOID ViewBase;
  64.         SIZE_T ViewSize;
  65.         std::map<std::wstring,FARPROC> FuncMap;//函数映射
  66. };
  67. std::map<std::wstring,DllStruct> DllMap;
  68. CRITICAL_SECTION DllLock;
  69. #define RtlGetProcessHeap() ( (PMPEB)((PMTEB)NtCurrentTeb())->Peb )->ProcessHeap

  70. BOOL WINAPI LoadLibraryTA(LPCSTR DllPath);
  71. BOOL WINAPI LoadLibraryTW(LPCWSTR DllPath);
  72. FARPROC WINAPI GetProcAddressTA(LPCSTR DllPath,LPCSTR ProcName);
  73. FARPROC WINAPI GetProcAddressTW(LPCWSTR DllPath,LPCWSTR ProcName);
  74. BOOL WINAPI FreeLibraryTA(LPCSTR DllPath);
  75. BOOL WINAPI FreeLibraryTW(LPCWSTR DllPath);

  76. BOOL WINAPI LoadLibraryTA(LPCSTR DllPath)
  77. {
  78.         ANSI_STRING DllPathA;
  79.         UNICODE_STRING DllPathW;
  80.         NTSTATUS status;
  81.         if(!DllPath || DllPath[0] == 0)
  82.                 return FALSE;
  83.         WCHAR tmp[0x1000];
  84.         memset(tmp,0,sizeof(tmp));
  85.         RtlInitAnsiString(&DllPathA,DllPath);
  86.         DllPathW.Buffer = tmp;
  87.         DllPathW.MaximumLength = 0x1000;
  88.         status = RtlAnsiStringToUnicodeString(&DllPathW,&DllPathA,FALSE);
  89.         if(!NT_SUCCESS(status))
  90.                 return FALSE;
  91.         return LoadLibraryTW(DllPathW.Buffer);
  92. }

  93. BOOL WINAPI LoadLibraryTW(LPCWSTR DllPath)
  94. {
  95.         if(!DllPath || DllPath[0] == 0)
  96.                 return FALSE;
  97.         BOOL result = FALSE;
  98.         EnterCriticalSection(&DllLock);
  99.         //查找Map,遍历导出表,更新Map
  100.         std::map<std::wstring,DllStruct>::iterator itor = DllMap.find(DllPath);
  101.         if(itor != DllMap.end())
  102.         {
  103.                 result = FALSE;
  104.                 goto ENDLOAD;
  105.         }

  106.         UNICODE_STRING NtPathDllName;
  107.         OBJECT_ATTRIBUTES ObjectAttributes;
  108.         HANDLE FileHandle = NULL,SectionHandle = NULL;
  109.         IO_STATUS_BLOCK IoStatusBlock;
  110.         NTSTATUS Status;
  111.         if(!RtlDosPathNameToNtPathName_U(DllPath,&NtPathDllName,NULL,NULL))
  112.         {
  113.                 result = FALSE;
  114.                 goto ENDLOAD;
  115.         }
  116.         InitializeObjectAttributes(&ObjectAttributes,&NtPathDllName,OBJ_CASE_INSENSITIVE,NULL,NULL);
  117.         Status = NtOpenFile(&FileHandle,SYNCHRONIZE | FILE_EXECUTE | FILE_READ_DATA,&ObjectAttributes,&IoStatusBlock,
  118.                 FILE_SHARE_READ | FILE_SHARE_DELETE,FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
  119.         if (!NT_SUCCESS(Status))
  120.         {//尝试以只读方式打开
  121.                 Status = NtOpenFile(&FileHandle,SYNCHRONIZE | FILE_EXECUTE,&ObjectAttributes,&IoStatusBlock,
  122.                         FILE_SHARE_READ | FILE_SHARE_DELETE,FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
  123.         }
  124.         if(!NT_SUCCESS(Status))
  125.         {
  126.                 result = FALSE;
  127.                 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathDllName.Buffer);
  128.                 goto ENDLOAD;
  129.         }
  130.         Status = NtCreateSection(&SectionHandle,SECTION_MAP_READ | SECTION_MAP_EXECUTE |SECTION_MAP_WRITE | SECTION_QUERY,
  131.                 NULL,NULL,PAGE_EXECUTE,SEC_IMAGE,FileHandle);
  132.         NtClose(FileHandle);
  133.         if(!NT_SUCCESS(Status))
  134.         {
  135.                 result = FALSE;
  136.                 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathDllName.Buffer);
  137.                 goto ENDLOAD;
  138.         }
  139.         RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathDllName.Buffer);

  140.         PVOID ViewBase = NULL;
  141.         SIZE_T ViewSize = 0;
  142.         PIMAGE_NT_HEADERS NtHeaders = NULL;
  143.         PIMAGE_DOS_HEADER DosHeader = NULL;
  144.         PVOID EntryPoint = NULL;
  145.         Status = NtMapViewOfSection(SectionHandle,(HANDLE)-1/*NtCurrentProcess()*/,&ViewBase,0,0,NULL,&ViewSize,1/*ViewShare*/,0,PAGE_READWRITE);

  146.         if(ViewBase)
  147.         {
  148.                 DosHeader = (PIMAGE_DOS_HEADER)ViewBase;
  149.                 if(DosHeader->e_magic == IMAGE_DOS_SIGNATURE && DosHeader->e_lfanew  && DosHeader->e_lfanew < ViewSize)
  150.                 {
  151.                         NtHeaders = (PIMAGE_NT_HEADERS)((BYTE*)DosHeader + DosHeader->e_lfanew);
  152.                         if(NtHeaders->Signature != IMAGE_NT_SIGNATURE)
  153.                                 NtHeaders = NULL;
  154.                 }
  155.                 if(!NtHeaders || NtHeaders->OptionalHeader.AddressOfEntryPoint == NULL || !(NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL))
  156.                 {
  157.                         result = FALSE;
  158.                         goto ENDLOAD;
  159.                 }
  160.                 EntryPoint = (PVOID)(NtHeaders->OptionalHeader.AddressOfEntryPoint + (BYTE*)ViewBase);
  161.         }

  162.         if(Status == STATUS_IMAGE_NOT_AT_BASE)
  163.         {//重定位
  164.                 if(!(NtHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED))
  165.                 {
  166.                         USHORT Directory = IMAGE_DIRECTORY_ENTRY_BASERELOC;
  167.                         ULONG RelocDataSize = 0;
  168.                         PVOID RelocData = NULL;
  169.                         if(NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
  170.                         {
  171.                                 PIMAGE_NT_HEADERS32 tpnh = (PIMAGE_NT_HEADERS32)NtHeaders;
  172.                                 if(Directory >= tpnh->OptionalHeader.NumberOfRvaAndSizes)
  173.                                         return NULL;
  174.                                 DWORD VA = tpnh->OptionalHeader.DataDirectory[Directory].VirtualAddress;
  175.                                 if(VA == NULL)
  176.                                         return NULL;
  177.                                 RelocDataSize = tpnh->OptionalHeader.DataDirectory[Directory].Size;
  178.                                 RelocData = (PVOID)((BYTE*)ViewBase + VA);
  179.                         }
  180.                         else
  181.                         {
  182.                                 PIMAGE_NT_HEADERS64 tpnh = (PIMAGE_NT_HEADERS64)NtHeaders;
  183.                                 if(Directory >= tpnh->OptionalHeader.NumberOfRvaAndSizes)
  184.                                         return NULL;
  185.                                 DWORD VA = tpnh->OptionalHeader.DataDirectory[Directory].VirtualAddress;
  186.                                 if(VA == NULL)
  187.                                         return NULL;
  188.                                 RelocDataSize = tpnh->OptionalHeader.DataDirectory[Directory].Size;
  189.                                 RelocData = (PVOID)((BYTE*)ViewBase + VA);
  190.                         }
  191.                         if(RelocData && RelocDataSize)
  192.                         {
  193.                                 Status = LdrpSetProtection(ViewBase,NtHeaders,FALSE);
  194.                                 if(NT_SUCCESS(Status))
  195.                                 {
  196.                                         Status = LdrRelocateImageWithBias(ViewBase, NtHeaders, 0LL, NULL, STATUS_SUCCESS,STATUS_CONFLICTING_ADDRESSES, STATUS_INVALID_IMAGE_FORMAT);
  197.                                         LdrpSetProtection(ViewBase,NtHeaders,TRUE);
  198.                                         if(NT_SUCCESS(Status))
  199.                                         {
  200.                                                 goto ENDLOAD1;
  201.                                         }
  202.                                 }
  203.                         }
  204.                 }
  205.                 if(!NT_SUCCESS(Status) || ViewBase)
  206.                 {
  207.                         NtUnmapViewOfSection((HANDLE)-1/*NtCurrentProcess()*/,ViewBase);
  208.                         result = FALSE;
  209.                 }
  210.         }
  211.         else if(!NT_SUCCESS(Status))
  212.         {
  213.                 result = FALSE;
  214.                 goto ENDLOAD;
  215.         }
  216. ENDLOAD1:
  217.         NtClose(SectionHandle);
  218.         if(NT_SUCCESS(Status))
  219.                 result = TRUE;
  220.         DllStruct& ds = DllMap[DllPath];
  221.         ds.EntryPoint = EntryPoint;
  222.         ds.ViewBase = ViewBase;
  223.         ds.ViewSize = ViewSize;
  224.         {
  225.                 typedef BOOLEAN (WINAPI *PDLL_INIT_ROUTINE)( PVOID DllHandle,ULONG Reason,PCONTEXT Context );
  226. //                ((PDLL_INIT_ROUTINE)EntryPoint)(ViewBase,DLL_PROCESS_ATTACH,NULL);
  227.                 PVOID BaseAddress = ViewBase;
  228.                 USHORT Directory = IMAGE_DIRECTORY_ENTRY_EXPORT;
  229.                 PIMAGE_EXPORT_DIRECTORY ExportDir = NULL;
  230.                 ULONG ExportDirSize = 0;
  231.                 if(NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
  232.                 {
  233.                         PIMAGE_NT_HEADERS32 tpnh = (PIMAGE_NT_HEADERS32)NtHeaders;
  234.                         if(Directory >= tpnh->OptionalHeader.NumberOfRvaAndSizes)
  235.                                 return NULL;
  236.                         DWORD VA = tpnh->OptionalHeader.DataDirectory[Directory].VirtualAddress;
  237.                         if(VA == NULL)
  238.                                 return NULL;
  239.                         ExportDirSize = tpnh->OptionalHeader.DataDirectory[Directory].Size;
  240.                         ExportDir = (PIMAGE_EXPORT_DIRECTORY)((BYTE*)ViewBase + VA);
  241.                 }
  242.                 else
  243.                 {
  244.                         PIMAGE_NT_HEADERS64 tpnh = (PIMAGE_NT_HEADERS64)NtHeaders;
  245.                         if(Directory >= tpnh->OptionalHeader.NumberOfRvaAndSizes)
  246.                                 return NULL;
  247.                         DWORD VA = tpnh->OptionalHeader.DataDirectory[Directory].VirtualAddress;
  248.                         if(VA == NULL)
  249.                                 return NULL;
  250.                         ExportDirSize = tpnh->OptionalHeader.DataDirectory[Directory].Size;
  251.                         ExportDir = (PIMAGE_EXPORT_DIRECTORY)((BYTE*)ViewBase + VA);
  252.                 }
  253.                 PULONG NameTable = (PULONG)((ULONG_PTR)BaseAddress + (ULONG_PTR)ExportDir->AddressOfNames);
  254.                 PUSHORT OrdinalTable = (PUSHORT)((ULONG_PTR)BaseAddress + (ULONG_PTR)ExportDir->AddressOfNameOrdinals);
  255.                 PULONG AddressOfFunctions = (PULONG)((ULONG_PTR)BaseAddress + (ULONG_PTR)ExportDir->AddressOfFunctions);
  256.                 USHORT Ordinal = -1;
  257.                 for(LONG i = 0;i < ExportDir->NumberOfNames;i++)
  258.                 {
  259.                         PCHAR FuncName = (PCHAR)((ULONG_PTR)BaseAddress + NameTable[i]);
  260.                         ANSI_STRING FuncNameA;
  261.                         UNICODE_STRING FuncNameW;
  262.                         WCHAR tmp[0x1000];
  263.                         memset(tmp,0,sizeof(tmp));
  264.                         RtlInitAnsiString(&FuncNameA,FuncName);
  265.                         FuncNameW.Buffer = tmp;
  266.                         FuncNameW.MaximumLength = 0x1000;
  267.                         Status = RtlAnsiStringToUnicodeString(&FuncNameW,&FuncNameA,FALSE);
  268.                         if(NT_SUCCESS(Status))
  269.                         {
  270.                                 Ordinal = OrdinalTable[i];
  271.                                 if(Ordinal >=0 && Ordinal < ExportDir->NumberOfFunctions)
  272.                                 {
  273.                                         ULONG_PTR Function = (ULONG_PTR)BaseAddress + AddressOfFunctions[Ordinal];
  274.                                         if(!(Function > (ULONG_PTR)ExportDir && Function < (ULONG_PTR)ExportDir + ExportDirSize))
  275.                                         {
  276.                                                 ds.FuncMap[FuncNameW.Buffer] = (FARPROC)Function;
  277.                                         }
  278.                                 }
  279.                         }
  280.                 }
  281.         }

  282. ENDLOAD:
  283.         LeaveCriticalSection(&DllLock);
  284.         return result;
  285. }

  286. NTSTATUS NTAPI LdrpSetProtection(PVOID ViewBase,PIMAGE_NT_HEADERS NtHeaders,BOOLEAN Restore)
  287. {
  288.         NTSTATUS Status;
  289.         PVOID SectionBase;
  290.         SIZE_T SectionSize;
  291.         ULONG NewProtection, OldProtection, i;
  292. #define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) ((ULONG_PTR)(ntheader) + FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + ((ntheader))->FileHeader.SizeOfOptionalHeader ))
  293.         PIMAGE_SECTION_HEADER Section = IMAGE_FIRST_SECTION(NtHeaders);
  294.         for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++)
  295.         {
  296.                 if ((Section->SizeOfRawData) && !(Section->Characteristics & IMAGE_SCN_MEM_WRITE))
  297.                 {
  298.                         if (Restore)
  299.                         {
  300.                                 if (Section->Characteristics & IMAGE_SCN_MEM_EXECUTE)
  301.                                 {
  302.                                         NewProtection = PAGE_EXECUTE;
  303.                                 }
  304.                                 else
  305.                                 {
  306.                                         NewProtection = PAGE_READONLY;
  307.                                 }

  308.                                 if (Section->Characteristics & IMAGE_SCN_MEM_NOT_CACHED)
  309.                                 {
  310.                                         NewProtection |= PAGE_NOCACHE;
  311.                                 }
  312.                         }
  313.                         else
  314.                         {
  315.                                 NewProtection = PAGE_READWRITE;
  316.                         }

  317.                         SectionBase = (PVOID)((ULONG_PTR)ViewBase + Section->VirtualAddress);
  318.                         SectionSize = Section->SizeOfRawData;
  319.                         if (SectionSize)
  320.                         {
  321.                                 Status = NtProtectVirtualMemory((HANDLE)-1,&SectionBase,&SectionSize,NewProtection,&OldProtection);
  322.                                 if (!NT_SUCCESS(Status)) return Status;
  323.                         }
  324.                 }
  325.                 Section++;
  326.         }
  327.         if (Restore) NtFlushInstructionCache((HANDLE)-1, NULL, 0);
  328.         return STATUS_SUCCESS;
  329. }

  330. ULONG NTAPI LdrRelocateImageWithBias(PVOID BaseAddress,PIMAGE_NT_HEADERS NtHeaders,LONGLONG AdditionalBias,PCCH  LoaderName,ULONG Success,ULONG Conflict,ULONG Invalid)
  331. {
  332. #define SWAPW(x) (x)
  333. #define SWAPD(x) (x)
  334. #define SWAPQ(x) (x)
  335.         PIMAGE_DATA_DIRECTORY RelocationDDir;
  336.         PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
  337.         ULONG Count;
  338.         ULONG_PTR Address;
  339.         PUSHORT TypeOffset;
  340.         LONGLONG Delta;

  341.         if (SWAPW(NtHeaders->FileHeader.Characteristics) & IMAGE_FILE_RELOCS_STRIPPED)
  342.         {
  343.                 return Conflict;
  344.         }
  345.         RelocationDDir = &NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
  346.         if (SWAPD(RelocationDDir->VirtualAddress) == 0 || SWAPD(RelocationDDir->Size) == 0)
  347.         {
  348.                 return Success;
  349.         }
  350.         Delta = (ULONG_PTR)BaseAddress - SWAPD(NtHeaders->OptionalHeader.ImageBase) + AdditionalBias;
  351.         RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)BaseAddress + SWAPD(RelocationDDir->VirtualAddress));
  352.         RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + SWAPD(RelocationDDir->Size));
  353.         while (RelocationDir < RelocationEnd && SWAPW(RelocationDir->SizeOfBlock) > 0)
  354.         {
  355.                 SHORT Offset;
  356.                 USHORT Type;
  357.                 ULONG i;
  358.                 PUSHORT ShortPtr;
  359.                 PULONG LongPtr;
  360.                 PULONGLONG LongLongPtr;

  361.                 Count = (SWAPW(RelocationDir->SizeOfBlock) - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
  362.                 Address = (ULONG_PTR)(RelocationDir->VirtualAddress);
  363.                 TypeOffset = (PUSHORT)(RelocationDir + 1);

  364.                 for (ULONG i = 0; i < Count; i++)
  365.                 {
  366.                         Offset = SWAPW(*TypeOffset) & 0xFFF;
  367.                         Type = SWAPW(*TypeOffset) >> 12;
  368.                         ShortPtr = (PUSHORT)Offset;

  369.                         if ((ULONG_PTR)ShortPtr < (ULONG_PTR)RelocationDir || (ULONG_PTR)ShortPtr >= (ULONG_PTR)RelocationEnd)
  370.                                 continue;

  371.                         switch (Type)
  372.                         {
  373.                                 /* case IMAGE_REL_BASED_SECTION : */
  374.                                 /* case IMAGE_REL_BASED_REL32 : */
  375.                         case IMAGE_REL_BASED_ABSOLUTE:
  376.                                 break;
  377.                         case IMAGE_REL_BASED_HIGH:
  378.                                 *ShortPtr = HIWORD(MAKELONG(0, *ShortPtr) + (Delta & 0xFFFFFFFF));
  379.                                 break;
  380.                         case IMAGE_REL_BASED_LOW:
  381.                                 *ShortPtr = SWAPW(*ShortPtr) + LOWORD(Delta & 0xFFFF);
  382.                                 break;
  383.                         case IMAGE_REL_BASED_HIGHLOW:
  384.                                 LongPtr = (PULONG)Offset;
  385.                                 *LongPtr = SWAPD(*LongPtr) + (Delta & 0xFFFFFFFF);
  386.                                 break;
  387.                         case IMAGE_REL_BASED_DIR64:
  388.                                 LongLongPtr = (PUINT64)Offset;
  389.                                 *LongLongPtr = SWAPQ(*LongLongPtr) + Delta;
  390.                                 break;
  391.                         case IMAGE_REL_BASED_HIGHADJ:
  392.                         case IMAGE_REL_BASED_MIPS_JMPADDR:
  393.                         default:
  394.                                 RelocationDir = (PIMAGE_BASE_RELOCATION)NULL;
  395.                         }
  396.                         TypeOffset++;
  397.                 }
  398.                 RelocationDir = (PIMAGE_BASE_RELOCATION)TypeOffset;
  399.                 if (RelocationDir == NULL)
  400.                 {
  401.                         return Invalid;
  402.                 }
  403.         }
  404.         return Success;
  405. }

  406. FARPROC WINAPI GetProcAddressTA(LPCSTR DllPath,LPCSTR ProcName)
  407. {
  408.         ANSI_STRING DllPathA,ProcNameA;
  409.         UNICODE_STRING DllPathW,ProcNameW;
  410.         NTSTATUS status;
  411.         if(!DllPath || !ProcName || DllPath[0] == 0 || ProcName[0] == 0)
  412.                 return NULL;
  413.         WCHAR tmp1[0x1000],tmp2[0x1000];
  414.         memset(tmp1,0,sizeof(tmp1));
  415.         memset(tmp2,0,sizeof(tmp2));
  416.         RtlInitAnsiString(&DllPathA,DllPath);
  417.         RtlInitAnsiString(&ProcNameA,ProcName);
  418.         DllPathW.Buffer = tmp1;
  419.         DllPathW.MaximumLength = 0x1000;
  420.         ProcNameW.Buffer = tmp2;
  421.         ProcNameW.MaximumLength = 0x1000;
  422.         status = RtlAnsiStringToUnicodeString(&DllPathW,&DllPathA,FALSE);
  423.         if(!NT_SUCCESS(status))
  424.                 return FALSE;
  425.         status = RtlAnsiStringToUnicodeString(&ProcNameW,&ProcNameA,FALSE);
  426.         if(!NT_SUCCESS(status))
  427.                 return FALSE;
  428.         return GetProcAddressTW(DllPathW.Buffer,ProcNameW.Buffer);
  429. }

  430. FARPROC WINAPI GetProcAddressTW(LPCWSTR DllPath,LPCWSTR ProcName)
  431. {
  432.         if(!DllPath || !ProcName || DllPath[0] == 0 || ProcName[0] == 0)
  433.                 return NULL;
  434.         FARPROC result = NULL;
  435.         EnterCriticalSection(&DllLock);
  436.         std::map<std::wstring,DllStruct>::iterator itor1 = DllMap.find(DllPath);
  437.         if(itor1 != DllMap.end())
  438.         {
  439.                 std::map<std::wstring,FARPROC>::iterator itor2 = (*itor1).second.FuncMap.find(ProcName);
  440.                 if(itor2 != (*itor1).second.FuncMap.end())
  441.                 {
  442.                         result = (*itor2).second;
  443.                 }
  444.         }
  445.         LeaveCriticalSection(&DllLock);
  446.         return result;
  447. }

  448. BOOL WINAPI FreeLibraryTA(LPCSTR DllPath)
  449. {
  450.         ANSI_STRING DllPathA;
  451.         UNICODE_STRING DllPathW;
  452.         NTSTATUS status;
  453.         if(!DllPath || DllPath[0] == 0)
  454.                 return FALSE;
  455.         WCHAR tmp[0x1000];
  456.         memset(tmp,0,sizeof(tmp));
  457.         RtlInitAnsiString(&DllPathA,DllPath);
  458.         DllPathW.Buffer = tmp;
  459.         DllPathW.MaximumLength = 0x1000;
  460.         status = RtlAnsiStringToUnicodeString(&DllPathW,&DllPathA,FALSE);
  461.         if(!NT_SUCCESS(status))
  462.                 return FALSE;
  463.         return FreeLibraryTW(DllPathW.Buffer);
  464. }

  465. BOOL WINAPI FreeLibraryTW(LPCWSTR DllPath)
  466. {
  467.         BOOL result = FALSE;
  468.         if(!DllPath || DllPath[0] == 0)
  469.                 return FALSE;

  470.         EnterCriticalSection(&DllLock);
  471.         std::map<std::wstring,DllStruct>::iterator itor = DllMap.find(DllPath);
  472.         if(itor == DllMap.end())
  473.         {
  474.                 result = FALSE;
  475.                 goto ENDFREE;
  476.         }

  477.         NTSTATUS Status;
  478.         PVOID BaseAddress = (*itor).second.ViewBase;
  479.         PVOID EntryPoint = (*itor).second.EntryPoint;

  480.         typedef BOOLEAN (WINAPI *PDLL_INIT_ROUTINE)( PVOID DllHandle,ULONG Reason,PCONTEXT Context );
  481.         ((PDLL_INIT_ROUTINE)EntryPoint)(BaseAddress,DLL_PROCESS_ATTACH,NULL);
  482.         Status = NtUnmapViewOfSection((HANDLE)-1, BaseAddress);
  483.         if(NT_SUCCESS(Status))
  484.                 result = TRUE;
  485. ENDFREE:
  486.         LeaveCriticalSection(&DllLock);
  487.         return result;
  488. }

  489. void main()
  490. {
  491.         InitializeCriticalSection(&DllLock);
  492.         LoadLibraryTA("d:\\1.dll");
  493.         FARPROC func=GetProcAddressTA("d:\\1.dll","func");
  494.         ((void (__cdecl *)())func)();
  495. }
复制代码


回复

使用道具 举报

 楼主| 发表于 2015-6-18 23:37:09 | 显示全部楼层
完善后的代码,,可以弹出MessageBox
  1. #undef _WIN32_WINNT
  2. #define _WIN32_WINNT 0x0500

  3. #include <windows.h>
  4. #include <winternl.h>
  5. #include <Shlwapi.h>
  6. #include <map>
  7. #include <string>
  8. using namespace std;

  9. #pragma comment(lib,"user32.lib")
  10. #pragma comment(lib,"Shlwapi.lib")

  11. #if defined(WIN64) || defined(_WIN64)
  12. #pragma comment(lib,"ntdll64.lib")
  13. #else
  14. #pragma comment(lib,"ntdll.lib")
  15. #endif

  16. #if defined(UNICODE) || defined(_UNICODE)
  17. #define GetProcAddressT GetProcAddressTW
  18. #define LoadLibraryT LoadLibraryTW
  19. #define FreeLibraryT FreeLibraryTW
  20. #else
  21. #define GetProcAddressT GetProcAddressTA
  22. #define LoadLibraryT LoadLibraryTA
  23. #define FreeLibraryT FreeLibraryTA
  24. #endif

  25. extern "C"
  26. {
  27.         BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(PCWSTR,PUNICODE_STRING,PCWSTR*,PVOID*);
  28.         NTSTATUS WINAPI NtMapViewOfSection(HANDLE,HANDLE,PVOID*,ULONG,SIZE_T,const LARGE_INTEGER*,SIZE_T*,ULONG,ULONG,ULONG);
  29.         BOOLEAN WINAPI RtlFreeHeap(PVOID,ULONG,PVOID);
  30.         NTSTATUS WINAPI NtCreateSection(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PLARGE_INTEGER,ULONG,ULONG,HANDLE);
  31.         NTSTATUS WINAPI NtUnmapViewOfSection(HANDLE,PVOID);
  32.         NTSTATUS WINAPI NtProtectVirtualMemory(HANDLE,PVOID,PSIZE_T,ULONG,PULONG);
  33.         NTSTATUS WINAPI NtFlushInstructionCache(HANDLE,PVOID,ULONG);
  34. };


  35. void RtlImageDirectoryEntryToData(PIMAGE_NT_HEADERS,USHORT,ULONG*,PVOID*,PVOID) ;
  36. ULONG NTAPI LdrRelocateImageWithBias(PVOID,PIMAGE_NT_HEADERS,LONGLONG ,PCCH,ULONG,ULONG,ULONG);
  37. NTSTATUS NTAPI LdrpSetProtection(PVOID,PIMAGE_NT_HEADERS,BOOLEAN);

  38. #define OBJ_CASE_INSENSITIVE    0x00000040L
  39. #define STATUS_IMAGE_NOT_AT_BASE ((NTSTATUS)0x40000003L)
  40. #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
  41. #define STATUS_CONFLICTING_ADDRESSES ((NTSTATUS)0xC0000018L)
  42. #define STATUS_INVALID_IMAGE_FORMAT ((NTSTATUS)0xC000007BL)
  43. #define FILE_NON_DIRECTORY_FILE 0x00000040
  44. #define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020

  45. typedef struct _CLIENT_ID
  46. {
  47.         HANDLE UniqueProcess;
  48.         HANDLE UniqueThread;
  49. } CLIENT_ID;

  50. typedef struct _MTEB
  51. {
  52.         _NT_TIB NtTib;
  53.         PVOID EnvironmentPointer;
  54.         CLIENT_ID ClientId;
  55.         PVOID ActiveRpcHandle;
  56.         PVOID ThreadLocalStoragePointer;
  57.         PPEB Peb;
  58. }MTEB,*PMTEB;

  59. typedef struct _MPEB_LDR_DATA
  60. {
  61.         UINT32 Length;
  62.         UCHAR Initialized;
  63.         PVOID SsHandle;
  64.         LIST_ENTRY InLoadOrderModuleList;
  65.         LIST_ENTRY InMemoryOrderModuleList;
  66.         LIST_ENTRY InInitializationOrderModuleList;
  67. }MPEB_LDR_DATA,*PMPEB_LDR_DATA;

  68. typedef struct _LDR_MODULE
  69. {
  70.         LIST_ENTRY InLoadOrderModuleList;
  71.         LIST_ENTRY InMemoryOrderModuleList;
  72.         LIST_ENTRY InInitializationOrderModuleList;
  73.         PVOID BaseAddress;
  74.         PVOID EntryPoint;
  75.         ULONG SizeOfImage;
  76.         UNICODE_STRING FullDllName;
  77. }LDR_MODULE,*PLDR_MODULE;

  78. typedef struct _MPEB
  79. {
  80.         DWORD flags;
  81.         PVOID Mutant;
  82.         PVOID ImageBaseAddress;
  83.         PMPEB_LDR_DATA Ldr;
  84.         PVOID ProcessParameters;
  85.         PVOID SubSystemData;
  86.         PVOID ProcessHeap;
  87. }MPEB,*PMPEB;

  88. struct DllStruct
  89. {
  90.         PVOID EntryPoint;
  91.         PVOID ViewBase;
  92.         SIZE_T ViewSize;
  93.         std::map<std::wstring,FARPROC> FuncMap;//函数映射
  94. };
  95. std::map<std::wstring,DllStruct> DllMap;
  96. CRITICAL_SECTION DllLock;
  97. #define RtlGetProcessHeap() ( (PMPEB)((PMTEB)NtCurrentTeb())->Peb )->ProcessHeap
  98. #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
  99. #define InitializeObjectAttributes( p, n, a, r, s ) { (p)->Length = sizeof( OBJECT_ATTRIBUTES ); (p)->RootDirectory = r; (p)->Attributes = a; (p)->ObjectName = n; (p)->SecurityDescriptor = s; (p)->SecurityQualityOfService = NULL; }
  100. #define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) ((ULONG_PTR)(ntheader) + FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + ((ntheader))->FileHeader.SizeOfOptionalHeader ))

  101. BOOL WINAPI LoadLibraryTA(LPCSTR DllPath);
  102. BOOL WINAPI LoadLibraryTW(LPCWSTR DllPath);
  103. FARPROC WINAPI GetProcAddressTA(LPCSTR DllPath,LPCSTR ProcName);
  104. FARPROC WINAPI GetProcAddressTW(LPCWSTR DllPath,LPCWSTR ProcName);
  105. BOOL WINAPI FreeLibraryTA(LPCSTR DllPath);
  106. BOOL WINAPI FreeLibraryTW(LPCWSTR DllPath);

  107. #define SWAPW(x) (x)
  108. #define SWAPD(x) (x)
  109. #define SWAPQ(x) (x)
  110. #define RVA(m, b) ((PVOID)((ULONG_PTR)(b) + (ULONG_PTR)(m)))

  111. typedef BOOLEAN (WINAPI *PDLL_INIT_ROUTINE)( PVOID DllHandle,ULONG Reason,PCONTEXT Context );

  112. void GetExportFuncs( PIMAGE_NT_HEADERS NtHeaders, PVOID ViewBase, DllStruct* ds)
  113. {
  114.         PIMAGE_EXPORT_DIRECTORY ExportDir = NULL;
  115.         ULONG ExportDirSize = 0;
  116.         if(!NtHeaders && ViewBase)
  117.         {
  118.                 PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)ViewBase;
  119.                 NtHeaders = (PIMAGE_NT_HEADERS)((BYTE*)DosHeader + DosHeader->e_lfanew);
  120.         }
  121.         if(!NtHeaders)
  122.                 return;
  123.         RtlImageDirectoryEntryToData(NtHeaders, IMAGE_DIRECTORY_ENTRY_EXPORT, &ExportDirSize, (PVOID*)&ExportDir, ViewBase);
  124.         PULONG NameTable = (PULONG)((ULONG_PTR)ViewBase + (ULONG_PTR)ExportDir->AddressOfNames);
  125.         PUSHORT OrdinalTable = (PUSHORT)((ULONG_PTR)ViewBase + (ULONG_PTR)ExportDir->AddressOfNameOrdinals);
  126.         PULONG AddressOfFunctions = (PULONG)((ULONG_PTR)ViewBase + (ULONG_PTR)ExportDir->AddressOfFunctions);
  127.         USHORT Ordinal = -1;
  128.         for(LONG i = 0;i < ExportDir->NumberOfNames;i++)
  129.         {
  130.                 PCHAR FuncName = (PCHAR)((ULONG_PTR)ViewBase + NameTable[i]);
  131.                 ANSI_STRING FuncNameA;
  132.                 UNICODE_STRING FuncNameW;
  133.                 WCHAR tmp[0x1000];
  134.                 memset(tmp,0,sizeof(tmp));
  135.                 RtlInitAnsiString(&FuncNameA,FuncName);
  136.                 FuncNameW.Buffer = tmp;
  137.                 FuncNameW.MaximumLength = 0x1000;
  138.                 NTSTATUS Status = RtlAnsiStringToUnicodeString(&FuncNameW,&FuncNameA,FALSE);
  139.                 if(NT_SUCCESS(Status))
  140.                 {
  141.                         Ordinal = OrdinalTable[i];
  142.                         if(Ordinal >=0 && Ordinal < ExportDir->NumberOfFunctions)
  143.                         {
  144.                                 ULONG_PTR Function = (ULONG_PTR)ViewBase + AddressOfFunctions[Ordinal];
  145.                                 if(!(Function > (ULONG_PTR)ExportDir && Function < (ULONG_PTR)ExportDir + ExportDirSize))
  146.                                 {
  147.                                         ds->FuncMap[FuncNameW.Buffer] = (FARPROC)Function;
  148.                                 }
  149.                         }
  150.                 }
  151.         }
  152. }

  153. BOOL WINAPI LoadLibraryTA(LPCSTR DllPath)
  154. {
  155.         ANSI_STRING DllPathA;
  156.         UNICODE_STRING DllPathW;
  157.         NTSTATUS status;
  158.         if(!DllPath || DllPath[0] == 0)
  159.                 return FALSE;
  160.         WCHAR tmp[0x1000];
  161.         memset(tmp,0,sizeof(tmp));
  162.         RtlInitAnsiString(&DllPathA,DllPath);
  163.         DllPathW.Buffer = tmp;
  164.         DllPathW.MaximumLength = 0x1000;
  165.         status = RtlAnsiStringToUnicodeString(&DllPathW,&DllPathA,FALSE);
  166.         if(!NT_SUCCESS(status))
  167.                 return FALSE;
  168.         return LoadLibraryTW(DllPathW.Buffer);
  169. }

  170. BOOL LdrpLoadImportModule(LPSTR ImportName, PVOID BaseAddress, LPWSTR pDllPath)
  171. {
  172.         PVOID Address = (PVOID)LoadLibraryA(ImportName);
  173.         Address = (PVOID)((ULONG_PTR)Address&~3);
  174.         //遍历Ldr找到全路径
  175.         PLIST_ENTRY ListHead = &((PMPEB)((PMTEB)NtCurrentTeb())->Peb)->Ldr->InLoadOrderModuleList;
  176.         PLIST_ENTRY Next = ListHead->Flink;
  177.         while(Next != ListHead)
  178.         {
  179.                 PLDR_MODULE Cur = (PLDR_MODULE)Next;
  180.                 if(Cur->BaseAddress == Address)
  181.                 {
  182.                         memset(pDllPath,0,0x1000);
  183.                         wcsncpy(pDllPath,Cur->FullDllName.Buffer,Cur->FullDllName.Length);
  184.                         std::map<std::wstring,DllStruct>::iterator itor = DllMap.find(pDllPath);
  185.                         if(itor == DllMap.end())
  186.                         {
  187.                                 DllStruct& ds= DllMap[pDllPath];
  188.                                 ds.EntryPoint = Cur->EntryPoint;
  189.                                 ds.ViewBase = Cur->BaseAddress;
  190.                                 ds.ViewSize = Cur->SizeOfImage;
  191.                                 GetExportFuncs(NULL,Address,&ds);
  192.                         }
  193.                         return TRUE;
  194.                 }
  195.                 Next = Next->Flink;
  196.         }
  197.         return FALSE;
  198. }

  199. void LdrpSnapThunk( PVOID ExportBase, PVOID ImportBase, PIMAGE_THUNK_DATA OriginalThunk, PIMAGE_THUNK_DATA Thunk, PIMAGE_EXPORT_DIRECTORY ExportEntry, ULONG ExportSize )
  200. {
  201.         PIMAGE_IMPORT_BY_NAME AddressOfData = (PIMAGE_IMPORT_BY_NAME)((ULONG_PTR)ImportBase + ((ULONG_PTR)OriginalThunk->u1.AddressOfData & 0xFFFFFFFF));
  202.         LPSTR ImportName = (LPSTR)AddressOfData->Name;
  203.         PULONG NameTable = (PULONG)((ULONG_PTR)ExportBase + (ULONG_PTR)ExportEntry->AddressOfNames);
  204.         PUSHORT OridinalTable = (PUSHORT)((ULONG_PTR)ExportBase + (ULONG_PTR)ExportEntry->AddressOfNameOrdinals);
  205.         USHORT Hint = AddressOfData->Hint;
  206.        
  207. }

  208. void LdrpSnapIAT(PIMAGE_NT_HEADERS NtHeaders, PIMAGE_IMPORT_DESCRIPTOR IatData, PVOID ViewBase,LPCWSTR DllPathW)
  209. {
  210.         NTSTATUS Status;
  211.         PVOID Iat = NULL;
  212.         SIZE_T ImportSize = 0;
  213.         ULONG IatSize = 0, ExportSize = 0;
  214.         ULONG OldProtect = 0;
  215.         RtlImageDirectoryEntryToData(NtHeaders, IMAGE_DIRECTORY_ENTRY_IAT, &IatSize, &Iat, ViewBase);
  216.         if(!Iat || !IatSize)
  217.         {
  218.                 PIMAGE_SECTION_HEADER SectionHeader = (PIMAGE_SECTION_HEADER)((ULONG_PTR)(NtHeaders) + FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + NtHeaders->FileHeader.SizeOfOptionalHeader );
  219.                 ULONG Rva = NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
  220.                 if(Rva)
  221.                 {
  222.                         for(ULONG i = 0;i < NtHeaders->FileHeader.NumberOfSections;i++)
  223.                         {
  224.                                 if((Rva >= SectionHeader->VirtualAddress) && Rva < (SectionHeader->VirtualAddress + SectionHeader->SizeOfRawData))
  225.                                 {
  226.                                         Iat = (PVOID)((ULONG_PTR)(ViewBase) + SectionHeader->VirtualAddress);
  227.                                         IatSize = SectionHeader->Misc.VirtualSize;
  228.                                         if(!IatSize)
  229.                                                 IatSize = SectionHeader->SizeOfRawData;
  230.                                         break;
  231.                                 }
  232.                                 SectionHeader++;
  233.                         }
  234.                 }
  235.                 else
  236.                         return;
  237.         }
  238.         ImportSize = IatSize;

  239.         Status = NtProtectVirtualMemory(((HANDLE)(LONG_PTR) -1), &Iat, &ImportSize, PAGE_READWRITE, &OldProtect);
  240.         if(!NT_SUCCESS(Status))
  241.                 return;
  242.         if(IatData->FirstThunk)
  243.         {
  244.                 PIMAGE_THUNK_DATA OriginalThunk = NULL;
  245.                 PIMAGE_THUNK_DATA FirstThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)ViewBase + IatData->FirstThunk);
  246.                 if((IatData->Characteristics < NtHeaders->OptionalHeader.SizeOfHeaders) || (IatData->Characteristics >= NtHeaders->OptionalHeader.SizeOfImage))
  247.                 {
  248.                         OriginalThunk = FirstThunk;
  249.                 }
  250.                 else
  251.                 {
  252.                         OriginalThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)ViewBase + IatData->OriginalFirstThunk);
  253.                 }
  254.                 LPSTR ImportName = (LPSTR)((ULONG_PTR)ViewBase + IatData->Name);
  255.                 while(OriginalThunk->u1.AddressOfData)
  256.                 {
  257.                         __try
  258.                         {
  259.                                 PIMAGE_IMPORT_BY_NAME AddressOfData = (PIMAGE_IMPORT_BY_NAME)((ULONG_PTR)ViewBase + (ULONG_PTR)OriginalThunk->u1.AddressOfData & 0xFFFFFFFF);
  260.                                 ImportName = (LPSTR)AddressOfData->Name;
  261.                                 ANSI_STRING FuncNameA;
  262.                                 WCHAR FuncName[0x1000];
  263.                                 UNICODE_STRING FuncNameW;
  264.                                 memset(FuncName,0,sizeof(FuncName));
  265.                                 RtlInitAnsiString(&FuncNameA,ImportName);
  266.                                 FuncNameW.Buffer = FuncName;
  267.                                 FuncNameW.MaximumLength = sizeof(FuncName);
  268.                                 RtlAnsiStringToUnicodeString(&FuncNameW,&FuncNameA,FALSE);
  269.                                 FirstThunk->u1.Function = (DWORD)GetProcAddressTW(DllPathW,FuncNameW.Buffer);
  270.                                 OriginalThunk++;
  271.                                 FirstThunk++;
  272.                         }
  273.                         __except(1)
  274.                         {

  275.                         }
  276.                 }
  277.         }
  278.         NtProtectVirtualMemory(((HANDLE)(LONG_PTR) -1),&Iat,&ImportSize,OldProtect,&OldProtect);
  279.         NtFlushInstructionCache(((HANDLE)(LONG_PTR) -1),Iat,IatSize);
  280. }

  281. void RtlImageDirectoryEntryToData(PIMAGE_NT_HEADERS NtHeaders, USHORT Directory, ULONG* RelocDataSize, PVOID* RelocData, PVOID ViewBase)
  282. {
  283.         if(NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
  284.         {
  285.                 PIMAGE_NT_HEADERS32 tpnh = (PIMAGE_NT_HEADERS32)NtHeaders;
  286.                 if(Directory < tpnh->OptionalHeader.NumberOfRvaAndSizes)
  287.                 {
  288.                         DWORD VA = tpnh->OptionalHeader.DataDirectory[Directory].VirtualAddress;
  289.                         if(VA)
  290.                         {
  291.                                 *RelocDataSize = tpnh->OptionalHeader.DataDirectory[Directory].Size;
  292.                                 *RelocData = (PVOID)((ULONG_PTR)ViewBase + VA);
  293.                         }
  294.                 }
  295.         }
  296.         else
  297.         {
  298.                 PIMAGE_NT_HEADERS64 tpnh = (PIMAGE_NT_HEADERS64)NtHeaders;
  299.                 if(Directory < tpnh->OptionalHeader.NumberOfRvaAndSizes)
  300.                 {
  301.                         DWORD VA = tpnh->OptionalHeader.DataDirectory[Directory].VirtualAddress;
  302.                         if(VA)
  303.                         {
  304.                                 *RelocDataSize = tpnh->OptionalHeader.DataDirectory[Directory].Size;
  305.                                 *RelocData = (PVOID)((BYTE*)ViewBase + VA);
  306.                         }
  307.                 }
  308.         }
  309. }

  310. BOOL WINAPI LoadLibraryTW(LPCWSTR DllPath)
  311. {
  312.         if(!DllPath || DllPath[0] == 0)
  313.                 return FALSE;
  314.         BOOL result = FALSE;

  315.         EnterCriticalSection(&DllLock);
  316.         //查找Map,遍历导出表,更新Map
  317.         std::map<std::wstring,DllStruct>::iterator itor = DllMap.find(DllPath);
  318.         if(itor != DllMap.end())
  319.         {
  320.                 result = FALSE;
  321.                 goto ENDLOAD;
  322.         }

  323.         UNICODE_STRING NtPathDllName;
  324.         OBJECT_ATTRIBUTES ObjectAttributes;
  325.         HANDLE FileHandle = NULL,SectionHandle = NULL;
  326.         IO_STATUS_BLOCK IoStatusBlock;
  327.         NTSTATUS Status;
  328.         if(!RtlDosPathNameToNtPathName_U(DllPath,&NtPathDllName,NULL,NULL))
  329.         {
  330.                 result = FALSE;
  331.                 goto ENDLOAD;
  332.         }
  333.         InitializeObjectAttributes(&ObjectAttributes,&NtPathDllName,OBJ_CASE_INSENSITIVE,NULL,NULL);
  334.         Status = NtOpenFile(&FileHandle,SYNCHRONIZE | FILE_EXECUTE | FILE_READ_DATA,&ObjectAttributes,&IoStatusBlock,
  335.                 FILE_SHARE_READ | FILE_SHARE_DELETE,FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
  336.         if (!NT_SUCCESS(Status))
  337.         {//尝试以只读方式打开
  338.                 Status = NtOpenFile(&FileHandle,SYNCHRONIZE | FILE_EXECUTE,&ObjectAttributes,&IoStatusBlock,
  339.                         FILE_SHARE_READ | FILE_SHARE_DELETE,FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
  340.         }
  341.         if(!NT_SUCCESS(Status))
  342.         {
  343.                 result = FALSE;
  344.                 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathDllName.Buffer);
  345.                 goto ENDLOAD;
  346.         }
  347.         Status = NtCreateSection(&SectionHandle,SECTION_MAP_READ | SECTION_MAP_EXECUTE |SECTION_MAP_WRITE | SECTION_QUERY,
  348.                 NULL,NULL,PAGE_EXECUTE,SEC_IMAGE,FileHandle);
  349.         NtClose(FileHandle);
  350.         if(!NT_SUCCESS(Status))
  351.         {
  352.                 result = FALSE;
  353.                 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathDllName.Buffer);
  354.                 goto ENDLOAD;
  355.         }
  356.         RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathDllName.Buffer);

  357.         PVOID ViewBase = NULL;
  358.         SIZE_T ViewSize = 0;
  359.         PIMAGE_NT_HEADERS NtHeaders = NULL;
  360.         PIMAGE_DOS_HEADER DosHeader = NULL;
  361.         PVOID EntryPoint = NULL;
  362.         Status = NtMapViewOfSection(SectionHandle,((HANDLE)(LONG_PTR) -1)/*NtCurrentProcess()*/,&ViewBase,0,0,NULL,&ViewSize,1/*ViewShare*/,0,PAGE_READWRITE);

  363.         if(ViewBase)
  364.         {
  365.                 DosHeader = (PIMAGE_DOS_HEADER)ViewBase;
  366.                 if(DosHeader->e_magic == IMAGE_DOS_SIGNATURE && DosHeader->e_lfanew  && DosHeader->e_lfanew < ViewSize)
  367.                 {
  368.                         NtHeaders = (PIMAGE_NT_HEADERS)((BYTE*)DosHeader + DosHeader->e_lfanew);
  369.                         if(NtHeaders->Signature != IMAGE_NT_SIGNATURE)
  370.                                 NtHeaders = NULL;
  371.                 }
  372.                 if(!NtHeaders || !(NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL))
  373.                 {
  374.                         result = FALSE;
  375.                         goto ENDLOAD;
  376.                 }
  377.                 if(NtHeaders->OptionalHeader.AddressOfEntryPoint)
  378.                         EntryPoint = (PVOID)(NtHeaders->OptionalHeader.AddressOfEntryPoint + (BYTE*)ViewBase);
  379.         }

  380.         if(Status == STATUS_IMAGE_NOT_AT_BASE)
  381.         {//重定位
  382.                 if(!(NtHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED))
  383.                 {
  384.                         ULONG RelocDataSize = 0;
  385.                         PVOID RelocData = NULL;
  386.                         RtlImageDirectoryEntryToData(NtHeaders, IMAGE_DIRECTORY_ENTRY_BASERELOC, &RelocDataSize, &RelocData, ViewBase);
  387.                         if(RelocData && RelocDataSize)
  388.                         {
  389.                                 Status = LdrpSetProtection(ViewBase,NtHeaders,FALSE);
  390.                                 if(NT_SUCCESS(Status))
  391.                                 {
  392.                                         Status = LdrRelocateImageWithBias(ViewBase, NtHeaders, 0LL, NULL, STATUS_SUCCESS,STATUS_CONFLICTING_ADDRESSES, STATUS_INVALID_IMAGE_FORMAT);
  393.                                         LdrpSetProtection(ViewBase,NtHeaders,TRUE);
  394.                                         if(NT_SUCCESS(Status))
  395.                                         {
  396.                                                 goto ENDLOAD1;
  397.                                         }
  398.                                 }
  399.                         }
  400.                 }
  401.                 if(!NT_SUCCESS(Status) || ViewBase)
  402.                 {
  403.                         NtUnmapViewOfSection(((HANDLE)(LONG_PTR) -1)/*NtCurrentProcess()*/,ViewBase);
  404.                         result = FALSE;
  405.                 }
  406.         }
  407.         else if(!NT_SUCCESS(Status))
  408.         {
  409.                 result = FALSE;
  410.                 goto ENDLOAD;
  411.         }
  412. ENDLOAD1:
  413.         NtClose(SectionHandle);
  414.         if(NT_SUCCESS(Status))
  415.                 result = TRUE;
  416.         DllStruct& ds = DllMap[DllPath];
  417.         ds.EntryPoint = EntryPoint;
  418.         ds.ViewBase = ViewBase;
  419.         ds.ViewSize = ViewSize;
  420.         {
  421.                 //处理导入表
  422.                 ULONG IatDataSize = 0;
  423.                 IMAGE_IMPORT_DESCRIPTOR* IatData = NULL;
  424.                 RtlImageDirectoryEntryToData(NtHeaders, IMAGE_DIRECTORY_ENTRY_IMPORT, &IatDataSize, (PVOID *)&IatData, ViewBase);
  425.                 PVOID BaseAddress = ViewBase;
  426.                 if(IatData && IatDataSize)
  427.                 {
  428.                         while(IatData->Name && IatData->FirstThunk)
  429.                         {
  430.                                 LPSTR ImportName = (LPSTR)((ULONG_PTR)BaseAddress + IatData->Name);
  431.                                 PIMAGE_THUNK_DATA FirstThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)BaseAddress + IatData->FirstThunk);
  432.                                 if(FirstThunk->u1.Function)
  433.                                 {
  434.                                         WCHAR FuncName[0x1000];
  435.                                         if(LdrpLoadImportModule(ImportName,BaseAddress,FuncName))//否则应该报错
  436.                                                 LdrpSnapIAT(NtHeaders, IatData, ViewBase, FuncName);
  437.                                         else
  438.                                         {
  439.                                                 MessageBoxA(NULL,ImportName,ImportName,MB_OK);
  440. //                                                 LeaveCriticalSection(&DllLock);
  441. //                                                 return FALSE;
  442.                                         }
  443.                                 }
  444.                                 IatData++;
  445.                         }
  446.                 }

  447. //                if(EntryPoint)
  448. //                        ((PDLL_INIT_ROUTINE)EntryPoint)(ViewBase,DLL_PROCESS_ATTACH,NULL);
  449.                 GetExportFuncs(NtHeaders, ViewBase, &ds);
  450.         }

  451. ENDLOAD:
  452.         LeaveCriticalSection(&DllLock);
  453.         return result;
  454. }

  455. NTSTATUS NTAPI LdrpSetProtection(PVOID ViewBase,PIMAGE_NT_HEADERS NtHeaders,BOOLEAN Restore)
  456. {
  457.         NTSTATUS Status;
  458.         PVOID SectionBase;
  459.         SIZE_T SectionSize;
  460.         ULONG NewProtection, OldProtection, i;
  461.         PIMAGE_SECTION_HEADER Section = IMAGE_FIRST_SECTION(NtHeaders);
  462.         for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++)
  463.         {
  464.                 if ((Section->SizeOfRawData) && !(Section->Characteristics & IMAGE_SCN_MEM_WRITE))
  465.                 {
  466.                         if (Restore)
  467.                         {
  468.                                 if (Section->Characteristics & IMAGE_SCN_MEM_EXECUTE)
  469.                                 {
  470.                                         NewProtection = PAGE_EXECUTE;
  471.                                 }
  472.                                 else
  473.                                 {
  474.                                         NewProtection = PAGE_READONLY;
  475.                                 }

  476.                                 if (Section->Characteristics & IMAGE_SCN_MEM_NOT_CACHED)
  477.                                 {
  478.                                         NewProtection |= PAGE_NOCACHE;
  479.                                 }
  480.                         }
  481.                         else
  482.                         {
  483.                                 NewProtection = PAGE_READWRITE;
  484.                         }

  485.                         SectionBase = (PVOID)((ULONG_PTR)ViewBase + Section->VirtualAddress);
  486.                         SectionSize = Section->SizeOfRawData;
  487.                         if (SectionSize)
  488.                         {
  489.                                 Status = NtProtectVirtualMemory(((HANDLE)(LONG_PTR) -1)/*NtCurrentProcess*/,&SectionBase,&SectionSize,NewProtection,&OldProtection);
  490.                                 if (!NT_SUCCESS(Status)) return Status;
  491.                         }
  492.                 }
  493.                 Section++;
  494.         }
  495.         if (Restore) NtFlushInstructionCache(((HANDLE)(LONG_PTR) -1)/*NtCurrentProcess*/, NULL, 0);
  496.         return STATUS_SUCCESS;
  497. }

  498. ULONG NTAPI LdrRelocateImageWithBias(PVOID BaseAddress,PIMAGE_NT_HEADERS NtHeaders,LONGLONG AdditionalBias,PCCH  LoaderName,ULONG Success,ULONG Conflict,ULONG Invalid)
  499. {

  500.         PIMAGE_DATA_DIRECTORY RelocationDDir;
  501.         PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
  502.         ULONG Count;
  503.         ULONG_PTR Address;
  504.         PUSHORT TypeOffset;
  505.         LONGLONG Delta;

  506.         if (SWAPW(NtHeaders->FileHeader.Characteristics) & IMAGE_FILE_RELOCS_STRIPPED)
  507.         {
  508.                 return Conflict;
  509.         }
  510.         RelocationDDir = &NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
  511.         if (SWAPD(RelocationDDir->VirtualAddress) == 0 || SWAPD(RelocationDDir->Size) == 0)
  512.         {
  513.                 return Success;
  514.         }
  515.         Delta = (ULONG_PTR)BaseAddress - SWAPD(NtHeaders->OptionalHeader.ImageBase) + AdditionalBias;
  516.         RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)BaseAddress + SWAPD(RelocationDDir->VirtualAddress));
  517.         RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + SWAPD(RelocationDDir->Size));
  518.         while (RelocationDir < RelocationEnd && SWAPW(RelocationDir->SizeOfBlock) > 0)
  519.         {
  520.                 SHORT Offset;
  521.                 USHORT Type;
  522.                 ULONG i;
  523.                 PUSHORT ShortPtr;
  524.                 PULONG LongPtr;
  525.                 PULONGLONG LongLongPtr;
  526.                 Count = (SWAPW(RelocationDir->SizeOfBlock) - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
  527.                 Address = (ULONG_PTR)RVA(BaseAddress,SWAPD(RelocationDir->VirtualAddress));
  528.                 TypeOffset = (PUSHORT)(RelocationDir + 1);
  529.                 for (ULONG i = 0; i < Count; i++)
  530.                 {
  531.                         Offset = SWAPW(*TypeOffset) & 0xFFF;
  532.                         Type = SWAPW(*TypeOffset) >> 12;
  533.                         ShortPtr = (PUSHORT)RVA(Address,Offset);
  534.                         if((ULONG_PTR)ShortPtr >= (ULONG_PTR)RelocationDir && (ULONG_PTR)ShortPtr < (ULONG_PTR)RelocationEnd)
  535.                                 continue;
  536.                         switch (Type)
  537.                         {
  538.                         case IMAGE_REL_BASED_ABSOLUTE:
  539.                                 break;
  540.                         case IMAGE_REL_BASED_HIGH:
  541.                                 *ShortPtr = HIWORD(MAKELONG(0, *ShortPtr) + (Delta & 0xFFFFFFFF));
  542.                                 break;
  543.                         case IMAGE_REL_BASED_LOW:
  544.                                 *ShortPtr = SWAPW(*ShortPtr) + LOWORD(Delta & 0xFFFF);
  545.                                 break;
  546.                         case IMAGE_REL_BASED_HIGHLOW:
  547.                                 LongPtr = (PULONG)RVA(Address,Offset);
  548.                                 *LongPtr = SWAPD(*LongPtr) + (Delta & 0xFFFFFFFF);
  549.                                 break;
  550.                         case IMAGE_REL_BASED_DIR64:
  551.                                 LongLongPtr = (PUINT64)RVA(Address,Offset);
  552.                                 *LongLongPtr = SWAPQ(*LongLongPtr) + Delta;
  553.                                 break;
  554.                         case IMAGE_REL_BASED_HIGHADJ:
  555.                         case IMAGE_REL_BASED_MIPS_JMPADDR:
  556.                         default:
  557.                                 RelocationDir = (PIMAGE_BASE_RELOCATION)NULL;
  558.                         }
  559.                         TypeOffset++;
  560.                 }
  561.                 RelocationDir = (PIMAGE_BASE_RELOCATION)TypeOffset;
  562.                 if (RelocationDir == NULL)
  563.                 {
  564.                         return Invalid;
  565.                 }
  566.         }
  567.         return Success;
  568. }

  569. FARPROC WINAPI GetProcAddressTA(LPCSTR DllPath,LPCSTR ProcName)
  570. {
  571.         ANSI_STRING DllPathA,ProcNameA;
  572.         UNICODE_STRING DllPathW,ProcNameW;
  573.         NTSTATUS status;
  574.         if(!DllPath || !ProcName || DllPath[0] == 0 || ProcName[0] == 0)
  575.                 return NULL;
  576.         WCHAR tmp1[0x1000],tmp2[0x1000];
  577.         memset(tmp1,0,sizeof(tmp1));
  578.         memset(tmp2,0,sizeof(tmp2));
  579.         RtlInitAnsiString(&DllPathA,DllPath);
  580.         RtlInitAnsiString(&ProcNameA,ProcName);
  581.         DllPathW.Buffer = tmp1;
  582.         DllPathW.MaximumLength = 0x1000;
  583.         ProcNameW.Buffer = tmp2;
  584.         ProcNameW.MaximumLength = 0x1000;
  585.         status = RtlAnsiStringToUnicodeString(&DllPathW,&DllPathA,FALSE);
  586.         if(!NT_SUCCESS(status))
  587.                 return FALSE;
  588.         status = RtlAnsiStringToUnicodeString(&ProcNameW,&ProcNameA,FALSE);
  589.         if(!NT_SUCCESS(status))
  590.                 return FALSE;
  591.         return GetProcAddressTW(DllPathW.Buffer,ProcNameW.Buffer);
  592. }

  593. FARPROC WINAPI GetProcAddressTW(LPCWSTR DllPath,LPCWSTR ProcName)
  594. {
  595.         if(!DllPath || !ProcName || DllPath[0] == 0 || ProcName[0] == 0)
  596.                 return NULL;
  597.         FARPROC result = NULL;
  598.         EnterCriticalSection(&DllLock);
  599.         std::map<std::wstring,DllStruct>::iterator itor1 = DllMap.find(DllPath);
  600.         if(itor1 != DllMap.end())
  601.         {
  602.                 std::map<std::wstring,FARPROC>::iterator itor2 = (*itor1).second.FuncMap.find(ProcName);
  603.                 if(itor2 != (*itor1).second.FuncMap.end())
  604.                 {
  605.                         result = (*itor2).second;
  606.                 }
  607.         }
  608.         LeaveCriticalSection(&DllLock);
  609.         return result;
  610. }

  611. BOOL WINAPI FreeLibraryTA(LPCSTR DllPath)
  612. {
  613.         ANSI_STRING DllPathA;
  614.         UNICODE_STRING DllPathW;
  615.         NTSTATUS status;
  616.         if(!DllPath || DllPath[0] == 0)
  617.                 return FALSE;
  618.         WCHAR tmp[0x1000];
  619.         memset(tmp,0,sizeof(tmp));
  620.         RtlInitAnsiString(&DllPathA,DllPath);
  621.         DllPathW.Buffer = tmp;
  622.         DllPathW.MaximumLength = 0x1000;
  623.         status = RtlAnsiStringToUnicodeString(&DllPathW,&DllPathA,FALSE);
  624.         if(!NT_SUCCESS(status))
  625.                 return FALSE;
  626.         return FreeLibraryTW(DllPathW.Buffer);
  627. }

  628. BOOL WINAPI FreeLibraryTW(LPCWSTR DllPath)
  629. {
  630.         BOOL result = FALSE;
  631.         if(!DllPath || DllPath[0] == 0)
  632.                 return FALSE;

  633.         EnterCriticalSection(&DllLock);
  634.         std::map<std::wstring,DllStruct>::iterator itor = DllMap.find(DllPath);
  635.         if(itor == DllMap.end())
  636.         {
  637.                 result = FALSE;
  638.                 goto ENDFREE;
  639.         }

  640.         NTSTATUS Status;
  641.         PVOID BaseAddress = (*itor).second.ViewBase;
  642.         PVOID EntryPoint = (*itor).second.EntryPoint;

  643.         ((PDLL_INIT_ROUTINE)EntryPoint)(BaseAddress,DLL_PROCESS_ATTACH,NULL);
  644.         Status = NtUnmapViewOfSection(((HANDLE)(LONG_PTR) -1)/*NtCurrentProcess*/, BaseAddress);
  645.         if(NT_SUCCESS(Status))
  646.                 result = TRUE;
  647.         DllMap.erase(itor);
  648. ENDFREE:
  649.         LeaveCriticalSection(&DllLock);
  650.         return result;
  651. }

  652. void main()
  653. {
  654.         InitializeCriticalSection(&DllLock);
  655.         LoadLibraryTA("d:\\1.dll");
  656.         FARPROC func=GetProcAddressTA("d:\\1.dll","func");
  657.         ((void (__cdecl *)())func)();
  658. }
复制代码
回复 赞! 靠!

使用道具 举报

发表于 2015-6-23 08:52:44 | 显示全部楼层
你可以去看看memorymodule
回复 赞! 靠!

使用道具 举报

本版积分规则

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

GMT+8, 2024-11-25 12:13 , Processed in 0.031486 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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