The question is mostly in the title. I am trying to write an example using this method however when I run it with the ALL flag and the handle for a process I get a -1 returned instead of a valid handle to a snapshot and when calling GetLastError I get 2 (The system cannot find the file specified.)
My question is does the th32ProcessID referenced in the MSDN link refer to a normal process handle or is there a different way to get this process ID?
I don't have a great deal of code for this at the moment but what I do have is below:
[DllImport("kernel32", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
internal static extern IntPtr CreateToolhelp32Snapshot([In] SnapshotFlags dwFlags, [In] IntPtr th32ProcessID);
IntPtr Handle = CreateToolhelp32Snapshot(SnapshotFlags.All, ProcessHandle);
Console.WriteLine("ProcessHandle = {0}", ProcessHandle.ToString("X"));
uint flags = 0;
bool result = GetHandleInformation(ProcessHandle, out flags);
Console.WriteLine("Last error = {0} and handle is valid = {1}", WinErrors.GetLastWin32Error(), result);
Console.WriteLine((int)Handle);
A process HANDLE is not the same thing as a process ID. They are not interchangeable.
CreateToolhelp32Snapshot() takes a process ID. And that parameter is a DWORD, so you should be using (u)int (aka (U)Int32), not IntPtr.
GetHandleInformation() takes a process HANDLE.
Since you are passing the wrong type of parameter value to CreateToolhelp32Snapshot(), it is failing, returning INVALID_HANDLE_VALUE, and then GetLastError() is telling you that the specified process ID was not found.
You can get a process HANDLE from a process ID by using OpenProcess().
You can get a process ID from a process HANDLE by using GetProcessId().
Related
Ordinarily XInput controllers are identified simply using an index corresponding to the player number of the controller. Is there a way to obtain more information about a controller with a specific index, such as its vendor ID, product ID, or device name?
Even better would be a identifier that corresponds uniquely and consistently to just that controller so that it can be distinguished from all other XInput devices regardless of its index, including another controller that's an identical model (i.e. same product and vendor ID), similar to the instance GUID available using DirectInput.
Can this be accomplished using XInput or another Microsoft API? I'm also open to using undocumented functions if need be.
There are a few undocumented functions inside the XInput1_4.dll. You can get the Vendor ID and Product ID like this:
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <Xinput.h>
#include <stdio.h>
struct XINPUT_CAPABILITIES_EX
{
XINPUT_CAPABILITIES Capabilities;
WORD vendorId;
WORD productId;
WORD revisionId;
DWORD a4; //unknown
};
typedef DWORD(_stdcall* _XInputGetCapabilitiesEx)(DWORD a1, DWORD dwUserIndex, DWORD dwFlags, XINPUT_CAPABILITIES_EX* pCapabilities);
_XInputGetCapabilitiesEx XInputGetCapabilitiesEx;
void main()
{
HMODULE moduleHandle = LoadLibrary(TEXT("XInput1_4.dll"));
XInputGetCapabilitiesEx = (_XInputGetCapabilitiesEx)GetProcAddress(moduleHandle, (char*)108);
for (int i = 0; i < 4; ++i)
{
printf("Gamepad %d ", i);
XINPUT_CAPABILITIES_EX capsEx;
if (XInputGetCapabilitiesEx(1, i, 0, &capsEx) == ERROR_SUCCESS)
{
printf("connected, vid = 0x%04X pid = 0x%04X\n", (int)capsEx.vendorId, (int)capsEx.productId);
}
else
{
printf("not connected\n");
}
}
}
What XInput internally does is open a device, then call DeviceIoControl on it every time it reads the joypad. (control code 0x8000e00c)
You need to hook these functions imported by "XInput1_4.dll":
CreateFileW from "api-ms-win-core-file-l1-1-0.dll"
DuplicateHandle from "api-ms-win-core-handle-l1-1-0.dll"
CloseHandle from "api-ms-win-core-handle-l1-1-0.dll"
DeviceIoControl from "api-ms-win-core-io-l1-1-0.dll"
Using the hooks for CreateFileW, DuplicateHandle and CloseHandle, you can keep track of what filename is associated with a handle.
Then when you see a call to DeviceIoControl with control code 0x8000e00c, you will know what filename is being read.
The first time you call XInputGetState, it will open multiple devices, and call DeviceIoControl multiple times, regardless of what player number you have asked for. You are only interested in the last filename seen by DeviceIoControl before XInputGetState returns. And if XInputGetState indicates the controller is not plugged in, disregard the filename you have collected for that controller number.
Examples of filenames I have seen on my own computer:
\\?\hid#{00001124-0000-1000-8000-00805f9b34fb}&vid_045e&pid_02e0&ig_00#8&7074921&2&0000#{ec87f1e3-c13b-4100-b5f7-8b84d54260cb}
\\?\usb#vid_045e&pid_028e#1&1a590e2c&1&01#{ec87f1e3-c13b-4100-b5f7-8b84d54260cb}
edit:
One more hook is required as well.
CoCreateInstance from "api-ms-win-core-com-l1-1-0.dll", to hook creating the undocumented IDeviceBroker COM object. If it can successfully create an IDeviceBroker COM object, it will use that instead of the call to CreateFileW. Parameters will be: CLSID_DeviceBroker = {acc56a05-e277-4b1e-a43e-7a73e3cd6e6c}, IID_IDeviceBroker = {8604b268-34a6-4b1a-a59f-cdbd8379fd98}. The method OpenDeviceFromInterfacePath will be called instead of CreateFileW. Alternatively, you can make creating the IDeviceBroker object simply fail, and it will proceed to use CreateFileW as usual.
I am building a dll for windows, using a Makefile, using cl.exe. I am using VS2015.. this dll uses CNG (bcrypt) for encryption operations, and bcryptr is loaded dynamically using loadlibrary call.
When i build with /Od option to disable optimization, i have no issues with any functionality. but if i use any optimization option /O1, /O2, /Ox, i see the strangest thing happen.. once i retrieve the address for a bcrypt function, such as BCryptGetFipsAlgorithmMode, using GetProcAddress, and then i make the call to that function ptr, the call stack goes away. This results in exception when the calling function tries to return.. it looks almost like when one calls a callback doesn't have the CALLBACK prefix, but i dont see the connection..
That bcrypt function's prototype looks like this:
NTSTATUS WINAPI BCryptGetFipsAlgorithmMode( __out BOOLEAN *pfEnabled)
and WINAPI seems to be defined:
define WINAPI __stdcall
Is there something I am missing? what does optimization have to do with this?
Any help would be appreciated.. Thank You!
Heres the code:
NTSTATUS GetFipsAlgorithmMode(BOOLEAN *pfEnabled )
{
FARPROC pBCryptGetFipsAlgorithmMode = NULL;
NTSTATUS (*_BCryptGetFipsAlgorithmMode)( __out BOOLEAN *);
NTSTATUS status = SPGC_ERR_LIBRARY_ADDRESS_LOOKUP_FAILURE;
if(g_hBCRYPTDLL != NULL)
{
pBCryptGetFipsAlgorithmMode = GetProcAddress(g_hBCRYPTDLL, _T("BCryptGetFipsAlgorithmMode"));
if(pBCryptGetFipsAlgorithmMode != NULL)
{
_BCryptGetFipsAlgorithmMode = (NTSTATUS (*)( __out BOOLEAN *)) pBCryptGetFipsAlgorithmMode;
status = _BCryptGetFipsAlgorithmMode(pfEnabled);
}
}
return status;
}
step over the call to _BCryptGetFipsAlgorithmMode(), and the call stack basically gets cleared.
I am trying to fix a problem in code I am not familiar with. I have traced it down to call to WriteProcessMemory always failing with ERROR_INVALID_ADDRESS. I have no idea why it fails.I tried to check if my process has the required access to write to its child process using VirtualQUery and it does. Can anyone shed some light on this? The code path is extremely convoluted so I have skipped a lot of it. Please let me know if left out any info.
CreateProcessAsUserW(hToken, exe, cmd_line,
NULL, // No security attribute.
NULL, // No thread attribute.
false, // do not inherit handles
CREATE_SUSPENDED | CREATE_UNICODE_ENVIRONMENT | DETACHED_PROCESS | EXTENDED_STARTUPINFO_PRESENT | CREATE_BREAKAWAY_FROM_JOB, // start suspended, extended startup info, break out of job
NULL, // Use the environment of the caller
NULL, // Use current directory of the caller.
&si,
&pi);
/*
....lots of work here
*/
void* address = {...};
void* var = address; // note this line
SIZE_T written;
if(!WriteProcessMemory( pi.handle,
var, address, // not completely sure what it is doing here - writing contents of address to address of var?
size, &written))
{
DWORD error = GetLastError(); // ERROR_INVALID_ADDRESS
MEMORY_BASIC_INFORMATION buffer;
SIZE_T num = VirtualQuery(address,&buffer,sizeof(MEMORY_BASIC_INFORMATION));
if(num > 0)
{
DWORD access = buffer.AllocationProtect; // PAGE_EXECUTE_WRITECOPY
DWORD state = buffer.State; // MEM_COMMIT
DWORD type = buffer.Type;
}
}
This is a 32-bit process running on 64-bit Win7.
You're performing a local VirtualQuery before trying to write into another process, whose address space may be wildly different.
If you want to be sure to have a valid pointer in that process's adress space, either you find where that process puts what interests you (good luck with ASLR), or you allocate some memory for you within that process (with, say VirtualAllocEx()).
Note: If you actually want shared memory, you should use CreateFileMapping(INVALID_HANDLE_VALUE) instead.
I wrote some code to watch for window title changes. It works fine with different windows in my Windows 7. I use SetWinEventHook like that:
SetWinEventHook(EVENT_OBJECT_NAMECHANGE,
EVENT_OBJECT_NAMECHANGE,
0,
WinEventCallback,
processId,
threadId,
WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS | WINEVENT_SKIPOWNTHREAD);
Callback:
void CALLBACK WinEventCallback(HWINEVENTHOOK hWinEventHook,
DWORD dwEvent,
HWND hwnd,
LONG idObject,
LONG idChild,
DWORD dwEventThread,
DWORD dwmsEventTime)
{
qDebug("Window %p", hwnd);
...
GetWindowText(hwnd, ...);
}
For one specific window I see the debug message "Window 0x0" all the time, e.g. I get the window handle set to zero in the callback. In this case GetWindowText fails. All other windows work fine. The question is why? I don't see anything extraordinary in Spy++:
Not all events generated may be associated with a window, especially for something as generic as a name change. The hook documentation specifically states that NULL windows are possible, so simply ignore them if your hook logic is window-oriented. If you are seeing a window change its title but you are getting a NULL window in your callback, then either it is not a real window, or there was an issue marshaling the window to your callback, or something like that.
The problem comes for the WinEventCallback's signature you are using.
Fix it by using this one: WinEventCallback(IntPtr hWinEventHook, uint iEvent, IntPtr hWnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
i have problem with this code:
int
WINAPI
Getdesc(IN WORD wcode,
OUT LPWSTR lpBuf)
{
WCHAR szDescription[256];
int res = LoadStringW(NULL,wcode,szDescription,256);
if(res == 0)
{
wcscpy(lpBuf, L"Undefined");
return 0;
}
else
{
wcscpy(lpBuf,szDescription);
return 0;
}
}
The function is placed in a DLL, and when i access it, it always returns "Undefined",
I think there is problem in my LoadString call, but i can't figure it out.
I'm new to windows programming, any help would be appreciated
The problem is that you are passing NULL as the HINSTANCE parameter. That means that you look for the resource in the executable host and not the DLL. You'll have to pass the module handle of the DLL. You are provided with that instance handle as the first parameter passed to your DllMain function.
If you are compiling with MSVC then you could use __ImageBase to obtain the module handle. Personally I would suggest that making a note of the value passed to DllMain is a cleaner approach. It avoids taking a dependency on one specific compiler.
Note also that you can call GetLastError in case LoadString fails to obtain more information about the reason for the error. It's quite possible that would have helped you identify the fault.