Question

I am trying to write a packer/self extracting exe type program but I am having problems with the segment order created by Visual C++'s linker.

Basically I have a stub program (the loader) that has a special variable defined like this:

#pragma const_seg(".blah")
const char blah[1];
#pragma const_seg()

And it does something with the data in blah (eg unpacks the data).

A second program (the packer) then uses the loader program as a template for creating a new program with some data in blah.

Basically the packer copies the loader file, then replaces the old .blah section with some new data. When the new file is executed the loader operates on this new data.

Now modifying exe files is tricky work, so to make it simple I would like .blah to be the last segment in the file so that I can simply append data to the loader, then fix up a few size fields in the PE header.

However I can't figure out how to control the order of segments in the Visual C++ linker to put .blah at the end of the file when it compiles the loader.

Currently the section order is this:

.textbss
.text
.rdata
.data
.idata
.blah
.rsrc
.reloc

As you can see .rsrc and .reloc are in the wrong place, I need them before .blah.

What can I do to change this order?

Was it helpful?

Solution 2

The way I ended getting around this is by not adding the .java section to the loader at link time.

Instead the packer creates a new .java section at the end of the file.

When the loader runs it gets it's base address (from GetModuleHandle) then parses the DOS, NT, and finally the section headers to get the relative virtual address of the .java section.

It is worth noting that when Windows loads the section headers, they are placed immediately after the data directory in the optional header, unlike on disk where it is offset to the file alignment.

The final address to the section is found by adding the base address to the relative address.

OTHER TIPS

The only control MSVC gives over segment is the ability to create custom ones and merge existing ones, and control the access flags of each segment, anything more beyond this becomes pointless, as there is no set rule for ordering, thus the compiler is free to pick the simplest/easiest option.

For what you want to do, rather just loop through the segment descriptors in the PE, find the biggest base address, and use that plus the segment size as your appending address, it'll be far more reliable.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top