libpeconv icon indicating copy to clipboard operation
libpeconv copied to clipboard

run_pe method not working for executables without .reloc table

Open harunkocacaliskan opened this issue 10 months ago • 2 comments

Hello,

I have an old executable which doesnt have any .reloc section, it was build with FIXED base address. When i tried to run it it says, Could not relocate the module.

I build Hello World Console App with FIXED address for testing.

Image

runpe output.

Image

Do we need to make some modifications for executables which doesnt have .reloc table, or we need to use alternative techniques?

harunkocacaliskan avatar Feb 26 '25 11:02 harunkocacaliskan

Hello! The problem with executables with a fixed base is, well, they can be loaded only at one, defined address. If it was impossible to allocate that memory at that precise address, they can't be run at all. There is no way to relocate the used addresses within it into a new base. This is why I don't support them by default.

It is possible to load them using RunPE method, but if and only if, we can manage to allocate within the target the exact base that is required by the payload. Sometimes, there is already something loaded at this address, so it is not free. If the previous main executable occupies it, we can free this space by unmapping the EXE (as it is done in a classic variant of RunPE).

In my current implementation of RunPE, I don't unmap the original EXE, but load the payload alongside, and then update the base address in the PEB. This is a bit stealthier variant of RunPE. But it won't support your case. I may do some refactoring that support it, but I am not sure if it is really worth it, since most of the modern PEs use dynamic base. Try using a different variant of RunPE that does the unmapping of the original module, it should help.

hasherezade avatar Feb 26 '25 23:02 hasherezade

Hello! The problem with executables with a fixed base is, well, they can be loaded only at one, defined address. If it was impossible to allocate that memory at that precise address, they can't be run at all. There is no way to relocate the used addresses within it into a new base. This is why I don't support them by default.

It is possible to load them using RunPE method, but if and only if, we can manage to allocate within the target the exact base that is required by the payload. Sometimes, there is already something loaded at this address, so it is not free. If the previous main executable occupies it, we can free this space by unmapping the EXE (as it is done in a classic variant of RunPE).

In my current implementation of RunPE, I don't unmap the original EXE, but load the payload alongside, and then update the base address in the PEB. This is a bit stealthier variant of RunPE. But it won't support your case. I may do some refactoring that support it, but I am not sure if it is really worth it, since most of the modern PEs use dynamic base. Try using a different variant of RunPE that does the unmapping of the original module, it should help.

Hello,

Yes i tried unmapping method it works for operating systems up to windows 11 24h2, as we discussed other issue, windows 11 24h2 throws an error 0xC0000141 STATUS_INVALID_ADDRESS. And patching of ntdll not working for fixed base executables. So thats not an issue for libpe. Thanks for your help.

harunkocacaliskan avatar Feb 27 '25 07:02 harunkocacaliskan