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:prawie 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:prawie 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:prawie 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);
	}
}
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)