#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;
}
PE导出表
最新推荐文章于 2025-05-07 14:18:55 发布