#include<Windows.h>
#include<stdio.h>
#include<tchar.h>
int main()
{
void *pPEB=NULL;
void *pPEB_LDR_DATA=NULL;
void *pModuleList=NULL;
void *pKernelBase=NULL;
void *pPEHeader=NULL;
void *pExportTable=NULL;
void *pAddressOfNames=NULL;
void *pAddressOfFunctions=NULL;
void *pAddressOfNameOrdinals=NULL;
DWORD *pNumberOfFunctions=NULL;
__asm
{
mov eax,fs:[0x30] //获得pPEB地址
mov pPEB,eax
mov eax,[eax+0x0c] //获得pPEB_LDR_DATA指针
mov pPEB_LDR_DATA,eax
//获取InInitializationOrderModuleList链表头第一个LDR_MODULE节点
//分别是按照加载顺序、在内存中的地址顺序和初始化顺序排列的模块信息结构的指针,
//三条链表一样,只不过排序规则不一样,位置不一样
mov eax,[eax+0x1c]
mov pModuleList,eax
mov eax,[eax]
mov eax,[eax+0x08]
mov pKernelBase,eax//Kernel基址
mov eax,[eax+0x3c]
add eax,pKernelBase
mov pPEHeader,eax//PE头
mov eax,[eax+0x78]
add eax,pKernelBase
mov pExportTable,eax//导出表
mov pNumberOfFunctions,eax
add pNumberOfFunctions,0x14//导出函数个数
mov eax,[eax+0x1c]
add eax,pKernelBase
mov pAddressOfFunctions,eax//指向输出函数地址的RVA
mov eax,pExportTable
mov eax,[eax+0x20]
add eax,pKernelBase
mov pAddressOfNames,eax//导出函数名表
mov eax,pExportTable
mov eax,[eax+0x24]
add eax,pKernelBase
mov pAddressOfNameOrdinals,eax//指向输出函数序号的RVA
}
void *p=pModuleList;
do
{
wprintf(L"FullPathName:%s\nDLLName:%s\nBaseAddress:%X\n",*(void **)((unsigned)p+0x18),*(void **)((unsigned)p+0x20),*(void **)((unsigned)p+0x08));
p=*((void **) p);
}while(p!=pModuleList);
void * pFunName;
WORD Ordinal=0;
for(int i=0;i<*pNumberOfFunctions;i++)
{
getchar();
pFunName=(void *)((unsigned)pAddressOfNames+i*4);
printf("第%d个导出函数:%s ",i+1,unsigned(*(void **)pFunName)+(unsigned)pKernelBase);
Ordinal=WORD(*(void**)(i*2+(unsigned)pAddressOfNameOrdinals));
printf("地址:%X\n",unsigned(*(void**)((unsigned)pAddressOfFunctions+Ordinal*4))+unsigned(pKernelBase));
}
return 0;
}
打印PE导出表
最新推荐文章于 2022-12-04 18:40:50 发布