日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

WindowsPE 第五章 导出表编程-1(枚举导出表)

發布時間:2025/6/17 windows 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WindowsPE 第五章 导出表编程-1(枚举导出表) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

導出表編程-1-枚舉導出表

開始前先回憶一下導出表:


1.枚舉dll函數的導出函數名字:

思路:

(1)加載dll到內存里。

(2)獲取PE頭,逐步找到可選頭部。

(3)然后找到里面的第一個結構(導出表)地址,這個地址指向一個IMAGE_EXPORT_DIRECTORY,然后找到里面的


這個地址是一個數組(DWORD),每個值都指向一個導出函數的名字字符串所在地址,然后根據


確定個數,直接枚舉就行了。

代碼如下:

#include "stdafx.h" #include <windows.h> #include <winbase.h> #include <stdio.h> #include <tchar.h> #include <imagehlp.h> #include <vector> #include <iostream> #include <string> using namespace std;typedef PVOID (CALLBACK* PFNEXPORTFUNC)(PIMAGE_NT_HEADERS,PVOID,ULONG,PIMAGE_SECTION_HEADER*);BOOL printAllFuncName(WCHAR* wcFileName ,vector<string> &vcFuncName){vcFuncName.clear();LPWIN32_FIND_DATA lpwfd_first=new WIN32_FIND_DATA;//接受findfirstfile的結構指針HANDLE hFile,hFileMap;//文件句柄和內存映射文件句柄DWORD fileAttrib=0;//存儲文件屬性用,在createfile中用到。void* mod_base;//內存映射文件的起始地址,也是模塊的起始地址PFNEXPORTFUNC ImageRvaToVax=NULL;HMODULE hModule=::LoadLibrary(L"DbgHelp.dll");if(hModule!=NULL){ImageRvaToVax=(PFNEXPORTFUNC)::GetProcAddress(hModule,"ImageRvaToVa");if(ImageRvaToVax==NULL){::FreeLibrary(hModule);//printf("取得函數失敗\n");return FALSE; } }else{//printf("加載模塊失敗\n");return FALSE;}if(FindFirstFile(wcFileName,lpwfd_first)==NULL){//返回值為NULL,則文件不存在,退出//printf("文件不存在: %s ",wcFileName);return FALSE;}else{DWORD fileAttrib=lpwfd_first->dwFileAttributes;}hFile=CreateFile(wcFileName,GENERIC_READ,0,0,OPEN_EXISTING,fileAttrib,0);if(hFile==INVALID_HANDLE_VALUE){//printf("打開文件出錯!");return FALSE; }hFileMap=CreateFileMapping(hFile,0,PAGE_READONLY,0,0,0);if(hFileMap==NULL){CloseHandle(hFile);//printf("建立內存映射文件出錯!");return FALSE;}mod_base=MapViewOfFile(hFileMap,FILE_MAP_READ,0,0,0);if (mod_base==NULL){//printf("建立內存映射文件出錯!");CloseHandle(hFileMap);CloseHandle(hFile);return FALSE;}IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)mod_base;IMAGE_NT_HEADERS * pNtHeader =(IMAGE_NT_HEADERS *)((BYTE*)mod_base+ pDosHeader->e_lfanew);//得到NT頭首址IMAGE_OPTIONAL_HEADER * pOptHeader =(IMAGE_OPTIONAL_HEADER *)((BYTE*)mod_base + pDosHeader->e_lfanew + 24);//optional頭首址IMAGE_EXPORT_DIRECTORY* pExportDesc = (IMAGE_EXPORT_DIRECTORY*)ImageRvaToVax(pNtHeader,mod_base,pOptHeader->DataDirectory[0].VirtualAddress,0);//導出表首址PDWORD nameAddr=(PDWORD)ImageRvaToVax(pNtHeader,mod_base,pExportDesc->AddressOfNames,0);//函數名稱表首地址每個DWORD代表一個函數名字字符串的地址PCHAR func_name = (PCHAR)ImageRvaToVax(pNtHeader,mod_base,(DWORD)nameAddr[0],0);DWORD i=0;DWORD unti=pExportDesc->NumberOfNames;for(i=0;i<unti;i++){func_name = (PCHAR)ImageRvaToVax(pNtHeader,mod_base,(DWORD)nameAddr[i],0);//printf("%s\n",func_name);vcFuncName.push_back(string(func_name));}::FreeLibrary(hModule);CloseHandle(hFileMap);CloseHandle(hFile);return TRUE; }int main(int argc, char* argv[]){vector<string>vcFuncName;printAllFuncName(L"C:\\A.dll" ,vcFuncName);for(vector<string>::iterator it = vcFuncName.begin(); it != vcFuncName.end();it++){ cout<<*(it)<<endl; } getchar();return 0; }

下面兩個不去實現了,和上面的差不多。

2.根據編號查找函數地址


3.根據名字查找函數地址


總結

以上是生活随笔為你收集整理的WindowsPE 第五章 导出表编程-1(枚举导出表)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。