hasherezade / libpeconv

A library to load, manipulate, dump PE files. See also: https://github.com/hasherezade/libpeconv_tpl
https://hasherezade.github.io/libpeconv
BSD 2-Clause "Simplified" License
1.07k stars 176 forks source link

Compiling on Linux #25

Open omern1 opened 3 years ago

omern1 commented 3 years ago

Are there any plans to make libpeconv platform independent?

hasherezade commented 3 years ago

LibPEconv is by definition dedicated to PE files. Do you mean compiling it on Linux via MinGW? Or your goal is to have an equivalent functionality but for ELF files?

omern1 commented 3 years ago

Hi, my intention is to use LibPEconv to do something like what https://github.com/taviso/loadlibrary does but for executables instead of DLLs. Is that something that you would be on board with?

Edit: I realised that would be similar to compiling it on Linux vs MinGW.

Currently an attempt to build LibPEconv on Linux fails due to a lack of Windows header files. As far as I have been able to understand (and my apologies if I'm wrong about this) libPEconv does not use any functions from the Windows headers, it only uses types, if I am correct it would be possible to make it platform independent, right?

hasherezade commented 3 years ago

Hi, my intention is to use LibPEconv to do something like what https://github.com/taviso/loadlibrary does but for executables instead of DLLs. Is that something that you would be on board with?

Edit: I realised that would be similar to compiling it on Linux vs MinGW.

Currently an attempt to build LibPEconv on Linux fails due to a lack of Windows header files. As far as I have been able to understand (and my apologies if I'm wrong about this) libPEconv does not use any functions from the Windows headers, it only uses types, if I am correct it would be possible to make it platform independent, right?

Currently libPEconv uses a lot of functions that belong to WinAPI, and that are not accessible on Linux. Yet, this problem is relatively easy to resolve with some refactoring, and making wrappers for each WinAPI function with ifdefs like:

#ifdef _WIN32
  data = VirtualAlloc(NULL, alloc_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
#else
  data = mmap(NULL, alloc_size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
#endif

So, it will be easy to replace those parts, and let the PE load to the memory (remap, relocate). The functions within the PE which have no external dependencies should execute without problems (assuming we are on the same architecture).

Yet the problems arise when we need to use imported functions within the PE. LibPEconv has a manual import loader, so in theory you can fill the thunks of the imports with anything you want. But the problem is, how to create wrappers (at scale) for each function that is going to be imported from a Windows DLL, so that it can run on Linux? At some point we are destined to meet the missing dependencies.

This is the main problem that causes incompatibility. When I get some free time, I will study how Taviso resolved this problem.

omern1 commented 3 years ago

Ah yes, apologies, I meant it doesn’t depend on the Windows API for any core functionality. Things like peconv::get_process_id and alloc_aligned of course do depend on the Windows API.

In the meanwhile, I am working on getting libPEconv to load a no external dependencies PE on Linux. I’ll make a pull request soon and then hopefully if you’re on board with it we can discuss further.

Yet the problems arise when we need to use imported functions within the PE. LibPEconv has a manual import loader, so in theory you can fill the thunks of the imports with anything you want. But the problem is, how to create wrappers (at scale) for each function that is going to be imported from a Windows DLL, so that it can run on Linux? At some point we are destined to meet the missing dependencies.

I think we can leave that to the user. If they are using libPEconv to load a PE on Linux, they can manually write all the wrappers that they need. Do you think that would be the right thing to do?

hasherezade commented 3 years ago

TBH I still have doubts if such refactoring pays of at all, because they will require too invasive changes in the library, and the end result will be still too far from perfection (lack of generic solutions for loading dependencies).

Maybe it pays of more to fork Taviso's project, which was designed for this purpose from the very beginning? BTW I saw his code briefly (still need to go in more details) but even his project has many limitations. Although it works for loading some DLLs on which he focused, it doesn't provide a generic way to load any chosen DLL without additional work.

hasherezade commented 3 years ago

BTW - I am just curious what is the usecase that you are trying to cover? What is the main goal you need to achieve? Maybe there are other solutions? For example there is a Qiling framework which is multiplatform. Some (but not all) of its usecases overlap with libPEconv.