Hook stops application
-
Hello! I'm new to the topic "Hooks" and a lot of C++ is new to me. I working on a small application to capture messages, which are send to a "log" window of another application. First I used Spy++ to analyze the messages, which showed me a bunch of WM_SETTEXT messages and that's what I want. from Spy++: <000001> 0000000000021E4E S WM_SETTEXT lpsz:03B50000 ("18.18s [INFO]: NC: ;Note...Rev: C00 - MAA...") I created a DLL, which is injected into the application and a console application to create the hook. At the moment the DLL is just writing some data(Handle, Msg, ThreadID, Title) into a text file and I see, that something is getting logged, which belongs to the same thread, but the part I need is missing. When I start the application the log window and it's app freezes. Normally I see text getting added all the time. Once I close the app, it continues. I'm using Visual Studio 2015 on Win7 64bit. Apps are all 64bit. This is the DLL code:
HHOOK hHook = 0;
extern "C" __declspec(dllexport) LRESULT CALLBACK GetMsgProc(INT nCode, WPARAM wParam, LPARAM lParam)
{// The lParam parameter contains a structure that provides information
// about the message being sent.if (nCode < 0)
{ /* pass it on */
CallNextHookEx(hHook, nCode, wParam, lParam);
return 0;
} /* pass it on */CWPSTRUCT* pCwp = (CWPSTRUCT*)lParam; // for WH_CALLWNDPROC
// Get/Convert Window Text
TCHAR tcWinTitle[255];
int len = GetWindowTextLength(pCwp->hwnd) + 1;
GetWindowText(pCwp->hwnd, tcWinTitle, len);
std::wstring wStr = tcWinTitle;
std::string strWinTitle = std::string(wStr.begin(), wStr.end());// Convert Window Handle
TCHAR tcWinHandle[256];
wsprintf(tcWinHandle, L"0x%08p", pCwp->hwnd);
wStr = tcWinHandle;
std::string strWinHandle = std::string(wStr.begin(), wStr.end());// Get Process ID
DWORD dwThreadId = GetWindowThreadProcessId(pCwp->hwnd, NULL);// Write Results to file
ofstream myfile;
myfile.open("c:\\temp\\example.txt", ios::app);
myfile << " Handle ::: " << strWinHandle << " Msg ::: " << std::to_string(pCwp->message) << " Title ::: " << strWinTitle << " ThreadID ::: " << std::to_string(dwThreadId) << "\n";
myfile.close();HWND hBingo = FindWindow(L"#32770", L"Bingo");
if (hBingo == 0)
{
HWND hWndOutputParent = FindWindow(L"#32770", L"[Output Window]");
HWND hWndOutput = FindWindowEx(hWndOutputParent, 0, L"Edi -
Hello! I'm new to the topic "Hooks" and a lot of C++ is new to me. I working on a small application to capture messages, which are send to a "log" window of another application. First I used Spy++ to analyze the messages, which showed me a bunch of WM_SETTEXT messages and that's what I want. from Spy++: <000001> 0000000000021E4E S WM_SETTEXT lpsz:03B50000 ("18.18s [INFO]: NC: ;Note...Rev: C00 - MAA...") I created a DLL, which is injected into the application and a console application to create the hook. At the moment the DLL is just writing some data(Handle, Msg, ThreadID, Title) into a text file and I see, that something is getting logged, which belongs to the same thread, but the part I need is missing. When I start the application the log window and it's app freezes. Normally I see text getting added all the time. Once I close the app, it continues. I'm using Visual Studio 2015 on Win7 64bit. Apps are all 64bit. This is the DLL code:
HHOOK hHook = 0;
extern "C" __declspec(dllexport) LRESULT CALLBACK GetMsgProc(INT nCode, WPARAM wParam, LPARAM lParam)
{// The lParam parameter contains a structure that provides information
// about the message being sent.if (nCode < 0)
{ /* pass it on */
CallNextHookEx(hHook, nCode, wParam, lParam);
return 0;
} /* pass it on */CWPSTRUCT* pCwp = (CWPSTRUCT*)lParam; // for WH_CALLWNDPROC
// Get/Convert Window Text
TCHAR tcWinTitle[255];
int len = GetWindowTextLength(pCwp->hwnd) + 1;
GetWindowText(pCwp->hwnd, tcWinTitle, len);
std::wstring wStr = tcWinTitle;
std::string strWinTitle = std::string(wStr.begin(), wStr.end());// Convert Window Handle
TCHAR tcWinHandle[256];
wsprintf(tcWinHandle, L"0x%08p", pCwp->hwnd);
wStr = tcWinHandle;
std::string strWinHandle = std::string(wStr.begin(), wStr.end());// Get Process ID
DWORD dwThreadId = GetWindowThreadProcessId(pCwp->hwnd, NULL);// Write Results to file
ofstream myfile;
myfile.open("c:\\temp\\example.txt", ios::app);
myfile << " Handle ::: " << strWinHandle << " Msg ::: " << std::to_string(pCwp->message) << " Title ::: " << strWinTitle << " ThreadID ::: " << std::to_string(dwThreadId) << "\n";
myfile.close();HWND hBingo = FindWindow(L"#32770", L"Bingo");
if (hBingo == 0)
{
HWND hWndOutputParent = FindWindow(L"#32770", L"[Output Window]");
HWND hWndOutput = FindWindowEx(hWndOutputParent, 0, L"EdiIt can't be done anymore on a console application for security to stop stupid hacker keyloggers which basically would only then require minimalistic access. Don't think you can do any of this stuff since Window7 or maybe Vista. Think you need the minimum of a windows message loop handler which has a valid windows thread id which basically means it must be a windows app or service. That means the hook can't hide, windows knows about it and registered it.
In vino veritas
-
It can't be done anymore on a console application for security to stop stupid hacker keyloggers which basically would only then require minimalistic access. Don't think you can do any of this stuff since Window7 or maybe Vista. Think you need the minimum of a windows message loop handler which has a valid windows thread id which basically means it must be a windows app or service. That means the hook can't hide, windows knows about it and registered it.
In vino veritas
Thank you for your reply! Are you sure about this? I'm using "SetWindowsHookEx" to set the hook, so Windows knows it anyway and the console is also a window. Please correct me, if I'm wrong. I made one mistake. I think using GetWindowTextLength & GetWindowText are not a good idea in the hook. The application is waiting for the hook and the hook is waiting to get an answer from the application now. I removed it and the app does not freezing anymore. The handle and message in "CWPSTRUCT* pCwp = (CWPSTRUCT*)lParam;" are good, but I'm having a hard time getting the string from the message. WM_SETTEXT message ::: lParam = A pointer to a null-terminated string that is the window text. In this case this should be pCwp->lParam It looks like the pointer address is different from the one I see in Spy++, but I'm not sure if I even convert it right. I tried this to get the pointer address as string, but it seems to be wrong
wsprintf(tcTemp, L"0x%08p", pCwp->lParam);
wStrTemp = tcTemp;
std::string strHexParam = std::string(wStrTemp.begin(), wStrTemp.end());I tried this to get the message string, but it's not working as well
LPCTSTR lpszString = (LPCTSTR)pCwp->lParam; COPYDATASTRUCT cds; cds.dwData = 0; cds.cbData = sizeof(TCHAR)\* (wcslen(lpszString) + 1); cds.lpData = (PVOID)lpszString;
-
Thank you for your reply! Are you sure about this? I'm using "SetWindowsHookEx" to set the hook, so Windows knows it anyway and the console is also a window. Please correct me, if I'm wrong. I made one mistake. I think using GetWindowTextLength & GetWindowText are not a good idea in the hook. The application is waiting for the hook and the hook is waiting to get an answer from the application now. I removed it and the app does not freezing anymore. The handle and message in "CWPSTRUCT* pCwp = (CWPSTRUCT*)lParam;" are good, but I'm having a hard time getting the string from the message. WM_SETTEXT message ::: lParam = A pointer to a null-terminated string that is the window text. In this case this should be pCwp->lParam It looks like the pointer address is different from the one I see in Spy++, but I'm not sure if I even convert it right. I tried this to get the pointer address as string, but it seems to be wrong
wsprintf(tcTemp, L"0x%08p", pCwp->lParam);
wStrTemp = tcTemp;
std::string strHexParam = std::string(wStrTemp.begin(), wStrTemp.end());I tried this to get the message string, but it's not working as well
LPCTSTR lpszString = (LPCTSTR)pCwp->lParam; COPYDATASTRUCT cds; cds.dwData = 0; cds.cbData = sizeof(TCHAR)\* (wcslen(lpszString) + 1); cds.lpData = (PVOID)lpszString;
Mark_G00 wrote:
wsprintf(tcTemp, L"0x%08p", pCwp->lParam);
wStrTemp = tcTemp;
std::string strHexParam = std::string(wStrTemp.begin(), wStrTemp.end());I tried this to get the message string, but it's not working as well
LPCTSTR lpszString = (LPCTSTR)pCwp->lParam;
COPYDATASTRUCT cds;
cds.dwData = 0;
cds.cbData = sizeof(TCHAR)* (wcslen(lpszString) + 1);
cds.lpData = (PVOID)lpszString;Why are you mixing the UNICODE strings with ANSI ones?
-
Mark_G00 wrote:
wsprintf(tcTemp, L"0x%08p", pCwp->lParam);
wStrTemp = tcTemp;
std::string strHexParam = std::string(wStrTemp.begin(), wStrTemp.end());I tried this to get the message string, but it's not working as well
LPCTSTR lpszString = (LPCTSTR)pCwp->lParam;
COPYDATASTRUCT cds;
cds.dwData = 0;
cds.cbData = sizeof(TCHAR)* (wcslen(lpszString) + 1);
cds.lpData = (PVOID)lpszString;Why are you mixing the UNICODE strings with ANSI ones?
-
At least you have to not mix UNICODE and ANSI functions/variables.
-
At least you have to not mix UNICODE and ANSI functions/variables.
-
Thank you for your reply! Are you sure about this? I'm using "SetWindowsHookEx" to set the hook, so Windows knows it anyway and the console is also a window. Please correct me, if I'm wrong. I made one mistake. I think using GetWindowTextLength & GetWindowText are not a good idea in the hook. The application is waiting for the hook and the hook is waiting to get an answer from the application now. I removed it and the app does not freezing anymore. The handle and message in "CWPSTRUCT* pCwp = (CWPSTRUCT*)lParam;" are good, but I'm having a hard time getting the string from the message. WM_SETTEXT message ::: lParam = A pointer to a null-terminated string that is the window text. In this case this should be pCwp->lParam It looks like the pointer address is different from the one I see in Spy++, but I'm not sure if I even convert it right. I tried this to get the pointer address as string, but it seems to be wrong
wsprintf(tcTemp, L"0x%08p", pCwp->lParam);
wStrTemp = tcTemp;
std::string strHexParam = std::string(wStrTemp.begin(), wStrTemp.end());I tried this to get the message string, but it's not working as well
LPCTSTR lpszString = (LPCTSTR)pCwp->lParam; COPYDATASTRUCT cds; cds.dwData = 0; cds.cbData = sizeof(TCHAR)\* (wcslen(lpszString) + 1); cds.lpData = (PVOID)lpszString;
A console window is not a normal window in any way, underneath they are very different at the thread and message queue level. The old console sits on the CSRSS subsystem Client/Server Runtime Subsystem - Wikipedia[^] It was officially abandonded since Windows 7 and the console is nothing more than a subprocess with drawing capabilities which has now even been extended to hosting ubuntu linux console on Windows 64. If you want to see how shutdown the message loop is you can't even use spy++ on the messages in a console window. Anyhow you want to waste your time .. good luck.
In vino veritas
-
A console window is not a normal window in any way, underneath they are very different at the thread and message queue level. The old console sits on the CSRSS subsystem Client/Server Runtime Subsystem - Wikipedia[^] It was officially abandonded since Windows 7 and the console is nothing more than a subprocess with drawing capabilities which has now even been extended to hosting ubuntu linux console on Windows 64. If you want to see how shutdown the message loop is you can't even use spy++ on the messages in a console window. Anyhow you want to waste your time .. good luck.
In vino veritas
I just used a console application to set the hook, which will inject the dll with the callback. I'm getting a valid handle and the hook is executed in the address space of the target application. There are no messages to or from the console application. I'm not trying to spy anything on a console window. Maybe that was not clear. I get a "CWPSTRUCT" with the right message code and I have trouble to convert the message/pointer to a string and write it to a file. All of this is done in the dll. I don't know, how to setup the debugger to stop inside the dll. It's more like a try and error at the moment and that can be frustrating. I don't see this as a waste of time, because I'm also learning. I appreciate your time and help! Thank you!