PE之写入打印资源表(12)

源码GitHub:https://github.com/TL-SN/_TLSN_RES.PE

最近复习PE学过的知识点,看到了资源表,感觉很有意思,就记录了下来

一、 改飞鸽的标题

 

 

 

 

这个飞鸽本来是 2007 版的,直接可以把标题改变成2022版,直接领先亿个版本(狗头)

方法: 找到标题的位置,直接在16进制编辑软件中修改(这是海哥课上讲的的方法)

 

1、先是在ResourceHacker下找到相对应的Dialog对话框,记下对话框的编号,我这里是101

 

 

2、用LoadPE工具Dump 相对应的对话框代码

 

 

3、 此时,要找的标题就在这一小块Dump的代码里,用16进制文本编辑工具打开,可以发现代码很少,很好找

 

 

 

  

 

 

4、 提取这一块的特征代码,在飞鸽的16进制文本中进行搜索

 

搜索到后,修改即可

 

 

我觉得直接根据LoadPe上写的RVA在16进制文本编译器上找就行了,不过海哥这样做应该有他的道理

 

 

 

 

 

 

 

 

 

二、

1.资源表及目录项结构

typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {

             

    union {

         

//目录项的名称、或者ID

 

        struct {

             

            DWORD NameOffset:31;

             

            DWORD NameIsString:1;

             

        };

             

        DWORD   Name;

             

        WORD    Id;

             

    };

             

    union {

             

        DWORD   OffsetToData;

         

//目录项指针

 

        struct {

             

            DWORD   OffsetToDirectory:31;

             

            DWORD   DataIsDirectory:1;

             

        };

             

    };

             

} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;

             

 

 

2.遍历资源表,首先资源表 注意,他的 NameOffset 的偏移是相对于第一张资源表的偏移:

 递归实现:  

部分关键代码:(我是用c++的类来分装的,考虑篇幅,这里只贴了部分代码,完整的代码都在GitHub上 ,或者查看这个链接 : https://www.cnblogs.com/lordtianqiyi/articles/15782773.html)

源码GitHub:https://github.com/TL-SN/_TLSN_RES.PE

VOID _PE_User::RelTestPrintResourceICO(PIMAGE_RESOURCE_DIRECTORY pResDirectorys,size_t floors) { PIMAGE_DATA_DIRECTORY pImageDataDiry; PIMAGE_RESOURCE_DIR_STRING_U pResDirUniString; DWORD NumOfFirEntry = pResDirectorys->NumberOfNamedEntries + pResDirectorys->NumberOfIdEntries; PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResDirectorys + sizeof(IMAGE_RESOURCE_DIRECTORY)); floors++; for(size_t i = 0;i<NumOfFirEntry;i++) { if(floors == 1) { printf("\n***************************************%x***************************************\n\n",RelFloors++); } if(floors == 2) printf("\t"); if(floors == 3) printf("\t\t"); printf("第 %x 层\n",floors); if( (pResDirEntry + i)->NameIsString == 0) { if(floors == 1) printf("序号:%x\n",(pResDirEntry + i)->Id); if(floors == 2) printf("\t资源编号:%x\n",(pResDirEntry + i)->Id); if(floors == 3) printf("\t\t代码页:%x\n",(pResDirEntry + i)->Id); } else if( (pResDirEntry + i)->NameIsString == 1) { printf("名称:"); pResDirUniString = (PIMAGE_RESOURCE_DIR_STRING_U)( (DWORD)File_PE_s.pResDirectory + (pResDirEntry + i)->NameOffset); for(int j = 0;j<pResDirUniString->Length;j++) { printf("%wc",pResDirUniString->NameString[j]); } printf("\n"); } if( (pResDirEntry + i)->DataIsDirectory == 1 ) { pResDirectorys = (PIMAGE_RESOURCE_DIRECTORY)((pResDirEntry + i)->OffsetToDirectory + (DWORD)File_PE_s.pResDirectory); RelTestPrintResourceICO(pResDirectorys,floors); } else { pImageDataDiry = (PIMAGE_DATA_DIRECTORY)((pResDirEntry + i)->OffsetToDirectory + (DWORD)File_PE_s.pResDirectory); printf("\t\t\t数据项:\n"); printf("\t\t\tVirtualAddress: %x Size:%x\n",pImageDataDiry->VirtualAddress,pImageDataDiry->Size); } } }

 

 3.我使用记事本做的实验:

 

 

 

 

 

 

 

 还算可以

 


__EOF__

本文作者_TLSN
本文链接https://www.cnblogs.com/lordtianqiyi/articles/15782742.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   TLSN  阅读(66)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示