1 #include "pe_resources.h"
2 
3 #define ADD_RESOURCE_ID(id) m_resourcenames[PEResources::id] = #id
4 #define NULL_RESOURCE std::make_pair<ImageResourceDirectory*, ImageResourceDirectoryEntry*>(nullptr, nullptr)
5 
6 namespace REDasm {
7 
PEResources(ImageResourceDirectory * resourcedirectory)8 PEResources::PEResources(ImageResourceDirectory *resourcedirectory): m_resourcedirectory(resourcedirectory)
9 {
10     ADD_RESOURCE_ID(CURSORS);
11     ADD_RESOURCE_ID(BITMAPS);
12     ADD_RESOURCE_ID(ICONS);
13     ADD_RESOURCE_ID(MENUS);
14     ADD_RESOURCE_ID(DIALOGS);
15     ADD_RESOURCE_ID(STRING_TABLES);
16     ADD_RESOURCE_ID(FONT_DIRECTORY);
17     ADD_RESOURCE_ID(FONTS);
18     ADD_RESOURCE_ID(ACCELERATORS);
19     ADD_RESOURCE_ID(RCDATA);
20     ADD_RESOURCE_ID(MESSAGE_TABLES);
21     ADD_RESOURCE_ID(CURSOR_GROUPS);
22     ADD_RESOURCE_ID(ICON_GROUPS);
23     ADD_RESOURCE_ID(VERSION_INFO);
24     ADD_RESOURCE_ID(HTML_PAGES);
25     ADD_RESOURCE_ID(CONFIGURATION_FILES);
26 }
27 
find(u16 id) const28 PEResources::ResourceItem PEResources::find(u16 id) const { return this->find(id, m_resourcedirectory); }
find(const std::string & name) const29 PEResources::ResourceItem PEResources::find(const std::string &name) const { return this->find(name, m_resourcedirectory); }
find(u16 id,const PEResources::ResourceItem & parentres) const30 PEResources::ResourceItem PEResources::find(u16 id, const PEResources::ResourceItem &parentres) const { return this->find(this->resourceid(id), parentres); }
31 
find(const std::string & name,const PEResources::ResourceItem & parentres) const32 PEResources::ResourceItem PEResources::find(const std::string &name, const PEResources::ResourceItem &parentres) const
33 {
34     if(!parentres.second->DataIsDirectory)
35         return NULL_RESOURCE;
36 
37     ImageResourceDirectory* resourcedir = RESOURCE_PTR(ImageResourceDirectory, parentres.first,
38                                                        parentres.second->OffsetToDirectory);
39 
40     return this->find(name, resourcedir);
41 }
42 
find(u16 id,ImageResourceDirectory * resourcedir) const43 PEResources::ResourceItem PEResources::find(u16 id, ImageResourceDirectory *resourcedir) const
44 {
45     return this->find(this->resourceid(id), resourcedir);
46 }
47 
find(const std::string & name,ImageResourceDirectory * resourcedir) const48 PEResources::ResourceItem PEResources::find(const std::string &name, ImageResourceDirectory *resourcedir) const
49 {
50     u32 c = resourcedir->NumberOfIdEntries + resourcedir->NumberOfNamedEntries;
51     ImageResourceDirectoryEntry* entries = reinterpret_cast<ImageResourceDirectoryEntry*>(resourcedir + 1);
52 
53     for(u32 i = 0; i < c; i++)
54     {
55         std::string n = this->entryName(&entries[i]);
56 
57         if(name == n)
58             return std::make_pair(resourcedir, &entries[i]);
59     }
60 
61     return NULL_RESOURCE;
62 }
63 
entryName(ImageResourceDirectoryEntry * entry) const64 std::string PEResources::entryName(ImageResourceDirectoryEntry *entry) const
65 {
66     if(entry->NameIsString)
67     {
68         ImageResourceDirStringU* name = RESOURCE_PTR(ImageResourceDirStringU, m_resourcedirectory, entry->NameOffset);
69         return REDasm::wtoa(&name->NameString, name->Length);
70     }
71 
72     return this->resourceid(entry->Id);
73 }
74 
resourceid(u16 id) const75 std::string PEResources::resourceid(u16 id) const
76 {
77     auto it = m_resourcenames.find(id);
78 
79     if(it == m_resourcenames.end())
80         return "#" + std::to_string(id);
81 
82     return it->second;
83 }
84 
85 }
86