Open illnyang opened 2 years ago
Hi @illnyang ! sorry for the late response, I am very busy nowadays. I am not sure if I understood correctly what exactly are you trying to achieve, so if you can provide some more context about your intentions that would be very helpful.
Is it that you have the full PE (the payload) mapped inside a section .payload
of the loader?
So, the layout of the loader is:
Name Start End R W X D Class
-------- -------- -------- - - - - -----
.payload 00401000 20401000 R W . . BSS -> this is where the whole new PE (payload) will be loaded
.og_bss 20401000 20402000 R W . . BSS
.og_text 20402000 20414000 R . X . CODE
.og_data 20414000 20415000 R W . . DATA
You said that your problem is related with the relocations of the payload. What exactly is the thing that libpeconv doesn't do correctly? Is your intention NOT to have the payload relocated, even if the relocation table isn't stripped? If so, it is possible to achieve, although it isn't default.
Or maybe you mean that libpeconv's API does not allow you to load a PE into the memory area that you specified, but instead, it does the allocation by itself, and therefore you cannot make it load to a predefined section? For example, this is how the loading function is implemented at the moment:
/**
Loads full PE from the raw buffer in a way in which it can be directly executed: remaps to virual format, applies relocations, loads imports.
Allows for supplying custom function resolver.
*/
BYTE* load_pe_executable(BYTE* payload_raw, size_t r_size, OUT size_t &v_size, t_function_resolver* import_resolver=NULL);
more details and alternative versions of this API here
And in order to load it into a predefined section, the API should look like this:
size_t load_pe_executable(BYTE* payload_raw, size_t r_size, BYTE* out_buffer, size_t out_size, t_function_resolver* import_resolver=NULL);
Please let me know, and I will make the appropriate changes soon.
Regarding the Linux support, it is another, long topic, and I will consider it as a direction of future development.
I found a rather peculiar edge case, which is not currently handled by libpeconv (and if it is, I am too dumb to figure it out). Consider following scenario:
Payload is an executable PE with stripped relocs, its imagebase is 0x400000. My loader accounts for this with an explicit section layout, like so:
The loader maps EXE payload into the
.payload
section, patches what's needed and jumps to its OEP. This technique is calledProcess Hiving
, I believe. I'm using it as an alternative toDLL load order hijacking
method (aka proxy DLLs) in my game modding framework.If payload is not reloc-stripped, the loader will relocate it into the
.payload
section anyway.I do not call VirtualAlloc at all, VirtualProtect is used to set appropriate section flags before jumping to the OEP.
My long-term goal is to have per-game targeted Linux compat patches as well - stuff like replacing XInput/WndProc with SDL2, replacing d3d9 with dxvk, etc. It would be nice for libpeconv to support Linux as well. taviso/loadlibrary is Linux-only and it feels redundant to have two separate dependencies of identical nature.
Similar approach is used in the following projects