A crash in injected / hooked target application - c++

I have injected my DLL into a target application where I've hooked few WINAPI-functions
as well. One of them is DrawTextExW. I'm trying to replace all 'l' letters to '!' before
it prints it out. My solution works fine for a few seconds, but then the target application crashes. I really don't understand why.
Here's the function:
Edit - Working solution:
int WINAPI DetouredDrawTextExW(__in HDC hdc,
__inout LPWSTR lpchText,
__in int cchText,
__inout LPRECT lprc,
__in UINT dwDTFormat,
__in LPDRAWTEXTPARAMS lpDTParams)
{
std::wstring s_wc(lpchText, cchText);
std::replace(s_wc.begin(), s_wc.end(), L'l', L'!');
return ::DrawTextExW(hdc, const_cast<wchar_t *>(s_wc.c_str()),
s_wc.length(), lprc, dwDTFormat, lpDTParams);
}
So, can somebody point it out to me what I'm doing wrong?

I see that you ignore cchText, could you be receiving an non-NULL-terminated string with a positive value for cchText, resulting in reading past the end of the string into invalid memory? That error would present as a Win32 exception in the constructor of s_wc, though.
Also, you aren't checking for DT_MODIFYSTRING in the dwDTFormat parameter. If that flag is present, then ::DrawTextExW() could be overwriting invalid memory. That would present as a Win32 exception in ::DrawTextExW() or perhaps as a C++ exception in the s_wc destructor.
edit
Here's uncompiled, untested code that I believe obeys the contract of ::DrawTextExW()
int WINAPI DetouredDrawTextExW(__in HDC hdc,
__inout LPWSTR lpchText,
__in int cchText,
__inout LPRECT lprc,
__in UINT dwDTFormat,
__in LPDRAWTEXTPARAMS lpDTParams)
{
std::vector<wchar_t> v_wc;
int strSize = cchText == -1 ? wcslen(lpchText) : cchText;
v_wc.resize(strSize + 4);
std::copy(lpchText, lpchText + strSize, &v_wc.front());
std::replace(v_wc.begin(), v_wc.end() - 4, L'l', L'!');
int result = ::DrawTextExW(hdc, &v_wc.front(),
strSize, lprc, dwDTFormat, lpDTParams);
if (dwDTFormat & DT_MODIFYSTRING)
{
std::copy(&v_wc.front(), &v_wc.front() + v_wc.size(), lpchText);
}
}

Related

no instance of overloaded function "strstr" matches the argument list

E0304 no instance of overloaded function "strstr" matches the argument list
I'm getting this error when try to compile, how can i fix this? post the code cus it's better to understand then photo.
So this is the error that i'm getting i don't have any idea what is causing this and how to fix.
int MakeWindows();
int CloseWindows();
int WINAPI WinMain(_In_HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{
HW_PROFILE_INFO hwProfileInfo;
const char* cHWID = "{1234-5678-9669-1337}"; //
if (GetCurrentHwProfile(&hwProfileInfo) != NULL) }
printf("Hardware ID: %s\n", hwProfileInfo.szHwProfileGuid);
if (strstr(hwProfileInfo.szHwProfileGuid, cHWID)) {
printf("Your hardware ID was successful\n\n");
Sleep(3069);
system("CLS");
}
else {
printf("Your Hardware ID was denied;\n");
Sleep(1000);
TerminateProcess(GetCurrentProcess(), NULL);
}
}
else {
return 0;
}
};
strstr wants a char* as its first arg. szHwProfileGuid is going to be a wide string. You need wccstr
So try :
const wcchar* cHWID = L"{1234-5678-9669-1337}";
The problem stems from your project being compiled as Unicode ('wide' characters, usually wchar_t types or defined in Windows as WCHAR), and you also using single-byte characters (char or CHAR), for example in your call to strstr().
(As you're seeing here, the two don't cooperate nicely!)
The Windows API defines two versions of many of its structures (and therefore the respective functions that use them), one to accommodate each character type. In your code example, HW_PROFILE_INFO is actually defined as HW_PROFILE_INFOW for the wide-character version of the API, and you're invoking GetCurrentHwProfileW(). This is fine and by design, since your build is instrumented as a Unicode build.
There are a few ways you could fix this; here's a simple method (your original code with two slight modifications):
int MakeWindows();
int CloseWindows();
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{
HW_PROFILE_INFOA hwProfileInfo; // <== Change # 1
const char* cHWID = "{1234-5678-9669-1337}"; //
if (GetCurrentHwProfileA(&hwProfileInfo) != NULL) } // <== Change # 2
printf("Hardware ID: %s\n", hwProfileInfo.szHwProfileGuid);
if (strstr(hwProfileInfo.szHwProfileGuid, cHWID)) {
printf("Your hardware ID was successful\n\n");
Sleep(3069);
system("CLS");
}
else {
printf("Your Hardware ID was denied;\n");
Sleep(1000);
TerminateProcess(GetCurrentProcess(), NULL);
}
}
else {
return 0;
}
};
This set of simple changes has you explicitly using the single-byte versions of the WINAPI functions, keeping your call to strstr() consistent for its two arguments.
(I'll mention again that this is only one way to fix this problem, and the "best" solution may be subjective. :))

Get processID using part of WINDOW heading

i use the following program in c++ ,in Visual C++ 6.0, to inform me with message box when the MS Paint program is opened. It uses the exact name of the WINDOW of MS Paint,which is "Untitled - Paint" . However now i need to make the program inform me with message box when i know only a part of the name of the actual WINDOW , for example , if the window is "Abcdefgh - Paint" and i set the string name in this way - std::wstring windowName(L"Paint"); - the program to work again. Using the following 3 rows of code the program works fine when the actual WINDOW name is the exact name of the MS Paint window:
HWND windowHandle = FindWindowW(NULL, windowName.c_str());
DWORD* processID = new DWORD;
GetWindowThreadProcessId(windowHandle, processID);
But it will not work if the string windowName is just part of the name, i mean if it is "Paint".
Can someone show me how to do this? I thought to take a list of the names of all opened WINDOWS and to compare them with my part of the real name, i mean to search match of the substring "Paint" in their names, but i don't know how to get all opened windows.
Also, this is very important, my computer is old and i am using Visual C++ 6.0, so i can not use all the evolution features of C++ and the program environments nowadays, i mean , i can not use code which is compiled correctly in .NET but does not compiles in Visual C++ 6.0.
Thanks
#include "stdafx.h"
#include < iostream>
#include < string>
#include < windows.h>
#include < sstream>
#include < ctime>
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
std::wstring windowName(L"Untitled - Paint");
while(true)
{
Sleep(1000*5);
time_t t = time(0); // get time now
struct tm * now = localtime( & t );
int tday = now->tm_mday;
int tmin = now->tm_min;
int thour = now->tm_hour;
HWND windowHandle = FindWindowW(NULL, windowName.c_str());
DWORD* processID = new DWORD;
GetWindowThreadProcessId(windowHandle, processID);
char probaintstr[20];
sprintf(probaintstr,"%d",*processID);
if(strlen(probaintstr) <=5 )
{
Sleep(1000*10);
MessageBox(NULL,"niama go Notepad ili Wordpad","zaglavie",MB_OK);
}
else {
}
}
return 0;
}
You can use EnumWindows, for example
BOOL CALLBACK enumWindow(HWND hwnd, LPARAM lp)
{
std::string str(512, 0);
int len = GetWindowText(hwnd, &str[0], str.size());
if (str.find("Paint") != std::string::npos)
{
MessageBox(0, str.c_str(), 0, 0);
}
return true;
}
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
EnumWindows(enumWindow, 0);
return 0;
}
Or you can use FindWindowEx and look for classname. The classname for MS Paint is "MSPaintApp". You can find this information from "Spy" utility for windows.
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
for (HWND hwnd = NULL;;)
{
hwnd = FindWindowExA(NULL, hwnd, "MSPaintApp", 0);
if (!hwnd)
break;
std::string str(512, 0);
int len = GetWindowText(hwnd, &str[0], 512);
str.resize(len);
if (str.find("Paint") != std::string::npos)
MessageBox(0, str.c_str(), 0, 0);
}
return 0;
}
For process id you don't need to allocate memory. Just use a reference:
DWORD processID;
GetWindowThreadProcessId(windowHandle, &processID);

SetWindowsHookEx(WH_KEYBOARD) not working with thread ID

I have a dll that gets called by a process and now I would like to implement an input check in the dll to react on certain inputs that occur in the application.
SetWindowsHookEx() with a KeyboardProc function seemed like a possible solution so I implemented it.
This is roughly how the code in the dll looks like:
static HHOOK hhk = NULL;
LRESULT CALLBACK keyboardProc(int code, WPARAM wParam, LPARAM lParam)
{
if(code == HC_ACTION && ((DWORD)lParam & 0x80000000) == 0) // if there is an incoming action and a key was pressed
{
switch(wParam)
{
case VK_SPACE:
printf("Space was pressed\n");
break;
}
}
return CallNextHookEx(hhk, code, wParam, lParam);
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
if(ul_reason_for_call == DLL_PROCESS_ATTACH)
{
if(AllocConsole()){
freopen("CONOUT$", "w", stdout); // redirect output to console for debugging
}
printf("Dll loaded, lastError = %i\n", GetLastError());
printf("lastError = %i\n", GetLastError());
// sidenote: for some reason the first GetLastError() returns 0 while the second one returns 6 (invalid handle)
hhk = SetWindowsHookEx(WH_KEYBOARD, keyboardProc, hModule, GetCurrentThreadId());
}
else if (ul_reason_for_call == DLL_PROCESS_DETACH)
{
printf("\nCleaning up...");
FreeConsole();
UnhookWindowsHookEx(hhk);
}
return TRUE;
}
However nothing happens (or gets printed) in the Console window when I press any key. It doesn't even seem like the keyboardProc function is accessed at any time.
It does work though when I pass NULL instead of GetCurrentThreadId() to SetWindowsHookEx().
But this causes the hook to work globally meaning that whenever I press a key in another application, a Console window pops up (because the dll gets called again) and he checks for key inputs there.
Obviously this is not desired and I would like to make this work with only the process that originally called the dll.
I already checked if GetCurrentThreadId() returns a valid ID and it seems to be indeed the main thread ID of the process that initially called the dll (checked with Process Explorer).
So now my question is what could be the problem and more importantly, what can I do to make it working?
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
uint process_id;
uint thread_id = GetWindowThreadProcessId(windowHandle, out process_id);
hhook = SetWindowsHookEx(WH_KEYBOARD, a_KeyboardProc, hInstance, 0);
I have used the code above to get the main thread_ID for a certain process. The good part is, the SetWindowsHookEx function gives a logical output. Unfortunately, the bad part is, if a key is pressed in the thread that has been hooked, the thread stops working.
In specific, the idHook parameter of SetWindowsHoookEx function was set to 2 (instead of 13) in my case for non-low-level keyboard events. It seems, at least to me, that LL corresponds to low-level, where keyboardProc should come with a WH_KEYBOARD instead of WH_KEYBOARD_LL.
I am not sure at this point how my response would be related to your question. Hopefully, we get what we need through discussion.

Why is CWnd::CreateEx failing to create my window?

I'm working on a sporadic production issue that's occurring within our 32 bit MFC VC2010 application. The application is running on Windows Server 2008 R2 Standard SP1 64-bit.
The issue is caused by a failure to create a CWnd derived class. When the failure occurs the AfxUnhookWindowCreate method returns false within CWnd::CreateEx. This is because the pThreadState->m_pWndInit variable is not NULL. It looks like _AfxCbtFilterHook should be setting this to NULL when HCBT_CREATEWND is hooked, but it appears this is not occurring. I've logged out the CREATESTRUCT and compared it to when the failure occurs vs. doesn't occur and the parameters are essentially the same.
Does anyone have ideas on what could cause this or how I could identify the cause? Thanks!
BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,
LPCTSTR lpszWindowName, DWORD dwStyle,
int x, int y, int nWidth, int nHeight,
HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam)
{
...
if (!PreCreateWindow(cs))
{
PostNcDestroy();
return FALSE;
}
AfxHookWindowCreate(this);
HWND hWnd = ::AfxCtxCreateWindowEx(cs.dwExStyle, cs.lpszClass,
cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy,
cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);
...
if (!AfxUnhookWindowCreate())
PostNcDestroy(); // cleanup if CreateWindowEx fails too soon
...
BOOL AFXAPI AfxUnhookWindowCreate()
{
_AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData();
#ifndef _AFXDLL
if (afxContextIsDLL && pThreadState->m_hHookOldCbtFilter != NULL)
{
::UnhookWindowsHookEx(pThreadState->m_hHookOldCbtFilter);
pThreadState->m_hHookOldCbtFilter = NULL;
}
#endif
if (pThreadState->m_pWndInit != NULL)
{
pThreadState->m_pWndInit = NULL;
return FALSE; // was not successfully hooked
}
return TRUE;
}
LRESULT CALLBACK
_AfxCbtFilterHook(int code, WPARAM wParam, LPARAM lParam)
{
_AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData();
if (code != HCBT_CREATEWND)
{
// wait for HCBT_CREATEWND just pass others on...
return CallNextHookEx(pThreadState->m_hHookOldCbtFilter, code,
wParam, lParam);
}
...
pThreadState->m_pWndInit = NULL;
I tracked the problem down to a window procedure hook that shouldn't have been executing at this time.

c++ WinApi : GetClientRect fails

I am coding a screensaver program running on Windows.
In preview mode, Windows calls the program this way :
Screensaver.exe /p ParentWindowHandle
However, when I make this call in my program :
BOOL res = GetClientRect(parentWindowHandle, rect)
res is FALSE, rect is NULL and I get ERROR_INVALID_WINDOW_HANDLE with GetLastError()
GetWindowRect gives me the same results.
But, if I make a call to BOOL res = IsWindow(parentWindowHandle) instead, I get res == TRUE. Does this not mean I have a valid window handle ?
The code looks like this :
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
unsigned int handle = GetHandleFromCommandLine(pCmdLine); // Custom function (tested and approved :) )
HWND parentWindowHandle = (HWND) handle;
LPRECT rect = NULL;
BOOL res = GetClientRect(parentWindowHandle, rect);
// here, rect == NULL, res == FALSE and GetLastError() returns ERROR_INVALID_WINDOW_HANDLE
// ...
// ...
}
On 64-bit Windows, a window handle is 64 bits and cannot fit in an unsigned int, so your cast is producing a value that is an invalid window handle. You should modify your GetHandleFromCommandLine function so that it returns a proper HWND, not an unsigned int, and no type cast is necessary.
Also, GetClientRect returns the rectangle by storing it into the value pointed at by the second parameter. If you pass it NULL, it has nowhere to store that, so it will either crash or fail with an invalid parameter error. To avoid that, pass in the address of a local variable:
RECT rect;
GetClientRect(..., &rect);