I'm trying to edit memory in a program. For the most part the code works, but when I try to initiate a handle on the process, it returns NULL.
#include <iostream>
#include <windows.h>
using namespace std;
int main() {
int playerTotalRam = 761;
HWND hwnd = FindWindowA(NULL, "generic game"); // specifies the window to act
upon
// error message if the window isn't found
if (hwnd == NULL) {
cout << "window not found!\n";
system("PAUSE");
} else {
DWORD processID;
// stores the process id of the window
GetWindowThreadProcessId(hwnd, &processID);
// gets the process id of the window
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
// opens the process with full access
if (!handle) {
cout << "couldnt initiate a handle on the process!\n";
system("PAUSE");
}
// error message if the process ID isn't found
if (processID == NULL) {
cout << "cannot find process!\n";
system("PAUSE");
} else {
WriteProcessMemory(handle, (LPVOID)0x044A52C8, &playerTotalRam,
4, 0); // this writes the new value to the listed address
}
}
return 0;
}
The program outputs "couldnt initiate a handle on the process!"
I have this same error with other programs.
What i want to know is what am I doing wrong, and how can I fix this.
My system is windows 10 home.
Either FindWindowA is failing, resulting in an incorrect process id because you have the wrong window title text or you're not running your program as administrator. You need to run as administrator to get PROCESS_ALL_ACCESS permissions and make sure your title text is correct. This will solve your problem.
Related
I can get handle from GetForegroundWindow function. And I want to get BaseName
of handle. So i used GetModelBaseName function. But I guess this function was not work correctly.
TCHAR TitleName[MAX_PATH] = TEXT("");
HANDLE hFirst = GetForegroundWindow();
GetModuleBaseName(hFirst, NULL, TitleName, MAX_PATH);
_tprintf(TEXT("%s \n"), TitleName);
Tell me, what is the problem?
You are doing it wrong, that's why it's returning false and GetLastError will return ERROR_INVALID_HANDLE (6).
HWND WINAPI GetForegroundWindow(void);
Will return the current foreground window and will return it's window handle of type HWND.
You can do this to retrieve the filename of your application:
TCHAR szName[MAX_PATH];
GetModuleBaseName(GetCurrentProcess(), GetModuleHandle(NULL), szName, MAX_PATH);
Besides, you can also use GetModuleFileName or GetMappedFileName to retrieve the full path of your application
Edit: He wants to do something else too. To retrieve the path of another process, you will have to open that process with a process id. For instance, if 9912 is the process id of Chrome then you can execute the following code to retrieve it's path
HANDLE process = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, 9912);
if (process)
{
char file_path[MAX_PATH];
if (::GetModuleFileNameEx(process, nullptr, file_path, MAX_PATH))
{
std::cout << file_path << std::endl;
}
else
{
std::cout << "Error retrieving path" << std::endl;
}
::CloseHandle(process);
}
I'm fairly new to C++ so my question is: Is there an alternative to OpenProcess()?The game does not let me get access to it, tried asking for smaller access than PROCESS_ACCESS_ALL since that might be a huge red flag. But here's my source code:
#include "stdafx.h"
#include <iostream>
#include <string.h>
#include <Windows.h>
int main()
{
HWND hWnd = FindWindow(NULL, "Growtopia");
if (hWnd == NULL)
{
std::cout << "ERROR: Unable to find window process" << std::endl;
Sleep(2500);
exit(-1);
}
DWORD pID;
GetWindowThreadProcessId(hWnd, &pID);
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, false, pID);
if (!hProc)
{
std::cout << "Error: Unable to gain access to window" << std::endl;
Sleep(2500);
exit(-1);
}
return 0;
}
PS: The game I'm trying to gain access to is Growtopia if you couldn't find it out by the FindWindow() function :)
Thanks in advance.
Edit: My purpouse of the program is to edit a value of an adress
My purpouse of the program is to edit a value of an adress
That requires the use of WriteProcessMemory(), which requires PROCESS_VM_WRITE and PROCESS_VM_OPERATION permissions to the target process:
HANDLE hProc = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, false, pID);
To open a process with those permissions, the calling thread needs the "SeDebugPrivilege" privilege enabled, which means it has to be running as a user that is allowed to obtain debug privileges, such as an admin.
Run your app as a debug user (or dynamically impersonate such a user), then use OpenThreadToken() to open the calling thread's current access token and adjust it with AdjustTokenPrivileges() to make sure the "SeDebugPrivilege" privilege is active, before then calling OpenProcess():
Changing Privileges in a Token
How to obtain a handle to any process with SeDebugPrivilege
Is it possible to launch process in system context from a parent process thats running under administrator account with elevation(say a command prompt). The problem is similar to what psexec does but more of how it actually implements this.
I was thinking opening the crss.exe/winlogon.exe process duplicating the token and launching a new process using that process token. But I fail to even open the process handle (Getlasterror return 5). Can someone let me know if this is the right approach or the process should be launched differently ?
HANDLE hWinLogonProcess;
for(const auto& ps : running_processes)
{
if(ps.id == GetCurrentProcessId() ||
0 != ps.short_name.CompareNoCase(L"winlogon.exe"))
{
continue;
}
DWORD dwWinLogonSessionId(0);
if(FALSE == ProcessIdToSessionId(GetCurrentProcessId(), &dwWinLogonSessionId))
{
std::wcerr<<"Could not get Winlogon process session id"<<std::endl;
continue;
}
if(dwWinLogonSessionId != dwCurSessionId)
{
continue;
}
hWinLogonProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ps.id);
if(FALSE == hWinLogonProcess)
{
std::wcerr<<"Failed to get winlogon process handle"<<std::endl;
return;
}
else
{
std::wcout<<"Able to open process "<<ps.short_name.GetString()<<" handle"<<std::endl;
break;
}
}
I am sure its possible as there is a working tool (psexec) but I couldnt find any reference online to do this.
Also this is similar to question, but posting separately as there was details on how it had to be achieved.
Yes, this is possible (without any service help).
But I fail to even open the process handle
Does your process have the SE_DEBUG_PRIVILEGE privilege enabled?
With this privilege, you can open a system process with all access if it is not protected (smss.exe, csrss.exe, services.exe), and use that handle in CreateProcessAsUser(), or with UpdateProcThreadAttribute(PROC_THREAD_ATTRIBUTE_PARENT_PROCESS) if you also have SE_ASSIGNPRIMARYTOKEN_PRIVILEGE and SE_TCB_PRIVILEGE privileges enabled (for setting the token's SessionId to 0), which you can get in 2 ways:
open a thread from an unprotected system process and impersonate it, then open your own thread token and adjust privileges on it.
open a token from any system process (this works even for protected processes), duplicate the token, adjust privileges on it, and then impersonate with this token.
To "launch a process in the system context", if you want to run the process:
with the LocalSystem token.
in the System terminal session (0)
Both, as I say, are possible. And all you need is SE_DEBUG_PRIVILEGE.
more simply - open some system process with PROCESS_CREATE_PROCESS access right. Use this handle with UpdateProcThreadAttribute(PROC_THREAD_ATTRIBUTE_PARENT_PROCESS). As a result, your started process inherits a token from the system process. This will be not work on XP, but there it is possible to hook NtCreateProcess/Ex() to replace HANDLE ParentProcess with your opened handle.
Another way is to use CreateProcessAsUser(). Before creating the process, you will be need SE_ASSIGNPRIMARYTOKEN_PRIVILEGE and SE_TCB_PRIVILEGE privileges to set the token's TokenSessionId (if you want to run in session 0).
Thanks to RbMm answer I figured a way to accomplish this task.
For any of you who did not succeed, I leave below something that might help:
//First we need to add debug privilege to this process
HANDLE hToken;
if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken))
{
std::cout << "OpenProcessToken failed: " << GetLastError();
return 0;
}
TOKEN_PRIVILEGES tk;
tk.PrivilegeCount = 1;
tk.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tk.Privileges[0].Luid))
{
std::cout << "LookupPrivilegeValue failed: " << GetLastError();
return 0;
}
AdjustTokenPrivileges(hToken, FALSE, &tk, 0, NULL, 0);
if((DWORD res = GetLastError()) != ERROR_SUCCESS)
{
std::cout << "AdjustTokenPrivileges failed: " << res;
}
CloseHandle(hToken);
//Now we need a handle to a process that already runs as SYSTEM.
//You can choose any process that is not protected (if OpenProcess fails try with other process)
//pid of chosen process (you can get this by opening task manager and go to
//Details tab or by enumerating all processes and extract that one you need)
DWORD pid;
HANDLE hProcess = OpenProcess(PROCESS_CREATE_PROCESS, FALSE, pid);
if (!hProcess)
{
std::cout << "OpenProcess with pid " << pid << "failed: " << GetLastError();
return 0
}
//We need to initialize a list that contains PROC_THREAD_ATTRIBUTE_PARENT_PROCESS
//to specify that parent process of the process we are going to start is the
//process we opened earlier (this will make the child process inherit the system context).
//This list will be specified in a STARTUPINFOEX object that CreateProcess will get
STARTUPINFOEX siex = { sizeof(STARTUPINFOEX) };
siex.StartupInfo.cb = sizeof(STARTUPINFOEXW);
//We need to initialize our list. To do this we call InitializeProcThreadAttributeList
//with a NULL list to get how big our list needs to be to store all attributes
//we want to specify, then we allocate our list with the size we got from first call
//and we call again the function to initialize the list.
SIZE_T cbAttributeListSize = 0;
if(!InitializeProcThreadAttributeList(NULL, 1, 0, &cbAttributeListSize))
{
std::cout << "InitializeProcThreadAttributeList failed: " << GetLastError();
return 0
}
siex.lpAttributeList = reinterpret_cast<PPROC_THREAD_ATTRIBUTE_LIST>(HeapAlloc(GetProcessHeap(), 0, cbAttributeListSize));
if(!InitializeProcThreadAttributeList(siex.lpAttributeList, 1, 0, &cbAttributeListSize))
{
std::cout << "InitializeProcThreadAttributeList failed: " << GetLastError();
return 0
}
if(!UpdateProcThreadAttribute(siex.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &hProcess, sizeof(hProcess), NULL, NULL))
{
std::cout << "UpdateProcThreadAttribute failed: " << GetLastError();
return 0
}
//path to program we want to run in system context
LPWSTR szCmdline = _wcsdup(TEXT("C:\\Windows\\System32\\notepad.exe"));
PROCESS_INFORMATION pi = { 0 };
if(!CreateProcess(NULL, szCmdline, nullptr, nullptr, FALSE, EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, reinterpret_cast<LPSTARTUPINFOW>(&siex), &pi))
{
std::cout << "CreateProcess failed: " << GetLastError();
return 0
}
The following code works fine in displaying the process id of all the processes (eg: notepad.exe) running under different users. But process under current user is alone getting killed. I need to kill all the processes running under different users.
#define SAMPLEAPP "notepad.exe"
void main()
{
KillProcessByName(SAMPLEAPP);
system("pause");
}
void KillProcessByName(const char *filename)
{
// Taking snapshot of all processes
HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
//structure to capture each entry in snapshot
PROCESSENTRY32 pEntry;
pEntry.dwSize = sizeof (pEntry);
//capture the first process in the list
BOOL hRes = Process32First(hSnapShot, &pEntry);
while (hRes)
{
char tempProcess[PROCESS_SIZE];// = pEntry.szExeFile;
wcstombs(tempProcess, pEntry.szExeFile, PROCESS_SIZE);
//if process name is equal to the process passed as argument to be killed
if (strcmp(tempProcess, filename) == 0)
{
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, 0,
(DWORD) pEntry.th32ProcessID);
std::cout << "Process ID of the Process " << tempProcess << " is : " << pEntry.th32ProcessID;
if (hProcess != NULL)
{
// Kill the process
TerminateProcess(hProcess, 9);
CloseHandle(hProcess);
}
}
//Capture the next process in process snapshot
hRes = Process32Next(hSnapShot, &pEntry);
}
CloseHandle(hSnapShot);
}
How can I kill a process, even if it belongs to another user?
Right-click your program, and then select "Run as administrator".
I am developing a little program for becoming more productive. It should disconnect the user from the Internet or shut your computer down after a preset number of minutes. The program shouldn't be closed with task manager. I could compile the program and it run, but I could close it with task manager. I got my inspiration from this page:
#include <iostream>
#include <Windows.h>
#include <AccCtrl.h>
#include <AclAPI.h>
#include <tchar.h>
#include "shutdown.cpp"
#include "disconnect.cpp"
static const bool ProtectProcess()
{
HANDLE hProcess = GetCurrentProcess();
EXPLICIT_ACCESS denyAccess = {0};
DWORD dwAccessPermissions = GENERIC_WRITE|PROCESS_ALL_ACCESS|WRITE_DAC|DELETE|WRITE_OWNER|READ_CONTROL;
BuildExplicitAccessWithName( &denyAccess, _T("CURRENT_USER"), dwAccessPermissions, DENY_ACCESS, NO_INHERITANCE );
PACL pTempDacl = NULL;
DWORD dwErr = 0;
dwErr = SetEntriesInAcl( 1, &denyAccess, NULL, &pTempDacl );
// check dwErr...
dwErr = SetSecurityInfo( hProcess, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pTempDacl, NULL );
// check dwErr...
LocalFree( pTempDacl );
CloseHandle( hProcess );
return dwErr == ERROR_SUCCESS;
}
int main()
{
using namespace std;
int abfrage;
ProtectProcess();
for (;;)
{
cout << "10.Cut your Internet connection" << endl
<< "11.Cut your Internet connection after 'x' minutes of surfing" << endl
<< "20.Shutdown" << endl;
cin >> abfrage;
switch(abfrage)
{
case 10: disconnectnow(); break;
case 11: disconnectlater(); break;
case 20: shutdown(); break;
default: cout << "nothing to see here" << endl;
}
}
return EXIT_SUCCESS;
}
This functionality is, deliberately, unsupported and actively made intractable:
Why can't you trap TerminateProcess?
If a user fires up Task Manager and clicks the End Task button on the Applications tab, Windows first tries to shut down your program nicely, by sending WM_CLOSE messages to GUI programs and CTRL_CLOSE_EVENT events to console programs. But you don't get a chance to intercept TerminateProcess. Why not?
TerminateProcess is the low-level process-killing function. It bypasses DLL_PROCESS_DETACH and anything else in the process. When you kill with TerminateProcess, no more user-mode code will run in that process. It's gone. Do not pass go. Do not collect $200.
If you could intercept TerminateProcess, you would be escalating the arms race between programs and users. Suppose you could intercept it. Well, then if you wanted to make your program unkillable, you would just hand in your TerminateProcess handler! And then people would ask for "a way to kill a process that is refusing to be killed with TerminateProcess," and we'd be back to where we started.
In practice, programs attempting to evade detection and task kill try to rename themselves to near isoforms of the Windows system processes. Don't do this. It guarantees your program will be submitted as malware and will kill your credibility dead.