Otwarcie procesu z SeDebugPrivilege

Otwarcie procesu z SeDebugPrivilege
MR
  • Rejestracja:około 18 lat
  • Ostatnio:ponad 14 lat
0

Witam,
Chce otworzyć pewien proces, by odczytać pewną wartość z pamięci.
Otwarcie procesu z flagą PROCESS_VM_READ jest niemożliwe.
Jednak wyczytałem w MSDN, że można taki proces otworzyć nakładając mu przywilej SeDebugPrivilege.

Jednego pojąć nie moge.
Do funkcji OpenProcessToken musze przekazać HANDLE procesu, którego nie mogę otworzyć.
http://msdn.microsoft.com/en-us/library/aa379295(VS.85).aspx

Oczywiście wystarczy ten proces otworzyć z flagą PROCESS_QUERY_INFORMATION i taki HANDLE przekazać do OpenProcessToken. Jednak również OpenProcess dla mojego procesu daje False.
Czy coś w kodzie namieszałem, czy mam jakiś super zabezpieczony proces?

Kopiuj
#include <windows.h>
#include <iostream>
#include <conio.h>

LPCWSTR lpstrWindowName = L"WindowName";
HWND hWindow;
DWORD dwProcess;
HANDLE hProcess;
int value = 0;
DWORD* pointer = (DWORD*)0x00540240;
HANDLE hToken;

BOOL SetPrivilege(
    HANDLE hToken,          // access token handle
    LPCTSTR lpszPrivilege,  // name of privilege to enable/disable
    BOOL bEnablePrivilege   // to enable or disable privilege
    ) 
{
	TOKEN_PRIVILEGES tp;
	LUID luid;

	if ( !LookupPrivilegeValue( 
			NULL,            // lookup privilege on local system
			lpszPrivilege,   // privilege to lookup 
			&luid ) )        // receives LUID of privilege
	{
		printf("LookupPrivilegeValue error: %u\n", GetLastError() ); 
		return FALSE; 
	}

	tp.PrivilegeCount = 1;
	tp.Privileges[0].Luid = luid;
	if (bEnablePrivilege)
		tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	else
		tp.Privileges[0].Attributes = 0;

	// Enable the privilege or disable all privileges.

	if ( !AdjustTokenPrivileges(
		   hToken, 
		   FALSE, 
		   &tp, 
		   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()
{	
	if (!(hWindow = FindWindow(NULL, lpstrWindowName)))
		printf ("Window not found\n");
		
	if (!GetWindowThreadProcessId(hWindow, &dwProcess))
		printf ("Process not found\n");	
	
	if (!(hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, false, dwProcess)))
		printf ("Cant open process! \n");

	if(!OpenProcessToken(hProcess,/*TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY*/TOKEN_ADJUST_PRIVILEGES,&hToken))
        printf ("Cannot open process token\n");	
	SetPrivilege(hToken, SE_DEBUG_NAME, true);
	
	if (!ReadProcessMemory(hProcess, pointer, &value, 4, NULL))
	{
		printf ("Cant read in: 0x00%X \n", pointer);
		printf ("Error: %d\n", GetLastError());
	}
	else
	{
		printf ("Memory: %s \n", value);
	}

	getch();
	return 0;
}
Kopiuj
Cant open process!
Cannot open process token
AdjustTokenPrivileges error: 6
Cant read in: 0x00740240
Error: 6

www.pcmod.pl - Forum o tematyce komputerowej. Diagnostyka, naprawa, overclocking, software.
adf88
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 12 lat
0

Próbowałeś na innym procesie?
Co zwraca GetLastError po nieudanej próbie otwarcia procesu?
Masz uprawnienia administratora? Jakiego masz Windows'a?

FA
  • Rejestracja:prawie 16 lat
  • Ostatnio:ponad 11 lat
0

A może tak spróbować otworzyć inny proces, kiedy samemu się ma SeDebugPrivilege? Znaczy się, musisz pobrać token SWOJEGO procesu (patrz OpenProcessToken(GetCurrentProcess(), pozostałe argi)), ustawić przywilej SeDebugPrivilege, a potem próbować otwierać procesy, wątki, konserwy itp. Na bank zadziała, chyba, że coś wyjątkowo popsujesz :>

MR
  • Rejestracja:około 18 lat
  • Ostatnio:ponad 14 lat
0

@adf88
GetLastError zwraca 6.
Wszystko jest tak jak powinno.

Testowałem na innym procesie i wszystko działa poprawnie.
Problem polega na tym, że mój proces jest zabezpieczony przed FindWindow ;).

@Fanael
A czy przypadkiem SeDebugPrivilege nie nadaję się osobno dla każdego z procesów?

W sumie zrobiłem to inaczej, skoro nie moge uzyskać ID mojego procesu to zrobiłem snapshot i stamtąd zgarnełem mój proces.
Jednak zjadł mnie taki banał. Jak porównać dwie zmienne tekstowe typu wchar_t? ;)

Kopiuj
PROCESSENTRY32 pe32;
wchar_t cProcessName[260] = L"term.exe";
//.......................
HANDLE hProcessSnap;

do
if (pe32.szExeFile == cProcessName)
 return pe32.th32ProcessID;
while (Process32Next( hProcessSnap, &pe32 ))
// .........................
 return false;

Debugowałem kod i w momencie kiedy proces nazywa się term.exe (zmienna p32.szExeFile) to if nadal nie uznaje że są takie same jak cProcessName. Nie wiem jak to załatwić ;d


www.pcmod.pl - Forum o tematyce komputerowej. Diagnostyka, naprawa, overclocking, software.
FA
  • Rejestracja:prawie 16 lat
  • Ostatnio:ponad 11 lat
0

Tak, nadaje się każdemu osobno. Ale jakbyś przeczytał MSDN, to byś widział, że OpenProcess się wywala, jeśli caller nie ma SeDebugPrivilege... Zrób to, o czym mówiłem, zamiast robić jakieś chore workaroundy, dopiero jak nie będzie działać, to mów, że nie działa.
Hm... Porównanie wcharowych cstringów... lstrcmpW?
A można wiedzieć, po co ten ID twojego procesu? Możesz sobie wyciągnąć uchwyt do niego przecież (GetCurrentProcess()).

MR
  • Rejestracja:około 18 lat
  • Ostatnio:ponad 14 lat
0

Ale jakbyś przeczytał MSDN, to byś widział, że OpenProcess się wywala, jeśli caller nie ma SeDebugPrivilege

To open a handle to another local process and obtain full access rights, you must enable the SeDebugPrivilege privilege.

Jeżeli chodzi Ci o tą linijkę to nie jest tu wyraźnie napisane, w którym procesie trzeba ustawić przywilej SeDebug.

A można wiedzieć, po co ten ID twojego procesu? Możesz sobie wyciągnąć uchwyt do niego przecież (GetCurrentProcess()).

Chce odczytać pamięć w nie moim procesie, dlatego najpierw potrzebuje znależć jego ID.

Hm... Porównanie wcharowych cstringów... lstrcmpW?

Dziękuje ;)

Zrób to, o czym mówiłem, zamiast robić jakieś chore workaroundy, dopiero jak nie będzie działać, to mów, że nie działa.

Ustawiłem dla siebie SeDebugPrivilege, mimo to nie mogę otworzyć tego drugiego procesu z flagą PROCESS_QUERY_INFORMATION.

Kopiuj
DWORD dwProcess; // ID mojego procesu
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
		
	SetPrivilege(hToken, SE_DEBUG_NAME, true);

	if (!(hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, false, dwProcess)))
	{		
		printError(L"OpenProcess");
	}

	if(!OpenProcessToken(hProcess,TOKEN_ADJUST_PRIVILEGES,&hToken))
        printError(L"OpenProcessToken");

OpenProcess failed, error 5 - Odmowa dostępu

Jest jakaś inna metoda na otwarcie tego procesu? ;)


www.pcmod.pl - Forum o tematyce komputerowej. Diagnostyka, naprawa, overclocking, software.
adf88
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 12 lat
0
Fanael napisał(a)

A może tak spróbować otworzyć inny proces, kiedy samemu się ma SeDebugPrivilege? Znaczy się, musisz pobrać token SWOJEGO procesu (patrz OpenProcessToken(GetCurrentProcess(), pozostałe argi)), ustawić przywilej SeDebugPrivilege, a potem próbować otwierać procesy, wątki, konserwy itp. Na bank zadziała, chyba, że coś wyjątkowo popsujesz :>
Zgadza się, zbyt pobieżnie przeglądnąłem wypowiedź. Tak jak Fanael mówi, ustaw SeDebugPrivilege swojemu procesowi a następnie otwórz proces do którego się chcesz dostać z prawem PROCESS_VM_READ | co_tam_potrzebujesz (zaleca się używania minimalnego zestawu praw).
Czyli najpierw nadajesz sobie uprawnienie:

Kopiuj
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
SetPrivilege(hToken, SE_DEBUG_NAME, true);
CloaseHandle(hToken);

następnie otwierasz inny proces:

Kopiuj
        if (!(hWindow = FindWindow(NULL, lpstrWindowName)))
                printf ("Window not found\n");
               
        if (!GetWindowThreadProcessId(hWindow, &dwProcess))
                printf ("Process not found\n");       
       
        if (!(hProcess = OpenProcess(PROCESS_VM_READ, false, dwProcess)))
                printf ("Cant open process! \n");

i grzebiesz w bebechach

Kopiuj
        if (!ReadProcessMemory(hProcess, pointer, &value, 4, NULL))
        {
                printf ("Cant read in: 0x00%X \n", pointer);
                printf ("Error: %d\n", GetLastError());
        }
        else
        {
                printf ("Memory: %s \n", value);
        }
MR
  • Rejestracja:około 18 lat
  • Ostatnio:ponad 14 lat
0

Tak jak już napisałem w poście wyżej. Dokładnie tak zrobiłem ;).
Niestety bez skutku, dalej odmowa dostępu.
Dodam, że funkcja nadająca przywilej SeDebugPrivilege mojemu procesowi zwraca true.
Mam uprawnienia administratora w systemie, zresztą inne procesy da rade tak otworzyć, tylko tego jednego nie na którym mi zależy. :/


www.pcmod.pl - Forum o tematyce komputerowej. Diagnostyka, naprawa, overclocking, software.
adf88
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 12 lat
0
tMbRaga napisał(a)

Tak jak już napisałem w poście wyżej. Dokładnie tak zrobiłem ;).
W poście napisałeś:

DWORD dwProcess; // ID mojego procesu
...
if (!(hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, false, dwProcess)))
czyli tak, jakbyś podawał nie to ID co trzeba.

MR
  • Rejestracja:około 18 lat
  • Ostatnio:ponad 14 lat
0

Chwila, bo już samemu mi się miesza.
HANDLE z mojego procesu otrzymałem z GetCurrentProcess(). Przekazuje do OpenProcessToken() i nadaje przywilej SeDebugPrivilege.
Następnie otwieram przez OpenProcess() ten proces, do którego chce uzyskać dostęp (oddzielna aplikacja). Bezskutecznie.

Nie muszę używać OpenProcess względem mojego procesu tak? ... bo HANDLE już posiadam.

EDIT:
Próbowałem też -> OpenProcess(PROCESS_QUERY_INFORMATION, false,GetCurrentProcessID()).
Następnie nadawałem uprawnienia. (W sumie to samo co wyżej, tylko bardziej namieszane)
Niestety nadal tamtego procesu otworzyć nie mogę.


www.pcmod.pl - Forum o tematyce komputerowej. Diagnostyka, naprawa, overclocking, software.
SA
  • Rejestracja:prawie 21 lat
  • Ostatnio:ponad 9 lat
  • Postów:513
0

Otwórz go za pomocą DuplicateHandle zamiast OpenProcess:

Kopiuj
#include <windows.h>

typedef DWORD (__stdcall *CSRPID)(void);
typedef DWORD (__stdcall *NTQSI)(ULONG SystemInformationClass,PVOID SystemInformation,ULONG SystemInformationLength, ULONG* ReturnLength);
#define SystemHandleInformation 16

typedef struct {
    ULONG OwnerPid;
    BYTE ObjectType;
    BYTE HandleFlags;
    USHORT HandleValue;
    PVOID ObjectPointer;
    ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE_ENTRY;

typedef struct {
    ULONG HandleCount;
    SYSTEM_HANDLE_ENTRY Handles[1];
} SYSTEM_HANDLE_INFORMATION;


BOOL OpenProcessEx(DWORD pid, HANDLE *ppv)
{
	BOOL success = FALSE;
	HMODULE ntdll = GetModuleHandle("ntdll");
	while (1)
	{
		CSRPID CsrGetProcessId = (CSRPID)GetProcAddress(ntdll, "CsrGetProcessId");
		NTQSI NtQuerySystemInformation = (NTQSI)GetProcAddress(ntdll, "NtQuerySystemInformation");

		if (!CsrGetProcessId || !NtQuerySystemInformation)
		{
			//MessageBox(0, TEXT("no api"),0,0);
			break;
		}
		// otwórz csrss.exe
		DWORD csrpid = CsrGetProcessId();
		HANDLE csrss = OpenProcess(PROCESS_DUP_HANDLE, FALSE, csrpid);
		if (!csrss)
		{
			//MessageBox(0, TEXT("Open csrss error"),0,0);
			break;
		}

		ULONG bsize = 32768;
		SYSTEM_HANDLE_INFORMATION *handles = (SYSTEM_HANDLE_INFORMATION*)malloc(bsize);
		DWORD status;
		while (handles)
		{
			ULONG cch;
			status = NtQuerySystemInformation(SystemHandleInformation, handles, bsize, &cch);
			if (!status || (status != 0xc0000004)) break;
			free(handles);
			bsize += 32768;
			handles = (SYSTEM_HANDLE_INFORMATION*)malloc(bsize);
		}

		if (!status && handles)
		{
			int i;
			for (i=0; i<handles->HandleCount; i++)
			{
				if (handles->Handles[i].OwnerPid == csrpid)
				{
					if (DuplicateHandle(csrss, (HANDLE)handles->Handles[i].HandleValue, GetCurrentProcess(),
						ppv, 0, FALSE, DUPLICATE_SAME_ACCESS))
					{
						if (GetProcessId(*ppv) == pid) // głupie ale łatwe
						{
							success = TRUE;
							break;
						}
						CloseHandle(*ppv);
					}
				}
			}
		}
		if (handles) free(handles);
		CloseHandle(csrss);
		break;
	}
	return success;
}

int main(void)
{
	TOKEN_PRIVILEGES tp;
	HANDLE hToken;
	OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
	tp.PrivilegeCount = 1;
	LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
	tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), 0, 0);
	CloseHandle(hToken);

	HANDLE hProcess;
	if (OpenProcessEx(wpisz_tutaj_pid, &hProcess))
	{
		MessageBox(0, TEXT("OK"),0,0);
		CloseHandle(hProcess);
	}
	else
	{
		MessageBox(0, TEXT("pid not found"),0,0);
	}
}

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.