Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to load multiple dll images #101

Open
posutsai opened this issue Jun 22, 2021 · 5 comments
Open

Unable to load multiple dll images #101

posutsai opened this issue Jun 22, 2021 · 5 comments

Comments

@posutsai
Copy link

Hi, I am trying to use loadlibrary to load a dll image which uses windows Component Object Model internally but some error happens. Seems like loadlibrary links multiple PE image incorrectly.

Since the function in my target PE image utilize COM, it is insufficient to load single PE image. Following is how I try to load both my target PE image and COM related symbols from ole32.dll.

int main() {
  struct pe_image images[2] = {
    {.entry = NULL, .name = "/path/to/my/taget.dll", },
    {.entry = NULL, .name = "ole32.dll"}
  };
  for (int i = 0; i < 2; i++) {
    pe_load_library(images[i].name, &images[i].image, &images[0].size);
  }
  link_pe_images(images, 2); // <- SegFault happens here.
}

I wonder if I link the images wrong. If so, how should I link multiple images?

@juju812
Copy link

juju812 commented Sep 13, 2021

I'm also trying to load multiple DLLs, and adapting code to setup struct to save info for dedicated DLL, instead of global varibles such as pe_exports and num_pe_exports.
At last, I'm trapped by a global struct pe_image image, required by Exception.c of x64 branch but not in x86.

@cube0x8 Could you please kindly clarify that why this struct is required in x64 implementation and how to fix this issue? And, if I have two dlls(target1.dll and target2.dll), is it possible to load these dlls in one process?

Thanks and looking forward your reply!

@cube0x8
Copy link
Collaborator

cube0x8 commented Sep 14, 2021

Hello @juju812 and @posutsai.

I've just noticed that this issue has never been addressed. Sorry for this.

  1. I am reasonably sure that loadlibrary is not meant to allow the loading of multiple DLLs.
    Despite the link_pe_images API was originally designed for this purpose (that's why it takes, as arguments, an array of images and the number of images to link), actually it's not providing this capability now. As @juju812 correctly stated, the exports of a library are stored in the pe_exports global variable, which gets overwritten at each iteration if you're linking multiple libraries (see here). In the end you will get a num_pe_exports which will sum up all the exports in all the DLLs, but the pe_exports variable will be inconsistent. All of this will subsequently leads to the SIGSEGV @posutsai reported.

  2. In the x64 version of loadlibrary, the SEH support is completely changed from its original x86 version. I won't get too much in detail here, but long story short: there are functions in the Exception.c file of the peloader library that will need the base address of the loaded library to work correctly, that's why I moved that struct as global in the x86_64 version.

I'm also trying to load multiple DLLs, and adapting code to setup struct to save info for dedicated DLL, instead of global varibles such as pe_exports and num_pe_exports.

I don't want to jump on conclusions for this, since I am not the owner of the project and this is not my call, but to be able to load and link multiple DLLs you will need to make radical changes to the framework, which I guess are out of the scope of the project itself, since loadlibrary provides a set of API to load a single self-contained DLL mostly for fuzzing purposes.

@juju812
Copy link

juju812 commented Sep 15, 2021

Hi, I commented out SEH functions in Exception.c and finally I can load two simple DLLs in one executable. Demo can be found here.

What I've done is just to introduce the pe_handle struct, save pe_exports of each DLL seperately, and adapt APIs affected.

I believe there's potential problems, for my demo is so simple that there's no dependency of any kernel32 API.
@cube0x8 @taviso, could you please help to figure out if this approach is feasible and how much further work is needed?

Thanks and looking forward your reply!

@cube0x8
Copy link
Collaborator

cube0x8 commented Sep 18, 2021

Hi,

It sounds like a good approach to me.

I guess you will need to modify some of the peloader APIs, but that should be quite simple and straightforward.

For example, if you are using the x86_64 version, you will have to modify the exception handling routine to look for the RUNTIME_FUNCTION entries in each of the loaded DLLs. A quick solution that comes to my mind is to store the pe_handle structures in a global list and then call RtlPcToFileHeader on all of them.

@kh-abd-kh
Copy link

Hi juju812 how can i clone your files and compile .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants