EnumProcessModules failed with error 299 on 32bit win7 - c++

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.

Related

Is there any way GetExitCodeProcess could set the exit code to the wrong value?

I'm maintaining code written by someone just before they retired, which means I can't find them to ask questions. :-) This is basically a C++ wrapper to launch a program. The chunk of code in question is this:
BOOL bSuccess = CreateProcess(NULL, (char *)strBatFile.c_str(),
NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, strLocalWorkingDir.c_str(), &si, &pi );
if( bSuccess )
{
DWORD dwMillisec = INFINITE;
DWORD dwWaitStatus = WaitForSingleObject( pi.hProcess, dwMillisec );
if( dwWaitStatus == WAIT_OBJECT_0 )
{
DWORD dwExitCode = NULL;
GetExitCodeProcess( pi.hProcess, &dwExitCode );
nRet = (int)dwExitCode;
}
CloseHandle( pi.hThread );
CloseHandle( pi.hProcess );
}
else
nRet = START_PROCESS_FAILED;
If just one instance is run at a time, it always works fine. If multiple are run within a very short time frame, though, about half of them are having dwExitCode set to 1 instead of 0, even though the process isn't crashing, and the log file that internal program writes is completing.
So to clarify, the process is always starting fine, and it's always getting into the if statements, but it's the value of dwExitCode set by GetExitCodeProcess that isn't containing what's expected. Since we error check on this, we're flagging a bunch of these runs as incomplete when they in fact are fine.
Is there any way this value could be set to something different than the process exit code? And/or is there a utility I could run at the same time to confirm the exit codes are what I think they are?
Thanks!
ETA: Just realised this is putting the internal program call in a .bat file - "C:\\ --flags etc..." and then calling that as a command line in the second argument, rather than just calling it directly using lpApplicationName. No idea if this makes a difference! But when I print the PID of the process, I can see it's the PID for a cmd.exe process, and then our program has a child PID. However, when I trace in Process Monitor, I can see that both parent and child are exiting with exit code 0.
Found it! The application itself was in fact returning a 0 error code...it was the shell around it that was returning 1. And that was due to that .bat file in the second argument. The name was being generated from time, so it ended up being exactly the same name if multiple instances were run too closely together. This is why the inner app would run fine...there was always a bat file there with that name. But there were access collisions when the different instances were trying to generate or clean up the bat, from what I can tell.
As a proof-of-concept hack I just added the current PID to the end of the file name, and everything worked perfectly. Now I just need to decide the real fix, which I think will likely be getting rid of the whole bat file mechanism entirely and calling the app directly.
Whew! Thanks for all the help, everyone! Sadly, the bit of code I included didn't have the offending line, but everyone's tips above helped me narrow in on the problem. :-)

How to check if a process is running or not using C++

I should not display certain context menu options if one process is not running?.
I am checking if the process is running or not using the process name.
But the issue is, the process name is showing different way in different windows platforms.
ie, windows 64 bit process name on windows task bar is " applicationname.exe"
some windows xp machine shows the same process name as "applica~2.exe"
Please let me know the consistent way to check if the process is running or not?
My development environment is C++ and Visual Studio 2010
DWORD getProcessID(const std::wstring& processName)
{
PROCESSENTRY32 info;
info.dwSize = sizeof(info);
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if ( snapshot == INVALID_HANDLE_VALUE )
return 0;
Process32First(snapshot, &info);
if ( !processName.compare(info.szExeFile) )
{
CloseHandle(snapshot);
return info.th32ProcessID;
}
while ( Process32Next(snapshot, &info) )
{
if ( !processName.compare(info.szExeFile) )
{
CloseHandle(snapshot);
return info.th32ProcessID;
}
}
CloseHandle(snapshot);
return 0;
}
EnumProcesses is the other way to enumerate active processes.
The difference is that you need to allocate the space for PIDs,call EnumProcesses, open each process with PROCESS_QUERY_INFORMATION access flag and then call GetProcessImageFileName on it's handle and do the comparison.
Using WMI to interrogate instances of Win32_Process allows you to check the fullpath of the running processes for a match on the one you need to see.
Are you the author of the process in question? If so, a more robust design would be to use IPC to interrogate the process directly. That way, you don't necessarily have to poll and you don't have irritating issues such as what happens if you detect the process, create the context menu and then the process goes down?

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.

Why is this code losing handles on Windows 7 Beta?

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.