zoukankan      html  css  js  c++  java
  • 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.根据名字查找函数地址


  • 相关阅读:
    桟错误分析方法
    gstreamer调试命令
    sqlite的事务和锁,很透彻的讲解 【转】
    严重: Exception starting filter struts2 java.lang.NullPointerException (转载)
    eclipse 快捷键
    POJ 1099 Square Ice
    HDU 1013 Digital Roots
    HDU 1087 Super Jumping! Jumping! Jumping!(动态规划)
    HDU 1159 Common Subsequence
    HDU 1069 Monkey and Banana(动态规划)
  • 原文地址:https://www.cnblogs.com/csnd/p/12062127.html
Copyright © 2011-2022 走看看