Programming language: C
Objective: Get the process id and name based on the current hwnd.
Current code:
HWND hwnd;
DWORD process_ID;
PWSTR process_name = NULL;
hwnd = GetForegroundWindow();
process_ID = GetWindowThreadProcessId(hwnd,&process_ID)
process_name = ????
I am not sure if I am passing correctly the arguments to the function GetWindowThreadProcessId. I found on Internet that I could use GetModuleFileNameW to get the process name but I cannot understand the documentation. Please forgive me if it is too easy to solve. I am starting in the world of C. Thanks in advance
The return value of GetWindowThreadProcessId() is a thread ID, not a process ID, so DO NOT assign that return value to your process_ID variable, or else it will overwrite the value that was output by the lpdwProcessId parameter.
HWND hwnd = GetForegroundWindow();
DWORD process_ID = 0;
if (GetWindowThreadProcessId(hwnd, &process_ID))
{
// get the process name ...
}
else
{
// error handling ...
}
Once you have the process ID, you can pass it to OpenProcess() to get a HANDLE to the running process, and then use that HANDLE with either GetModuleFileNameEx(), GetProcessImageFileName() (XP+), or QueryFullProcessImageName() (Vista+) to get the full path and filename of that process's EXE file:
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, process_ID);
if (hProcess)
{
WCHAR process_name[MAX_PATH] = {};
if (GetModuleFileNameExW(hProcess, NULL, process_name, MAX_PATH))
{
// use process_name as needed...
}
else
{
// error handling ...
}
CloseHandle(hProcess);
}
else
{
// error handling ...
}
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_ID);
if (hProcess)
{
WCHAR process_name[MAX_PATH] = {};
if (GetProcessImageFileNameW(hProcess, process_name, MAX_PATH))
{
// use process_name as needed...
}
else
{
// error handling ...
}
CloseHandle(hProcess);
}
else
{
// error handling ...
}
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_ID);
if (hProcess)
{
WCHAR process_name[MAX_PATH] = {};
DWORD size = MAX_PATH;
if (QueryFullProcessImageNameW(hProcess, 0, process_name, &size))
{
// use process_name as needed...
}
else
{
// error handling ...
}
CloseHandle(hProcess);
}
else
{
// error handling ...
}
Related
I'm experiencing a strange issue with the Restart Manager API.
I'm trying to debug a runtime error that is causing my program to crash in the middle of execution.
I have created a logging system that writes a simple log text file during the course of execution. I tried to debug the program, but it doesn't appear in my system, and the program crashes on calling RmShutdown().
This function crashes on specific files, and sometimes it doesn't appear. For example, most times it appears on C:\Users\Administrator\ntuser.dat.LOG1.
I know I shouldn't kill a system process, but it's a test when the crash happens. Does killing a process that has a handle of file make my program crash?
What could possibly be wrong here? Why would RmShutdown() fail?
BOOL KillFileOwner(__in LPCWSTR PathName)
{
BOOL Result = FALSE;
DWORD dwSession = 0xFFFFFFFF; // Invalid handle value
DWORD ret = 0;
WCHAR szSessionKey[CCH_RM_SESSION_KEY + 1] = { 0 };
if (RmStartSession(&dwSession, 0, szSessionKey) == ERROR_SUCCESS)
{
if (RmRegisterResources(dwSession, 1, &PathName, 0, NULL, 0, NULL) == ERROR_SUCCESS)
{
DWORD dwReason = 0x0;
UINT nProcInfoNeeded = 0;
UINT nProcInfo = 0;
PRM_PROCESS_INFO ProcessInfo = NULL;
// RtlSecureZeroMemory(&ProcessInfo, sizeof(ProcessInfo));
ret = (DWORD)RmGetList(dwSession, &nProcInfoNeeded, &nProcInfo, NULL, &dwReason);
if (ret != ERROR_MORE_DATA || !nProcInfoNeeded) {
RmEndSession(dwSession);
return FALSE;
}
ProcessInfo = (PRM_PROCESS_INFO)calloc(nProcInfoNeeded, sizeof(RM_PROCESS_INFO));
if (!ProcessInfo) {
RmEndSession(dwSession);
return FALSE;
}
nProcInfo = nProcInfoNeeded;
ret = (DWORD)RmGetList(dwSession, &nProcInfoNeeded, &nProcInfo, ProcessInfo, &dwReason);
if (ret != ERROR_SUCCESS || !nProcInfoNeeded) {
free(ProcessInfo);
RmEndSession(dwSession);
return FALSE;
}
DWORD ProcessId = (DWORD)GetProcessId(GetCurrentProcess());
if (!ProcessId) {
free(ProcessInfo);
RmEndSession(dwSession);
return FALSE;
}
for (UINT i = 0; i < nProcInfo; i++) {
if (ProcessInfo[i].Process.dwProcessId == ProcessId) {
free(ProcessInfo);
RmEndSession(dwSession);
return FALSE;
}
}
Result = (RmShutdown(dwSession, RmForceShutdown, NULL) == ERROR_SUCCESS);
free(ProcessInfo);
}
RmEndSession(dwSession);
}
return Result;
}
How can I check if window is already created? I tried this
BOOL isWindowReady = FALSE;
while(!isWindowReady)
{
hwnd = FindWindow(windowClass, NULL);
if (hwnd == NULL) {
hwnd = FindWindow(windowClass, NULL);
}
else {
isWindowReady = TRUE;
}
}
but id doesn't work.
Your code is technically fine (though your second call to FindWindow() is redundant) - provided you are supplying the correct value for windowClass, that is.
That being said, your loop can be simplified:
while (!FindWindow(windowClass, NULL)) { Sleep(100); }
Or, if you need the HWND to access the window later:
HWND hWindow;
do
{
hWindow = FindWindow(windowClass, NULL);
if (hWindow) break;
Sleep(100);
}
while (true);
I'm working on creating a virtual HID device in Windows 10. To prepare myself for writing the drivers, I've been analyzing the sample provided here: https://github.com/Microsoft/Windows-driver-samples/tree/master/hid/vhidmini2.
In the file app/testvhid.c, HidD_GetAttributes is used to retrieve the attributes of the HID device. It appears that the attributes are initialized in driver/vhidmini.c (hidAttributes in the EvtDeviceAdd function). However, hidAttributes is stored inside of a DEVICE_CONTEXT structure, which (from my understanding) is defined by the driver.
If hidAttributes is a user defined attribute, then how does HidD_GetAttributes know to retrieve it from the device?
I've tried to replicate this for myself by creating a KMDF driver which is based mostly on the sample given. The relevant driver code is as follows (The majority of this was taken from the sample, with the exception of the call to WdfDeviceCreateDeviceInterface):
NTSTATUS
kmdfTest2CreateDevice(
_Inout_ PWDFDEVICE_INIT DeviceInit
)
{
WDF_OBJECT_ATTRIBUTES deviceAttributes;
PDEVICE_CONTEXT deviceContext;
WDFDEVICE device;
NTSTATUS status;
PHID_DEVICE_ATTRIBUTES hidAttributes;
WdfFdoInitSetFilter(DeviceInit);
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT);
status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);
if (NT_SUCCESS(status)) {
deviceContext = DeviceGetContext(device);
deviceContext->Device = device;
deviceContext->DeviceData = 0;
hidAttributes = &deviceContext->HidDeviceAttributes;
RtlZeroMemory(hidAttributes, sizeof(HID_DEVICE_ATTRIBUTES));
hidAttributes->Size = sizeof(HID_DEVICE_ATTRIBUTES);
hidAttributes->VendorID = HIDMINI_VID;
hidAttributes->ProductID = HIDMINI_PID;
hidAttributes->VersionNumber = HIDMINI_VERSION;
if (NT_SUCCESS(status)) {
status = kmdfTest2QueueInitialize(device);
}
deviceContext->HidDescriptor = G_DefaultHidDescriptor;
deviceContext->ReportDescriptor = G_DefaultReportDescriptor;
status = WdfDeviceCreateDeviceInterface(
device,
&GUID_DEVINTERFACE_HID,
NULL // ReferenceString
);
}
return status;
}
The relevant section of code in the user mode test application is as follows (this code is virtually entirely from the given sample):
BOOLEAN
CheckIfOurDevice(
HANDLE file)
{
PHIDP_PREPARSED_DATA Ppd; // The opaque parser info describing this device
HIDP_CAPS Caps; // The Capabilities of this hid device.
HIDD_ATTRIBUTES attr; // Device attributes
if (!HidD_GetAttributes(file, &attr))
{
printf("Error: HidD_GetAttributes failed \n");
return FALSE;
}
printf("Device Attributes - PID: 0x%x, VID: 0x%x \n", attr.ProductID, attr.VendorID);
if ((attr.VendorID != HIDMINI_VID) || (attr.ProductID != HIDMINI_PID))
{
printf("Device attributes doesn't match the sample \n");
return FALSE;
}
if (!HidD_GetPreparsedData(file, &Ppd))
{
printf("Error: HidD_GetPreparsedData failed \n");
return FALSE;
}
if (!HidP_GetCaps(Ppd, &Caps))
{
printf("Error: HidP_GetCaps failed \n");
HidD_FreePreparsedData(Ppd);
return FALSE;
}
if ((Caps.UsagePage == g_MyUsagePage) && (Caps.Usage == g_MyUsage)) {
printf("Success: Found my device.. \n");
return TRUE;
}
else {
printf("failed: UsagePage: %d, Usage: %d \n", Caps.UsagePage, Caps.Usage);
}
return FALSE;
}
BOOLEAN
GetHidInterface(_Out_ HANDLE* Handle) {
CONFIGRET cr = CR_SUCCESS;
*Handle = INVALID_HANDLE_VALUE;
ULONG deviceInterfaceListLength = 0;
GUID InterfaceGuid;
PSTR deviceInterfaceList = NULL;
HANDLE devHandle = INVALID_HANDLE_VALUE;
if (NULL == Handle) {
printf("Error: Invalid device handle parameter\n");
return FALSE;
}
HidD_GetHidGuid(&InterfaceGuid);
cr = CM_Get_Device_Interface_List_Size(
&deviceInterfaceListLength,
&InterfaceGuid,
NULL,
CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
if (cr != CR_SUCCESS) {
printf("Error 0x%x retrieving device interface list size.\n", cr);
return FALSE;
}
if (deviceInterfaceListLength <= 1) {
printf("Error: No active device interfaces found.\n"
" Is the sample driver loaded?");
return FALSE;
}
deviceInterfaceList = (PSTR)malloc(deviceInterfaceListLength * sizeof(WCHAR));
if (deviceInterfaceList == NULL) {
printf("Error allocating memory for device interface list.\n");
return FALSE;
}
ZeroMemory(deviceInterfaceList, deviceInterfaceListLength * sizeof(WCHAR));
cr = CM_Get_Device_Interface_List(
&InterfaceGuid,
NULL,
deviceInterfaceList,
deviceInterfaceListLength,
CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
if (cr != CR_SUCCESS) {
printf("Error 0x%x retrieving device interface list.\n", cr);
return FALSE;
}
printf("\n....looking for our HID device (with UP=0x%04X "
"and Usage=0x%02X)\n", g_MyUsagePage, g_MyUsage);
PSTR currentInterface;
for (currentInterface = deviceInterfaceList;
*currentInterface;
currentInterface += strlen(currentInterface) + 1) {
devHandle = CreateFile(currentInterface,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, // no SECURITY_ATTRIBUTES structure
OPEN_EXISTING, // No special create flags
0, // No special attributes
NULL); // No template file
if (INVALID_HANDLE_VALUE == devHandle) {
printf("Warning: CreateFile failed: %d\n", GetLastError());
continue;
}
if (CheckIfOurDevice(devHandle)) {
*Handle = devHandle;
return TRUE;
}
else {
CloseHandle(devHandle);
}
}
return FALSE;
}
The HidD_GetAttributes function passes, but the CheckIfOurDevice function fails when checking the device attributes ("Device attributes doesn't match the sample"). I've checked some of the attribute values that are being set by HidD_GetAttributes, but they don't match up with the ones set by the driver. Is the sample making some other call that I'm missing?
I have following code, after CopyMemory my pBuf is empty, it contains no data from newCommand, or when I want to add something in that struct it doesnt work... What am I doing wrong?
struct StCommand
{
TCHAR sourcePath[MAX_PATH];
TCHAR sourceFile[MAX_PATH];
TCHAR fileName[MAX_PATH];
bool endThread;
};
handlesInstance.mapFileHandle = CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // maximum object size (high-order DWORD)
sizeof(StCommand), // maximum object size (low-order DWORD)
handlesInstance.valueBuffer); // name of mapping object
if (handlesInstance.mapFileHandle == NULL)
{
_tprintf(TEXT("Could not create file mapping object (%d).\n"),
GetLastError());
return 0;
}
handlesInstance.pBuf = (StCommand*) MapViewOfFile(
handlesInstance.mapFileHandle, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
sizeof(StCommand));
if (handlesInstance.pBuf == NULL)
{
_tprintf(TEXT("Could not map view of file (%d).\n"),
GetLastError());
return 0;
}
StCommand newCommand = { NULL, NULL, NULL, false };
CopyMemory(handlesInstance.pBuf, &newCommand, sizeof(StCommand));
CopyFiles(*handlesInstance.pBuf);
Here is CopyFiles function, where I send (*handlesInstance.pBuf) and I want to set values of pBuf here, to create path, to copy file later
void CopyFiles(StCommand stCommand)
{
while (!stCommand.endThread)
{
DWORD dwWaitEventResult;
dwWaitEventResult = WaitForSingleObject(handlesInstance.dataInEvent, INFINITE);
switch (dwWaitEventResult)
{
// Event object was signaled
case WAIT_OBJECT_0:
{
//Command processing
if (!stCommand.endThread)
{
GetSzSetting(pathValueName, REPOSITORY_PATH);
TCHAR newFile[MAX_PATH];
_tcscpy_s(newFile, handlesInstance.valueBuffer);
_tcscat_s(newFile, _T("/"));
TCHAR buffer[MAX_PATH];
swprintf_s(buffer, _T("%d"), GetDwordSetting(indexValueName, 0));
_tcscat_s(newFile, buffer);
_tcscat_s(newFile, _T("."));
_tcscat_s(newFile, stCommand.fileName);
TCHAR oldFile[MAX_PATH];
_tcscpy_s(oldFile, stCommand.sourcePath);
_tcscat_s(oldFile, _T("/"));
_tcscat_s(oldFile, stCommand.fileName);
if (CopyFile(oldFile, newFile, FALSE))
{
_tprintf(_T("File %s copied successfully into repository.\n"), stCommand.fileName);
SetDwordSetting(indexValueName, GetDwordSetting(indexValueName, 0) + 1);
}
else
{
_tprintf(_T("Could not copy file %s.\n"), stCommand.fileName);
_tprintf(_T("Failed with error code: %d\n"), GetLastError());
}
}
ResetEvent(handlesInstance.dataInEvent);
if (!SetEvent(handlesInstance.dataOutEvent))
{
printf("SetEvent OutEvent failed (%d)\n", GetLastError());
}
break;
}
// An error occurred
default:
printf("Wait error (%d)\n", GetLastError());
break;
}
}
}
I am trying to inject a dll into an existing process. I am trying to use the CreateRemoteThread LoadLibrary way. I understand how it works, but I cannot figure out why CreateRemoteThread is returning null (failing)... I am on Windows 7 so this may be the reason, but I don't know for sure if it is.. Perhaps I need to set privaleges? My code is below:
#define DLL_NAME "message.dll"
void main()
{
InjectDLL(1288, DLL_NAME);
}
BOOL InjectDLL(DWORD dwProcessId, LPCSTR lpszDLLPath)
{
HANDLE hProcess, hThread;
LPVOID lpBaseAddr, lpFuncAddr;
DWORD dwMemSize, dwExitCode;
BOOL bSuccess = FALSE;
HMODULE hUserDLL;
if((hProcess = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION
|PROCESS_VM_WRITE|PROCESS_VM_READ, FALSE, dwProcessId)))
{
dwMemSize = lstrlen(lpszDLLPath) + 1;
if(lpBaseAddr = VirtualAllocEx(hProcess, NULL, dwMemSize, MEM_COMMIT, PAGE_READWRITE))
{
if(WriteProcessMemory(hProcess, lpBaseAddr, lpszDLLPath, dwMemSize, NULL))
{
if(hUserDLL = LoadLibrary(TEXT("kernel32.dll")))
{
if(lpFuncAddr = GetProcAddress(hUserDLL, TEXT("LoadLibraryA")))
{
if(hThread = CreateRemoteThread(hProcess, NULL, 0, lpFuncAddr, lpBaseAddr, 0, NULL))
{
WaitForSingleObject(hThread, INFINITE);
if(GetExitCodeThread(hThread, &dwExitCode)) {
bSuccess = (dwExitCode != 0) ? TRUE : FALSE;
}
CloseHandle(hThread);
}
}
FreeLibrary(hUserDLL);
}
}
VirtualFreeEx(hProcess, lpBaseAddr, 0, MEM_RELEASE);
}
CloseHandle(hProcess);
}
return bSuccess;
}
yes you need privileges before you open the precess, here's the code:
int GimmePrivileges(){
HANDLE Token;
TOKEN_PRIVILEGES tp;
if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &Token)
{
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid); tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(Token, 0, &tp, sizeof(tp), NULL, NULL);
}
}
An other thing... this code is confusing!!! you need to synthesize!