Firefox pr_write hook. dll injection, windows hooks - c++

The problem was that the DLL which contains PR_Write() is called not npsr4.dll, but nss3.dll and hooks couldn't find GetProcAddress() from non-existing library.
I'm trying to create Firefox hook, which collects data from the PR_Write() Firefox method (it is located in nspr4.dll).
I googled much and tried many ways to do that, but unfortunately when I inject the hook, Firefox crashes.
Firstly, I tried not to use DLL, using this method http://redkiing.wordpress.com/2012/04/30/firefox-formgrabber-iii-code-injection/ (source at the beginning of the article) Firefox crashed at CreateRemoteProcess()*
I read that CreateRemoteProcess() doesn't work on Win7 because of security issues. I decided to use this method: http://syprog.blogspot.com/2012/05/createremotethread-bypass-windows.html But it didn't even load my DLL. (source at the beginning of the article)
Then I decided to inject the DLL with SetWindowsHookEx(). DLL worked, I used test MessageBox to check that (but I'm not sure if I specified the last parametr of SetWindowsHookEx() correctly).
I've found Chrom library with Firefox example (I cannot post more than 2 links but google: "chrom-lib"). I applied the code to my DLL, but when I inject it, Firefox crashes.
I don't know ASM, stack and memory managment well and I have no idea what is wrong and how to fix it. I only know I should use asm jump hook, but how?. I need a ready-to-use code :/
Maybe there is a way to get pr_write() address, then get its call stack (function arguments) and use them to call my own function? Or maybe I should try with "API Hooking with MS Detours" (again I cannot post link :< )
What should I do?
EDIT I nocticed that there is no npsr4.dll on my computer. So how does Firefox build HTTP request without this lib?
Current DLL code (Chrom-based with VirtualProtect() usage)
#define SIZE 6
struct Hook{
DWORD original_function;
DWORD destination_function;
BYTE original_bytes[SIZE];
BYTE JMP_instruction[SIZE];
DWORD original_protection, new_protection;
Hook(){
original_protection= PAGE_EXECUTE_READWRITE;
new_protection = PAGE_EXECUTE_READWRITE;
}
~Hook(){
memcpy((void*) original_function, original_bytes, SIZE);
}
int Initialize(char * function, char * module_name, void * destination_function_ptr)
{
original_function = (DWORD)GetProcAddress(GetModuleHandle(module_name),
function);
destination_function = (DWORD) destination_function_ptr;
if (original_function==NULL){
return FALSE;}
return TRUE;
}
int Start()
{
BYTE JMP_temporary[SIZE] = {0xE9, 0x90, 0x90, 0x90, 0x90, 0xC3};
memcpy(JMP_instruction, JMP_temporary, SIZE);
DWORD JMP_size = ((DWORD)destination_function - (DWORD)original_function - 5);
VirtualProtect((LPVOID)original_function, SIZE, PAGE_EXECUTE_READWRITE, &original_protection);
MessageBox(NULL,"Works", ":D",0);
memcpy(original_bytes,(void*)original_function, SIZE);
memcpy(&JMP_instruction[1], &JMP_size, 4);
memcpy((void*)original_function, JMP_instruction, SIZE);
VirtualProtect((LPVOID)original_function, SIZE, original_protection, NULL);
return TRUE;
}
int Reset(){
VirtualProtect((LPVOID)original_function, SIZE, new_protection, NULL);
memcpy((void*)original_function, original_bytes, SIZE);
return TRUE;
}
int Place_Hook(){
memcpy((void*)original_function, JMP_instruction, SIZE);
VirtualProtect((LPVOID)original_function, SIZE, original_protection, NULL);
return TRUE;
}
};
//...
Hook Firefox; // use chrom library
DWORD PR_Write_H (DWORD *fd, void *buf,DWORD amount); // this is our overiding-function
typedef DWORD (*prWrite)(DWORD*,void*,DWORD); // defination of our original function
prWrite prw = NULL; // create a orginal function, we later point this to orginal function
// address
// example test function
int write_log(char * log, char * data)
{
ofstream fout("D:\\log2.txt", ios::app);fout << data;fout.close();
return TRUE;
}
void create_hooks() //this is called when DLL is initialized
{
// Override PR_Write function in nspr4.dll with our PR_Write_H,
// Note nspr4.dll must already be
// loaded in process space
Firefox.Initialize("PR_Write", "nspr4.dll", PR_Write_H);
// Write jump instruction on orginal function address
Firefox.Start();
}
// our overriding function
DWORD PR_Write_H (DWORD *fd, void *buf,DWORD amount){
// reset hooks, this will replace the jump instruction to original data
Firefox.Reset();
// point prw(function) to original function
prw = (prWrite)Firefox.original_function;
// log the headers
write_log(log_file, (char*) buf);
// call the real PR_Write function
DWORD ret = prw(fd, buf, amount);
// again place the jump instruction on the original function
Firefox.Place_Hook();
return ret;
}
*I'm using Win8 x64 but the hook must work at Vista/Win7/Win8 32 and 64 bit! I also tested it at Win7 x86 laptop. I compile with Visual Studio 2012

Here are the basic steps I use when injecting a dll:
1) You use OpenProcess in order to gets Firefox's process HANDLE
2) You allocate memory for the path of your dll using VirtualAllocEx into Firefox's process
3) You write the dll path into this allocated space using WriteProcessMemory
4) You get the HANDLE of the dll kernel32.dll using GetModuleHandleA. This one should be present in every windows's process. kernel32.dll contains window's core API stuff.
5) In this kernel32.dll you will find the function LoadLibrary that will help you loading your dll. Get its address with GetProcAddress.
6) Now you have all the keys to create a new remote thread that will load your dll into Firefox's process.
You just call CreateRemoteThreadEx with lpStartAddress pointing to the address of LoadLibrary and lpParameter to your dll path string.
7) Enjoy your injected dll.
Now that your dll is in the process memory, you can start to hook. Here are two basic ways:
- On the Import Address Table (IAT):
The import address table is table that contain the address of each external functions use by your module/process.
In your case you want to change the address of PR_Write by the address of your manually created function. You must remove the memory page protection of the IAT using VirtualProtect. Now you can freely override the adress by your own.
- Override parts of the process code to make it jump in your functions:
Using VirtualProtect, you once against remove the protection on the code parts you need.
You then change the current instructions by the opcode of CALL or JUMP pointing to your function. The overrided instructions MUST be rewritten at the beginning of your function in order to keep the real flow intact. After your hook function, you must jump back after the overrided instruction.
All these hooks tricks may need a intermediate function called a trampoline. This function may have to save the registers and load them back later. It can also ensure that the calling conventions are respected.
When dealing with hooks, I would suggest to learn assembly and how to use debugging tools like OllyDbg.

Related

winapi - find DLL path from file name [duplicate]

If I do
LoadLibrary("MyTest.dll")
Windows will locate and load it from "C:\TestFolder\Test\MyTest.dll", because "C:\TestFolder\Test\" is in %PATH% folder.
How can I emulate same function? I need to locate C:\TestFolder\Test\MyTest.dll (C:\TestFolder\Test\ is in %PATH%) by passing MyTest.dll as an argument to a function. Is there such an API? or a function?
P.S. I can't do LoadLibrary and then GetModuleHandle and finding Path, sometimes this DLL could be malicious DLL and I can't load it. So I need to find PATH without having to load it.
To load the DLL without running any malicious code inside, use LoadLibraryEx with the DONT_RESOLVE_DLL_REFERENCES and LOAD_LIBRARY_AS_DATAFILE flags.
Then you can use GetModuleFileName.
You should also read about all the other flags, which allow you to perform all the various searches Windows is capable of.
The accepted answer to this question will not work in all scenarios. More specifically, using GetModuleFileName together with LOAD_LIBRARY_AS_DATAFILE will only work if the library was already loaded prior without this flag. For example, it will work for a library like KERNEL32.DLL which is already loaded by the process, but it will not work with your own library being loaded into the process for the first time.
This is because, to quote The Old New Thing, a library loaded via LOAD_LIBRARY_AS_DATAFILE (or similar flags) doesn't get to play in any reindeer module games.
If you load a library with the LOAD_LIBRARY_AS_DATA­FILE flag, then it
isn’t really loaded in any normal sense. In fact, it’s kept completely
off the books. If you load a library with the
LOAD_LIBRARY_AS_DATA­FILE, LOAD_LIBRARY_AS_DATA­FILE_EXCLUSIVE, or
LOAD_LIBRARY_AS_IMAGE_RESOURCE flag (or any similar flag added in the
future), then the library gets mapped into the process address space,
but it is not a true module. Functions like Get­Module­Handle,
Get­Module­File­Name, Enum­Process­Modules and
Create­Toolhelp32­Snapshot will not see the library, because it was
never entered into the database of loaded modules.
At that point, you might as well just use GetModuleHandle, since it'll only work with previously loaded libraries. Obviously not ideal, and doesn't actually answer the question of getting the path without executing DllMain.
What about the other flag, DONT_RESOLVE_DLL_REFERENCES? Well, technically yes it will work. However, you'll notice in the Microsoft documentation the following note.
Do not use this value; it is provided only for backward compatibility.
If you are planning to access only data or resources in the DLL, use
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE or LOAD_LIBRARY_AS_IMAGE_RESOURCE
or both.
The flag is only provided for backwards compatibility, and that is for good reason. To quote The Old New Thing a second time, DONT_RESOLVE_DLL_REFERENCES is a time bomb.
It is common for somebody to call GetModuleHandle to see if a DLL is
loaded, and if so, use GetProcAddress to get a procedure address and
call it. If the DLL had been loaded with DONT_RESOLVE_DLL_REFERENCES,
both the GetModuleHandle will succeed, but the resulting function will
crash when called. The code doing this has no idea that the DLL was
loaded with DONT_RESOLVE_DLL_REFERENCES; it has no way of protecting
itself.
Other threads will see the library is loaded. If they attempt to use the loaded library, as would be entirely normal to do, they will crash the program because it has not actually been initialized. So this flag, while it does work with GetModuleFileName, will cause instability in the program. Still not ideal.
So then, if we can't use DONT_RESOLVE_DLL_REFERENCES or LOAD_LIBRARY_AS_DATAFILE with GetModuleFileName, then what is the solution? Well, the solution is to not use GetModuleFileName - and instead use GetMappedFileName.
At this point, if you know what GetMappedFileName does, you may be confused. Normally, GetMappedFileName is used to get a filename from a File Mapping, created with the File Mapping API. Well, the secret is that under the hood, image loading is accomplished with MapViewOfFile. This is subtly hinted at by the Dbghelp documentation - for example, the ImageNtHeader documentation which states an image base must be...
The base address of an image that is mapped into memory by a call to
the MapViewOfFile function.
This means that not only is a module handle a pointer to a module, but also a mapped file pointer. Unlike GetModuleFileName however, GetMappedFileName has no concept of "the reindeer module games," so it works even with the LOAD_LIBARY_AS_DATAFILE flag of LoadLibraryEx. Not only that, but GetMappedFileName has an additional benefit over GetModuleFileName.
Something you might not know is that simply loading a library with LoadLibrary does not exclusively lock the DLL file. Try it yourself: write a simple program which loads your own library with LoadLibrary, and then while the program is running, cut and paste the DLL file to a different location. This will work (and yes, has always worked regardless of Windows version) so long as no other application has a lock on the DLL file. The File Mapping API just keeps on chugging, regardless of the DLL file's new location.
However, when you call GetModuleFileName, it will always return the path of the DLL file as of whenever the library was loaded with LoadLibrary. This has security ramifications. It would be possible to cut and paste the DLL file to a new location, and put a different one at the old location. If the path returned by GetModuleFileName is used to load the library again, it could actually result in loading a different DLL file altogether. As such, GetModuleFileName is only useful for the purpose of displaying the name or getting the DLL file name passed to LoadLibrary, and can't be depended upon for the current file path.
GetMappedFileName has no such issue, because it has no concept of when LoadLibrary was called. It returns an up to date path to the file, even if it has been moved while it's loaded.
There is one minor downside though: GetMappedFileName returns a device path, in the format of \Device\HarddiskVolume1\Example.DLL. This appears to be due to the File Mapping API originally being from DOS - why a "GetMappedFileNameEx" that returns a drive path doesn't exist is beyond me.
Thankfully, it's a resolvable issue. We can use QueryDosDevice to turn the device path into a drive path.
bool getFilePathNameFromMappedView(HANDLE process, LPVOID mappedView, std::string &filePathName) {
if (!process) {
return false;
}
if (!mappedView) {
return false;
}
CHAR mappedFileName[MAX_PATH] = "";
if (!GetMappedFileName(process, mappedView, mappedFileName, MAX_PATH - 1)) {
return false;
}
// the mapped file name is a device path, we need a drive path
// https://learn.microsoft.com/en-us/windows/win32/fileio/defining-an-ms-dos-device-name
const SIZE_T DEVICE_NAME_SIZE = 3;
CHAR deviceName[DEVICE_NAME_SIZE] = "A:";
// the additional character is for the trailing slash we add
size_t targetPathLength = 0;
CHAR targetPath[MAX_PATH + 1] = "";
// find the MS-DOS Device Name
DWORD logicalDrives = GetLogicalDrives();
do {
if (logicalDrives & 1) {
if (!QueryDosDevice(deviceName, targetPath, MAX_PATH - 1)) {
return false;
}
// add a trailing slash
targetPathLength = strnlen_s(targetPath, MAX_PATH);
targetPath[targetPathLength++] = '\\';
// compare the Target Path to the Device Object Name in the Mapped File Name
// case insensitive
// https://flylib.com/books/en/4.168.1.23/1/
if (!_strnicmp(targetPath, mappedFileName, targetPathLength)) {
break;
}
}
deviceName[0]++;
} while (logicalDrives >>= 1);
if (!logicalDrives) {
return false;
}
// get the drive path
filePathName = std::string(deviceName) + "\\" + (mappedFileName + targetPathLength);
return true;
}
GetLogicalDrives just gets a list of which drives are available (like C:, D:, etc.) in the form of a bitmask (where the first bit corresponds to A:, the second bit corresponds to B:, etc.) We then loop through the available drives, getting their paths, and comparing them against the one in the Mapped File Name. The result of this function is a path that could be passed to the CreateFile function.
The only source I could find for whether these device paths are case-insensitive or not was this book claiming that they used to be case-sensitive, but are case-insensitive as of Windows XP. I'm going to assume you are not targeting Windows 9x anymore, so I just compare them case-insensitively.
Hold on a second though: this still may not be enough. If your intention is, as mine was, to try and get a file handle to the DLL file, but using the DLL search path, then just getting the path and passing it to CreateFile opens us up to a filesystem race condition, like the kind explained in this LiveOverflow video. A technique like this could be abused by a hacker so the handle doesn't actually point to the file we want. There isn't any GetMappedFileHandle function, so what can we do?
I thought about this for a while, and here is the workaround I came up with. The idea is that we call our own getFilePathNameFromMappedView function once just to get the path to pass to CreateFile, and exclusively lock the file in place with the FILE_SHARE_READ flag. However, we then confirm, with a second call to getFilePathNameFromMappedView, that the file is still actually there. If the paths match, knowing that the file at that path is now locked, we can know for sure the handle we got is to the library that was actually loaded. If the file was moved before the call to CreateFile finished, however, the paths will not match, because GetMappedFileName returns the up to date path to the file. At that point, we can try again. I decided to do this as a recursive function, but you could decide to throw an error and have the caller handle it.
inline bool stringsCaseInsensitiveEqual(const char* leftHandSide, const char* rightHandSide) {
return !_stricmp(leftHandSide, rightHandSide);
}
bool getHandleFromModuleHandle(HMODULE moduleHandle, HANDLE &file) {
if (!moduleHandle) {
return false;
}
HANDLE currentProcess = GetCurrentProcess();
// pass the Module Handle as a Mapped View
// to get its current path
std::string filePathName = "";
if (!getFilePathNameFromMappedView(currentProcess, moduleHandle, filePathName)) {
return false;
}
// prevent the Example File from being written to, moved, renamed, or deleted
// by acquiring it and effectively locking it from other processes
file = CreateFile(filePathName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (!file || file == INVALID_HANDLE_VALUE) {
return false;
}
bool recursive = false;
{
// we now know this path is now protected against race conditions
// but the path may have changed before we acquired it
// so ensure the File Path Name is the same as before
// so that we know the path we protected is for the Mapped View
std::string _filePathName = "";
if (!getFilePathNameFromMappedView(currentProcess, moduleHandle, _filePathName)) {
goto error;
}
if (!stringsCaseInsensitiveEqual(filePathName.c_str(), _filePathName.c_str())) {
// race condition occured
recursive = true;
goto error;
}
}
return true;
error:
if (file && file != INVALID_HANDLE_VALUE) {
if (!CloseHandle(file)) {
return false;
}
file = NULL;
}
if (recursive) {
return getHandleFromModuleHandle(moduleHandle, file);
}
return false;
}
Then we can call it like this...
HMODULE exampleModuleHandle = LoadLibraryEx("Example.DLL", NULL, LOAD_LIBRARY_AS_DATAFILE);
if (!exampleModuleHandle) {
return false;
}
// we want this to be a handle to the Example File
HANDLE exampleFile = NULL;
if (!getHandleFromModuleHandle(exampleModuleHandle, exampleFile)) {
return false;
}
This is just something I thought of, so let me know in the responses if there are issues with it.
Once you have a handle to the file, it can then be passed to GetFileInformationByHandle to confirm it is the same library as is loaded in another process, and subsequently closed with CloseHandle.

How do I detect a module loaded using LoadLibraryEx

I need to use a windows function like GetModuleHandle or GetModuleFileName to find out if a specific dll is loaded in the same process where my code is executing.
One module I'm looking for is System.Windows.Forms.dll, but even when it is loaded in process... (Here you can see it using Process Explorer)
GetModuleHandle still will not find it!
HMODULE modHandle = GetModuleHandle(L"System.Windows.Forms.dll");
GetLastError() returns ERROR_MOD_NOT_FOUND
If the function succeeds, the return value is a handle to the specified module.
If the function fails, the return value is NULL.
I think it may be something to do with how the CLR loads these dlls. I see a note on LoadLibraryEx that if the LOAD_LIBRARY_AS_DATAFILE flag is used then:
If this value is used, the system maps the file into the calling
process's virtual address space as if it were a data file. Nothing is
done to execute or prepare to execute the mapped file. Therefore, you
cannot call functions like GetModuleFileName, GetModuleHandle or
GetProcAddress with this DLL.
Maybe this is my problem, but regardless of the cause - does anyone know a way to find a managed DotNet dll in a process using native / c++ code?
Thanks!
EDIT:
Based on suggestions from Castorix in the comments I tried to use EnumProcessModules:
HMODULE modules[100];
void* hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, GetCurrentProcessId());
if (hProcess)
{
DWORD bytesNeeded;
BOOL rc = EnumProcessModules(hProcess, modules, sizeof(modules), &bytesNeeded);
if (rc)
{
int count = (int)(bytesNeeded / sizeof(HMODULE));
for (int i = 0; i < count; i++)
{
wchar_t moduleName[260];
GetModuleFileName(modules[i], moduleName, 260);
}
}
}
CloseHandle(hProcess);
This code finds a lot of the modules but not System.Windows.Forms.dll
OK, this is an attempt to an answer (or really just a too long comment, sorry).
Personally, I have never seen managed .NET DLLs in the Process Explorer pane, but might not have been looking hard / often enough. However, what I can (and always could) see are the NGENed images (*.ni.dll).
Note also the presence of System.Data.dll here, which is not NGENed, but is a mixed mode assembly and contains native code as well as managed code.
So one could conclude, that you can only see NGENed and mixed mode "assemblies" here, because they are still loaded by LoadLibrary or LoadLibraryEx.
Also note my comment, which I reproduce here for easier access:
I think the CLR does not use LoadLibrary, which would explain why you
cannot "see" them using the APIs you described. In fact,
CLR 4 Does Not Use LoadLibrary to Load Assemblies
is a blog entry that is relevant. You could always check the sources
(CoreCLR, but shouldn't matter), about how it is done in particular. I
have no really good place, but you could start
here
and then go from it. Use the ICorDebug interface instead.
Here are some relevant quotes from the blog entry linked above:
You may be asking yourself: …who cares? Well, first of all it’s good
to know. I haven’t noticed a public service announcement to the above.
It is an implementation detail, however—CLR assemblies are not even
guaranteed to be implemented using files, not to mention DLL files in
a specific format that are loaded using the LoadLibrary Win32 API.
However, there are several tools and scenarios which have come to rely
on the fact the CLR loads assemblies using LoadLibrary. For example,
up to CLR 4, if you wanted to know which .NET assemblies were loaded
in your process, a fairly reliable heuristic would be to fire up
Sysinternals Process Explorer and look at the DLLs view of a given
process. This doesn’t work for CLR 4, as you can see here:
Frankly, I don't know how Process Explorer manages to show assemblies (not NGENed and not mixed mode) in your case - appart from you are watching a CLR2 process. However, mind you that PE does not only use Win32 APIs. It also uses WMI and probably also uses the CLR directly for more information. For example, the "Process Properties/.NET Assemblies" and "Process Properties/.NET Performance" tabs most likely use ICorDebug/ICorProfile and performance counters/ETW respectively.
You might need to use on of those interfaces as well, or something else from the unmanaged Debugging API or the unmanaged API in general.
Whatever it is, I don't think that EnumProcessModules, etc. will get you there for reasons above.
To add to the above answer and provide relevant code; it was not possible to use a native function like EnumProcessModules to detect the non-ngen'ed DotNet dlls and instead I had to use c++ interfaces to the CLR.
There is a lot more info here: https://blogs.msdn.microsoft.com/calvin_hsia/2013/12/05/use-reflection-from-native-c-code-to-run-managed-code/ The code most relevant to this particular question was:
HRESULT GetAssemblyFromAppDomain(_AppDomain* pAppDomain, LPCWSTR wszAssemblyName, _Deref_out_opt_ _Assembly **ppAssembly)
{
*ppAssembly = NULL;
// get the assemblies into a safearray
SAFEARRAY *pAssemblyArray = NULL;
HRESULT hr = pAppDomain->GetAssemblies(&pAssemblyArray);
if (FAILED(hr))
{
return hr;
}
// put the safearray into a smart ptr, so it gets released
CComSafeArray<IUnknown*> csaAssemblies;
csaAssemblies.Attach(pAssemblyArray);
size_t cchAssemblyName = wcslen(wszAssemblyName);
long cAssemblies = csaAssemblies.GetCount();
for (long i=0; i<cAssemblies; i++)
{
CComPtr<_Assembly> spAssembly;
spAssembly = csaAssemblies[i];
if (spAssembly == NULL)
continue;
CComBSTR cbstrAssemblyFullName;
hr = spAssembly->get_FullName(&cbstrAssemblyFullName);
if (FAILED(hr))
continue;
// is it the one we want?
if (cbstrAssemblyFullName != NULL &&
_wcsnicmp(cbstrAssemblyFullName,
wszAssemblyName,
cchAssemblyName) == 0)
{
*ppAssembly = spAssembly.Detach();
hr = S_OK;
break;
}
}
if (*ppAssembly == 0)
{
hr = E_FAIL;
}
return hr;
}
There's some information on the CLR interfaces here:
ICLRMetaHost
ICLRRuntimeInfo
ICorRuntimeHost
_AppDomain
_Assembly

LoadLibrary() : How to handle invalid DLLs?

I have an application that relies heavily on plugins.
On startup it scans a directory for DLLs and loads them one by one, looking for ones that implement a certain exported function. However - if someone were to rename a different type of file to *.dll and put it in the directory, that file would then also be loaded by LoadLibrary(). LoadLibrary() doesn't like that and produces an error [dialog].
Is there a way to simply ignore invalid / incompatible .dll files (either detecting them prior to the call or have LoadLibrary() return NULL rather than throwing a fit)?
You need to set the error mode for your process. Do this once and for all at startup:
UINT oldMode = SetErrorMode(0);
SetErrorMode(oldMode | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
After you've set the process error mode, when LoadLibrary fails no dialog box will be displayed and LoadLibrary will return NULL.
The documentation says:
Best practice is that all applications call the process-wide SetErrorMode function with a parameter of SEM_FAILCRITICALERRORS at startup. This is to prevent error mode dialogs from hanging the application.
I also recommend adding SEM_NOOPENFILEERRORBOX for reasons that I guess should be obvious.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175%28v=vs.85%29.aspx
Remarks
To enable or disable error messages displayed by the loader during DLL loads, use the SetErrorMode function.
Don't forget to restore the error mode after you are finished.
If you wanted to do this yourself, in a primitive manner you could parse the PE header to identify obvious cases of bad DLL files, however it is not really possible to determine if a DLL is valid and loadable without a full PE loader which requires a lot of work and is already built into the operating system.
Updated answer after feedback in comments from djgandy and Remy Lebeau. Now a complete
function, better preservation of error mode at entry:
// This function will load the DLL named by pszPath if it is a valid library.
// If the function succeeds, it will return a valid HMODULE for the DLL. This
// handle should be passed to FreeLibrary when it is no longer needed.
// If the function fails, it will return NULL and no annoying dialog boxes will
// be displayed. It is therefore up to the caller to notify the user about what
// happened or take any other appropriate action. The reason for failure can
// be obtained from GetLastError(). Common problems:
// ERROR_BAD_EXE_FORMAT - Bad DLL (tested function with text file)
// ERROR_MOD_NOT_FOUND - Missing DLL (tested with file that did not exist)
//
// Module-loading functions can return several other errors, look at winerror.h
// list starting at ERROR_INVALID_MODULETYPE
//
// Obviously, since it's just a wrapper around LoadLibrary this function is not
// safe to call from DllMain.
//
// NB: GetErrorMode() is only available on Vista / Server 2003 or later.
HMODULE LoadLibraryIfValid(LPCTSTR pszPath)
{
HMODULE hModule = NULL;
UINT prevErrorMode = GetErrorMode();
SetErrorMode(prevErrorMode | SEM_FAILCRITICALERRORS);
hModule = LoadLibrary(pszPath);
SetErrorMode(prevErrorMode);
return hModule;
}
If targeting Windows 7 / Server 2008 R2 or later, the Get/SetThreadErrorMode()
functions are available, but might not be worth it or even a good alternative
(discussion in comments, below)
If anyone cared enough to put the time into it (I sure don't), a version of
this function could easily be written using GetModuleHandle for kernel32 and
GetProcAddress to be compatible with earlier versions of Windows as well as
provide a global/per-thread error mode option for platforms that support it
(truly pointless because it's only changed for the duration of one call anyway).
This is the largest commentary-to-code ratio in my life.

Remote thread is failing on call to LoadLibrary with error 87

I am tring to create a Remote thread that will load a DLL I wrote, and run a function from it.
The DLL is working fine (Checked) but from some reason, the Remote thread fails and the proccess in which it was created stop responding.
I used ollyDebug to try and see what is going wrong and I noticed two things...
My strings (dll name and function name) are passed to the remote thread correctly
The thread fails on LoadLibrary with lasterror code 87 "ERROR_INVALID_PARAMETER"
My best guess is that somehow, The remote thread can't find LoadLibrary (Is this because the linker is done with repspect to my proccess???, Just a guess...)
What am I doing wrong?
This is the code to the remote function:
static DWORD WINAPI SetRemoteHook (DATA *data)
{
HINSTANCE dll;
HHOOK WINAPI hook;
HOOK_PROC hookAdress;
dll = LoadLibrary(data->dll);
hookAdress = (HOOK_PROC) GetProcAddress(dll,data->func);
if (hookAdress != NULL)
{
(hookAdress)();
}
return 1;
}
Edit:
This is the part in which I allocate the memory to the remote proccess:
typedef struct
{
char* dll;
char* func;
} DATA;
char* dllName = "C:\\Windows\\System32\\cptnhook.dll";
char* funcName = "SetHook";
char* targetPrgm = "mspaint.exe";
Data lData;
lData.dll = (char*) VirtualAllocEx( explorer, 0, sizeof(char)*strlen(dllName), MEM_COMMIT, PAGE_READWRITE );
lData.func = (char*) VirtualAllocEx( explorer, 0, sizeof(char)*strlen(funcName), MEM_COMMIT, PAGE_READWRITE );
WriteProcessMemory( explorer, lData.func, funcName, sizeof(char)*strlen(funcName), &v );
WriteProcessMemory( explorer, lData.dll, dllName, sizeof(char)*strlen(dllName), &v );
rDataP = (DATA*) VirtualAllocEx( explorer, 0, sizeof(DATA), MEM_COMMIT, PAGE_READWRITE );
WriteProcessMemory( explorer, rDataP, &lData, sizeof(DATA), NULL );
Edit:
It looks like the problem is that the remote thread is calling a "garbage" address
instead of LoadLibrary base address. Is there a possibily Visual studio linked
the remote proccess LoadLibrary address wrong?
Edit:
when I try to run the same exact code as a local thread (I use a handle to the current procces in CreateRemoteThread) the entire thing works just fine. What can cause this?
Should I add the calling function code? It seems to be doing its job as
the code is being executed in the remote thread with the correct parameters...
The code is compiled under VS2010.
data is a simple struct with char* 's to the names. (As explicetly writing the strings in code would lead to pointers to my original proccess).
What am I doing wrong?
Failing with ERROR_INVALID_PARAMETER indicates that there is a problem with the parameters passed.
So one should look at data->dll which represents the only parameter in question.
It is initialised here:
lData.dll = VirtualAllocEx(explorer, 0, sizeof(char) * (strlen(dllName) + 1), MEM_COMMIT, PAGE_READWRITE);
So let's add a check whether the allocation of the memory which's reference should be store into lData.dll really succeded.
if (!lData.dll) {
// do some error logging/handling/whatsoever
}
Having done so, you might have detected that the call as implemented failed because (verbatim from MSDN for VirtualAllocEx()):
The function fails if you attempt to commit a page that has not been
reserved. The resulting error code is ERROR_INVALID_ADDRESS.
So you might like to modifiy the fourth parameter of the call in question as recommended (again verbatim from MSDN):
To reserve and commit pages in one step, call VirtualAllocEx with
MEM_COMMIT | MEM_RESERVE.
PS: Repeat this exercise for the call to allocate lData.func. ;-)
It's possible that LoadLibrary is actually aliasing LoadLibraryW (depending on project settings), which is the Unicode version. Whenever you use the Windows API with "char" strings instead of "TCHAR", you should explicitly use ANSI version names. This will prevent debugging hassles when the code is written, and also in the future for you or somebody else in case the project ever flips to Unicode.
So, in addition to fixing that horrible unterminated string problem, make sure to use:
LoadLibraryA(data->dll);

How do I get a string description of a Win32 crash while in Top level filter (I am looking for the address of the instruction at the top of the stack)

If I use a class/method like the one described here how can I get the description/address of the call at the top of the stack?
Basically I want some value I can use in a call to our bug tracking system. I want to "uniquely" identify based on the address of the instruction that caused the exception.
(It is usually something of the form of mydll.dll!1234ABDC())
EDIT:
Some background information:
I am creating a minidump to email to a defect tracking system (fogbugz). In order to reduce duplicates I am trying to come up with a reasonable "signature" for the crash. I know there is an xml PI for FB, but it requires a user logon and we are not sure yet that we can afford to have people sniffing our traffic and getting user information. Emailing is also simpler for now to implement. Later on we will use the XML API to submit minidumps.
You need to put the code to do this in your exception filter, by the time you get to the exception handler much of the context information for the exception has been lost.
try
{
// whatever
}
except (MyExceptionFilter(GetExceptionInformation()))
{
}
Your filter will look something like this
LONG WINAPI MyExceptionFilter (
EXCEPTION_POINTERS * pExcept,
BOOL fPassOn)
{
EXCEPTION_RECORD * pER = pExcept->ExceptionRecord;
DWORD dwExceptionCode = pER->ExceptionCode;
TCHAR szOut[MAX_PATH*4]; // exception output goes here.
szOut[0] = 0;
MEMORY_BASIC_INFORMATION mbi;
DWORD cb = VirtualQuery (pER->ExceptionAddress, &mbi, sizeof(mbi));
if (cb == sizeof(mbi))
{
TCHAR szModule[MAX_PATH];
if (GetModuleFileName ((HMODULE)mbi.AllocationBase, szModule, MAX_PATH))
{
wsprintf(szOut, "Exception at '%s' + 0x%X", szModule,
(ULONG_PTR)pER->ExceptionAddress - (ULONG_PTR)mbi.AllocationBase);
}
}
return EXCEPTION_EXECUTE_HANDLER;
}
Of course, you will need to adjust your output a bit for 64 bit architectures, since the ExceptionAddress and AllocationBase will be 64 bit quantities in that case.
The EXCEPTION_POINTERS struct which is sent to TopLevelFilter() contains an EXCEPTION_RECORD struct which contains the ExceptionAddress. Which this address you can figure out in which DLL the offending opcode is by enumerating the modules with CreateToolhelp32Snapshot. You can also use the functions in dbghelp.dll to find the symbol which correspond to the address (the function it is in)
GetExceptionInformation will return the EXCEPTION_POINTERS struct which contains information about the exception. The ExceptionRecord member contains an ExceptionAddress member, which is the address of the exception.
You'll need to map this address to a module relative location in your code to be useful. You can use GetModuleHandleEx with the GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS to get the HMODULE (which is also the base address of the module). GetModuleInformation can then be used to get the actual name of the module that the exception occurred in.
This may not be that helpful to you if the fault is actually inside of a system DLL. A more sophisticated scheme would be to generate a stack trace (using Stackwalk64 in dbghelp), and ignoring the topmost frames that are not in your code.
You can avoid the pain of printing a string for the exception (what happens if you can save the minidump but can't format a string without crashing?) by saving the minidump instead and using cdb.exe or windbg.exe to extract the exception information.