DLL causes program to crash only when memory is allocated - c++

I am writing a small DLL, which once injected into my target process, will find a hwnd and write the window's text to a file. I have it setup like this:
hWnd = FindWindow(L"tSkMainForm",NULL);
chat = FindWindowEx(hWnd, NULL, L"TConversationForm", NULL);
ofstream myfile("X:\\Handles.txt", ios::out | ios::app);
if (myfile.is_open())
{
int len;
len = SendMessage(chat, WM_GETTEXTLENGTH, 0, 0) + 1; // + 1 is for the null term.
char* buffer = new char[len];
SendMessageW(chat, WM_GETTEXT, (WPARAM)len, (LPARAM)buffer);
myfile.write(buffer,len); /* << buffer <<endl; */
myfile.close();
delete[] buffer;
}
It works for a seemingly random amount of time, then the application (Skype) crashes. It only crashes when I allocate memory. I have tried using malloc with:
char* buffer = (char*)malloc(len); //I even tried removing "(char*) before malloc
//Do the rest of the stuff here
free((void*) buffer);
But that crashes too.
My DLL calls CreateThread, adds an extra menu item via AppendMenu, and handles the messages for it, all perfectly. It just seems that allocating memory doesn't want to work, but only at random times. I am not sure, but I think Skype is overwriting my memory, or I am overwriting Skype's memory (how would I ensure that the two don't overwrite each other then?)
Also, I know an API exists for Skype, but I want to do it this way. I would use the Skype API if I wanted to write a serious program.
Thanks.

Of course it crashes. "Injecting a DLL in another process" is something you shouldn't be doing in the first place, and certainly not if you cannot figure this out.
Your problem is that your DLL makes assumptions about the environment it's running in. In particular, you assume there's a C++ heap (or a C heap, for malloc), and that is has precisely the right state for your program. That's just not the case. Normal C++ rules do not apply to injected DLL's; your DLL must be able to stand on its own legs.

Related

Leadtools Not enough memory available

I have to correct a bug where Leadtools function " L_LoadBitmap() returns ERROR_NO_MEMORY " , more info about it you can find Here.
The application I am working on has to be able to handle images despites the size of each image or their count.
Here the function is called:
HENHMETAFILE hemf = 0;
BITMAPHANDLE bmh = {0};
hemf = LoadMetaFile( (LPCTSTR)strPath, hDC );
if ( !hemf )
{
memset( &bmh, 0, sizeof(BITMAPHANDLE) );
L_INT nResult = 0;
nResult = L_LoadBitmap( const_cast<LPTSTR>( (LPCTSTR)strPath ), &bmh, 0, ORDER_BGR );
if ( nResult != SUCCESS )
{
MFDebugString( DL_FORMULAR, __FUNCTION__ "( %s ): Can't load background file via L_LoadBitmap (%d)\n", (LPCTSTR)strPath, nResult );
return nullptr;
}
}
pOrigBg = std::make_shared<CBackgroundImage>(strPath, hemf, bmh);
m_ImageCache[strKey.GetString()] = pOrigBg;
return pOrigBg;
Here pOrigBgis an std::shared_ptr<CBackgroundImage> object that gets constructed this way:
NxFE::CBackgroundImage::CBackgroundImage(LPCTSTR strPath, HENHMETAFILE emf, const BITMAPHANDLE& bmp)
: m_Filename(strPath), m_Metafile(emf), m_pLeadBitmap(new BITMAPHANDLE(bmp)),
m_pGdiplusBitmap(NxClass::Win32::GDIPlus::CreateBitmapFromFile((LPCSTR) m_Filename))
{
}
How can you see, pOrigBg contains a std::unique_ptr of type BITMAPHANDLE and Gdiplus::Bitmap.
Firstly, I thought that removing constructor of m_pGdiplusBitmap may help , but it doesn't.
Is any possible way to deallocate/reduce the usage of graphic memory ? Or at least some tools of inspecting Graphic Memory Usage (I'm using Microsoft Visual Studio 2017).
As you found out, functions in LEADTOOLS that allocate pixel data must be followed by calling L_FreeBitmap() when you no longer need the bitmap in memory. This is actually mentioned in the help topic you mentioned in your original question, which states: “Since the function allocates storage to hold the image, it is up to you to free this storage by calling L_FreeBitmap.”
Placement of the L_FreeBitmap call can be crucial in avoiding memory leaks. Since pixel data is typically the largest memory object in the bitmap handle, failing to free it correctly could cause huge leaks.
Also, if your code is allocating the BITMAPHANDLE structure itself using the “new” operator, you need to delete it once done with it. Even though the structure itself is typically much smaller in size than the pixel data, you should never allow any type of memory leak in your application.
If you run into any problem related to LEADTOOLS functions, feel free to email the details to our support address support#leadtools.com. Email support is free for all versions of the toolkit, whether Release (purchased) or free evaluation.
Ok, this statement worked, just had to put it in a different place
if ((bmh).Flags.Allocated)
L_FreeBitmap(&bmh);
Still got problems with GdiplusBitmap and loading images with .bmp extension, but that's already something else.
Also, in VS2017 you can go Debug -> Performance Profiler()... (Alt+F2) to use some tools for inspecting CPU / GPU / Memory Usage.

c++ win32 DLL - need to dynamically load a base64 string (very strange!)

First of all, sorry if the title isn't really accurate, I have no idea how I can put my problem into a single sentence.
The problem I'm facing is that I have a win32 DLL which needs to dynamically load a binary file and do something with it (the binary file is found in a base64 string, which the DLL then decodes and writes to disk).
Pretty simple, in theory. However, here come the problems:
I tried putting the string into the resources by an external program. That worked and it does appear in the resources (according to reshack), BUT when I try to access it from inside the DLL it doesn't work. And yes, I do know that you need the hInstance of the DLL itself, not from the executable file that contains it, it didn't work either though.
I also tried to load the string from another source (I tried file, URL and even the registry), but whenever I save it in a variable, the program crashes ("X stopped working" message), I'm assuming that the program which loaded the DLL didn't clear enough RAM to store that extra variable.
And last but not least an extra note: I do not have access to the source code of the program containing the DLL (I'm writing a plugin more or less), so I couldn't pass a parameter either.
I really hope someone can help me out of this dilemma.
Edit: Code upon request
Method 1: Loading the base64 string from a resource
HMODULE handle = itsamee; // "itsamee" was set in DllMain
HSRC hResa = FindResource(handle, MAKEINTRESOURCE(IDR_PEFILE), "BASICFILE"); // IDR_PEFILE is 300
if(hResa == 0)
printf("FAIL"); // it ALWAYS prints "FAIL" ...
.rc file:
#include "resource.h" // there it just defines IDR_PEFILE and includes <windows.h>
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
IDR_PEFILE BASICFILE "app.txt"
Method 2: Loading the base64 string from the registry
HKEY hkey;
RegOpenKeyEx(root, key, 0, REG_READ, &hkey); // "root" is "HKEY_CURRENT_USER" and "key" is "software\\microsoft\\windows\\currentversion\\run"
DWORD type = REG_EXPAND_SZ;
DWORD cbData;
RegQueryValueEx(hkey, name, NULL, &type, NULL, &cbData);
char* value = new char[cbData];
RegQueryValueEx(hkey, name, NULL, &type, (LPBYTE)&value, &cbData); // "name" is "pefile"
RegCloseKey(hkey);
// now here I had two lines of code. the first one is:
printf("Okay"); // it would always print "Okay"
// this is the second version:
printf("Okay, value is %s", value); // it wouldn't print this, instead I'd get the "X stopped working" error
std::vector<char> dec = base64_decode(value); // this would never happen, "stopped working", regardless of which printf was called before
The mistake was that (LPBYTE)&value made the function write to the pointer and not the buffer itself. It had to be changed to (LPBYTE)value. Thanks to Mark Ransom for this answer!

Holding scroll-bar gets command prompt to pause in Windows

I have a program where I record data through an ADC system from National Instruments (NI).
The device buffers information for some time, and then the program collects the buffer data at some point. If the program collects data larger than the buffer, then the buffer would have to free without my program receiving the data, which will cause the NI library to throw an exception saying that requested data isn't available anymore, since it was lost.
Since my program is a command-prompt program, if the user clicks and holds the scrollbar, the program pauses, which could get this problem to happen.
How can I get over this problem without increasing the buffer size? Can I disable this holding thing in Windows?
Thanks.
Only the thread that is attempting to output to the console is blocked. Make this a separate thread, and your problem goes away.
Of course, you'll need to buffer up your output, and do something sensible if the buffer overflows.
For reference, here's the simple code I used to test this, you will note that the counter continues to increase even when the scroll bar is held down:
#include <Windows.h>
#include <stdio.h>
volatile int n = 0;
DWORD WINAPI my_thread(LPVOID parameter)
{
for (;;)
{
n = n + 1;
Sleep(800);
}
}
int main(int argc, char ** argv)
{
if (!CreateThread(NULL, 0, my_thread, NULL, 0, NULL))
{
printf("Error %u from CreateThread\n", GetLastError());
return 0;
}
for (;;)
{
printf("Hello! We're at %u\n", n);
Sleep(1000);
}
return 0;
}
Whilst there may be ways to bypass each individual problem you can possibly conceive with the output [including for example running it over a network on a sometimes slow output link, or some such], I think the correct thing to do is to disconnect your output from your collecting of data. It shouldn't be hard to do this by adding a separate thread that collects the data, and having the main thread display to the command prompt window. That way, not matter which variation of "output is blocked" Windows throws at you, it will work - at least until you run out of RAM, but tat that point it's YOUR program's decision to do something [e.g. throw away some data or some such].
This is generally how the problem "I need to collect something, and I also need to allow users to view the data, but I don't want the two to interfere with each other" is solved.
First use the GetConsoleWindow winapi function and get the HWND of your console.
now i suggest two ways to do this,
Method I
Subclass the window by creating your own WindowProcedure. (get help from here)
Now that you have subclassed it, you can intercept the WM_VSCROLL and WM_HSCROLL messages and do your own remedy to your code.
Method II
Change the size of the window using some function like SetWindowPos so that the scroll bars are not needed.
or Change the size of the console screen buffer so that the scroll bars are not needed.
Method I has lot of control over the application, but its a little bit complex than the method II which is very simple.
If you want to forbid the user from resizing the console window, just remove the WS_THICKFRAME from the WindowStyle of the console window.
I was in a similar situation and found that this kind of blocking behaviour could be caused by the quick edit "feature" of the command prompt. This question explains about it and the answer shows how to disable it. Hope that helps, even after some years :)

Remote thread is failing on call to LoadLibrary with error 87

I am tring to create a Remote thread that will load a DLL I wrote, and run a function from it.
The DLL is working fine (Checked) but from some reason, the Remote thread fails and the proccess in which it was created stop responding.
I used ollyDebug to try and see what is going wrong and I noticed two things...
My strings (dll name and function name) are passed to the remote thread correctly
The thread fails on LoadLibrary with lasterror code 87 "ERROR_INVALID_PARAMETER"
My best guess is that somehow, The remote thread can't find LoadLibrary (Is this because the linker is done with repspect to my proccess???, Just a guess...)
What am I doing wrong?
This is the code to the remote function:
static DWORD WINAPI SetRemoteHook (DATA *data)
{
HINSTANCE dll;
HHOOK WINAPI hook;
HOOK_PROC hookAdress;
dll = LoadLibrary(data->dll);
hookAdress = (HOOK_PROC) GetProcAddress(dll,data->func);
if (hookAdress != NULL)
{
(hookAdress)();
}
return 1;
}
Edit:
This is the part in which I allocate the memory to the remote proccess:
typedef struct
{
char* dll;
char* func;
} DATA;
char* dllName = "C:\\Windows\\System32\\cptnhook.dll";
char* funcName = "SetHook";
char* targetPrgm = "mspaint.exe";
Data lData;
lData.dll = (char*) VirtualAllocEx( explorer, 0, sizeof(char)*strlen(dllName), MEM_COMMIT, PAGE_READWRITE );
lData.func = (char*) VirtualAllocEx( explorer, 0, sizeof(char)*strlen(funcName), MEM_COMMIT, PAGE_READWRITE );
WriteProcessMemory( explorer, lData.func, funcName, sizeof(char)*strlen(funcName), &v );
WriteProcessMemory( explorer, lData.dll, dllName, sizeof(char)*strlen(dllName), &v );
rDataP = (DATA*) VirtualAllocEx( explorer, 0, sizeof(DATA), MEM_COMMIT, PAGE_READWRITE );
WriteProcessMemory( explorer, rDataP, &lData, sizeof(DATA), NULL );
Edit:
It looks like the problem is that the remote thread is calling a "garbage" address
instead of LoadLibrary base address. Is there a possibily Visual studio linked
the remote proccess LoadLibrary address wrong?
Edit:
when I try to run the same exact code as a local thread (I use a handle to the current procces in CreateRemoteThread) the entire thing works just fine. What can cause this?
Should I add the calling function code? It seems to be doing its job as
the code is being executed in the remote thread with the correct parameters...
The code is compiled under VS2010.
data is a simple struct with char* 's to the names. (As explicetly writing the strings in code would lead to pointers to my original proccess).
What am I doing wrong?
Failing with ERROR_INVALID_PARAMETER indicates that there is a problem with the parameters passed.
So one should look at data->dll which represents the only parameter in question.
It is initialised here:
lData.dll = VirtualAllocEx(explorer, 0, sizeof(char) * (strlen(dllName) + 1), MEM_COMMIT, PAGE_READWRITE);
So let's add a check whether the allocation of the memory which's reference should be store into lData.dll really succeded.
if (!lData.dll) {
// do some error logging/handling/whatsoever
}
Having done so, you might have detected that the call as implemented failed because (verbatim from MSDN for VirtualAllocEx()):
The function fails if you attempt to commit a page that has not been
reserved. The resulting error code is ERROR_INVALID_ADDRESS.
So you might like to modifiy the fourth parameter of the call in question as recommended (again verbatim from MSDN):
To reserve and commit pages in one step, call VirtualAllocEx with
MEM_COMMIT | MEM_RESERVE.
PS: Repeat this exercise for the call to allocate lData.func. ;-)
It's possible that LoadLibrary is actually aliasing LoadLibraryW (depending on project settings), which is the Unicode version. Whenever you use the Windows API with "char" strings instead of "TCHAR", you should explicitly use ANSI version names. This will prevent debugging hassles when the code is written, and also in the future for you or somebody else in case the project ever flips to Unicode.
So, in addition to fixing that horrible unterminated string problem, make sure to use:
LoadLibraryA(data->dll);

Error while reading files with native code on windows mobile

I'm new here and my english is not really good. Apologize any inconvenience!
I'm programming an application for windows mobile with native code (MFC). I'm trying to open a file and this is driving me crazy. I've tried to open it in a thousand diferent ways... And I really achieve it, but when I try to read (fread or getline) the program crashes without any explanation:
The program 'x' finalize with code 0 (0x0)
The GetLastError() method, in some cases, returns me a 183.
Then, I put the code I've used to open the file:
std::wifstream file(L"\\Archivos de programa\\Prog\\properties.ini");
wchar_t lol[100];
if (file) {
if(!file.eof()) {
file.getline(lol,99);
}
}
It enters on all the if's, but the getline crashes.
FILE * lol = NULL;
lol = _wfope n(ruta, L"rb");
DWORD a = GetLastError();
if ( lol != NULL )
return 1;
else
return -1;
It returns 1 (correct), and after, in a later getline, it stores trash on the string. However, it doesn't crash!!
fp.open (ruta, ifstream::in);
if ( fp.is_open() ) {
return 1;
}else{
return -1;
}
It enters on the return 1, but when executing the later getline() crashes.
I've debugged the getline() method and it crashes on the library fstream, right there:
if ((_Meta = fget c (_File)) == EOF)
return (false);
In the if. The fgetc(), I supose.
I'm going completely crazy!! I need some clue, please!!
The path of the file is correct. First, because, in theory, the methods open the file, and second, I obtain the path dinamically and it matches.
Emphasize that the fread method also crashes.
Thanks in advance!
P.S.:
Say that when I do any fopen, the method fp.good() returns me FALSE, and the GetLastError returns me 183. By the other hand, if I use fp.fopen(path, ifstream::in); or std::wifstream fp(path); the fp.good(); returns me TRUE, and the GetLastError() doesn't throw any error (0).
A hint: use the Process Monitor tool to see what goes wrong in the file system calls.
The path accepted by wifstream is lacking a drive ("C:" or the like) (I don't know what the ruta variable points to)
Apart from the streams problem itself, you can save yourself a lot of trouble by using the GetProfileString and related functions, when using a windows .ini file.
I'm shooting in the dark here, but your description sounds like a runtime mismatch story. Check that MFC and your project use the same runtime link model (static/dynamic). If you link to MFC dynamically, then the restriction is stricter: both MFC and your project have to use dynamic runtime.
I don't know why, but with the CFile class... it works...
Programming mysteries!
Shooting in the dark too.
Unexplained random crash in MFC often comes from a mismatch message handler prototype.
For example the following code is wrong but it won't generate any warning during compilation and it may work most of the time :
ON_MESSAGE(WM_LBUTTONDOWN, onClick)
...
void onClick(void) //wrong prototype given the macro used (ON_MESSAGE)
{
//do some stuff
}
Here the prototype should be :
LRESULT onClick(WPARAM, LPARAM)
{
}
It often happens when people get confident enough to start modifying manually the message maps.