C++ Alternative to OpenProcess() (Program not willing to grant me permission) - c++

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

Related

Privilege Escalation and Access Token Rights Modification

I have started to learn more and more about Windows access token and privilege adjustment but as I progress, I am getting confused. I ask some questions here to better understand this security mechanism of Windows.
In windows, when I run whoami /priv command for non-administrator users, it gives me the following result:
C:\Users\light>whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ==================================== ========
SeShutdownPrivilege Shut down the system Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeUndockPrivilege Remove computer from docking station Disabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
SeTimeZonePrivilege Change the time zone Disabled
But when I run this command with administrator account it gives me a long list of privilege names which most of them are disabled. Now my first question is: Why some of these privileges are disabled? When a privilege disabled, it means user couldn't take the right to use that privilege?
My second question: How should I exactly modify an access token to get Se_Debug privilege? I do the following steps, but my application has not modify the token:
Call OpenProcessToken to open a process for access token query.
Initialized TOKEN_PRIVILEGES for querying access token.
Call LookupPrivilegeValue to check privilege
Call AdjustTokenPrivileges to adjust that privilege
My source code:
#include <Windows.h>
#include <iostream>
#pragma comment(lib, "advapi32.lib")
class privilege
{
private:
BOOL m_ok;
LUID m_luid;
LUID m_privilege_id;
HANDLE m_handle_token;
BOOL m_has_priviliege;
PRIVILEGE_SET m_privilege_set;
TOKEN_PRIVILEGES m_token_privilege;
public:
BOOL check(LPCWSTR arg_privilege)
{
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &m_handle_token))
m_ok = LookupPrivilegeValue(NULL, arg_privilege, &m_privilege_id);
if (m_ok)
{
m_privilege_set.PrivilegeCount = 1;
m_privilege_set.Control = PRIVILEGE_SET_ALL_NECESSARY;
m_privilege_set.Privilege[0].Luid = m_privilege_id;
m_privilege_set.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
m_ok = PrivilegeCheck(m_handle_token, &m_privilege_set, &m_has_priviliege);
}
if (m_ok && !m_has_priviliege)
return FALSE;
else
return TRUE;
}
BOOL set(HANDLE arg_token, LPCTSTR arg_privilege, BOOL arg_enable_privilege)
{
if (!LookupPrivilegeValue(NULL, arg_privilege, &m_luid))
{
printf("LookupPrivilegeValue error: %u\n", GetLastError());
return FALSE;
}
m_token_privilege.PrivilegeCount = 1;
m_token_privilege.Privileges[0].Luid = m_luid;
if (arg_enable_privilege)
m_token_privilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
m_token_privilege.Privileges[0].Attributes = 0;
// Enable the privilege or disable all privileges.
if (!AdjustTokenPrivileges(arg_token, FALSE, &m_token_privilege, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL))
{
printf("AdjustTokenPrivileges error: %u\n", GetLastError());
return FALSE;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
printf("The token does not have the specified privilege. \n");
return FALSE;
}
return TRUE;
}
};
int main(int argc, wchar_t* argv)
{
HANDLE process_handle;
PHANDLE token_handle = NULL;
privilege o_privilege;
BOOL open_token_status = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, token_handle);
if (open_token_status != NULL)
{
std::wcout << L"OpenProcessToken has been failed." << std::endl;
return EXIT_FAILURE;
}
else
{
std::wcout << L"Process has Backup privilege: " << std::boolalpha << o_privilege.check(L"SE_BACKUP_NAME") << std::endl;
BOOL privilege_adjust_status = o_privilege.set(token_handle, L"SeBackupPrivilege", TRUE);
std::wcout << L"Process has Backup privilege: " << std::boolalpha << o_privilege.check(L"SE_BACKUP_NAME") << std::endl;
return privilege_adjust_status;
}
return 0;
}
But this program couldn't set backup privilege for the process. Somebody could explain token enumeration and adjustment in Windows OS with a step by step approach?
Also I have a real problem with impersonation concept. Why we need such thing in Windows OS?
How should I exactly modify an access token to get Se_Debug privilege?
According to Changing Privileges in a Token,
You can change the privileges in either a primary or an impersonation
token in two ways:
Enable or disable privileges by using the AdjustTokenPrivileges function.
Restrict or remove privileges by using the CreateRestrictedToken function.
To assign privileges to a user account, according to Assigning Privileges to an Account
You can assign privileges to accounts either by using the Local
Security Policy Microsoft Management Console (MMC) snap-in
(Secpol.msc) or by calling the LsaAddAccountRights function.

c++ my program cannot initialize a handle on a process

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.

How to get ModuleBaseName using GetForegroundWindow function?

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

Running Process in system context

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
}

Prevent process from being closed in task manager

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.