Jump to content
  • Advertisement
Sign in to follow this  
Salvinger

Loading msvcr90.dll with loadlibrary

This topic is 3415 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm attempting to manually map a dll into a target process, and so far everything is going well but with one hitch. The dll I am mapping is being linked dynamically with the c++ runtime, but the target process does not have that dependency, so I am having to load msvcr90.dll before I can call the entrypoint. When I try to load msvcr90.dll with loadlibrary, I always get the error that the dll is not found. If I specify the full path, the dll says that it has been loaded incorrectly. Does anyone have experience in doing this? When I just flat out call loadlibrary on my own dll in the target process, msvcr90.dll somehow then gets successfully loaded so it's not a problem with the actual target program. I also know that I could statically link to the runtime, but I would prefer not to do that. Any help would be appreciated.

Share this post


Link to post
Share on other sites
Advertisement
Can you post the exact text of the error you get when you pass LoadLibrary the full DLL path?

Also, what version of Windows are you on?

Share this post


Link to post
Share on other sites
It occurs both on windows XP and 7, it's actually windows error code 126 which is where I got the dll not found from.

About the manifiest file, I think I might have that, it's the file with the .manifest extension right? Do I need to place that in the same folder as my dll?

Share this post


Link to post
Share on other sites
If you're injecting a DLL into another process, you should be minimizing it's external dependencies as much as possible (kernel32.dll and that's about it, in my opinion). So with that in mind, I would suggest if you really need the C++ runtime in your injected DLL (and maybe you don't), you should statically link to it.

Share this post


Link to post
Share on other sites
Since MSVC 2005, the runtime DLLs have been shared side-by-side assemblies, so you need the manifest attached to your application. You would do that using mt.exe.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
Since MSVC 2005, the runtime DLLs have been shared side-by-side assemblies, so you need the manifest attached to your application. You would do that using mt.exe.
The problem is that he's injecting a DLL into another process, so he can't modify the manifest of the other process.

Share this post


Link to post
Share on other sites
Codeka: Statically linking would be a good option, but it adds a lot of bloat to the exe (like an extra 50kb), and when I have more than one I want injected I would end up with two copies of that. But if I end up not being able to solve this then I will just have to deal with that.

SiCrane: I tried using mt.exe, and looked on msdn on how to use it. When I ran it from the command line with what I thought was the right input, the output from the console seemed to suggest that it worked fine, but my actual file was unchanged and loadlibrary still did not work. Here is what I used if it helps:

mt.exe -manifest "Self extracting injector.exe.intermediate.manifest" -outputresource:"Self extracting injector.exe";1


And the output:

Microsoft (R) Manifest Tool version 5.2.3790.2075
Copyright (c) Microsoft Corporation 2005.
All rights reserved.


The output from the console looks fine to me but may be it is supposed to say more than that.

Edit: Yea I just read what Codeka posted, I was thinking about that problem too but was thinking I might be able to solve that with this manifest thing.

I'm still confused on how the windows loader loads the msvcr90.dll in the target process too since I didn't embed the manifest in the dlls I made.

Share this post


Link to post
Share on other sites
To use LoadLibrary on SxS versioned dll, you've first got to create and activate an activation context. That requires a manifest to achieve, but you don't need mt.exe to create one as they're simple XML files.


<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<dependency>
<dependentAssembly>
<assemblyIdentity type='win32' name='Microsoft.VC90.CRT' version='9.0.30729.1' processorArchitecture='*' publicKeyToken='1fc8b3b9a1e18e3b' />
</dependentAssembly>
</dependency>
</assembly>




Save that as example.manifest (change the version number to match the file version of msvcr90 on your machine), or change the path in the code below to point to the one in <VS Install Path>\VC\redist\<arch>\Microsoft.VC90.CRT\. Then in code, you use the ActCtx family of functions to load and activate it before LoadLibrary-ing:


ACTCTX ctx = {sizeof(ACTCTX), 0};
ctx.lpSource = TEXT("D:\\Path\\To\\Saved\\example.manifest");
HANDLE hCtx = CreateActCtx(&ctx);
if(hCtx != INVALID_HANDLE_VALUE)
{
ULONG_PTR actToken;
BOOL activated = ActivateActCtx(hCtx, &actToken);
if(activated)
{
HMODULE hCRT = LoadLibrary(TEXT("D:\\WINDOWS\\WinSxS\\x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.30729.1_x-ww_6f74963e\\msvcr90.dll"));
if(hCRT)
{
// use the dynamic CRT
typedef int (__cdecl*PrintF)(const char*, ...);
PrintF print = reinterpret_cast<PrintF>(GetProcAddress(hCRT, "printf"));
if(print)
{
print("The dynamic CRT is loaded at 0x%p\n", hCRT);
}
FreeLibrary(hCRT);
}
DeactivateActCtx(0, actToken);
}
ReleaseActCtx(hCtx);
}


Share this post


Link to post
Share on other sites
Dang that's way complicated just to achieve loading the runtime, I think it was just something simple I had to do. Not sure how that would work out on a machine without the same version that I am running too. I appreciate the help though, but unfortunately I'm just going to have to do it the other way and just statically link to the runtime.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!