• 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("取得函数失败
    ");
    			return FALSE; 
            } 
    	}else{
             //printf("加载模块失败
    ");
             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
    ",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.根据名字查找函数地址


  • 相关阅读:
    非同名数据库导入sql
    mybatis中的异常
    使用MyBatis时为什么Dao层不需要@Repository
    springboot项目启动后执行一段程序的方式
    构建SpringBoot项目
    springboot项目添加webapp目录
    springboot项目启动异常
    使用restTemplate出现的异常
    Spring中Bean的属性赋值@Value()---使用类配置的方式
    使用BeanUtils复制Java对象
  • 原文地址:https://www.cnblogs.com/csnd/p/12062127.html
Copyright © 2020-2023  润新知