滴水逆向——PE导出表
Ⅰ.知识点:
1.如何定位导出表:
数据目录项的第一个结构,就是导出表.
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
VirtualAddress 导出表的RVA
Size 导出表大小
2.导出表结构
上面的结构,只是说明导出表在哪里,有多大,并不是真正的导出表.
如何在FileBuffer中找到这个结构呢?在VirtualAddress中存储的是RVA,如果想在FileBuffer中定位
必须要先将该RVA转换成FOA.
真正的导出表结构如下:
3.AddressOfFunctions说明:
该表中元素宽度为4个字节
该表中存储所有导出函数的地址
该表中个数由NumberOfFunctions决定
该表项中的值是RVA, 加上ImageBase才是函数真正的地址
定位:
IMAGE_EXPORT_DIRECTORY->AddressOfFunctions 中存储的是该表的RVA 需要先转换成FOA
4.AddressOfNames说明:
该表中元素宽度为4个字节
该表中存储所有以名字导出函数的名字的RVA
该表项中的值是RVA, 指向函数真正的名称
5.AddressOfNameOrdinals
Ⅱ.关键点:
为什么要分成3张表?
1、函数导出的个数与函数名的个数未必一样.所以要将函数地址表和函数名称表分开.
2、函数地址表是不是一定大于函数名称表?
未必,一个相同的函数地址,可能有多个不同的名字.
3、如何根据函数的名字获取一个函数的地址?
Ⅲ.问题描述:
打印导出表
根据函数的导出序号获取一个函数的地址
Ⅳ.代码实现:
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>#define test 1
#define ordianl 3DWORD ToLoaderPE(LPSTR file_path, PVOID* pFileBuffer);
BOOL MemoryToFile(PVOID pMemBuffer, DWORD size, LPSTR lpszFile);
DWORD FoaToImageOffset(PVOID pBuffer, DWORD dwFoa);
DWORD RvaToFileOffset(PVOID pBuffer, DWORD dwRva);
DWORD GetSctionEmptySpace(PVOID pFileBuffer, DWORD SectionOrdinal);
DWORD Alignment(DWORD alignment_value, DWORD addend, DWORD address);
DWORD GetFunctionAddrByName(PVOID pFileBuffer, LPSTR fun_name);
DWORD GetFunctionAddrByOrdinals(PVOID pFileBuffer, DWORD fun_ordinal);
VOID LogExportTable(PVOID pFileBuffer);//char file_path[] = "c:\\users\\desktop\\notepad.exe";
char file_path[] = "c:\\users\\desktop\\dll1test.dll";
//char file_path[] = "c:\\users\\desktop\\ipmsg2007.exe";
char fun_name[] = "Mul";
char write_file_path[] = "D:\\Lib\\cp_XX.exe";
char write_adddata_file_path[] = "D:\\Lib\\cp_adddata_XX.exe";
char write_addsec_file_path[] = "D:\\Lib\\cp_addsec_XX.exe";
char write_enlargersec_file_path[] = "D:\\Lib\\cp_enlargersec_XX.exe";
char write_mergesec_file_path[] = "D:\\Lib\\cp_mergesec_XX.exe";//返回PE文件大小
DWORD ToLoaderPE(LPSTR file_path, PVOID* pFileBuffer)
{FILE *pFile = NULL;DWORD FileSize = 0;PVOID pFileBufferTemp = NULL;pFile = fopen(file_path, "rb");if (!pFile){printf("(ToLoaderPE)Can't open file!\n");return 0;}fseek(pFile, 0, SEEK_END);FileSize = ftell(pFile);printf("FileBuffer: %#x\n", FileSize);fseek(pFile, 0, SEEK_SET);pFileBufferTemp = malloc(FileSize);if (!pFileBufferTemp){printf("(ToLoaderPE)Allocate dynamic memory failed!\n");fclose(pFile);return 0;}DWORD n = fread(pFileBufferTemp, FileSize, 1, pFile);if (!n){printf("(ToLoaderPE)Read file failed!\n");free(pFileBufferTemp);fclose(pFile);return 0;}*pFileBuffer = pFileBufferTemp;pFileBufferTemp = NULL;fclose(pFile);return FileSize;
}BOOL MemoryToFile(PVOID pMemBuffer, DWORD size, LPSTR lpszFile)
{FILE *fp;fp = fopen(lpszFile, "wb");if (fp != NULL){fwrite(pMemBuffer, size, 1, fp);}fclose(fp);printf("Store file success!\n");return 1;
}DWORD RvaToFileOffset(PVOID pBuffer, DWORD dwRva)
{PIMAGE_DOS_HEADER pDosHeader = NULL;PIMAGE_NT_HEADERS pNTHeader = NULL;PIMAGE_FILE_HEADER pPEHeader = NULL;PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;PIMAGE_SECTION_HEADER pSectionHeader = NULL;if (!pBuffer){printf("(RvaToFileOffset)Can't open file!\n");return 0;}if (*((PWORD)pBuffer) != IMAGE_DOS_SIGNATURE){printf("(RvaToFileOffset)No MZ flag, not exe file!\n");return 0;}pDosHeader = (PIMAGE_DOS_HEADER)pBuffer;if (*((PDWORD)((DWORD)pBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE){printf("(RvaToFileOffset)Not a valid PE flag!\n");return 0;}//printf("ImageOffset: %#x\n", dwRva);pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pBuffer + pDosHeader->e_lfanew);pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); // 这里必须强制类型转换pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);PIMAGE_SECTION_HEADER pSectionTemp = pSectionHeader;if (dwRva <= pOptionHeader->SizeOfHeaders)return (DWORD)dwRva;else{for (int n = 0; n < pPEHeader->NumberOfSections; n++, pSectionTemp++){ //判断 : 文件对齐+文件偏移>file_panyi>文件偏移 (即是在文件的哪个节中)if ((dwRva >= pSectionTemp->VirtualAddress) && (dwRva < pSectionTemp->VirtualAddress + pSectionTemp->Misc.VirtualSize)){return dwRva - pSectionTemp->VirtualAddress + pSectionTemp->PointerToRawData;}}}printf("RvaToFoa failed!\n");return 0;
}DWORD FoaToImageOffset(PVOID pBuffer, DWORD dwFoa)
{PIMAGE_DOS_HEADER pDosHeader = NULL;PIMAGE_NT_HEADERS pNTHeader = NULL;PIMAGE_FILE_HEADER pPEHeader = NULL;PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;PIMAGE_SECTION_HEADER pSectionHeader = NULL;if (!pBuffer){printf("(FoaToImageOffset)Can't open file!\n");return 0;}if (*((PWORD)pBuffer) != IMAGE_DOS_SIGNATURE){printf("(FoaToImageOffset)No MZ flag, not exe file!\n");return 0;}pDosHeader = (PIMAGE_DOS_HEADER)pBuffer;if (*((PDWORD)((DWORD)pBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE){printf("(FoaToImageOffset)Not a valid PE flag!\n");return 0;}printf("FileOffset: %#x\n", dwFoa);pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pBuffer + pDosHeader->e_lfanew);pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); // 这里必须强制类型转换pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);PIMAGE_SECTION_HEADER pSectionTemp = pSectionHeader;if (dwFoa <= pOptionHeader->SizeOfHeaders)return (DWORD)dwFoa;else{for (int n = 0; n < pPEHeader->NumberOfSections; n++, pSectionTemp++){ //判断 : 文件对齐+文件偏移>file_panyi>文件偏移 (即是在文件的哪个节中)if ((dwFoa >= pSectionTemp->PointerToRawData) && (dwFoa < pSectionTemp->PointerToRawData + pSectionTemp->SizeOfRawData)){return dwFoa - pSectionTemp->PointerToRawData + pSectionTemp->VirtualAddress;}}}printf("FoaToRva failed!\n");return 0;
}DWORD Alignment(DWORD alignment_value, DWORD addend, DWORD address)
{int n = 0;if (addend / alignment_value){if (addend%alignment_value){n = addend / alignment_value + 1;}else{n = addend / alignment_value;}}else{if (addend)n = 1;elsen = 0;}address += n * alignment_value;return address;
}DWORD GetSctionEmptySpace(PVOID pFileBuffer, DWORD SectionOrdinal)
{PIMAGE_DOS_HEADER pDosHeader = NULL;PIMAGE_NT_HEADERS pNTHeader = NULL;PIMAGE_FILE_HEADER pPEHeader = NULL;PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;PIMAGE_SECTION_HEADER pSectionHeader = NULL;if (!pFileBuffer){printf("(GetSctionEmptySpace)Can't open file!\n");return 0;}if (*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE){printf("(GetSctionEmptySpace)No MZ flag, not exe file!\n");return 0;}pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;if (*((PDWORD)((DWORD)pFileBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE){printf("(GetSctionEmptySpace)Not a valid PE flag!\n");return 0;}pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew);pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); // 这里必须强制类型转换pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);if (SectionOrdinal > pPEHeader->NumberOfSections){printf("(GetSctionEmptySpace)There are only %#x sections ,no %#x th.\n", pPEHeader->NumberOfSections, SectionOrdinal);return 0;}for (DWORD n = 0; n < SectionOrdinal - 1; n++){pSectionHeader++;}DWORD EmptySpace = pSectionHeader->SizeOfRawData - pSectionHeader->Misc.VirtualSize;return EmptySpace;
}VOID LogExportTable(PVOID pFileBuffer)
{PIMAGE_DOS_HEADER pDosHeader = NULL;PIMAGE_NT_HEADERS pNTHeader = NULL;PIMAGE_FILE_HEADER pPEHeader = NULL;PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;PIMAGE_SECTION_HEADER pSectionHeader = NULL;PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL;if (!pFileBuffer){printf("(LogExportTable)Can't open file!\n");return 0;}if (*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE){printf("(LogExportTable)No MZ flag, not exe file!\n");return 0;}pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;if (*((PDWORD)((DWORD)pFileBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE){printf("(LogExportTable)Not a valid PE flag!\n");return 0;}pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew);pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); // 这里必须强制类型转换pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);pDataDirectory = (PIMAGE_DATA_DIRECTORY)pOptionHeader->DataDirectory;if (!pDataDirectory->VirtualAddress){printf("(LogExportTable)This program has no export table.\n");return 0;}printf("Export Table Rva: %#x\n", pDataDirectory->VirtualAddress);DWORD Foa_ExportTable = RvaToFileOffset(pFileBuffer, pDataDirectory->VirtualAddress);printf("Export Table Foa: %#x\n", Foa_ExportTable);pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + Foa_ExportTable);printf("Characteristics: %#x\n", pExportDirectory->Characteristics);printf("TimeDateStamp: %#x\n", pExportDirectory->TimeDateStamp);printf("MajorVersion: %#x\n", pExportDirectory->MajorVersion);printf("MinorVersion: %#x\n", pExportDirectory->MinorVersion);printf("Name: %s\n", (PVOID)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pExportDirectory->Name)));printf("Base: %#x\n", pExportDirectory->Base);printf("NumberOfFunctions: %#x\n", pExportDirectory->NumberOfFunctions);printf("NumberOfNames: %#x\n", pExportDirectory->NumberOfNames);printf("AddressOfFunctions: %#x\n", pExportDirectory->AddressOfFunctions);printf("AddressOfNames: %#x\n", pExportDirectory->AddressOfNames);printf("AddressOfNameOrdinals: %#x\n", pExportDirectory->AddressOfNameOrdinals);
}DWORD GetFunctionAddrByOrdinals(PVOID pFileBuffer, DWORD fun_ordinal)
{printf("Function Ordinal: %#x\n", fun_ordinal);// 初始化PE头部结构体PIMAGE_DOS_HEADER pDosHeader = NULL;PIMAGE_NT_HEADERS pNTHeader = NULL;PIMAGE_FILE_HEADER pPEHeader = NULL;PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;PIMAGE_SECTION_HEADER pSectionHeader = NULL;PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL;// 判断pImageBuffer是否有效if (!pFileBuffer){printf("(GetFunctionAddrByOrdinals)Can't open file!\n");return 0;}//判断是不是exe文件if (*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE){printf("(GetFunctionAddrByOrdinals)No MZ flag, not exe file!\n");return 0;}// 强制结构体类型转换pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;if (*((PDWORD)((DWORD)pFileBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE){printf("(GetFunctionAddrByOrdinals)Not a valid PE flag!\n");return 0;}// 强制结构体类型转换pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew);pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); // 这里必须强制类型转换pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);pDataDirectory = (PIMAGE_DATA_DIRECTORY)pOptionHeader->DataDirectory;if (!pDataDirectory->VirtualAddress){printf("This program has no export table.\n");return 0;}printf("Export Table Rva: %#x\n", pDataDirectory->VirtualAddress);DWORD Foa_ExportTable = RvaToFileOffset(pFileBuffer, pDataDirectory->VirtualAddress);printf("Export Table Foa: %#x\n", Foa_ExportTable);pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + Foa_ExportTable);if (!test){printf("Characteristics: %#x\n", pExportDirectory->Characteristics);printf("TimeDateStamp:%#x\n", pExportDirectory->TimeDateStamp);printf("MajorVersion: %#x\n", pExportDirectory->MajorVersion);printf("MinorVersion: %#x\n", pExportDirectory->MinorVersion);printf("Name: %s\n", (PVOID)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pExportDirectory->Name)));printf("Base: %#x\n", pExportDirectory->Base);printf("NumberOfFunctions: %#x\n", pExportDirectory->NumberOfFunctions);printf("NumberOfNames: %#x\n", pExportDirectory->NumberOfNames);printf("AddressOfFunctions: %#x\n", pExportDirectory->AddressOfFunctions);printf("AddressOfNames: %#x\n", pExportDirectory->AddressOfNames);printf("AddressOfNameOrdinals: %#x\n", pExportDirectory->AddressOfNameOrdinals);}DWORD Sequence = fun_ordinal - pExportDirectory->Base;DWORD Foa_AddressOfFunctions = RvaToFileOffset(pFileBuffer, pExportDirectory->AddressOfFunctions);if (!test){DWORD test1 = Foa_AddressOfFunctions + (DWORD)pFileBuffer;printf("AddressOfFunctions in this moment: %#x\n", test1);printf("Foa_AddressOfFunctions: %#x\n", Foa_AddressOfFunctions);}PDWORD pFoa_AddressOfFunctions = (PBYTE)(Foa_AddressOfFunctions + (DWORD)pFileBuffer);for (DWORD n = 0; n < Sequence; n++){pFoa_AddressOfFunctions++;}//DWORD Foa_AddrFun = RvaToFileOffset(pFileBuffer, *pFoa_AddressOfFunctions);return *pFoa_AddressOfFunctions;
}DWORD GetFunctionAddrByName(PVOID pFileBuffer, LPSTR fun_name)
{printf("Function Name: %s\n", fun_name);// 初始化PE头部结构体PIMAGE_DOS_HEADER pDosHeader = NULL;PIMAGE_NT_HEADERS pNTHeader = NULL;PIMAGE_FILE_HEADER pPEHeader = NULL;PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;PIMAGE_SECTION_HEADER pSectionHeader = NULL;PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL;// 判断pImageBuffer是否有效if (!pFileBuffer){printf("(GetFunctionAddrByName)Can't open file!\n");return 0;}//判断是不是exe文件if (*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE){printf("(GetFunctionAddrByName)No MZ flag, not exe file!\n");return 0;}// 强制结构体类型转换pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;if (*((PDWORD)((DWORD)pFileBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE){printf("(GetFunctionAddrByName)Not a valid PE flag!\n");return 0;}// 强制结构体类型转换pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew);pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); // 这里必须强制类型转换pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);pDataDirectory = (PIMAGE_DATA_DIRECTORY)pOptionHeader->DataDirectory;if (!pDataDirectory->VirtualAddress){printf("This program has no export table.\n");return 0;}printf("Export Table Rva: %#x\n", pDataDirectory->VirtualAddress);DWORD Foa_ExportTable = RvaToFileOffset(pFileBuffer, pDataDirectory->VirtualAddress);printf("Export Table Foa: %#x\n", Foa_ExportTable);pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + Foa_ExportTable);if (!test){printf("Characteristics: %#x\n", pExportDirectory->Characteristics);printf("TimeDateStamp: %#x\n", pExportDirectory->TimeDateStamp);printf("MajorVersion: %#x\n", pExportDirectory->MajorVersion);printf("MinorVersion: %#x\n", pExportDirectory->MinorVersion);printf("Name: %s\n", (PVOID)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pExportDirectory->Name)));printf("Base: %#x\n", pExportDirectory->Base);printf("NumberOfFunctions: %#x\n", pExportDirectory->NumberOfFunctions);printf("NumberOfNames: %#x\n", pExportDirectory->NumberOfNames);printf("AddressOfFunctions: %#x\n", pExportDirectory->AddressOfFunctions);printf("AddressOfNames: %#x\n", pExportDirectory->AddressOfNames);printf("AddressOfNameOrdinals: %#x\n", pExportDirectory->AddressOfNameOrdinals);}DWORD Foa_AddressOfNames = RvaToFileOffset(pFileBuffer, pExportDirectory->AddressOfNames);DWORD Foa_AddressOfNameOrdinals = RvaToFileOffset(pFileBuffer, pExportDirectory->AddressOfNameOrdinals);DWORD Foa_AddressOfFunctions = RvaToFileOffset(pFileBuffer, pExportDirectory->AddressOfFunctions);if (!test){DWORD test1 = Foa_AddressOfNames + (DWORD)pFileBuffer;printf("AddressOfNames in this moment: %#x\n", test1);printf("Foa__AddressOfNames: %#x\n", Foa_AddressOfNames);}//1.循环从名字表中找与目标函数名相同的;如有有返回该名字在表中的索引DWORD ordIndex = -1;for (DWORD i = 0; i < pExportDirectory->NumberOfNames; i++){DWORD nameOffset = *(PDWORD)((DWORD)pFileBuffer + (DWORD)((LPDWORD)Foa_AddressOfNames + i));LPSTR nameAddr = (LPSTR)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, nameOffset));if (!strcmp(nameAddr, fun_name)){ordIndex = i;break;}}if (ordIndex == -1){printf("The export table does not have this function name.\n");return 0;}//2.用获得的索引从序号表中找函数的序号WORD ord = *(PWORD)((DWORD)pFileBuffer + (DWORD)((LPWORD)Foa_AddressOfNameOrdinals + ordIndex));if (!test){DWORD test1 = Foa_AddressOfNameOrdinals + (DWORD)pFileBuffer;printf("AddressOfNameOrdinals in this moment: %#x\n", test1);printf("Foa__AddressOfNameOrdinals: %#x\n", Foa_AddressOfNameOrdinals);printf("ordInex in AddressOfNames: %#x\n", ordIndex);printf("ordInex in AddressOfNameOrdinals: %#x\n", ord);}//3.以序号表中查出来的序号为索引从函数地址表中找函数地址DWORD addr = *(PDWORD)((DWORD)pFileBuffer + (DWORD)((LPDWORD)Foa_AddressOfFunctions + ord));//DWORD Foa_AddrFun = RvaToFileOffset(pFileBuffer, addr);return addr;
}VOID operate()
{PVOID pFileBuffer = NULL;PVOID pNewFileBuffer = NULL;PVOID pImageBuffer = NULL;DWORD pRVA = 0x0003123;DWORD pFOA = 0x00020450;DWORD ret1 = ToLoaderPE(file_path, &pFileBuffer); // &pFileBuffer(void**类型) 传递地址对其值可以进行修改printf("exe->filebuffer 返回值为计算所得文件大小:%#x\n", ret1);LogExportTable(pFileBuffer);DWORD ret9 = GetFunctionAddrByOrdinals(pFileBuffer, ordianl);printf("GetFunctionAddr is %#x\n", ret9);DWORD ret10 = GetFunctionAddrByName(pFileBuffer, fun_name);printf("GetFunctionAddr is %#x\n", ret10);free(pFileBuffer);free(pNewFileBuffer);free(pImageBuffer);
}int main()
{operate();getchar();return 0;
}
Ⅴ.结果展示:
滴水逆向——PE导出表相关推荐
- 滴水逆向三期实践1:PE头字段解析,附PE结构下载
视频资源详见网盘搜索 或 在线的B站滴水逆向三期 其课件也能在CSDN或百度搜索到,以下部分为课件内容摘要,部分为自己的理解 最后附上详细注释的自写代码 PE(Portable Executable) ...
- 导出表结构_十分钟教你轻松掌握移动PE导出表,快来学习!
今天的文章分享是 i 春秋论坛作者flag0原创的文章,浅析移动PE导出表的相关内容,文章未经许可禁止转载! 注:i 春秋公众号旨在为大家提供更多的学习方法与技能技巧,文章仅供学习参考. 导出表概述 ...
- 滴水逆向4月16日学习
滴水逆向 进制 1>.进制的定义: 十进制的定义:由十个符号组成,分别是0,1,2,3,4,5,6,7,8,9,逢十进一. 八进制的定义:由八个符号组成,分别是0,1,2,3,4,5,6,7,逢 ...
- 滴水逆向win32学习笔记1
滴水逆向win32学习笔记 一.字符编码 基本介绍 关于utf-16.utf-8和unicode的关系 BOM头 二.宽字符 基本介绍 常用函数 三.Win32 API中的宽字符 什么是win32 A ...
- b站滴水逆向课后练习(入伍停更中)
B站滴水逆向,想学习逆向知识的一起学习吧! 评论区有热心网友提供了全部课件,真心非常感谢! 提取链接:https://pan.baidu.com/s/1YwUP9I7Vctqiq1sOW9feBA 提 ...
- 静态链接库,动态链接库【滴水逆向三期48笔记】
在开发过程中,我们通常会有很多函数,需要多次使用或在不同的程序中使用该函数,也有可能我们会将我们写好的函数给别人使用,但是我们又不想给他源代码,毕竟代码是我们花了很多功夫写出来的,那么我们如何不发给其 ...
- 【滴水逆向P77】加载进程(PE查看器)应用程序源码解析
在上一篇文章中讲解了通用控件,做了一个基本的加载进程(PE查看器)的应用程序项目,Win32通用控件,加载进程(PE查看器)项目初步,大家如果有不懂的可以去看看,由于不是很了解Win32编程,所以有很 ...
- Windows PE导出表编程4(重构导出表实现私有函数导出)
本次是尝试调用DLL里面的私有函数. 一: 之前先探索一下,首先可以考虑用偏移量来调用,就是如果知道了某个私有函数和某个导出的公共函数的相对便宜的话,直接加载dll获取公共函数地址,然后自己手动去偏移 ...
- Windows PE导出表编程3(暴力覆盖导出函数)
今天要尝试的导出表相关编程内容是:覆盖函数地址部分的指令代码. 这种覆盖技术,是将AddressOfFunctions指向的地址空间指令字节码实施覆盖,这种技术又繁衍出两种: 暴力覆盖,即将所有的代码 ...
最新文章
- python常用英语单词-python – 获取英语单词的基本形式
- python3安装pymysql_Python3 MySQL 数据库连接 - PyMySQL 驱动
- 【转】介绍设置Session失效的几种方法
- ibatis java配置文件,ibatis学习-sqlMap.xml配置文件 | 学步园
- Delphi拖放编程
- 【干货】31篇关于深度学习必读论文汇总(附论文下载地址)
- Google Chrome修改网页背景颜色的办法
- OSChina 周三乱弹 —— 你们谁给我把盖扣上
- 学习MyBatis-Plus
- java中cleanup的使用_【Lombok注解】@Cleanup 自动资源管理:安全无困扰地调用close方法...
- 用友u8安装应用服务器输什么,用友u8服务器安装教程
- 防CC攻击 软件防火墙和WEB防火墙大比较
- access口 环路_交换机二层环路问题处理指南[苍松参考]
- 二叉树前序遍历、中序遍历、后序遍历、层序遍历的直观理解
- 必备:产品经理工作文档大全
- 超好用的PDF阅读器——Xodo PDF Reader
- python获取数组中最多的元素(用max函数)
- 英特尔OpenVINO工具套件快速构建一款AI应用之课程体验
- 【EMC专题】电磁辐射的危害
- 学生信息管理系统(数据库设计)
热门文章
- ubantu 安装显卡
- 微信公众账号使用获取token次数到达上限reach max api daily quota limit rid: 5fd6fd6a-49fcc7d4-65df845f
- 【ChatGPT】ChatGPT+MindShow三分钟生成PPT
- 如何安装和使用 Windows XP 的故障恢复控制台
- 利用TCP重传机制来玩端口敲门服务
- m118w重置墨粉_富士施乐 Fuji Xerox DocuPrint M118w/M118z重置墨粉页面计数器及重置硒鼓...
- 计算机图形学3——Boundary-Fill Algorithm
- MySQL(入门篇18)SQLyog 的用户权限管理 ; SQL语句的用户权限管理。
- 关于scope.$index, scope.row是什么意思
- Vue.js is detected on this page. Devtools inspection is not available becaus...的解决方法