TCP/UDP hole punching or NAT traversal works as following:
A and B are behind NAT and want to communicate, while you have public relay server, S.
1. A connects to S, B connects to S
2. S send A ip and port to B, and send B ip and port to A
3. One of A or B try to connect to the other by the address S shared
Note1: For hole punching you don’t need uPnP IGD or port forwarding
Note2: UDP hole punching works more reliably than TCP hole punching as it’s connectionless by nature and don’t need SYN packet
Note3: Hole punching isn’t a reliable technique as router or other firewall may see B ip address is different from S ip address and block the inbound connection
Note4: STUN is a standard protocol that implement UDP hole punching although you can create a custom protocol as well following the above steps
There’s a lot of controversial discussion over the internet about achieving accurate sleep function on Windows platforms. The problem is most of them are very old and with the introduction of multicore processors many of the older functions break down but this is not the case in 2023.
Nowadays you can easily call the cross-platform C++ 11 chrono function and with the following source code, I could achieve one millisecond accuracy which is more than enough for my application.
#include <chrono>
#include <thread>
std::this_thread::sleep_for(std::chrono::microseconds(500));
Before I used the QThread::msleep
function which had an accuracy of about 5ms
to 15ms
which was a lot more than what I imagined even when I used the QThread::usleep
function.
There is an issue that is if you call the sleep function on a thread the OS scheduling system will put your application to sleep and it may take a while till the scheduler picks up your application again. To prevent this issue you need to specifically tell OS to treat your application differently than others and C++ 11 introduces chrono which uses QueryPerformanceCounter
in the background Windows API to make sure Windows scheduler will pick your application up at the right time
You can go ahead and directly call the Windows API function but nowadays C++ 11 is nicely integrated into a lot of environments and it’s also a cross-platform solution so lucky you, you don’t need to get your hands dirty anymore.
The Windows 10 may restart unexpectedly. In order to find out why you can execute the following command:
wevtutil qe System /q:"*[System[(EventID=41) or (EventID=1074) or (EventID=6008)]]" /c:1 /f:text /rd:true
If the case is Operating System: Service pack (Planned)
, set the following registry key to disable automatic Windows update restart:
HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU\NoAutoRebootWithLoggedOnUsers
Previously, we learned we needed to put our callback function in a separate DLL and then load that DLL in another program. So you did that you create a separate dll, you put the callback there you call the SetWindowsHookEx
function to set up the callback, But the callback doesn’t get called at all. So what’s wrong?
In order to figure this out, you need to notice that the SetWindowsHookEx
function is actually a DLL injector. What does that mean? It means it first loads or injects your DLL inside the target application, And then it will hook your callback to the Windows messages queue or any other callback that you specified.
So for this to work, there are several conditions that need to be met otherwise several things can go wrong. And in my case, all of them went wrong. I’m going to list them here. So maybe it will help you. By any chance if you bump into any other issue and you finally got to solve it. Then please mention that in the comments, so other people and I can learn from your mistakes as well. Alright, let’s get to the problems.
The first problem that I had was the thread ID. So there are several ways to get the thread ID. First, don’t use the GetWindowThreadProcessId
function
the best and most legitimate way to get the thread ID is by using the CreateToolhelp32Snapshot
function which goes through all threads and checks if they are the main thread for an application. Actually, I found that the CreateToolhelp32Snapshot
function is returning a different value than the GetWindowThreadProcessId
, and it was actually the reason why my DLL doesn’t get floats. So that’s first.
Second, you have to be aware that your callback is going to inject your DLL into another program. So you have to make sure that the DLL that you wrote is not dependent on any other libraries other than the one that is already installed in the “System Path”.
so in my case, I was using the Qt library and the SetWindowsHookEx
function was installing the hook successfully, But in reality, the dll never gets injected into the target program.
The last dilemma was, don’t use the printf
function without taking extra care. So in my case, I was using this
To know why you got to understand that when you’re calling this function from your application and then you call AllocConsole
function, it will open up a console that is hooked up to your application not to the DLL that is injected into the program so if you printf
something in your callback, you won’t see anything because it’s running on a thread on your main application. If you want to see that you need to call the AllocConsole
function inside your DLL main function.
Otherwise when you use the printf
function that will write to the output of the console of the target processor instead of the console that you had opened
Previously we discussed why it isn’t required to inject the DLL containing the callback to every application you need to set a hook on. In this post, we are going to see if it’s possible to create a hook or a global Hook with SetWindowsHookEx
function without using any sort of DLL.
There is this cool trick in which you can use some known Dll to grab their handle and use that to legitimately install the hook with this function. Here is the code for doing that
HMODULE dll_handle = GetModuleHandle(L"user32.dll");
windows_exhook = SetWindowsHookExA(WH_GETMESSAGE, CallWndProcHook,
dll_handle, tid); //0: System wide event
DWORD error = GetLastError();
if( windows_exhook==NULL )
{
qDebug() << "Failed to set the hook. Error code: "
<< error;
}
qDebug() << "hook was successfully installed="
<< windows_exhook << dll_handle
<< error << tid;
Although this code runs successfully and installs the hook if you install this globally by setting the thread id to 0, it will Instantly crash your whole explorer
processor.
If you try that on a single application it also crashes the application.
I tried and spend some time to figure this out and it turns out that the callback will never get executed. I tried to simplify the callback do some sanity tests and it looks like the hook is installed without any problems and sometimes the callback called and most of the time it won’t but at the end in all test cases the targeted application were always crashes. Here is the simplified callback function that I used:
LRESULT CALLBACK CallWndProcHook(int nCode, WPARAM wParam,
LPARAM lParam)
{
// Call the next hook in the chain
// The first argument is ignored so any value will work
return CallNextHookEx(windows_exhook, nCode,
wParam, lParam);
}
I searched a bit about this and there were two comments around this issue
Although at the beginning it seems that you can get away using SetWindowsHookEx
function without a Dll currently at least up to what I know there is no possible way to use SetWindowsHookEx
function without having the callback inside another Dll
There was this special application that I wanted to intercept all Windows messages for a specific remote processor. For that, I came to SetWindowsHookEx
function but in order to install this hook on an external application you cannot do that simply by calling this function inside your code because it will fail with the following error
ERROR_HOOK_NEEDS_HMOD
1428 (0x594)
Cannot set nonlocal hook without a module handle.
In order to fix that at first I thought I need to create a DLL which contains the hook function and then inject that into every application that I need to intercept its messages. What I later found out was that this is not required
To shed some light in there there are two subjects around this, first, there is this DLL injection topic which you can use this function to inject some DLL into other programs and the second one is my application which intercepts events from other applications. For the first one you need to inject the dll which contains the codes you want to inject into the application you want, obviously.
But for the second application that I mentioned you just need to write your codes inside some dll and then just load that codes inside your application and because you wrote down the SetWindowsHookEx
function and the hook callback inside the DLL main function your code will successfully execute and actually you don’t need to inject it into any other application so it is pretty straightforward.
Because at first, it seems to be so complicated I decided to write this down so I wouldn’t forget it later.
That it, enjoy and if it was helpful please send some feedback.
P.S.: SetWinEventHook
Is a completely different Hook. What exactly it does is it reports the events regarding the window manager. To be more specific it reports events related to window creation and destruction, window resizing and losing, or getting Focus around different windows. But it would never give any response regarding the window internal messages.
Mark Jansen: WindowsHookEx GitHub Project
Stmxcsr: Reinventing the wheel, DLL Injection via SetWindowsHookExA
run in cmd
reg ADD HKLM\SOFTWARE\Policies\Mozilla\Firefox /v DisableAppUpdate /t REG_DWORD /d 1 /f
or run ff_update_dis.reg
reg ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer /v NoWinKeys /t REG_DWORD /d 1 /f
or run win_key_dis.reg
reg ADD HKCU\Control Panel\Desktop /v AutoEndTasks /t REG_SZ /s "1" /f
or run win_end_task.reg
privacy.webrtc.hideGlobalIndicator
media.navigator.permission.disabled
media.
extensions.webextensions.restrictedDomains -> set to null
privacy.resistFingerprinting.block_mozAddonManager -> true
I starting to use WinRT with Qt today and now after long time with MinGW, I’m switching to MSVC in Windows. Here is why
• CoInitialize: | Initializes the COM library for use by the calling thread, sets the thread’s concurrency model, and creates a new apartment |
• CoInitializeEx: | More advanced version CoInitialize that specify the thread’s concurrency model |
• CoUninitialize: | Should be called on deconstructor |
On the way to develop a driver for Scarlet Solo Gen3 to harness the power of Shure SM57 Dynamic Microphone.
Useful links to preserve:
Microsoft – Universal Audio Architecture: Guideline to for Sound Card Without Propriety Driver
Update 1: Finished developing! Here is the link to the released driver
GitHub – BijanBina/BAudio Windows 7 x64