PE基础3-资源表-重定位表-TLS表-DLL延迟加载表
发布时间:2020-12-14 03:56:01 所属栏目:Windows 来源:网络整理
导读:PE基础3 导入表的作用是什么? 没有它exe能运行吗? 导入外部模块,提供的API,变量,类 可以没有导入表(这个程序没有用到其它模块) 导出表的作用是什么? 没有它exe能运行吗? 导出模块名,函数(序号),变量,类 通常导出表用于dll,没有导出表程序也可以运行
导入表的作用是什么? 没有它exe能运行吗?
导出表的作用是什么? 没有它exe能运行吗?导出模块名,函数(序号),变量,类 通常导出表用于dll,没有导出表程序也可以运行 已知一个dll名,和一个dll导出函数的名字,如何得到这个函数名的地址?导出表中查找 ENT(导出名称表) EOT(导出序号表) EAT(导出地址表) ? 怎么才能知道一个exe都使用了哪些API?通过遍历导入表(INT,IAT) 如何判断导入函数是以序号导入或是以名称导入?IMAGE_THUNK_DATA.DWORD 最高位1,说明序号导入 IMAGE_THUNK_DATA.DWORD 最高位0,说明名称导入 怎么才知道导出函数是仅以序号导出还是以名称导出?遍历导出地址表,再遍历导出序号表,序号表中的值与导出地址表下标对应, 说明这个函数是名称导出, 如果序号表中的值没有与地址表下标对应,那么它是序号导出(序号+BASE) ? 资源表概述windows的资源有菜单、图标、快捷键、版本信息以及其它未格式化的二进制资源比如菜单、图标、快捷键、 版本信息以及其它未格式化的二进制资源。。。 资源由三层一样的结构体组成 第一层:资源的类型是什么(图标,位图,菜单....) 第二次:资源的叫什么名字 (1.png,2.png) 第三层:资源的语言,资源的信息(大小,文件中位置) ? ? 资源表结构资源表位于数据目标表,下标为2 资源目录结构体 typedef struct _IMAGE_RESOURCE_DIRECTORY { ?
typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
当资源的名字为字符时,它指向这样一个结构体 typedef struct _IMAGE_RESOURCE_DIR_STRING_U { ?
最后一层指向真正数据的信息 typedef struct _IMAGE_RESOURCE_DATA_ENTRY { ?
解析资源表//获取资源表 PIMAGE_RESOURCE_DIRECTORY PE::GetResourceDirectory() { //资源表位于数据目录表, 下标为2 DWORD dwResourceRva = GetNtHeader()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress; ? DWORD dwResourceFoa = RvaToFoa(dwResourceRva) + (DWORD)m_pBuff; ? return (PIMAGE_RESOURCE_DIRECTORY)(dwResourceFoa); } //自定义 const WCHAR* RES[20] = { L"光标",L"位图",L"图标",L"菜单",L"对话框",L"字符串列表",L"字体目录",L"字体",L"快捷键",L"非格式化资源",L"消息列表",L"鼠标指针数组",L"NULL",L"图标组",L"版本信息",}; ? //显示资源表 void PE::ShowResourceInfo() { //1. 获取资源目录表 PIMAGE_RESOURCE_DIRECTORY pResourceOne = GetResourceDirectory(); //获取资源数组项 PIMAGE_RESOURCE_DIRECTORY_ENTRY pResouceOneEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pResourceOne + 1); //1.2 遍历所有资源类型 //资源总个数 DWORD dwResourceNumber = pResourceOne->NumberOfIdEntries + pResourceOne>NumberOfNamedEntries; for (int i = 0; i < dwResourceNumber; i++) { //1.3 判断资源类型,是数字还是字符串 if (pResouceOneEntry[i].NameIsString) { //资源ID是字符串 //那么NameOffset 有效(基于资源表的偏移) PIMAGE_RESOURCE_DIR_STRING_U szName = (PIMAGE_RESOURCE_DIR_STRING_U)(pResouceOneEntry[i].NameOffset + (DWORD)pResourceOne); TCHAR szBuff[100]; wcsncpy_s(szBuff,szName->NameString,szName->Length); printf("%Sn",szBuff); } else { //资源ID是数字 // 系统定义的 0 - 16 if (pResouceOneEntry[i].Id < 16) { wprintf(L"%sn",RES[pResouceOneEntry[i].Id]); } // 自定义的 else { printf("%02dn",pResouceOneEntry[i].Id); } } //2 解析第二层数据 //2.1 是否有第二层数据 if (pResouceOneEntry[i].DataIsDirectory) { //2.2 获取第二层资源表 PIMAGE_RESOURCE_DIRECTORY pResourceTwo = (PIMAGE_RESOURCE_DIRECTORY)(pResouceOneEntry[i].OffsetToDirectory + (DWORD)pResourceOne); //获取资源数组项 PIMAGE_RESOURCE_DIRECTORY_ENTRY pResouceTwoEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pResourceTwo + 1); //这种资源有多少个 DWORD dwNumber2 = pResourceTwo->NumberOfIdEntries + pResourceTwo>NumberOfNamedEntries; //2.3 遍历资源 for (int i = 0; i < dwNumber2; i++) { //资源名字是 数字,还是字符串 if (pResouceTwoEntry[i].NameIsString) { PIMAGE_RESOURCE_DIR_STRING_U szName = (PIMAGE_RESOURCE_DIR_STRING_U)(pResouceTwoEntry[i].NameOffset + (DWORD)pResourceOne); TCHAR szBuff[100]; wcsncpy_s(szBuff,szName->Length); printf(" %Sn",szBuff); } else { printf(" %02dn",pResouceTwoEntry[i].Id); } //3. 解析第3层 //3.1 是否有第三层数据 if (pResouceTwoEntry[i].DataIsDirectory) { //3.2 获取第三层资源表 PIMAGE_RESOURCE_DIRECTORY pResourceThree = (PIMAGE_RESOURCE_DIRECTORY)(pResouceTwoEntry[i].OffsetToDirectory + (DWORD)pResourceOne); PIMAGE_RESOURCE_DIRECTORY_ENTRY pResourceThreadEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pResourceThree + 1); //第三层 执行真正数据 PIMAGE_RESOURCE_DATA_ENTRY pResourceData = (PIMAGE_RESOURCE_DATA_ENTRY)(pResourceThreadEntry->OffsetToData + (DWORD)pResourceOne); printf(" 资源位置 %08X,资源大小 %02dn",pResourceData>OffsetToData,pResourceData->Size); } } } } } ? ? |