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("取得函数失败\n");
return FALSE;
}
}else{
//printf("加载模块失败\n");
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\n",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.根据名字查找函数地址
WindowsPE 第五章 导出表编程-1(枚举导出表)的更多相关文章
- WindowsPE 第五章 导出表
导出表 PE中的导出表存在于动态链接库文件里.导出表的主要作用是将PE中存在的函数导出到外部,以便其他人可以使用这些函数,实现代码重用. 5.1导出表的作用 代码重用机制提供了重用代码的动态链接库,它 ...
- #《Essential C++》读书笔记# 第五章 面向对象编程风格
基础知识 继承机制定义了父子(parent/child)关系.父类(parent)定义了所有子类(children)共通的共有接口(public interface)和私有实现(private imp ...
- 第五章 javascript编程可养成的好习惯
用户点击某个链接时弹出一个新窗口javascript使用window对象的open()方法来创建新的浏览器窗口,这个方法有三个参数:window.open(url,name,features)url: ...
- 《java编程思想》读书笔记(一)开篇&第五章(1)
2017 ---新篇章 今天终于找到阅读<java编程思想>这本书方法了,表示打开了一个新世界. 第一章:对象导论 内容不多但也有20页,主要是对整本书的一个概括.因为已经有过完整JAV ...
- UNIX 网络编程第五章读书笔记
刚看完 UNIX 第五章内容,我想按照自己的方式将自己获得的知识梳理一遍,以便日后查看!先贴上一段简单的 TCP 服务器端代码: #include <sys/socket.h> #incl ...
- 安卓权威编程指南 - 第五章学习笔记(两个Activity)
学习安卓编程权威指南第五章的时候自己写了个简单的Demo来加深理解两个Activity互相传递数据的问题,然后将自己的学习笔记贴上来,如有错误还请指正. IntentActivityDemo学习笔记 ...
- C#高级编程 (第六版) 学习 第五章:数组
第五章 数组 1,简单数组 声明:int[] myArray; 初始化:myArray = new int[4]; 为数组分配内存. 还可以用如下的方法: int[] myArray = new in ...
- [书籍翻译] 《JavaScript并发编程》第五章 使用Web Workers
本文是我翻译<JavaScript Concurrency>书籍的第五章 使用Web Workers,该书主要以Promises.Generator.Web workers等技术来讲解Ja ...
- 《Linux命令行与shell脚本编程大全》 第十五章 学习笔记
第十五章:控制脚本 处理信号 重温Linux信号 信号 名称 描述 1 HUP 挂起 2 INT 中断 3 QUIT 结束运行 9 KILL 无条件终止 11 SEGV 段错误 15 TERM 尽可能 ...
随机推荐
- 通过穷举法快速破解excel或word加密文档最高15位密码
1.打开文件 2.工具 --- 宏 ---- 录制新宏 --- 输入名字如 :aa 3.停止录制 ( 这样得到一个空宏 ) 4.工具 --- 宏 ---- 宏 , 选 aa, 点编辑按钮 5.删除窗口 ...
- python基础(8)python中is和==的区别详解
前置知识点 当我们创建一个对象时,我们要知道它内部干了些什么 1.创建了一个随机id,开辟了一片内存地址 2.自动声明了这个对象的类型type 3.给这个对象赋值value 小例子 a = 1 pri ...
- 使用自定义注解和切面AOP实现Java程序增强
1.注解介绍 1.1注解的本质 Oracle官方对注解的定义为: Annotations, a form of metadata, provide data about a program that ...
- Java 树结构实际应用 一(堆排序2秒排完800w数据)
堆排序 1 堆排序基本介绍 1) 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复 杂度均为 O(nlogn),它也是不稳定排序. 2) 堆是具有以下性 ...
- 【Django必备01】——什么是Django框架?有什么优势?模块组成介绍。
01.什么是Django框架? Django是一个开放源代码的Web应用框架,由Python写成.采用了MTV的框架模式.使用这种架构,程序员可以方便.快捷地创建高品质.易维护.数据库驱动的应用程序. ...
- WorkSkill整理之 技能体系
- 攻防世界 reverse hackme
hackme XCTF 3rd-GCTF-2017 __int64 __fastcall sub_400F8E(__int64 a1, __int64 a2) { char input[136]; / ...
- [源码解析] 并行分布式框架 Celery 之架构 (1)
[源码解析] 并行分布式框架 Celery 之架构 (1) 目录 [源码解析] 并行分布式框架 Celery 之架构 (1) 0x00 摘要 0x01 Celery 简介 1.1 什么是 Celery ...
- Java中对象的生与灭- 核心篇
前言 大家好啊,我是汤圆,今天给大家带来的是<Java中对象的生与灭- 核心篇>,希望对大家有帮助,谢谢 文章纯属原创,个人总结难免有差错,如果有,麻烦在评论区回复或后台私信,谢啦 简介 ...
- 面试关于Spring循环依赖问题,我建议你这么答!
写在前面 在关于Spring的面试中,我们经常会被问到一个问题:Spring是如何解决循环依赖的问题的. 这个问题算是关于Spring的一个高频面试题,因为如果不刻意研读,相信即使读过源码,面试者也不 ...