I need help for a project that uses Microsoft Detours.
Premise: I am trying to use a class I found in a project on CodeProject that uses the Detours library. I downloaded the latest version of Detuors from Github and recompiled it, but I can't find the definition of the macro DETOUR_TRAMPOLINE. I imagine that in the new version of Detours it has been replaced in some way.
In the project that uses this missing macro, it's used like this:
DETOUR_TRAMPOLINE(BOOL WINAPI Detour_EnableScrollBar(HWND hwnd, int wSBflags, UINT wArrows), EnableScrollBar);
DETOUR_TRAMPOLINE(BOOL WINAPI Detour_GetScrollInfo (HWND hwnd, int fnBar, LPSCROLLINFO lpsi), GetScrollInfo);
DETOUR_TRAMPOLINE(int WINAPI Detour_GetScrollPos (HWND hwnd, int nBar), GetScrollPos);
DETOUR_TRAMPOLINE(BOOL WINAPI Detour_GetScrollRange (HWND hwnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos), GetScrollRange);
DETOUR_TRAMPOLINE(int WINAPI Detour_SetScrollInfo (HWND hwnd, int fnBar, LPSCROLLINFO lpsi, BOOL fRedraw), SetScrollInfo);
DETOUR_TRAMPOLINE(int WINAPI Detour_SetScrollPos (HWND hwnd, int nBar, int nPos, BOOL fRedraw), SetScrollPos);
DETOUR_TRAMPOLINE(int WINAPI Detour_SetScrollRange (HWND hwnd, int nBar, int nMinPos, int nMaxPos, BOOL fRedraw), SetScrollRange);
DETOUR_TRAMPOLINE(BOOL WINAPI Detour_ShowScrollBar (HWND hwnd, int wBar, BOOL fShow), ShowScrollBar);
Question:
Is there a way in the new version of Detours to get the same effect as the old macro?
If it is not asking too much, can I ask you some advice on how I could rewrite the code I reported above to be compatible with the new method?
Thanks in advance for the help!
Googling for "#define DETOUR_TRAMPOLINE" brings up:
#define DETOUR_TRAMPOLINE(trampoline,target) \
static PVOID __fastcall _Detours_GetVA_##target(VOID) \
{ \
return ⌖ \
} \
As JHBonarius explained in his comment, many versions of Detours have been released since the macro in question was deleted, so it's probably not so easy to make a quick change to the code in question.
I wanted to point out to those interested a very simple and contained library that, like Detours, allows you to redirect the Windows API (even if it provides much less functionality).
The library in question is MinHook, and the source code is still available here.
Related
I'm writing a C++ program that has to execute a function once every millisecond in order to interact with hardware. Since Windows 10 is not real-time, I found that the Multimedia timer is the best thing that I could use.
Setup:
I am on Windows 10 using the Visual Studio 2019 compiler version 19.28.29914 for x86.
I have the following code that sets up the multimedia timer:
// Get the minimum timer resolution
TIMECAPS tc_;
timeGetDevCaps(&tc_, sizeof(TIMECAPS));
// Set the minimum timer resolution
UINT wTimerRes_ = min(max(tc_.wPeriodMin, 1), tc_.wPeriodMax);
timeBeginPeriod(wTimerRes_);
// Start the timer
UINT uDelay = max(min(1, tc_.wPeriodMax), wTimerRes_);
MMRESULT status = timeSetEvent(uDelay, wTimerRes_, (LPTIMECALLBACK)&Foo::callback, 0, TIME_PERIODIC);
The callback function is declared as a static private member function of the class Foo as follows:
static void PASCAL callback(UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR);
and implemented as:
void PASCAL Foo::callback(UINT wTimerID, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2){
// My "real-time" code
}
Question:
At first I didn't have the PASCAL keyword in the return type, and my program crashed immediately when it was started. Some other times, it ran for a bit, but eventually crashed as well. When I added this keyword in, all of the problems seemed to have disappeared. I couldn't find much information about this online, so my questions are:
What is this mysterious keyword and why is it needed for the Multimedia timer to work correctly?
What other alternatives to Multimedia timer are there for achieving as real-time as possible performance on Windows?
I answer only the first question.
Declaration of timeSetEvent says the callback must be of type LPTIMECALLBACK:
MMRESULT timeSetEvent(
UINT uDelay,
UINT uResolution,
LPTIMECALLBACK lpTimeProc,
DWORD_PTR dwUser,
UINT fuEvent
);
Declaration of LPTIMECALLBACK says the calling convention must be CALLBACK:
typedef void ( CALLBACK *LPTIMECALLBACK)(
UINT uTimerID,
UINT uMsg,
DWORD_PTR dwUser,
DWORD_PTR dw1,
DWORD_PTR dw2
);
CALLBACK is declared for your Visual Studio version as __stdcall:
#define CALLBACK __stdcall
Thus timeSetEvent requires a pointer to a function that has __stdcall calling convention.
When you did not change your projects default calling convention, the defalut calling convention for static member function is cdecl.
Mismatching calling conventions causes undefined behavior. In your case this sometimes led to crashes.
The compiler should warn you about mismatched types, but you did an explicit cast to LPTIMECALLBACK, thus hiding the error.
By accident PASCAL is declared as __stdcall too:
#define PASCAL __stdcall
Thus changing your function to PASCAL worked. But the right solution is to use CALLBACK calling convention for callback.
For example, the function definition of SetWindowPos used to be like so:
BOOL WINAPI SetWindowPos(
_In_ HWND hWnd,
_In_opt_ HWND hWndInsertAfter,
_In_ int X,
_In_ int Y,
_In_ int cx,
_In_ int cy,
_In_ UINT uFlags
);
This used to be very clear on the calling convention and which parameters are optional/in/out, etc.
However, now the MSDN makes it much simpler, but drops the calling convention and SAL annotations like so:
BOOL SetWindowPos(
HWND hWnd,
HWND hWndInsertAfter,
int X,
int Y,
int cx,
int cy,
UINT uFlags
);
Question: Is there anyway to see the SAL annotations and the calling convention now? Why did they think to remove it though?
No, they didn't. With all do respect, I can see it. I am using MS 2019 Community installed well after this question was asked. And since no one answered, here are my 5 cents:
Type this function anywhere in your code, assuming it is in scope.
Select -> right-click -> Go To Declaration or hit Ctrl+F12.
And you should be send to WinUser.h
If you still can't see SAL annotation, try to upgrade the include files...
...or simply install newer VS.
Community is FREE!
I began C++ quite recently and I obviously have the famous LNK2019 issue. I roamed a few hours on google but nothing solved my problem.
My project is half way coded, since I separate the view and the model.
I work with Visual Studio 2010.
Here is the class whose function is not retrieved:
Display.h:
#ifndef DEF_DISPLAY
#define DEF_DISPLAY
#include <Windows.h>
#include <exception>
class Display{
public:
HWND mainWindow, gameWindow;
WNDCLASS mainClass, gameClass;
public:
Display();
static LRESULT CALLBACK mainWindowProc(HWND mainWin, UINT message, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK gameWindowProc(HWND gameWin, UINT message, WPARAM wParam, LPARAM lParam);
**int run();** // This function is not retrieved by the linker.
};
#endif
And here is the Display.cpp:
#include "Display.h"
HINSTANCE instanceMain = 0, instanceGame = 0;
Display::Display(){...}
LRESULT CALLBACK Display::mainWindowProc(HWND mainWin, UINT message, WPARAM wParam, LPARAM lParam){...}
LRESULT CALLBACK Display::gameWindowProc(HWND gameWin, UINT message, WPARAM wParam, LPARAM lParam){...}
int run(){
MSG message;
while(GetMessage(&message, 0, 0, 0)){
TranslateMessage(&message);
DispatchMessage(&message);
}
return message.wParam;
}
And finally here is my main.cpp:
#include "Display.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow){
Display game;
return game.run();
}
I did not finished to code my project because I found out that issue when building it:
1> All outputs are up-to-date.
1>main.obj : error LNK2019: unresolved external symbol "public: int __thiscall Display::run(void)" (?run#Display##QAEHXZ) referenced in function _WinMain#16
1>C:\Users\glembalis\Documents\Visual Studio 2010\Projects\pendu\Debug\pendu.exe : fatal error LNK1120: 1 unresolved externals
1>
1>Build FAILED.
I don't know where the error can occur.
Display.h and Display.cpp are included in the project
The option in Project > Properties > Linker > System > SubSystem is "Windows"
I do not use external libraries (only Windows.h and exception)
The compiler seems to work well. I don't really care if the program works properly, I would correct it later. For now, this linker issue is my major concern! I guess it is just a tiny little stupid mistake, but I cannot find it out!
Thanks to everyone for your time and attention, looking forward to have your answers! Last, I apologise but english is not my native language and I may have written some mistakes.
Have a nice day!
NoobFeeder
Your definition (implementation) has the wrong signature.
It should look like this:
int Display::run(){
This tells the compiler that your run is the one that's a member of your Display class.
Currently you have implemented a free function called run.
I want to modify the native functions available in Windows API, such as CreateWindowEx or ShowWindow in a way that when an application is compiled with those functions included, it will instead call my functions, perform the tasks there, and then call the original native function.
In other words, I want to in a way proxy the functions, while still using the same names (so if a program was written to be compiled with the native API, simply adding these functions would modify the way those native functions are handled)
HWND WINAPI CreateWindowEx(
__in DWORD dwExStyle,
__in_opt LPCTSTR lpClassName,
__in_opt LPCTSTR lpWindowName,
__in DWORD dwStyle,
__in int x,
__in int y,
__in int nWidth,
__in int nHeight,
__in_opt HWND hWndParent,
__in_opt HMENU hMenu,
__in_opt HINSTANCE hInstance,
__in_opt LPVOID lpParam
) {
//my custom code here....
// done with my custom code... so now I want to run the native function
return CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
}
This (for obvious reasons) gives a stack overflow, as it keeps on calling itself over and over. What I would want it to do is, when it is called, it runs through the custom function I've created, and thereafter runs the native functions available in Windows API.
I am quite new to c++, but for example in many other languages, I could store a reference to the native function under another name, which I could then call inside my custom function. Is there anything similar available in c++?
As I've written in the comment, the parent of many hooking libraries was probably the microsoft Detours
Now that it isn't free anymore there are various alternatives. Here there is a comparison of some of them (link removed. I'm not sure it was safe. Try googling for "Microsoft Detours is a library utilized in the particular interception" and select a source or more simply for Detours Alternatives.
Mmmh it seems the only free alternative at this time are http://easyhook.codeplex.com/ and http://www.codeproject.com/KB/system/mini_hook_engine.aspx
There is a SO question: Detours alternative for Registry interception if you are interested.
One interpretation of your question is that you have a project, with source code, and you want to change that project so it uses your own versions of certain winapi functions.
Here is a solution which you can implement for each imported API function. Example here is for ShowWindow:
#define ShowWindow Deleted_Winapi_ShowWindow // prevent windows.h from defining ShowWindow
#include <windows.h>
#undef ShowWindow
namespace HiddenWinapi
{
extern "C"
{
// Do what windows.h does, but hide it inside a namespace.
WINUSERAPI BOOL WINAPI ShowWindow( __in HWND hWnd, __in int nCmdShow);
}
}
// make your own function to be called instead of the API, and delegate to the actual API in the namespace.
BOOL WINAPI ShowWindow(HWND hwnd, int nCmdShow)
{
// ... do stuff ...
// call the original API
return HiddenWinapi::ShowWindow(hwnd, nCmdShow);
}
To use this solution for CreateWindowEx, you need to stub the actual imported function name (e.g. CreateWindowExW), because CreateWindowEx is just a macro which expands to CreateWindowExW or CreateWindowExA.
Here is a solution which replaces the macro with your own, but I think in all cases it would be better to use the above solution.
#include <windows.h>
#undef CreateWindowEx
// Note that this is a unicode-only version. If your app mixes A and W versions, see
// the solution below for non-macro APIs.
HWND WINAPI CreateWindowEx(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
{
// ... do stuff ...
// call the REAL function.
return CreateWindowExW(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
}
If you want to do this yourself the easiest way is to modify the import address table in the PE (portable executable) header. This is not trivial, though.
However, I believe there's a standard library for what you want called Detours. I've never used that one myself, though, because it wasn't around when I started doing this, so I have a - not for public consumption - library for doing it via the import table when I need it.
I have created a global Keyboard hook.
Hook is created in a DLL.
#pragma comment(linker, "/SECTION:.SHARED,RWS")
#pragma data_seg(".SHARED")
static HHOOK hkb=NULL;
static CMyFile *pLF;
#pragma data_seg()
HINSTANCE hins = NULL;
extern "C"
LRESULT __declspec(dllexport) __stdcall CALLBACK KeyBoardHookProc(
int nCode,
WPARAM wParam,
LPARAM lParam)
{
if (nCode < 0) {
return CallNextHookEx(0, nCode, wParam, lParam);
}
return CallNextHookEx(hkb, nCode, wParam, lParam);
}
extern "C"
LRESULT __declspec(dllexport) __stdcall CALLBACK Install()
{
pLF = new CMyFile(L"c:\\1.txt");
hkb = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyBoardHookProc,hins,0);
return 0;
}
extern "C"
BOOL __declspec(dllexport) __stdcall CALLBACK UnInstall()
{
return UnhookWindowsHookEx(hkb);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH :
hins = (HINSTANCE) hModule;
break;
case DLL_THREAD_ATTACH :
break;
case DLL_THREAD_DETACH :
break;
case DLL_PROCESS_DETACH :
break;
}
return TRUE;
}
I have craeted one EXe that loads this dll and calls install function of the hook dll.
HMODULE hMod = LoadLibrary(L"hk.dll");
if(hMod!=NULL)
{
typedef LRESULT (__stdcall CALLBACK *_installhk)() ;
_installhk installProc;
installProc = (_installhk) GetProcAddress(hMod,"Install");
if(installProc!=NULL)
{
installProc();
}
}
While debugging breakpoint on KeyBoardHookProc is being hit only once when I launch the exe.
The exe keeps on running unless I close it but if I enter anything else from keyboard the hook procedure not getting called.
What could be the reason for this?
Is this not the right way to setup global keyboard hook?
How did you test that the hook procedure is not called ? If you tried to check it with a breakpoint, you have to take care that your hook dll is loaded in every process but your breakpoint is only put in your current process.
If you have any window in your application, focus on it before hitting keys or debug it using logs.
Another solution is to hook with WH_KEYBOARD_LL which does not require an extra DLL. You can hook directly from your process.
Have a look at the late Paul DiLascia's code which installs a global keyboard hook to trap the Ctrl+Alt+Del, Task Manager. MSDN September 2002 'Disabling keys in XP with TrapKeys'
Hope this helps,
Best regards,
Tom.
This may not be directly related to your main problem, but your use of the CMyFile object has several issues:
The CMyFile object is allocated dynamically using new CMyFile(...). This will create it only in the memory space of one process.
The pLF pointer is uninitialized. This means it will be placed in the BSS segment instead of the shared data segment. To fix this, declare it with CMyFile *pLF = NULL;.
CMyFile itself probably has members containing file handles and/or pointers which won't work properly in other processes.
Regarding your main question:
You seem to be creating the hook correctly as far as I can see.
There is no need to cast to HOOKPROC in the call to SetWindowsHookEx. If you get a warning without it, there is a problem with your function type.
There's no need for the if statement in the hook proc - the first parameter to CallNextHookEx is ignored anyway on modern Windows, so both branches effectively do the same thing.
I don't know if I'd trust debugger breakpoints on a hook procedure called from different processes - it's possible that the procedure is called but the debugger isn't catching it.
extern "C" is good it will get rid of the name mangling mentioned above but __stdcall will conflict with this.
You should use the RegisterHoyKey API call instead - it's much less hassle (as I found out myself recently when I replaced a similar keyboard hook DLL!).
Check your export section for DLL and see what name linker exported your "Install" function. C++ mangles with export function names. I bet you anything it is not "Install" but rather _Install#12 or something like that.