Skip to content
Karsten Hahn edited this page Feb 11, 2023 · 17 revisions

Loading the Resource Section

Like other special sections the resource section is loaded via the section loader. The section loader determines the location of the resource section, extracts the neccessary bytes from the file for you and creates the resource section instance.

File file = new File("sample.exe");
PEData data = PELoader.loadPE(file);
ResourceSection rsrc = new SectionLoader(data).loadResourceSection();

Fetching all Resources

The resource section instance can return a list of all resources for you.

Get all resources in the resource section and print information about them:

List<Resource> resources = rsrc.getResources();
for (Resource r : resources) {
    System.out.println(r);
}

An alternative way of loading all resources is by using the PEData instance (since 4.0.0). This way you do not have to load the resource section manually.

List<Resource> resources = data.loadResources();

This will not load the raw data of the resources into memory, because resources might be too big for that. If you want access to the raw data, use the location information in every resource. The following example will print the raw resource data as raw string or hex string.

Resource resource = resources.get(0);
Location loc = resource.rawBytesLocation();
long offset = loc.from();
assert loc.size() == (int) loc.size();
int size = (int) loc.size();
try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
    byte[] bytes = IOUtil.loadBytes(offset, size, raf);
    // print as hex string
    System.out.println(ByteArrayUtil.byteToHex(bytes));
    // print as string (e.g. for ASCII resources)
    System.out.println(new String(bytes));
}

Extraction of ICO files from resources

PortEx can extract icons from the resource section and save them as ICO files. The following code will extract all icon resources that can be found in the file.

List<GroupIconResource> grpIcoResources = IconParser.extractGroupIcons(file);
int nr = 0;
for(GroupIconResource grpIconResource : grpIcoResources) { 
    nr++;
    IcoFile icoFile = grpIconResource.toIcoFile();
    File dest = new File("icon" + nr + ".ico");
    icoFile.saveTo(dest);
    System.out.println("ico file " + dest.getName() + " written");
}

Since 4.0.0 a list of icons can also be obtained using the PEData instance. The IcoFile can return the icon as byte array or InputStream.

List<IcoFile> icons = data.loadIcons();
for(IcoFile i : icons) {
    byte[] iconBytes = i.getBytes();
    InputStream iconStream = i.getInputStream();
}

Access to Structures of the Resource Tree

If you need very detailed information about the structure of the resource section (like RVAs), get the root of the resource tree instead:

ResourceDirectory tree = rsrc.getResourceTree();

This is the first table in the resource section. It provides access to its header and data directory entries.

Resource Directory Header

Example how to get some header information. There are two ways. You can get the header map:

Map<ResourceDirectoryKey, StandardField> header = tree
            .getHeader();
long majorVersion = header.get(ResourceDirectoryKey.MAJOR_VERSION).getValue();

Or use the table directly to get the values of a header key:

long majorVersion = tree.getHeaderValue(ResourceDirectoryKey.MAJOR_VERSION);

Resource Directory Entries

Each entry of the resource directory table is either a data entry or a subdirectory entry. The data entry is a leave of the tree and provides access to the raw resource bytes. The subdirectory entry links to another resource directory table with its entries.

Fetching all directory table entries:

// get a list of all entries, regardless which subtype
List<ResourceDirectoryEntry> entries = tree.getEntries();
// get a list of all data entries
List<DataEntry> dataEntries = tree.getDataEntries();
// get a list of all subdirectory entries
List<SubDirEntry> subdirEntries = tree.getSubDirEntries();