Using Loadlibrary("cmd.exe") but not work - c++

as we all know when we start a CMD.exe it will appear a console window and start with lines like:
Microsoft Windows [版本 6.1.7601]
版权所有 (c) 2009 Microsoft Corporation。保留所有权利。
C:\Users\hey>
but when i crate a windows console project in VS and my code like this:
int _tmain(int argc, _TCHAR* argv[])
{
auto h = LoadLibrary(__TEXT("cmd.exe"));
Sleep(99999);
}
just turns out a black window.no lines out!
as i expect,i can load this PE(windows executable format) file in my process so i do not have to start a new cmd.exe and redirect its stdIO to the process which start cmd.exe.(i know Loadlibrary with an exe file could start a exe in calling process without creating a new process)
and why is Loadlibrary not working?(it did not appear any words in the console window)

(i know Loadlibrary with an exe file could start a exe in calling process without creating a new process)
No, it can't.
You can pass the name of an EXE file to LoadLibraryEx if you use the LOAD_LIBRARY_AS_DATAFILE flag, in order to access its resources, but LoadLibrary neither runs the code in an EXE nor prepares the code for being run.
The entry point for an EXE is designed for having its own process. (I'm talking about the real entry point, which is usually provided by a language support library. It may have a name such as wmainCRT and its address, not the address of user-provided main(), appears in the PE header). Typically it exits by calling ExitProcess(), which will have catastrophic effects on your host EXE even if you do manage to map it into your memory space and call it.
The requirements for the entry point of a dynamically loadable library and an executable file are very, very different.

You can't run an executable via LoadLibrary. Use CreateProcess (or one of its siblings) instead.
From the LoadLibrary function docs (highlight in bold is mine):
LoadLibrary can also be used to load other executable modules. For example, the function can specify an .exe file to get a handle that can be used in FindResource or LoadResource. However, do not use LoadLibrary to run an .exe file. Instead, use the CreateProcess function.

Related

LoadLibray FileNotFound depending on which application calls

I'm trying to impletement a C++ dll named (let's say) name.dll, which loads another dll (not mine) that is also named name.dll.
In my name.dll implementation I'm loading the real name.dll using this line :
driver_library = LoadLibrary(_T("c:\\windows\\system32\\name.dll"));
My dll is in a program.exe.local folder so that the program load mine before the real one in System32.
Depending on which program.exe uses my dll, LoadLibrary either works fine or returns my own name.dll handle as driver_library, with GetLastError() returning "file not found".
In https://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx it is explicit stated that "If the string specifies a full path, the function searches only that path for the module." Why and how does it load itself for some applications ?
What in the program.exe application could affect LoadLibrary's behavior ?
#Franck Boyne commented :
"You have two programs - let's call them fine.exe and own.exe. The fine.exe program loads your own name.dll and then loads the other name.dll from System32. The own.exe program loads your own name.dll but when it calls LoadLibrary you get back another handle to your own name.dll instead of a handle to the one from System32."
About own.exe (which is not at all my "own" application) :
-> name.dll is located in an own.exe.local folder I created, which is located in own.exe directory.
-> own.exe had an application.manifest file that I deleted (the application still launches correctled without it if not using my dll). own.exe does not have an embedded manifest (checked using sigcheck).
-> name.dll is not one of Windows "known dlls" from HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs
-> own.exe does not load name.dll using LoadLibrary() (checked by setting a breakpoint into LoadLibrary/A/W/Ex functions)
-> own.exe and name.dll are both 64 bits.
About fine.exe (it's a sample, I have access to the code):
-> name.dll is located in the fine.exe application directory.
-> No manifest file (either embedded or text).
Is it possible your problem program is using DLL Redirection?
From the LoadLibrary documentation (emphasis added) ...
If a path is specified and there is a redirection file for the application, the function searches for the module in the application's directory. If the module exists in the application's directory, LoadLibrary ignores the specified path and loads the module from the application's directory. If the module does not exist in the application's directory, LoadLibrary loads the module from the specified directory. For more information, see Dynamic Link Library Redirection.
Update 6/4/2018
Here's what I think is happening.
Both of your programs are using load-time dynamic linking (sometimes called implicit linking) to link to a DLL called name.dll. I'm assuming both programs just specify name.dll without a full path name. If you want to check I think you can run dumpbin /imports against fine.exe and own.exe to examine the DLL name.
fine.exe
In the case of the program that does what you expect (loads the second name.dll from \Windows\System32) there's no DLL redirection involved so the standard DLL Search Order is followed during the implicit link. The application directory is searched before the system directory so your copy of name.dll gets loaded.
Then your name.dll executes a LoadLibrary call specifying a full path to the file C:\Windows\System32\name.dll. Since there's no redirection going on, the system directory version of name.dll gets loaded as you expect.
own.exe
In the case of the program that doesn't do what you expect (gets a handle to your own version of name.dll twice) there is DLL redirection going on because you have a directory called own.exe.local in the application folder. Since there's redirection going on, during the implicit link the standard search order is ignored and name.dll is loaded from own.exe.local.
Then your name.dll executes a loadlibrary call specifying a full path to the file C:\Windows\System32\name.dll. But this time there is redirection going on. The full path specified in the LoadLibrary call is ignored and the module is loaded from the redirection folder own.exe.local.
Since that copy of name.dll has already been loaded by the implicit linking you just get another handle to the module.
As was pointed out in the comments, the GetLastError result is misleading. The LoadLibrary call didn't return NULL (it returned a handle to your own name.dll) so the value returned by GetLastError doesn't apply to the LoadLibrary call.

Is using an absolute path to load system DLLs with LoadLibrary() and GetModuleHandle() better to prevent DLL hijacking?

In many cases to load some newer API one would use a construct as such:
(FARPROC&)pfnZwQueryVirtualMemory = ::GetProcAddress(::GetModuleHandle(L"ntdll.dll"), "ZwQueryVirtualMemory");
But then, considering a chance of Dll hijacking, is it better to specify a DLL's absolute path, as such. Or is it just an overkill?
WCHAR buff[MAX_PATH];
buff[0] = 0;
if(::GetSystemDirectory(buff, MAX_PATH) &&
::PathAddBackslash(buff) &&
SUCCEEDED(::StringCchCat(buff, MAX_PATH, L"ntdll.dll")))
{
(FARPROC&)pfnZwQueryVirtualMemory = ::GetProcAddress(::GetModuleHandle(buff), "ZwQueryVirtualMemory");
}
else
{
//Something went wrong
pfnZwQueryVirtualMemory = NULL;
}
The problem with the latter method is that it doesn't always work (for instance with Comctl32.dll.)
You don't have to do anything special for ntdll.dll and kernel32.dll because they are going to be loaded before you get the chance to do anything, they are also on the known-dlls list.
The dll hijacking issues often include auxiliary libraries. Take version.dll for example, it is no longer on the known-dlls list so explicitly linking to it is problematic, it needs to be loaded dynamically.
The best solution is a combination of 3 things:
Call SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32) if it is available (Win8+ and updated Win7).
Call LoadLibrary with the full path (GetSystemDirectory) before calling GetModuleHandle.
Don't explicitly link to anything other than kernel32, user32, gdi32, shlwapi, shell32, ole32, comdlg32 and comctl32.
If SetDefaultDllDirectories is not available then it is really hard to protect yourself if you don't control the application directory because various Windows functions will delay-load dlls like shcore.dll without full paths (especially the shell APIs). SetDllDirectory("") helps against the current/working directory but there is no good application directory workaround for unpatched pre-Win8 systems, you just have to test with Process Monitor and manually load the problematic libraries early in WinMain.
The application directory is a problem because some users just put everything in the downloads folder and run it from there. This means you might end up with a malicious dll in your application directory.

dll loading error using LoadLibraryA

We are trying to load a dll-library from inside a 64-bit dll using LoadLibraryA function. It returns 126 error - mod not found. The dll file path given to the function is correct, we are sure.
We have tried a dummy dll to test and it worked, it is loaded.
We also tried adding the dll (which is a dependcy of the first dll that we want to load) to the dummy dll. It also worked. So the problem seems not about the dependency dlls, but the original dll that we want to load in the first place.
We also tried converting the dl to 64-bit, and tried that, still no good.
We also checked the dependencies with Dependency Walker. Everything is OK.
The operating system that we are using is Windows 8, 64bit. If it makes any difference..
Does anyone have any idea about this poblem?
EDIT:
We also tried this code:
hModule = LoadLibraryW(L"C:\\temp\\dllToLoad.dll");
and received this error code:
"First-chance exception at 0x00000000 in C_Test_TSMPPKCS11.exe: 0xC0000005: Access violation at location 0x0000000000000000."
EDIT 2:
The code that we used in the first place is:
hModule = LoadLibraryA((char*)aDLLFile);
EDIT 3:
We are using complete path to load the dll. In order to test this we tried this code:
FILE *fp;
int size = 0;
fp=fopen("C:\\temp\\dllToLoad.dll", "r");
size = fgetc(fp);
printf("size:%d\n",size);
fclose(fp);
There was no problem, we received the file size which is 77.
We also tried converting the dl to 64-bit, and tried that, still no good.
There's no way you can load a 32-bit dll as executable code into a 64-bit process (and since you're using LoadLibraryA() that's all you can be trying to do).
Assuming the dll that you are trying to load and the process that you're loading it into are the same type then are you passing a complete path to LoadLibraryA() or a relative path or just a dll name? If you're not using a complete path then consider using LoadLibraryEx() if possible as this gives you much more control over the search path used. If you are using a complete path try opening the file using normal file operations if you fail to load the dll, does this work? If that works then try LoadLibraryEX() with LOAD_LIBRARY_AS_DATAFILE and see if that will load the dll as a simple data file (which proves that it's finding the file).
Run up Sysinternal's ProcMon and watch the code open the DLL, that may show you dependent DLL load failures.

CreateProcess STATUS_DLL_NOT_FOUND - which dll?

I have a process which calls CreateProcess. It appears that CreateProcess returns nonzero indicating success. However, the HANDLE to the process then gets immediately set, indicating the process has exited. When I call GetExitCodeProcess, STATUS_DLL_NOT_FOUND is then returned.
I understand that a DLL is missing. I even know exactly which one. However, what I don't understand is how to figure that out programmatically.
I noticed that Windows will present a dialog saying that the process failed to start because it couldn't find the specified DLL (screenshot: http://www.mediafire.com/view/?kd9ddq0e2dlvlb9 ). In the dialog, Windows specifies which DLL is missing. However, I find no way to get that information myself programmatically.
If a process fails to start and would return STATUS_DLL_NOT_FOUND, how do I programmatically retrieve the library name to which the target process was linked which couldn't be found? That way I can automatically record in an error report what DLL appears to be missing or corrupt in a given installation.
CreateProcess returns 0 indicating success.
CreateProcess() returns a BOOL, where 0 is FALSE, aka failure not success.
If a process fails to start and would return STATUS_DLL_NOT_FOUND, how do I programmatically retrieve the library name to which the target process was linked which couldn't be found?
Unfortunately, there is no API for that. Your only option would be to manually access and enumerate the executable's IMPORTS table to find out what DLLs it uses, and then recursively access and enumerate their IMPORTS tables, manually checking every DLL reference you find to see whether that DLL file exists on the OS's search path or not.
If the dll is statically linked you can walk the iat and see if the dll exists. If the dll is dynamically loaded then starting the process suspended and hooking LoadLibrary (or instead of hooking emulate a debugger) is the only way I see.
The best way is to use loader snaps. Basically you use gflags.exe (which is included with windbg) to enable loader snaps; then, run the process with the debugger attached. Loader snaps will enable the loader to print out dbg messages of the process and it will print the failures.
gflags.exe -i yourcode.exe +sls
windbg yourcode.exe
I know this is not a "programmatic" way to find out the problem, but what the loader does is complicated, and you don't really want to be redoing its logic to find the failure. That is why loader snaps were invented.
The very hard way would be: Parsing the .EXE and .DLL files and create the dependency tree of .DLL files.
I don't think there is a way to get a list of DLL files that are missing: When Windows finds one missing DLL file it stops loading so if one DLL file is missing you won't find out if more DLL files are missing.
Another problem you could have is that old DLL versions could have missing "exports" (functions). This is even harder to detect than the dependency tree.
Just since this is somehow the top stackoverflow result on Google for "STATUS_DLL_NOT_FOUND". How to trace and solve any random occurence:
Download SysInternals procmon64.exe (or just the entire set). After startup immediately hit the looking glass 'Stop capture' button (Ctrl+E). And 'Clear' (Ctrl+X).
Set filters for:
'Process name' is to whatever the mentioned process name was (for me it was 'build-script-build.exe') [Add]
'Result' is not 'SUCCESS' [Add]
'Path' ends with '.dll' [Add] [OK]
Start capture again (Ctrl+E).
Run the thing that had a problem again (for me: build cargo). Google for the last listed DLL file.
For me that was VCRUNTIME140.dll, so I installed the VC++ 2015 to 2019 redistributable.
ProcMon is kind of like unix strace.

Listing all LoadLibrary and GetProcAddress calls in a PE file

I need a sample code/tools which parses the PE file and lists all LoadLibrary and GetProcAddress calls. Along with that I also need the DLL name passed to LoadLibrary and function name passed to each of the listed GetProcAddress calls.
There is no way to statically check for the calls made to LoadLibrary/GetProcAddress.
To get a list of imports and exports from the PE file statically, use PEDUMP (or you can use this online utility: http://pedump.me).
To profile an application for LoadLibrary/GetProcAddress you'll want something like WinDbg. Attach WinDbg to the process you want to profile and put a breakpoint on LoadLibrary/GetProcAddress. You'll then be able to see the parameter. For example:
bp kernel32!LoadLibraryA "da poi(esp+4); g;"
will print out all calls to LoadLibraryA as they happen.
You can also use Dependency walker. This tool shows the all types (implicit, delay-loaded, forwarded) dependencies. Using this tool you can even test the dynamic dependencies (the ones that are made by invoking LoadLibrary/GetProcAddress)! To make the later, you must run Dependency walker in profiling mode.
In some cases on 64-bit Windows you won't be able to use Dependency Walker. In that case use this in WinDbg:
bu KERNELBASE!LoadLibraryExW "du/c100 rcx;g;"