I try to hook CopyFile2 function, for that I wrote this dll:
#include "..\..\..\minhook-1.3.3\include\MinHook.h"
WCHAR msgbuf[1024];
#define DbgPrint(format, ...) wsprintf(msgbuf, format, __VA_ARGS__); \
OutputDebugString(msgbuf);
#if defined _M_X64
#pragma comment(lib, "libMinHook.x64.lib")
#elif defined _M_IX86
#pragma comment(lib, "libMinHook.x86.lib")
#endif
typedef HRESULT(WINAPI *COPY_FILE_2)(
_In_ PCWSTR pwszExistingFileName,
_In_ PCWSTR pwszNewFileName,
_In_opt_ COPYFILE2_EXTENDED_PARAMETERS *pExtendedParameters
);
COPY_FILE_2 fpCopyFile2 = NULL;
HRESULT WINAPI DetourCopyFile2(
_In_ PCWSTR pwszExistingFileName,
_In_ PCWSTR pwszNewFileName,
_In_opt_ COPYFILE2_EXTENDED_PARAMETERS *pExtendedParameters
)
{
DbgPrint(L"=> DetourCopyFile2\n");
DbgPrint(L"DetourCopyFile2.pwszExistingFileName = %ws\n", pwszExistingFileName);
DbgPrint(L"DetourCopyFile2.pwszNewFileName = %ws\n", pwszNewFileName);
return fpCopyFile2(pwszExistingFileName, pwszNewFileName, pExtendedParameters);
}
void InstallHook()
{
DbgPrint(L"=> InstallHook\n");
// Initialize MinHook.
if (MH_Initialize() != MH_OK)
{
DbgPrint(L"failed MH_Initialize\n");
return;
}
if (MH_CreateHook(&CopyFile2, &DetourCopyFile2, (LPVOID*)&fpCopyFile2) != MH_OK)
{
DbgPrint(L"failed MH_CreateHook\n");
}
else
{
if (MH_EnableHook(&CopyFile2) != MH_OK)
{
DbgPrint(L"failed MH_EnableHook\n");
}
}
}
HINSTANCE hInstance = NULL;
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
DbgPrint(L"DLL_PROCESS_ATTACH");
hInstance = hinstDLL;
DisableThreadLibraryCalls(hInstance);
InstallHook();
break;
}
return TRUE;
}
When I inject this dll to test prograg its work, and DebugView shows the Messages:
int main()
{
OutputDebugString(L"=> main");
printf("inject now");
getchar();
CopyFile2(L"", L"", NULL);
system("pause");
return 0;
}
I run the CSharpConsole64.exe from Deviare2 project, and I saw that Explorer uses CopyFile2 function to copy files.
My question is why when I inject this DLL into the Windows Explorer I get Only the first messages that the hook was successful, but when I copy a file there are no messages from the detour function in the DebugView? And how can I solve the problem?
I am using Visual Studio 2017 Operating System Windows 10 64 bit.
I also tried Hook ReadFile function and I got messages in debugview but not every time I copied a file, something here is not clear to me what is different in Explorer, any help would be greatly appreciated.
I know it's been a long time since this question was asked. I am answering so that it may be helpful for others.
I have the same problem, tested it with Detours. With the same test program you used I see DebugView messages in hooked CopyFile2 function but explorer.exe does not show any messages in hooked function. Also same as you for explorer.exe I saw that hooking was successful from DetourAttach function in DllMain.
After analyzing call stack of CopyFile2 in explorer.exe using x64dbg, I found that CopyFile2 in kernel32.dll is never called. I realized that both kernel32.dll and kernelbase.dll have a CopyFile2 function with the same signature. I saw that actually CopyFile2 function in kernelbase.dll is called instead of the one in kernel32.dll.
I think your hooking is certainly correct but you are hooking CopyFile2 from kernel32.dll. Since explorer.exe uses CopyFile2 from kernelbase.dll instead of kernel32.dll the hooking function is never called. You need to hook CopyFile2 from kernelbase.dll.
I haven't used MinHook before but it should support hooking a function in a specified module. Detours library has DetourFindFunction to get address of a function in specified module. Or you can try using GetProcAddress.
Related
Hi everyone and thank you for your time. This was created in Visual Studio 2012,and I'm using the standard Windows Libraries.
I am attempting to call a DLL function explicitly and I believe the code I've written is correct; however, I am receiving an error. I'm not sure if it's an error in something that I've written in the small C console application or from the DLL which I do not have access to the internal workings of.
//global area
HINSTANCE _createInstance;
typedef UINT (CALLBACK* LPFNDLLFUNCLOOKUP)(AccuInput*, AccuOut*);
LPFNDLLFUNCLOOKUP lpfnDllFuncCASSLookup;
typedef UINT (CALLBACK* LPFNDLLFUNCINIT)(BSTR);
LPFNDLLFUNCINIT lpfnDllFuncInit;
typedef UINT (CALLBACK* LPFNDLLFUNCCLOSE)();
LPFNDLLFUNCCLOSE lpfnDllFuncClose;
HMODULE unmanagedLib;
Here is my main function:
int main() {
// Load Library
BSTR configFile;
unmanagedLib = LoadLibraryA((LPCSTR) "AccuAddressUnMgd.dll");
// Initialize AccuAddress COM dll
lpfnDllFuncInit = (LPFNDLLFUNCINIT)GetProcAddress(unmanagedLib, (LPCSTR)"Init");
// This function will lookup the address
lpfnDllFuncCASSLookup = (LPFNDLLFUNCLOOKUP)GetProcAddress(unmanagedLib, (LPCSTR)"AccuCassLookup");
// This function will call AccuAddress COM DLL Close function
lpfnDllFuncClose = (LPFNDLLFUNCCLOSE)GetProcAddress(unmanagedLib, (LPCSTR)"Close");
// Append “config.acu” file path.
configFile = SysAllocString(L"C:\PathTo\Config.acu");
printf("ConfigPath created");
lpfnDllFuncInit(configFile);
printf("ConfigFile consumed");
SysFreeString(configFile);
return 0;
}
This is the error that I receive:
Unhandled exception at at 0x75D4C54F in RDISample1.exe: Microsoft C++ exception: _com_error at memory location 0x001AFAC0.
The error occurs at:
lpfnDllFuncInit(configFile);
So, I guess my question is two parts. Based off the code can I say for a fact that the error is in the DLL function?
Second question, when calling GetProcAddress what would be the point (if any) for encapsulating the string in LPCSTR like a function versus typecasting?
ie
lpfnDllFuncClose = (LPFNDLLFUNCCLOSE)GetProcAddress(unmanagedLib, LPCSTR("Close"));
Thanks again for the help. I've been doing a fair amount of research yet DLLs still have been puzzled.
The initial error is caused by the library you're using failing to correctly handle a file that doesn't exist.
The path you gave contains single slashes \, which are treated as escape characters, not path separators. Path separators must be escaped, i.e. \\ to be treated correctly.
There is no point casting a string literal to LPCSTR.
As for the _com_error that is definitely coming from the DLL. I would suggest wrapping that in a:
try
{
...
} catch(_com_error const & e)
{
wprintf(L"Caught a com error: %s\r\n", e.ErrorMessage());
}
And then you might be able to figure out what is wrong.
I have made a short DLL which will display a MessageBox when it is loaded by a process. However, the message box is displayed two times. So, it looks like the DLL Export Function is called twice. Could you please see if there is something that needs to be modified in my code so that the MessageBox is displayed only once?
#include <windows.h>
#include <stdio.h>
__declspec(dllexport) void sampledllmain()
{
MessageBox(NULL, "sample text","sample title", 0);
}
BOOL APIENTRY DllMain(HANDLE hHandle, DWORD dwReason, LPVOID Reserved)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
sampledllmain();
break;
}
return 1;
}
I load the DLL using rundll32 as shown below:
rundll32 "path to DLL",sampledllmain
As described by the information page about rundll32.exe :
It loads the specified DLL via LoadLibrary().
It obtains the address of the function via GetProcAddress().
It calls the function, passing the command line tail which is the .
In your case :
When LoadLibrary() is invoked it calls DllMain, in your case DllMain calls sampledllmain.
Obtains the address of sampledllmain
calls sampledllmain ( second time ).
to fix your issue:
add a second function dummy (for example )
use rundll32 "path to DLL",dummy on the command line
PS: On an additional note you could also debug your dll there are guides that describe how to do it
An example with MessageBox call in dllMain
#include <windows.h>
__declspec(dllexport) void sample(void)
{
MessageBox(NULL, "sample text test", "sample title test", 0);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBox(NULL, "attach", "DllMain", 0);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
MessageBox(NULL, "detach", "DllMain", 0);
break;
}
return TRUE;
}
Run with rundll32.exe lib.dll,sample
I really need your help because I'm having many problems integrating one .DLL function into my Console Application.This .DLL consists on getting 2 chars(Char a and Char b)(Input) and adding them to one char.For example:
Char A=H
Char B=I
Output=HI
But here's the problem.When I compile the console application and when I run it,it says that the function hasn't been detected.And here's my question..Why the hell doesn't it find the function even though in the .def file I've listed the LIBRARY and the only exported function?Please help me.
THIS IS THE .DLL SOURCE
#include "stdafx.h"
char concatenazione(char a,char b)
{
return a+b;
}
**THIS IS THE .DEF FILE OF THE .DLL**
LIBRARY Concatenazione
EXPORTS
concatenazione #1
**And this is the dllmain.cpp**
#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved )
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
**This is the Console Application partial source(For now it just includes the functions import part)**
#include <iostream>
#include <windows.h>
#include <stdio.h>
typedef int (__cdecl *MYPROC)(LPWSTR);
int main( void )
{
HINSTANCE hinstLib;
MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
// Get a handle to the DLL module.
hinstLib = LoadLibrary(TEXT("C:\\ConcatenazioneDiAyoub.dll"));
// If the handle is valid, try to get the function address.
if (hinstLib != NULL)
{
ProcAdd = (MYPROC) GetProcAddress(hinstLib, "concatenazione");
// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
fRunTimeLinkSuccess = TRUE;
(ProcAdd) (L"Message sent to the DLL function\n");
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
// If unable to call the DLL function, use an alternative.
if (! fRunTimeLinkSuccess)
printf("Message printed from executable\n");
return 0;
}
**The Console Applications runs fine but the output is "Message printed from executable".This means that the function hasn't been detected.**
Ok, I looked at what you have above and wondered where in your code you import the dll. I'm kind of new at this myself, so I found this article on how to do it.
If I understand correctly, in your console application you need to have a line like (assuming the name of your dll is "your.dll":
[DllImport("your.Dll")]
by the way, welcome to Stack Overflow, I noticed it is your first day! CHEERS!
How can I use the functions in a DLL in C without a LIB file to go with it? I know all of the function prototypes and their names.
Yes you can. You should use the GetProcAddress function, to call the function directly in the DLL, without involving the LIB
Processes explicitly linking to a DLL call GetProcAddress to obtain
the address of an exported function in the DLL. You use the returned
function pointer to call the DLL function.
To quote the Example from the above link:
typedef UINT (CALLBACK* LPFNDLLFUNC1)(DWORD,UINT);
...
HINSTANCE hDLL; // Handle to DLL
LPFNDLLFUNC1 lpfnDllFunc1; // Function pointer
DWORD dwParam1;
UINT uParam2, uReturnVal;
hDLL = LoadLibrary("MyDLL");
if (hDLL != NULL)
{
lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL,
"DLLFunc1");
if (!lpfnDllFunc1)
{
// handle the error
FreeLibrary(hDLL);
return SOME_ERROR_CODE;
}
else
{
// call the function
uReturnVal = lpfnDllFunc1(dwParam1, uParam2);
}
}
You can use LoadLibrary() and GetProcAddress() as described in the answer by DarkXphenomenon. Or, another alternative is to create your own import library for the DLL by creating a .def file then running that through the LIB command to generate an import library. Additional details here:
http://support.microsoft.com/kb/131313
I try to be more clear this time.
I have a main program for test that call Sinacor.DLL that for it turn call PasswordManager.dll a 3er part dll without code (its a IDM system);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Sinacor.DLL
...code ....
LPSTR *GetSenha (int FAR nicas)
.... code.....
char * Mypwd = NULL; // for return porpouse
Mypwd = call dynamically PasswordManager.dll // works fine
return Mypwd; } // return the encrypted password, in test case return "sinacor01"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Sinacor..h
extern "C" { LPSTR FAR *GetSenha(int); }
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
the Sinacor.dll is also loaded dynamically too in the main program for testing:
the main code:
.....some code ..............
typedef LPSTR (CALLBACK *ULPRET)(int);
LPSTR Mypwd = " ";
hLib = LoadLibrary ( "C:\\Ricardo\\Sinacor\\Sinacor.dll");
lpfnDLLProc = (ULPRET) GetProcAddress (hLib,"GetSenha");
Mypwd = (*lpfnDLLProc)(0); //Got runtime error in this statement
I now is a parameter convention error that why I complied both (main and Sinacor.dll) as a C programs with C conventions. The stack show all modules as a C module with C conventions Should works but isn´t .
Please advice.
both programs were complited with _cstl (like CALLBACK).