PE导出表


#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <windows.h>
#pragma   warning(disable:4996) 
#define openll "C:\\Users\\Administrator\\Desktop\\dialer.exe"
LPVOID OpenFile()
{
    DWORD Size = NULL;
    FILE* fp;
    fp = fopen(openll, "rb");
    fseek(fp, 0, SEEK_END);
    Size = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    //申请内存;
    LPVOID ptr = NULL;
    ptr = (LPVOID)malloc(Size);
    if (!ptr)
    {
        printf("申请不成功!");
        free(ptr);
        return 0;
    }
    else
    {
        memset(ptr, 0, Size);
        fread(ptr, Size, 1, fp);
    }
    fclose(fp);
    return ptr;
}
//Rva->Foa
LPVOID Rva(LPVOID filebuffer, DWORD RVA)
{
    //LPVOID IMbuffer = filebuffer;
    PIMAGE_DOS_HEADER pDos = NULL;
    PIMAGE_NT_HEADERS pNT = NULL;
    PIMAGE_FILE_HEADER pFile = NULL;
    PIMAGE_OPTIONAL_HEADER pOption = NULL;
    PIMAGE_SECTION_HEADER pSection = NULL;
    PIMAGE_EXPORT_DIRECTORY pex = NULL;
    //目录
    PIMAGE_DATA_DIRECTORY Data = NULL;
    if (*(PWORD)((DWORD)filebuffer) != IMAGE_DOS_SIGNATURE)
    {
        printf("不是Mz标志");
    }
    pDos = (PIMAGE_DOS_HEADER)(PWORD)((DWORD)filebuffer);
    pNT = (PIMAGE_NT_HEADERS)(PDWORD)((DWORD)filebuffer + pDos->e_lfanew);
    pFile = (PIMAGE_FILE_HEADER)(PWORD)((DWORD)pNT + 4);
    pOption = (PIMAGE_OPTIONAL_HEADER)(PWORD)((DWORD)pFile + IMAGE_SIZEOF_FILE_HEADER);
    pSection = (PIMAGE_SECTION_HEADER)((DWORD)pOption + pFile->SizeOfOptionalHeader);
    Data = (PIMAGE_DATA_DIRECTORY)(PWORD)((DWORD)pOption + 0x60);
    //printf("%x",Data->Size);
    //printf("%x", Data->VirtualAddress);
    PIMAGE_SECTION_HEADER pSectionHreder = pSection;
    //RVA-> FVA 通过VA的内存偏移计算在文件中的位置
    //第一步训循环判断 RVA在哪个节表里 
    for (int i = 0; i < pFile->NumberOfSections; i++, pSectionHreder++)
    {

        if (RVA >= (pSection + i)->VirtualAddress)//判断是否大于 i节表数据 如果大于就进入再次判断是否小于i+1节表
        {
            if (RVA < (pSection + i + 1)->VirtualAddress)
            {
                //printf("%s", (pSection + i)->Name);//打印节信息  并通过RVA == RVA - i节里的virtualaddress +i节文件开始的位置 == 导出表文件偏移位置
                pex = (PIMAGE_EXPORT_DIRECTORY)((DWORD)RVA - (pSection + i)->VirtualAddress + (pSection + i)->PointerToRawData);
            }
        }
    }
    return pex;
}
LPVOID imports()
{
    LPVOID IMbuffer = OpenFile();
    PIMAGE_DOS_HEADER pDos = NULL;
    PIMAGE_NT_HEADERS pNT = NULL;
    PIMAGE_FILE_HEADER pFile = NULL;
    PIMAGE_OPTIONAL_HEADER pOption = NULL;
    PIMAGE_SECTION_HEADER pSection = NULL;
    PIMAGE_EXPORT_DIRECTORY pex = NULL;
    //目录
    PIMAGE_DATA_DIRECTORY Data = NULL;
    if (*(PWORD)((DWORD)IMbuffer) != IMAGE_DOS_SIGNATURE)
    {
        printf("不是Mz标志");
    }
    pDos = (PIMAGE_DOS_HEADER)(PWORD)((DWORD)IMbuffer);
    pNT = (PIMAGE_NT_HEADERS)(PDWORD)((DWORD)IMbuffer+pDos->e_lfanew);
    pFile = (PIMAGE_FILE_HEADER)(PWORD)((DWORD)pNT+4);
    pOption = (PIMAGE_OPTIONAL_HEADER)(PWORD)((DWORD)pFile + IMAGE_SIZEOF_FILE_HEADER);
    pSection = (PIMAGE_SECTION_HEADER)((DWORD)pOption + pFile->SizeOfOptionalHeader);
    Data = (PIMAGE_DATA_DIRECTORY)(PWORD)((DWORD)pOption + 0x60);
    //printf("%x",Data->Size);
    //printf("%x", Data->VirtualAddress);
    PIMAGE_SECTION_HEADER pSectionHreder = pSection;
    //RVA-> FVA 通过VA的内存偏移计算在文件中的位置
    //第一步训循环判断 RVA在哪个节表里 
    for (int i =0;i<pFile->NumberOfSections;i++,pSectionHreder++)
    {
        
        if (Data->VirtualAddress>(pSection+i)->VirtualAddress)//判断是否大于 i节表数据 如果大于就进入再次判断是否小于i+1节表
        {
            if (Data->VirtualAddress < (pSection + i+1)->VirtualAddress)
            {
                //printf("%s", (pSection + i)->Name);//打印节信息  并通过RVA == RVA - i节里的virtualaddress +i节文件开始的位置 == 导出表文件偏移位置
                pex = (PIMAGE_EXPORT_DIRECTORY)((DWORD)IMbuffer+Data->VirtualAddress - (pSection + i)->VirtualAddress + (pSection + i)->PointerToRawData);
            }
        }
    }
    printf("\n%08x\n",pex->Characteristics);
    printf("%08x\n", pex->TimeDateStamp);
    printf("%04x\n", pex->MajorVersion);
    printf("%04x\n", pex->MinorVersion);
    printf("%08x\n", pex->Name);
    printf("Base:       %08x\n", pex->Base);
    printf("NumberOfFunctions:      %08x\n", pex->NumberOfFunctions);
    printf("NumberOfNames:      %08x\n", pex->NumberOfNames);
    printf("AddressOfFunctions:     %08x\n", pex->AddressOfFunctions);
    printf("AddressOfNames:     %08x\n", pex->AddressOfNames);
    printf("AddressOfNameOrdinals:   %08x\n", pex->AddressOfNameOrdinals);


    //输出函数地址表信息
    //AddressofFunction
    DWORD exAddFunction = pex->AddressOfNames; //导出函数名的 RVA
    DWORD exaddNames = NULL;
    exaddNames = (DWORD)Rva(IMbuffer, exAddFunction);
    printf("\n%x", exaddNames);
    DWORD Numberofnames = pex->NumberOfNames; //以函数名字导出的函数个数
    PDWORD pExAddressofName = NULL;
    pExAddressofName = (PDWORD)((DWORD)IMbuffer + exaddNames);
    for (int k = 0x0; k <= Numberofnames; k++){
        printf("\n %d :%x \n", k, *pExAddressofName);
        //函数名的地址转化为FOA,输出函数名
        PBYTE Nameaddress = (PBYTE)Rva(IMbuffer, *pExAddressofName);
        //输出函数名
        unsigned char* FunctionName = (PBYTE)((DWORD)IMbuffer + (DWORD)Nameaddress);
        printf(" %s \n", FunctionName);
        pExAddressofName++;
    }

    //函数序号表
    printf("\n-----------函数序列表-----------\n");

    DWORD ExAddress = pex->AddressOfNameOrdinals;
    DWORD Exrdinals = (DWORD)Rva(IMbuffer, ExAddress);
    Numberofnames = pex->NumberOfNames;;
    PWORD pAddressOrdinals = NULL;
    pAddressOrdinals = (PWORD)((DWORD)IMbuffer + ExAddress);

    for (int y = 0x0; y < Numberofnames; y++){
        printf("\n%d :%x", y, *pAddressOrdinals);
        pAddressOrdinals++;
    }
    printf("\n--------------------------------\n");
    return 0;
}
LPVOID GetFunctionAddrByName(LPVOID filebuffer, DWORD AddName)
{
    
    PIMAGE_DOS_HEADER pDos = NULL;
    PIMAGE_NT_HEADERS pNT = NULL;
    PIMAGE_FILE_HEADER pFile = NULL;
    PIMAGE_OPTIONAL_HEADER pOption = NULL;
    PIMAGE_SECTION_HEADER pSection = NULL;
    PIMAGE_EXPORT_DIRECTORY pex = NULL;
    //目录
    PIMAGE_DATA_DIRECTORY Data = NULL;
    if (*(PWORD)((DWORD)filebuffer) != IMAGE_DOS_SIGNATURE)
    {
        printf("不是Mz标志");
    }
    pDos = (PIMAGE_DOS_HEADER)(PWORD)((DWORD)filebuffer);
    pNT = (PIMAGE_NT_HEADERS)(PDWORD)((DWORD)filebuffer + pDos->e_lfanew);
    pFile = (PIMAGE_FILE_HEADER)(PWORD)((DWORD)pNT + 4);
    pOption = (PIMAGE_OPTIONAL_HEADER)(PWORD)((DWORD)pFile + IMAGE_SIZEOF_FILE_HEADER);
    pSection = (PIMAGE_SECTION_HEADER)((DWORD)pOption + pFile->SizeOfOptionalHeader);
    Data = (PIMAGE_DATA_DIRECTORY)(PWORD)((DWORD)pOption + 0x60);
    //printf("%x",Data->Size);
    //printf("%x", Data->VirtualAddress);
    PIMAGE_SECTION_HEADER pSectionHreder = pSection;
    //定位导出表的位置
    for (int i = 0; i < pFile->NumberOfSections; i++, pSectionHreder++)
    {

        if (Data->VirtualAddress > (pSection + i)->VirtualAddress)//判断是否大于 i节表数据 如果大于就进入再次判断是否小于i+1节表
        {
            if (Data->VirtualAddress < (pSection + i + 1)->VirtualAddress)
            {
                //printf("%s", (pSection + i)->Name);//打印节信息  并通过RVA == RVA - i节里的virtualaddress +i节文件开始的位置 == 导出表文件偏移位置
                pex = (PIMAGE_EXPORT_DIRECTORY)((DWORD)filebuffer + Data->VirtualAddress - (pSection + i)->VirtualAddress + (pSection + i)->PointerToRawData);
            }
        }
    }
    //输出每个函数的地址表
    DWORD pExaddressofNameFoa = (DWORD)Rva(filebuffer, pex->AddressOfNames);
    DWORD pExNumberNames = pex->NumberOfNames;
    //得到函数名地址
    PDWORD pExAddressofNames = NULL;
    pExAddressofNames = (PDWORD)((DWORD)filebuffer+pExaddressofNameFoa);
    WORD u = 0;
    for ( u = 0; u < pExNumberNames;u++) {
        //printf("%d :%x", u, *pExAddressofNames);
        //函数名的地址转化成FoA
        PBYTE FoaAddressOfName = (PBYTE)Rva(filebuffer, *pExAddressofNames);
        //打印转化后的Foa对应的函数名
        //printf("%s\n", (PBYTE)((DWORD)FoaAddressOfName));
        pExAddressofNames++;
    }

    //函数的位置u
    WORD Location_Fun = u-1;
    printf("函数的位置:%d", Location_Fun);
    //函数序号表
    DWORD pExAddressOfOrdinals =(DWORD)Rva(filebuffer,pex->AddressOfNameOrdinals);
    DWORD pExNumberOfNames = pex->NumberOfNames;//以函数名导出的函数个数
    PWORD pExAddressofOrdinals = NULL;
    pExAddressofOrdinals = (PWORD)((DWORD)filebuffer+pExAddressOfOrdinals);

    //函数表的序号
    WORD NUM_Fun = pExAddressofOrdinals[Location_Fun];
    printf("NUM_Fun:%d", NUM_Fun);
    //输出函数地址表信息
    DWORD FoaAddressFunction = pex->AddressOfFunctions;
    FoaAddressFunction = (DWORD)Rva(filebuffer, FoaAddressFunction);
    DWORD NumberofFunction = pex->NumberOfFunctions;//导出函数个数
    PDWORD pExaddressofFunction = NULL;
    pExaddressofFunction = (PDWORD)((DWORD)filebuffer+ FoaAddressFunction);
    //确定函数的地址
    DWORD Fun_Addr = pExaddressofFunction[NUM_Fun];
    printf("\n%x", Fun_Addr);

    return 0;
}


int main()
{
    LPVOID blank = OpenFile();
    //imports();
    GetFunctionAddrByName(blank, 0);
    return 0;
}








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值