Why is this code losing handles on Windows 7 Beta? - c++

I'm looking for some random crashes in an old c++ application. Using sysinternals process explorer, I noticed the app losing handles, and extracted the exact situation, where the program is losing handles to a very short piece of code.
DWORD WINAPI MyTestThread( void* PThread)
{
_endthreadex(0);
return 0;
}
int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR PParameter, int)
{
for (int i=0;i<10000;i++)
{
unsigned int threadID;
HANDLE hThread= (HANDLE)_beginthreadex( (void*)NULL, (unsigned int)32768, (unsigned int (__stdcall *)(void *))MyTestThread, (void*)NULL, (unsigned int)0, &threadID);
WaitForSingleObject((HANDLE)hThread, 1000);
CloseHandle((HANDLE)hThread);
}
return 0;
}
My problem: I can't figure out what's wrong with this code. It loses exactly 5 handles on every iteration, but it looks OK to me.
Funny thing: it seems not to lose handles on windows vista, but I'd be very surprised if this should be a bug in windows 7.
[Update] I tried using _beginthread/_endthread and CreateThread/ExitThread instead, those two are losing 5 handles, too, just like _beginthreadex.
[2nd Update] the code does run as expected. All return values are good. It is 'just' losing handles like there is no tomorrow.
[3rd Update] Big new Info The code only loses handles, if compiled with /clr! And more, if I call GC::Collect() on each iteration the handles will be reclaimed!
So, how do I find what clr-objects are being collected there?

Check whether some DLL which is linked to your exe is doing something strange in its DLLMain in response to DLL_THREAD_ATTACH notifications.

Have you checked if the functions succeed? The return values and GetLastError() could give some hints what's going wrong.

From http://msdn.microsoft.com/en-us/library/kdzttdcb.aspx
"If successful, each of these functions returns a handle to the newly created thread; however, if the newly created thread exits too quickly, _beginthread might not return a valid handle (see the discussion in the Remarks section). _beginthread returns -1L on an error, in which case errno is set to EAGAIN if there are too many threads, to EINVAL if the argument is invalid or the stack size is incorrect, or to EACCES in the case of insufficient resources (such as memory). _beginthreadex returns 0 on an error, in which case errno and _doserrno are set. "
Your thread does exit kind of quickly doesn't it.

Have you tried testing this with Win32's CreateThread? That could possibly narrow down the problem to the CRT.

Related

EnumProcessModules failed with error 299 on 32bit win7

My code is running on win7 32bit, but when I use EnumProcessModules, it returned false and getlasterror() return error code 299, which declare that the program is 32bit and this statement can not be running on 64bit system.
I wonder why this happens, and why the system thinks that I am running on a 64bit OS?
The code I use:
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
if (hProcess)
{
HMODULE hMod = NULL;
DWORD cbNeeded = 0;
if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
{
//do something here...
}
}
dwPid is the id of the process I want to manipulate.
PS.This error just happen on one of my test machine, others are fine. So This problem may be related to that specific machine or system configration?
Though It has been a while since you posted this question.But I thought of giving it a try .
Reason might be because You are using CreateProcessA in your code.. and suddenly calling EnumProcessModules.Thus windows is not able to create ModuleInfo by that time.And it returns error 299(Thinking its a 64 bit system.. as it fails to read the memory).
Actually I was stuck at this too and figured it out..after looking at your post.
Thanks
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx
CreatProcess Remarks.. It ask to call WaitforInput Idle before proceeding.;-)
The calling thread can use the WaitForInputIdle function to wait until the new process has finished its initialization and is waiting for user input with no input pending. This can be useful for synchronization between parent and child processes, because CreateProcess returns without waiting for the new process to finish its initialization. For example, the creating process would use WaitForInputIdle before trying to find a window associated with the new process.

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);

Where inside injected DLL to loop?

So I've got an application that starts another application with my DLL injected (with Detours). The entry point is DllMain. I can't do much from DllMain, and certainly cannot loop. So how do I call my DLL monitor functions every x seconds? I read you cannot create a thread from DllMain (at least until it returns) and its true because it crashed me. So I tried creating it in the attach thread event and it crashed me. So now what I'm trying to do is inject it again (incase Detours fails) so I can get the module handle. Then I get the address of an initializer function which creates my thread. I get the module handle fine, but I don't think I can get the function address. I made the function empty, and it still crashed me. So it doesn't even get as far as calling the function. Visual Studio said I have no read access.
So what am I suppose to do? What do you do to loop your DLL functions when you don't own the attached program (exe).
//Application.exe
STARTUPINFO si = {sizeof(STARTUPINFO)};
PROCESS_INFORMATION pi = {0};
DetourCreateProcessWithDll(filename, NULL, NULL, NULL, TRUE,
CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED, NULL, path,
&si, &pi, detoured, hook, NULL);
processID = pi.dwProcessId;
hDll = InjectDLL(processID, hook);
if(hDll != NULL)
{
STARTER Starter = (STARTER)GetProcAddress(hDll, "Starter");
if(Starter != NULL)
Starter();
}
ResumeThread(pi.hThread);
The function Starter is extern C exported and looks fine inspected (it's ordinal 1).
I have no idea what could possibly be wrong, and merely hope someone out there has had experience with this topic and crashing.
Here's the DLL code:
//Hook.h
extern "C"
{
void __declspec(dllexport) Starter(void);
}
//Hook.cpp
void Starter(void)
{
}
Thanks
You can't do it that way because the DLL is injected into a different process and you're trying to execute the function in the address space of your hooking process.
What you'll have to do is call CreateRemoteThread, passing in the address that you get from GetProcAddress in the lpStartAddress parameter. This will create a new thread on the remote process, and execute the function in the address space of that process, in the context of the new thread.
BTW, technically you should be able to create a new thread in DllMain/DLL_PROCESS_ATTACH, as long as you're not doing any synchronizing with other threads, though it's not recommended. I'm not sure what issues might exist if doing this when the DLL is being injected though.

WriteProcessMemory to SYSTEM process with SeDebugPrivilege enabled. (C, Vista)

I'm interested in injecting DLLs into SYSTEM owned processes on my Vista machine. I'm going about this using the traditional method of VirtualAllocEx, WriteProcessMemory and CreateRemoteThread. However, because this will be operating on SYSTEM processes, I enable SeDebugPivilege on the injecting process before opening the target process.
int EnableDebugPriv(LPCTSTR name) {
HANDLE hToken;
LUID luid;
TOKEN_PRIVILEGES tkp;
if(!OpenProcessToken(GetCurrentProcess(),
/*TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY*/
TOKEN_ALL_ACCESS,
&hToken))
return 0;
if(!LookupPrivilegeValue(NULL,name,&luid))
return 0;
tkp.PrivilegeCount=1;
tkp.Privileges[0].Luid=luid;
tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
if(!AdjustTokenPrivileges(hToken,false,&tkp,sizeof(tkp),NULL,NULL))
{
printf("!AdjustTokenPrivileges - %d\n",GetLastError());
return 0;
}
if(GetLastError()==ERROR_NOT_ALL_ASSIGNED)
{
return 0;
}
CloseHandle(hToken);
return 1;
}
Where the SE_DEBUG_NAME constant is passed as name.
After enabling SeDebugPrivilege, I go through the process of opening the target process, locating LoadLibrary, allocating space, writing the DLL path to memory, and creating the thread (checking all return values along the way):
if(NULL==(p=OpenProcess(PROCESS_ALL_ACCESS,FALSE,(DWORD)pid)))
...
if(NULL==(loadLib=(LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"),
"LoadLibraryA")))
...
if(NULL==(dllBuff=(LPVOID)VirtualAllocEx(p,
NULL,
strlen(dllPath)+1,
MEM_RESERVE|MEM_COMMIT,
PAGE_READWRITE)))
...
if(NULL==WriteProcessMemory(p,
(LPVOID)dllBuff,
dllPath,
strlen(dllPath),
&written))
...
if(!CreateRemoteThread(p,
NULL,
NULL,
(LPTHREAD_START_ROUTINE)loadLib,
(LPVOID)dllBuff,
NULL,
NULL))
...
dllPath is a char* of the DLL's path (obviously), and pid is the PID of the target process. Both of these values are taken in through the command line and validated before being used.
The problem I'm having is that nothing is returning errors until CreateRemoteThread, which is returning an 8 ("Not enough storage"). HOWEVER, WriteProcessMemory is NOT writing any bytes to the process. After the call the written variable is always 0. No bytes are being written, but the function is not failing. I'm not sure why this is happening. I looked into other privileges, like the SeRestorePrivilege which promises write access to all processes, but nothing works.
I'm executing this program with Administrator rights.
Note: this WriteProcessMemory and CreateRemoteThread problem only happen when I run this program against higher privileged users (SYSTEM, LOCAL SERVICE, etc...). It works perfectly against a program owned by me (same privileges).
Edit: Here's a link to the whole source. http://pastebin.com/m77110d8e There's not much else there besides basic error checking, but maybe it will help?
This has to do with session isolation in Vista or higher versions of Windows. Check out the source or disassembly for password dumping tools like Cain and Abel that purport Vista functionality. Essentially the process is the same but you'll be calling a different function for CreateRemoteThread (sorry, I don't think the function is exported, you just have to find it, so disassembly of working software is probably the best bet).
You could try using RtlCreateUserThread, instead of CreateRemoteThread. This routine doesn't care what session the target process lives in. Just remember to have the thread call RtlExitUserThread before it ends. These threads don't clean up after themselves, like the CreateThread/CreateRemoteThread ones do.
The reactos code can give you a good look at what these routines are doing.