内核分析PE获取DLL导出函数地址

环境:VS2012+WIN8 64

类型:C++编写的WDM驱动程序

测试:VM WIN7

用途:主要用于驱动程序中得到WIN32 API地址,也可得到自定义的DLL中的函数导出地址,记录内核文件相关操作以便以后查看。

说明:此段代码来源于网络,经修改调试而成。


头文件 HelloWDM.h

  1. #if __cplusplus  
  2. extern "C"  
  3. {  
  4. #endif  
  5. #include <wdm.h>  
  6. #include <windef.h>  
  7. #ifdef __cplusplus  
  8. }  
  9. #endif  
  10.   
  11. //winnt.h中的定义 由于是WDM不能引用该文件 所以只有复制过来  
  12. #define SEC_IMAGE         0x1000000    
  13.   
  14. //PE相关结构  
  15. typedef struct _SECTION_IMAGE_INFORMATION  
  16. {  
  17.      PVOID TransferAddress;  
  18.      ULONG ZeroBits;  
  19.      ULONG MaximumStackSize;  
  20.      ULONG CommittedStackSize;  
  21.      ULONG SubSystemType;  
  22.      union  
  23.      {  
  24.           struct  
  25.           {  
  26.                WORD SubSystemMinorVersion;  
  27.                WORD SubSystemMajorVersion;  
  28.           };  
  29.           ULONG SubSystemVersion;  
  30.      };  
  31.      ULONG GpValue;  
  32.      WORD ImageCharacteristics;  
  33.      WORD DllCharacteristics;  
  34.      WORD Machine;  
  35.      UCHAR ImageContainsCode;  
  36.      UCHAR ImageFlags;  
  37.      ULONG ComPlusNativeReady: 1;  
  38.      ULONG ComPlusILOnly: 1;  
  39.      ULONG ImageDynamicallyRelocated: 1;  
  40.      ULONG Reserved: 5;  
  41.      ULONG LoaderFlags;  
  42.      ULONG ImageFileSize;  
  43.      ULONG CheckSum;  
  44. } SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;  
  45.   
  46. typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header  
  47.     WORD   e_magic;                     // Magic number  
  48.     WORD   e_cblp;                      // Bytes on last page of file  
  49.     WORD   e_cp;                        // Pages in file  
  50.     WORD   e_crlc;                      // Relocations  
  51.     WORD   e_cparhdr;                   // Size of header in paragraphs  
  52.     WORD   e_minalloc;                  // Minimum extra paragraphs needed  
  53.     WORD   e_maxalloc;                  // Maximum extra paragraphs needed  
  54.     WORD   e_ss;                        // Initial (relative) SS value  
  55.     WORD   e_sp;                        // Initial SP value  
  56.     WORD   e_csum;                      // Checksum  
  57.     WORD   e_ip;                        // Initial IP value  
  58.     WORD   e_cs;                        // Initial (relative) CS value  
  59.     WORD   e_lfarlc;                    // File address of relocation table  
  60.     WORD   e_ovno;                      // Overlay number  
  61.     WORD   e_res[4];                    // Reserved words  
  62.     WORD   e_oemid;                     // OEM identifier (for e_oeminfo)  
  63.     WORD   e_oeminfo;                   // OEM information; e_oemid specific  
  64.     WORD   e_res2[10];                  // Reserved words  
  65.     LONG   e_lfanew;                    // File address of new exe header  
  66.   } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;  
  67.   
  68. typedef struct _IMAGE_DATA_DIRECTORY {  
  69.     DWORD   VirtualAddress;  
  70.     DWORD   Size;  
  71. } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;  
  72.   
  73. typedef struct _IMAGE_OPTIONAL_HEADER {  
  74.     //  
  75.     // Standard fields.  
  76.     //  
  77.   
  78.     WORD    Magic;  
  79.     BYTE    MajorLinkerVersion;  
  80.     BYTE    MinorLinkerVersion;  
  81.     DWORD   SizeOfCode;  
  82.     DWORD   SizeOfInitializedData;  
  83.     DWORD   SizeOfUninitializedData;  
  84.     DWORD   AddressOfEntryPoint;  
  85.     DWORD   BaseOfCode;  
  86.     DWORD   BaseOfData;  
  87.   
  88.     //  
  89.     // NT additional fields.  
  90.     //  
  91.   
  92.     DWORD   ImageBase;  
  93.     DWORD   SectionAlignment;  
  94.     DWORD   FileAlignment;  
  95.     WORD    MajorOperatingSystemVersion;  
  96.     WORD    MinorOperatingSystemVersion;  
  97.     WORD    MajorImageVersion;  
  98.     WORD    MinorImageVersion;  
  99.     WORD    MajorSubsystemVersion;  
  100.     WORD    MinorSubsystemVersion;  
  101.     DWORD   Win32VersionValue;  
  102.     DWORD   SizeOfImage;  
  103.     DWORD   SizeOfHeaders;  
  104.     DWORD   CheckSum;  
  105.     WORD    Subsystem;  
  106.     WORD    DllCharacteristics;  
  107.     DWORD   SizeOfStackReserve;  
  108.     DWORD   SizeOfStackCommit;  
  109.     DWORD   SizeOfHeapReserve;  
  110.     DWORD   SizeOfHeapCommit;  
  111.     DWORD   LoaderFlags;  
  112.     DWORD   NumberOfRvaAndSizes;  
  113.     IMAGE_DATA_DIRECTORY DataDirectory[16];  
  114. } IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;  
  115.   
  116. typedef struct _IMAGE_EXPORT_DIRECTORY {  
  117.     DWORD   Characteristics;  
  118.     DWORD   TimeDateStamp;  
  119.     WORD    MajorVersion;  
  120.     WORD    MinorVersion;  
  121.     DWORD   Name;  
  122.     DWORD   Base;  
  123.     DWORD   NumberOfFunctions;  
  124.     DWORD   NumberOfNames;  
  125.     DWORD   AddressOfFunctions;     // RVA from base of image  
  126.     DWORD   AddressOfNames;         // RVA from base of image  
  127.     DWORD   AddressOfNameOrdinals;  // RVA from base of image  
  128. } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;  

HelloWDM.cpp文件

  1. #include "HelloWDM.h"  
  2.   
  3. //得到DLL中的指定函数地址 相当于应用层的GetProcAddress函数  
  4. DWORD GetDllFunctionAddress(PTSTR lpFunctionName, PTSTR pDllName)  
  5. {  
  6.     HANDLE hThread, hSection, hFile, hMod;  
  7.     SIZE_T size=0;  
  8.     NTSTATUS status;  
  9.     PVOID BaseAddress = NULL;  
  10.   
  11.     //转换DLL名称  
  12.     UNICODE_STRING strDllName;  
  13.     RtlInitUnicodeString(&strDllName, pDllName);  
  14.   
  15.     OBJECT_ATTRIBUTES objectAttributes={0};  
  16.     IO_STATUS_BLOCK iosb={0};  
  17.   
  18.     //初始化 objectAttributes  
  19.     InitializeObjectAttributes(&objectAttributes, &strDllName, OBJ_KERNEL_HANDLE, NULL, NULL);  
  20.   
  21.     //打开文件  
  22.     status=ZwOpenFile(&hFile,  FILE_EXECUTE | SYNCHRONIZE, &objectAttributes, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT);  
  23.     if(!NT_SUCCESS(status))  
  24.     {  
  25.         return status;  
  26.     }  
  27.     objectAttributes.ObjectName = 0;  
  28.   
  29.     //创建内存块  
  30.     status=ZwCreateSection(&hSection, SECTION_ALL_ACCESS, &objectAttributes, 0, PAGE_READONLY, SEC_IMAGE, hFile); //PAGE_READONLY页面保护属性,必须结合SEC_IMAGE属性  
  31.     if(!NT_SUCCESS(status))  
  32.     {  
  33.         return status;  
  34.     }  
  35.   
  36.     //内存映射文件  
  37.     status=ZwMapViewOfSection(hSection,   
  38.                             ZwCurrentProcess(),   
  39.                             &BaseAddress,   
  40.                             0,   
  41.                             1024,   
  42.                             0,   
  43.                             &size,   
  44.                             ViewUnmap,   
  45.                             MEM_LARGE_PAGES,        //针对DLL文件较小是可以用MEM_TOP_DOWN 文件较大比如USER32.DLL时需要用MEM_LARGE_PAGES  
  46.                             PAGE_READWRITE);          
  47.     if(!NT_SUCCESS(status))  
  48.     {  
  49.         return status;  
  50.     }  
  51.     //关闭文件句柄  
  52.     ZwClose(hFile);  
  53.   
  54.     //读取PE头信息  
  55.     IMAGE_DOS_HEADER* dosheader;  
  56.     IMAGE_OPTIONAL_HEADER* opthdr;  
  57.     IMAGE_EXPORT_DIRECTORY* pExportTable;  
  58.     PDWORD arrayOfFunctionAddresses, arrayOfFunctionNames;  
  59.     USHORT* arrayOfFunctionOrdinals;  
  60.     DWORD functionOrdinal, functionAddress=0;  
  61.     PSTR functionName;  
  62.     ANSI_STRING anFunName;  
  63.     UNICODE_STRING unFunctionName, unFunctionNameSearch;  
  64.     //模块句柄  
  65.     hMod = BaseAddress;  
  66.     //得到DOS头  
  67.     dosheader = (PIMAGE_DOS_HEADER)hMod;  
  68.     //得到PE选项头  
  69.     opthdr =(PIMAGE_OPTIONAL_HEADER) ((PBYTE)hMod+dosheader->e_lfanew+24);  
  70.     //得到导出表  
  71.     pExportTable =(PIMAGE_EXPORT_DIRECTORY)((PBYTE) hMod + opthdr->DataDirectory[0].VirtualAddress);  
  72.     //得到函数地址列表  
  73.     arrayOfFunctionAddresses = (PDWORD)( (PBYTE)hMod + pExportTable->AddressOfFunctions);  
  74.     //得到函数名称列表  
  75.     arrayOfFunctionNames = (PDWORD)( (PBYTE)hMod + pExportTable->AddressOfNames);  
  76.     //得到函数序号  
  77.     arrayOfFunctionOrdinals = (USHORT*)( (PBYTE)hMod + pExportTable->AddressOfNameOrdinals);  
  78.     //导出表基地址  
  79.     DWORD Base = pExportTable->Base;  
  80.   
  81.     //转换函数名  
  82.     RtlInitUnicodeString(&unFunctionNameSearch, lpFunctionName);  
  83.     //循环导出表  
  84.     for(DWORD x = 0; x < pExportTable->NumberOfNames; x++)            //导出函数有名称 编号之分,导出函数总数=名称导出+编号导出,这里是循环导出名称的函数  
  85.     {  
  86.         //得到函数名   
  87.         functionName = (PSTR)( (PBYTE)hMod + arrayOfFunctionNames[x]);  
  88.   
  89.         //转化为ANSI_STRING  
  90.         RtlInitAnsiString(&anFunName, functionName);  
  91.         //转化为UNICODE_STRING  
  92.         RtlAnsiStringToUnicodeString(&unFunctionName, &anFunName, TRUE);  
  93.         //打印调试信息  
  94.         KdPrint(("%d/%d,FunName:%wZ\n", x+1, pExportTable->NumberOfNames, &unFunctionName));  
  95.         //比较函数名称  
  96.         if (RtlCompareUnicodeString(&unFunctionName, &unFunctionNameSearch, TRUE) == 0)  
  97.         {  
  98.             //得到该函数地址  
  99.             functionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1;  
  100.             functionAddress = (DWORD)( (PBYTE)hMod + arrayOfFunctionAddresses[functionOrdinal]);  
  101.             break;  
  102.         }  
  103.     }  
  104.   
  105.     ZwClose(hSection);  
  106.   
  107.     return functionAddress;  
  108. }  

以上代码虽可以运行但没有考虑到 ZwMapViewOfSection的资源释放问题 修改如下:

  1. //HelloWDM.h  
  2.   
  3. #if __cplusplus  
  4. extern "C"  
  5. {  
  6. #endif  
  7. #include <wdm.h>  
  8. #include <windef.h>  
  9. #ifdef __cplusplus  
  10. }  
  11. #endif  
  12.   
  13. //定义设备扩展  
  14. typedef struct _DEVICE_EXTERSION  
  15. {  
  16.     PDEVICE_OBJECT fdo;  
  17.     PDEVICE_OBJECT NextStatckDevice;  
  18.     UNICODE_STRING ustrDeviceName;        //设备名  
  19.     UNICODE_STRING ustrSymLinkName;        //符号链接名  
  20.     PVOID tmpPoint;                        //记录临时指针  
  21. }DEVICE_EXTENSION, *PDEVICE_EXTENSION;  
  22.   
  23. //全局变量   
  24. PDEVICE_EXTENSION gDevExt=NULL;  
  25.   
  26. //winnt.h中的定义 由于是WDM不能引用该文件 所以只有复制过来  
  27. #define SEC_IMAGE         0x1000000    
  28.   
  29. //PE相关结构  
  30. typedef struct _SECTION_IMAGE_INFORMATION  
  31. {  
  32.      PVOID TransferAddress;  
  33.      ULONG ZeroBits;  
  34.      ULONG MaximumStackSize;  
  35.      ULONG CommittedStackSize;  
  36.      ULONG SubSystemType;  
  37.      union  
  38.      {  
  39.           struct  
  40.           {  
  41.                WORD SubSystemMinorVersion;  
  42.                WORD SubSystemMajorVersion;  
  43.           };  
  44.           ULONG SubSystemVersion;  
  45.      };  
  46.      ULONG GpValue;  
  47.      WORD ImageCharacteristics;  
  48.      WORD DllCharacteristics;  
  49.      WORD Machine;  
  50.      UCHAR ImageContainsCode;  
  51.      UCHAR ImageFlags;  
  52.      ULONG ComPlusNativeReady: 1;  
  53.      ULONG ComPlusILOnly: 1;  
  54.      ULONG ImageDynamicallyRelocated: 1;  
  55.      ULONG Reserved: 5;  
  56.      ULONG LoaderFlags;  
  57.      ULONG ImageFileSize;  
  58.      ULONG CheckSum;  
  59. } SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;  
  60.   
  61. typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header  
  62.     WORD   e_magic;                     // Magic number  
  63.     WORD   e_cblp;                      // Bytes on last page of file  
  64.     WORD   e_cp;                        // Pages in file  
  65.     WORD   e_crlc;                      // Relocations  
  66.     WORD   e_cparhdr;                   // Size of header in paragraphs  
  67.     WORD   e_minalloc;                  // Minimum extra paragraphs needed  
  68.     WORD   e_maxalloc;                  // Maximum extra paragraphs needed  
  69.     WORD   e_ss;                        // Initial (relative) SS value  
  70.     WORD   e_sp;                        // Initial SP value  
  71.     WORD   e_csum;                      // Checksum  
  72.     WORD   e_ip;                        // Initial IP value  
  73.     WORD   e_cs;                        // Initial (relative) CS value  
  74.     WORD   e_lfarlc;                    // File address of relocation table  
  75.     WORD   e_ovno;                      // Overlay number  
  76.     WORD   e_res[4];                    // Reserved words  
  77.     WORD   e_oemid;                     // OEM identifier (for e_oeminfo)  
  78.     WORD   e_oeminfo;                   // OEM information; e_oemid specific  
  79.     WORD   e_res2[10];                  // Reserved words  
  80.     LONG   e_lfanew;                    // File address of new exe header  
  81.   } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;  
  82.   
  83. typedef struct _IMAGE_DATA_DIRECTORY {  
  84.     DWORD   VirtualAddress;  
  85.     DWORD   Size;  
  86. } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;  
  87.   
  88. typedef struct _IMAGE_OPTIONAL_HEADER {  
  89.     //  
  90.     // Standard fields.  
  91.     //  
  92.   
  93.     WORD    Magic;  
  94.     BYTE    MajorLinkerVersion;  
  95.     BYTE    MinorLinkerVersion;  
  96.     DWORD   SizeOfCode;  
  97.     DWORD   SizeOfInitializedData;  
  98.     DWORD   SizeOfUninitializedData;  
  99.     DWORD   AddressOfEntryPoint;  
  100.     DWORD   BaseOfCode;  
  101.     DWORD   BaseOfData;  
  102.   
  103.     //  
  104.     // NT additional fields.  
  105.     //  
  106.   
  107.     DWORD   ImageBase;  
  108.     DWORD   SectionAlignment;  
  109.     DWORD   FileAlignment;  
  110.     WORD    MajorOperatingSystemVersion;  
  111.     WORD    MinorOperatingSystemVersion;  
  112.     WORD    MajorImageVersion;  
  113.     WORD    MinorImageVersion;  
  114.     WORD    MajorSubsystemVersion;  
  115.     WORD    MinorSubsystemVersion;  
  116.     DWORD   Win32VersionValue;  
  117.     DWORD   SizeOfImage;  
  118.     DWORD   SizeOfHeaders;  
  119.     DWORD   CheckSum;  
  120.     WORD    Subsystem;  
  121.     WORD    DllCharacteristics;  
  122.     DWORD   SizeOfStackReserve;  
  123.     DWORD   SizeOfStackCommit;  
  124.     DWORD   SizeOfHeapReserve;  
  125.     DWORD   SizeOfHeapCommit;  
  126.     DWORD   LoaderFlags;  
  127.     DWORD   NumberOfRvaAndSizes;  
  128.     IMAGE_DATA_DIRECTORY DataDirectory[16];  
  129. } IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;  
  130.   
  131. typedef struct _IMAGE_EXPORT_DIRECTORY {  
  132.     DWORD   Characteristics;  
  133.     DWORD   TimeDateStamp;  
  134.     WORD    MajorVersion;  
  135.     WORD    MinorVersion;  
  136.     DWORD   Name;  
  137.     DWORD   Base;  
  138.     DWORD   NumberOfFunctions;  
  139.     DWORD   NumberOfNames;  
  140.     DWORD   AddressOfFunctions;     // RVA from base of image  
  141.     DWORD   AddressOfNames;         // RVA from base of image  
  142.     DWORD   AddressOfNameOrdinals;  // RVA from base of image  
  143. } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;  

  1. //HelloWDM.cpp  
  2.   
  3. //得到DLL中的指定函数地址 相当于应用层的GetProcAddress函数  
  4. DWORD GetDllFunctionAddress(PTSTR lpFunctionName, PTSTR pDllName)  
  5. {  
  6.     HANDLE hSection=NULL, hFile=NULL;  
  7.     SIZE_T size=0;  
  8.     NTSTATUS status;  
  9.     PVOID BaseAddress = NULL;  
  10.   
  11.     //转换DLL名称  
  12.     UNICODE_STRING strDllName;  
  13.     RtlInitUnicodeString(&strDllName, pDllName);  
  14.   
  15.     OBJECT_ATTRIBUTES objectAttributes={0};  
  16.     IO_STATUS_BLOCK iosb={0};  
  17.   
  18.     //初始化 objectAttributes  
  19.     InitializeObjectAttributes(&objectAttributes, &strDllName, OBJ_KERNEL_HANDLE, NULL, NULL);  
  20.   
  21.     __try  
  22.     {  
  23.         //打开文件  
  24.         status=ZwOpenFile(&hFile,  FILE_EXECUTE | SYNCHRONIZE, &objectAttributes, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT);  
  25.         if(!NT_SUCCESS(status))  
  26.         {  
  27.             __leave;  
  28.         }  
  29.         objectAttributes.ObjectName = 0;  
  30.   
  31.         //创建内存块  
  32.         status=ZwCreateSection(&hSection, SECTION_ALL_ACCESS, &objectAttributes, 0, PAGE_READONLY, SEC_IMAGE, hFile); //PAGE_READONLY页面保护属性,必须结合SEC_IMAGE属性  
  33.         if(!NT_SUCCESS(status))  
  34.         {  
  35.             __leave;  
  36.         }  
  37.   
  38.         //内存映射文件  
  39.         status=ZwMapViewOfSection(hSection,   
  40.             ZwCurrentProcess(),   
  41.             &BaseAddress,   
  42.             0,   
  43.             1024,   
  44.             0,   
  45.             &size,   
  46.             ViewUnmap,   
  47.             MEM_LARGE_PAGES,        //针对DLL文件较小是可以用MEM_TOP_DOWN 文件较大比如USER32.DLL时需要用MEM_LARGE_PAGES  
  48.             PAGE_READWRITE);          
  49.     }  
  50.     __finally  
  51.     {  
  52.         if(hFile != NULL)  
  53.         {  
  54.             //关闭文件句柄  
  55.             ZwClose(hFile);       
  56.         }  
  57.         if(!NT_SUCCESS(status) && hSection != NULL)  
  58.         {  
  59.             //关闭内存块  
  60.             ZwClose(hSection);  
  61.         }  
  62.     }  
  63.     //如果失败 直接返回  
  64.     if(!NT_SUCCESS(status))  
  65.     {  
  66.         return 0;  
  67.     }  
  68.   
  69.     //读取PE头信息  
  70.     IMAGE_DOS_HEADER* dosheader;  
  71.     IMAGE_OPTIONAL_HEADER* opthdr;  
  72.     IMAGE_EXPORT_DIRECTORY* pExportTable;  
  73.     PDWORD arrayOfFunctionAddresses, arrayOfFunctionNames;  
  74.     USHORT* arrayOfFunctionOrdinals;  
  75.     DWORD functionOrdinal, functionAddress=0;  
  76.     PSTR functionName;  
  77.     ANSI_STRING anFunName;  
  78.     UNICODE_STRING unFunctionName, unFunctionNameSearch;  
  79.     //模块句柄  
  80.     HANDLE hMod = BaseAddress;  
  81.     //得到DOS头  
  82.     dosheader = (PIMAGE_DOS_HEADER)hMod;  
  83.     //得到PE选项头  
  84.     opthdr =(PIMAGE_OPTIONAL_HEADER) ((PBYTE)hMod+dosheader->e_lfanew+24);  
  85.     //得到导出表  
  86.     pExportTable =(PIMAGE_EXPORT_DIRECTORY)((PBYTE) hMod + opthdr->DataDirectory[0].VirtualAddress);  
  87.     //得到函数地址列表  
  88.     arrayOfFunctionAddresses = (PDWORD)( (PBYTE)hMod + pExportTable->AddressOfFunctions);  
  89.     //得到函数名称列表  
  90.     arrayOfFunctionNames = (PDWORD)( (PBYTE)hMod + pExportTable->AddressOfNames);  
  91.     //得到函数序号  
  92.     arrayOfFunctionOrdinals = (USHORT*)( (PBYTE)hMod + pExportTable->AddressOfNameOrdinals);  
  93.     //导出表基地址  
  94.     DWORD Base = pExportTable->Base;  
  95.   
  96.     //转换函数名  
  97.     RtlInitUnicodeString(&unFunctionNameSearch, lpFunctionName);  
  98.     //循环导出表  
  99.     for(DWORD x = 0; x < pExportTable->NumberOfNames; x++)            //导出函数有名称 编号之分,导出函数总数=名称导出+编号导出,这里是循环导出名称的函数  
  100.     {  
  101.         //得到函数名   
  102.         functionName = (PSTR)( (PBYTE)hMod + arrayOfFunctionNames[x]);  
  103.   
  104.         //转化为ANSI_STRING  
  105.         RtlInitAnsiString(&anFunName, functionName);  
  106.         //转化为UNICODE_STRING  
  107.         RtlAnsiStringToUnicodeString(&unFunctionName, &anFunName, TRUE);  
  108.         //打印调试信息  
  109.         KdPrint(("%d/%d,FunName:%wZ\n", x+1, pExportTable->NumberOfNames, &unFunctionName));  
  110.         //比较函数名称  
  111.         if (RtlCompareUnicodeString(&unFunctionName, &unFunctionNameSearch, TRUE) == 0)  
  112.         {  
  113.             //得到该函数地址  
  114.             functionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1;  
  115.             functionAddress = (DWORD)( (PBYTE)hMod + arrayOfFunctionAddresses[functionOrdinal]);  
  116.             break;  
  117.         }  
  118.     }  
  119.     //这里释放资源返回的地址将无效 所以先存放起来  
  120.     //ZwUnmapViewOfSection (NtCurrentProcess(), BaseAddress);  
  121.     gDevExt->tmpPoint=BaseAddress;  
  122.   
  123.     ZwClose(hSection);  
  124.   
  125.     return functionAddress;  
  126. }  

调用代码如下:

  1. ULONG ulOriginalProcAddr=GetDllFunctionAddress(TEXT("NtOpenProcess"), TEXT("\\SystemRoot\\system32\\ntdll.dll"));  
  2. //释放GetDllFunctionAddress的内存块  
  3. if(gDevExt->tmpPoint!=0)  
  4. {  
  5.     ZwUnmapViewOfSection (NtCurrentProcess(), gDevExt->tmpPoint);  
  6.     gDevExt->tmpPoint=0;  
  7. }  
展开阅读全文

[文挡]获取PE文件的导出函数列表

06-27

//fromrnhttp://ccrun.com/article/go.asp?i=653&d=b2m5o1rnrnuses ImageHlp;rnrnfunction GetDLLFileExports(rn szFileName: PChar;rn mStrings: TStringsrn): Boolean;rnvarrn hFile: THANDLE;rn hFileMapping: THANDLE;rn lpFileBase: Pointer;rn pImg_DOS_Header: PImageDosHeader;rn pImg_NT_Header: PImageNtHeaders;rn pImg_Export_Dir: PImageExportDirectory;rn ppdwNames: ^PDWORD;rn szFunc: PChar;rn i: Integer;rnbeginrn Result := False;rn if not Assigned(mStrings) then Exit;rn hFile := CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, nil,rn OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);rn if(hFile = INVALID_HANDLE_VALUE) then Exit;rn hFileMapping := CreateFileMapping(hFile, nil, PAGE_READONLY, 0, 0, nil);rn if hFileMapping = 0 thenrn beginrn CloseHandle(hFile);rn Exit;rn end;rnrn lpFileBase := MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);rn if lpFileBase = nil thenrn beginrn CloseHandle(hFileMapping);rn CloseHandle(hFile);rn Exit;rn end;rnrn pImg_DOS_Header := PImageDosHeader(lpFileBase);rn pImg_NT_Header := PImageNtHeaders(rn Integer(pImg_DOS_Header) + Integer(pImg_DOS_Header._lfanew));rnrn if IsBadReadPtr(pImg_NT_Header, SizeOf(IMAGE_NT_HEADERS)) orrn (pImg_NT_Header.Signature <> IMAGE_NT_SIGNATURE) thenrn beginrn UnmapViewOfFile(lpFileBase);rn CloseHandle(hFileMapping);rn CloseHandle(hFile);rn Exit;rn end;rnrn pImg_Export_Dir := PImageExportDirectory(rn pImg_NT_Header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].rn VirtualAddress);rn if not Assigned(pImg_Export_Dir) thenrn beginrn UnmapViewOfFile(lpFileBase);rn CloseHandle(hFileMapping);rn CloseHandle(hFile);rn Exit;rn end;rn // 63 63 72 75 6E 2E 63 6F 6Drn pImg_Export_Dir := PImageExportDirectory(rn ImageRvaToVa(pImg_NT_Header, pImg_DOS_Header, DWORD(pImg_Export_Dir),rn PImageSectionHeader(Pointer(nil)^)));rnrn ppdwNames := Pointer(pImg_Export_Dir.AddressOfNames);rnrn ppdwNames := Pointer(ImageRvaToVa(pImg_NT_Header, pImg_DOS_Header,rn DWORD(ppdwNames), PImageSectionHeader(Pointer(nil)^)));rn if not Assigned(ppdwNames) thenrn beginrn UnmapViewOfFile(lpFileBase);rn CloseHandle(hFileMapping);rn CloseHandle(hFile);rn Exit;rn end;rnrn for i := 0 to pImg_Export_Dir.NumberOfNames - 1 dorn beginrn szFunc := PChar(ImageRvaToVa(pImg_NT_Header, pImg_DOS_Header,rn DWORD(ppdwNames^), PImageSectionHeader(Pointer(nil)^)));rn mStrings.Add(szFunc);rn Inc(ppdwNames);rn end;rn UnmapViewOfFile(lpFileBase);rn CloseHandle(hFileMapping);rn CloseHandle(hFile);rn Result := True;rnend;rnrnprocedure TForm1.Button1Click(Sender: TObject);rnbeginrn GetDLLFileExports('C:\WINDOWS\SYSTEM32\MSSIP32.DLL', Memo1.Lines);rnend;rn 论坛

没有更多推荐了,返回首页