I am trying to list all modules on a specific process, but I am getting "Access denied", even when I set token privileges.
Here is the code:
#include <cstdlib>
#include <iostream>
#include <windows.h>
#include <psapi.h>
#include <Tlhelp32.h>
using namespace std;
#pragma comment(lib, "cmcfg32.lib")
BOOL SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
{
TOKEN_PRIVILEGES tp;
LUID luid;
if (!LookupPrivilegeValue(NULL, lpszPrivilege, &luid))
{
char buf[256];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 255, NULL);
cout << "LookupPrivilegeValue error: " << buf;
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; }
if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD)NULL))
{
char buf[256];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 255, NULL);
cout << "AdjustTokenPrivileges error: " << buf;
return FALSE;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
printf("The token does not have the specified privilege. \n");
return FALSE;
}
return TRUE;
}
int GetPID(char pname[])
{
PROCESSENTRY32 pEntry;
HANDLE hSnapshot = NULL;
pEntry.dwSize = sizeof(PROCESSENTRY32);
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
Process32First(hSnapshot,&pEntry);
do { if(strcmp(pEntry.szExeFile, pname) == 0) { return pEntry.th32ProcessID; } } while(Process32Next(hSnapshot,&pEntry));
return 0;
}
int main()
{
HANDLE currentToken;
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, ¤tToken);
if (!SetPrivilege(currentToken, SE_DEBUG_NAME, TRUE))
{
MessageBox(0, "Unable to adjust privileges", "Error", MB_ICONERROR);
}
DWORD ID = GetPID("test.exe");
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ID);
if(!hProcess)
{
MessageBox(0, "Process not found", "Error", MB_ICONERROR);
}
else
{
HMODULE hMods[2048];
DWORD cbNeeded;
if(EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
{
for (unsigned int i = 0; i < (cbNeeded/sizeof(HMODULE)); i++)
{
TCHAR szModName[MAX_PATH];
if (GetModuleFileNameEx(hProcess, hMods[i], szModName, sizeof(szModName)/sizeof(TCHAR)))
{
cout << "DLL: " << szModName << " Handle: " << hMods[i] << endl;
}
}
}
else
{
char buf[256];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 255, NULL);
cout << "Error: " << buf;
}
system("pause");
}
CloseHandle(hProcess);
return 0;
}
Note that I can list process modules of any other process, but I can't with a specific one.
Both process are running with the same user credentials.
Can you tell me if I am doing something wrong?
Use Process Explorer to see the Security of kernel objects you are interested in. May be the target process has set its owner/DACL information such that it disallows READ for other processes. AntiVirus programs, services, file-system/kernel-driver are such kind of processes denying such actions.
And more importantly: it depends on the elevation/admin/ring-level of your own process.
ADDED:
Privileges doesn't directly apply to objects, but to the system as a whole. Try opening with TOKEN_ALL_ACCESS and see if it succeeds.
Related
I try to use OpenProcess() function to read some information from the "System" process. But I always get the error code 5 which means ERROR_ACCESS_DENIED.
I have used AdjustTokenPrivileges() function to get the debug privilege and it still not works. I just don't know what's wrong with my code. Here is part of my code:
int GetInfo()
{
PROCESSENTRY32 pe32{ sizeof(PROCESSENTRY32) };
THREADENTRY32 th32{ sizeof(THREADENTRY32) };
MODULEENTRY32 md32{ sizeof(MODULEENTRY32) };
PWCHAR Name;
DWORD id = 0;
int err = 0;
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
return -1;
}
BOOL pResult = Process32First(hProcessSnap, &pe32);
while (pResult)
{
Name = pe32.szExeFile;
if (lstrcmpW(Name, L"System") == 0)
{
id = pe32.th32ProcessID;
PrivilegeEscalation();
HANDLE ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION, false, pe32.th32ProcessID);
err = GetLastError();
cout << err << endl;
cout << "The thread number of System is : " << pe32.cntThreads << endl;
CloseHandle(ProcessHandle);
break;
}
pResult = Process32Next(hProcessSnap, &pe32);
}
CloseHandle(hProcessSnap);
return 0;
BOOL PrivilegeEscalation()
{
HANDLE hToken;
TOKEN_PRIVILEGES Tp;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
return FALSE;
}
Tp.PrivilegeCount = 1;
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Tp.Privileges[0].Luid);
Tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &Tp, sizeof(Tp), NULL, NULL);
//int err = GetLastError();
CloseHandle(hToken);
return TRUE;
}
The System process is not a real process, it represents the kernel. You can't expect all process related functions to work on it.
If you are cloning something like Process Explorer, call the undocumented NT API like the Windows Task manager has been doing all its life.
I am making a DLL injector. A really simple one: console app, input DLL, input process. But I'm getting an error on line 26:
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
Can someone help me?
#include<Windows.h> //DWORD
#include <iostream>
#include <string>
#include <psapi.h> //EnumProcessModules
#include <VersionHelpers.h>
#include <atlstr.h> // CString
#define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
BOOL InjectDLL(DWORD ProcessID)
{
LPCSTR DLL_PATH = "dll file here";
LPVOID LoadLibAddy, RemoteString;
if (!ProcessID)
return false;
HANDLE Proc = OpenProcess(CREATE_THREAD_ACCESS, FALSE, ProcessID);
if (!Proc)
{
std::cout << "OpenProcess() failed: " << GetLastError() << std::endl;
return false;
}
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
RemoteString = (LPVOID)VirtualAllocEx(Proc, NULL, strlen(DLL_PATH) + 1, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(Proc, RemoteString, (LPVOID)DLL_PATH, strlen(DLL_PATH)+1, NULL);
CreateRemoteThread(Proc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, RemoteString, NULL, NULL);
CloseHandle(Proc);
return true;
...
You did not say what kind of error you are getting. But I suspect you are getting a compile-time error on GetModuleHandle("kernel32.dll"). If your project is set to use the Unicode character set, you would need to use GetModuleHandle(L"kernel32.dll") instead. Or better, since GetModuleHandle() is a TCHAR-based macro, use TEXT("kernel32.dll") to match:
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryA");
Otherwise, use GetModuleHandleA() or GetModuleHandleW() instead:
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "LoadLibraryA");
That being said, you are also not doing any error handling when allocating memory or creating the remote thread. And your logic is incomplete as you are leaking allocated memory and resources. You need to wait for the remote thread to finish, and then free the virtual memory you allocate, and close the handle to the thread.
Try this instead:
#include <Windows.h> //DWORD
#include <iostream>
#include <string>
#include <psapi.h> //EnumProcessModules
#include <VersionHelpers.h>
#include <atlstr.h> // CString
#define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
bool InjectDLL(DWORD ProcessID)
{
LPCSTR DLL_PATH = "dll file here";
int DLL_PATH_SIZE = strlen(DLL_PATH) + 1;
if (ProcessID == 0)
return false;
FARPROC LoadLibAddy = GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryA");
if (!LoadLibAddy)
{
DWORD err = GetLastError();
std::cout << "Can't find LoadLibraryA: " << err << std::endl;
return false;
}
HANDLE Proc = OpenProcess(CREATE_THREAD_ACCESS, FALSE, ProcessID);
if (!Proc)
{
DWORD err = GetLastError();
std::cout << "OpenProcess() failed: " << err << std::endl;
return false;
}
LPVOID RemoteString = VirtualAllocEx(Proc, NULL, DLL_PATH_SIZE, MEM_COMMIT, PAGE_READWRITE);
if (!RemoteString)
{
DWORD err = GetLastError();
std::cout << "VirtualAllocEx() failed: " << err << std::endl;
CloseHandle(Proc);
return false;
}
if (!WriteProcessMemory(Proc, RemoteString, DLL_PATH, DLL_PATH_SIZE, NULL))
{
DWORD err = GetLastError();
std::cout << "WriteProcessMemory() failed: " << err << std::endl;
VirtualFreeEx(Proc, RemoteString, 0, MEM_RELEASE);
CloseHandle(Proc);
return false;
}
HANDLE Thread = CreateRemoteThread(Proc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, RemoteString, NULL, NULL);
if (!Thread)
{
DWORD err = GetLastError();
std::cout << "CreateRemoteThread() failed: " << err << std::endl;
VirtualFreeEx(Proc, RemoteString, 0, MEM_RELEASE);
CloseHandle(Proc);
return false;
}
WaitForSingleObject(Thread, INFINITE);
// If the target process is 32bit, you can use GetExitCodeThread()
// to find out if LoadLibraryA() was successful or not.
//
// If the target process is 64bit, it is much harder to determine
// that. You would have to allocate an entire function containing
// shellcode that calls LoadLibraryA() and saves the result in
// memory that you can then read via ReadProcessMemory(). Or,
// you would have to enumerate the target process's modules list
// looking for the DLL that you just injected.
CloseHandle(Thread);
VirtualFreeEx(Proc, RemoteString, 0, MEM_RELEASE);
CloseHandle(Proc);
return true;
}
Well, basically I need to write a DLL in C++ that I will inject into notepad.exe.
This DLL suppose to open a pop-out message or a window with my name in it.
The problem is that I'm kinda new with DLL and I started a week ago. I'm having trouble opening a window or a message with a DLL using "windows.h".
I did try using MessageBox but it's not working.
that's my injector
that i took from: https://www.fxp.co.il/showthread.php?t=15051062
#include <iostream>
#include <direct.h>
#include <windows.h>
#include <Tlhelp32.h>
LPCTSTR SzToLPCTSTR(char* szString);
char* GetCurrentDir();
void WaitForProcessToAppear(LPCTSTR lpcszProc, DWORD dwDeley);
DWORD GetProcessIdByName(LPCTSTR lpcszProc);
BOOL InjectDll(DWORD dwPid, char* szDllPath);
int main()
{
char szProc[MAX_PATH], szDll[MAX_PATH];
char* szDllPath = (char*)malloc(MAX_PATH);
LPTSTR lpszProc = NULL;
while (true)
{
std::cout << "Process: ";
std::cin >> szProc;
std::cout << "DLL Injection: ";
std::cin >> szDll;
szDllPath = GetCurrentDir();
strcat_s(szDllPath, MAX_PATH, "\\");
strcat_s(szDllPath, MAX_PATH, szDll);
std::cout << "Waiting for process..." << std::endl;
WaitForProcessToAppear(SzToLPCTSTR(szProc), 100);
if (InjectDll(GetProcessIdByName(SzToLPCTSTR(szProc)), szDllPath)) std::cout << "Injection succeeded!" << std::endl;
else std::cout << "Injection failed!" << std::endl;
std::cout << "\n";
}
return 0;
}
char* GetCurrentDir()
{
char* szRet = (char*)malloc(MAX_PATH);
_getcwd(szRet, MAX_PATH);
return szRet;
}
LPCTSTR SzToLPCTSTR(char* szString)
{
LPTSTR lpszRet;
size_t size = strlen(szString) + 1;
lpszRet = (LPTSTR)malloc(MAX_PATH);
mbstowcs_s(NULL, lpszRet, size, szString, _TRUNCATE);
return lpszRet;
}
void WaitForProcessToAppear(LPCTSTR lpcszProc, DWORD dwDeley)
{
HANDLE hSnap;
PROCESSENTRY32 peProc;
BOOL bAppeared = FALSE;
while (!bAppeared)
{
if ((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE)
{
peProc.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hSnap, &peProc))
while (Process32Next(hSnap, &peProc) && !bAppeared)
if (!lstrcmp(lpcszProc, peProc.szExeFile))
bAppeared = TRUE;
}
CloseHandle(hSnap);
Sleep(dwDeley);
}
}
DWORD GetProcessIdByName(LPCTSTR lpcszProc)
{
HANDLE hSnap;
PROCESSENTRY32 peProc;
DWORD dwRet = -1;
if ((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE)
{
peProc.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hSnap, &peProc))
while (Process32Next(hSnap, &peProc))
if (!lstrcmp(lpcszProc, peProc.szExeFile))
dwRet = peProc.th32ProcessID;
}
CloseHandle(hSnap);
return dwRet;
}
BOOL InjectDll(DWORD dwPid, char* szDllPath)
{
DWORD dwMemSize;
HANDLE hProc;
LPVOID lpRemoteMem, lpLoadLibrary;
BOOL bRet = FALSE;
if ((hProc = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD, FALSE, dwPid)) != NULL)
{
dwMemSize = strlen(szDllPath) + 1;
if ((lpRemoteMem = VirtualAllocEx(hProc, NULL, dwMemSize, MEM_COMMIT, PAGE_READWRITE)) != NULL)
if (WriteProcessMemory(hProc, lpRemoteMem, (LPCVOID)szDllPath, dwMemSize, NULL))
{
lpLoadLibrary = GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
if (CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)lpLoadLibrary, lpRemoteMem, 0, NULL) != NULL)
bRet = TRUE;
}
}
CloseHandle(hProc);
return bRet;
}
And that's my DLL:
#include <windows.h>
BOOL WINAPI DllMain( HMODULE hModule,
DWORD fdwReason,
LPVOID lpvReserved
)
{
if (fdwReason == DLL_PROCESS_ATTACH)
MessageBox(NULL, L"Injected by Matan Oshri", L"Hello World", MB_OK);
return TRUE;
}
Please let me know if u see any kind of mistake.
I appreciate all the help I can get.
Thank you.
First I can inject the DLL with the sample code, make sure the Dll, injector.exe and notepad.exe are in the same bits(Usually, notepad.exe starts with 64-bit).
I am getting the error code = 5 if I use 32-bits of DLL or injector.exe with 64-bits notepad.exe
Second, According to the CreateRemoteThread document:
hProcess
A handle to the process in which the thread is to be created. The
handle must have the PROCESS_CREATE_THREAD, PROCESS_QUERY_INFORMATION,
PROCESS_VM_OPERATION, PROCESS_VM_WRITE, and PROCESS_VM_READ access
rights, and may fail without these rights on certain platforms. For
more information, see Process Security and Access Rights.
(Although the above sample works for me with out PROCESS_QUERY_INFORMATION and PROCESS_VM_READ)
Third, There is something worth improving in your code:
char* szDllPath = (char*)malloc(MAX_PATH);
szDllPath = GetCurrentDir();
/*{
char* szRet = (char*)malloc(MAX_PATH);
_getcwd(szRet, MAX_PATH);
return szRet;
}*/
This will cause the memory of the first application to be leaked.
LPCTSTR SzToLPCTSTR(char* szString);
We could use Unicode string directly.
sample:
#include <iostream>
#include <direct.h>
#include <windows.h>
#include <Tlhelp32.h>
//LPCWSTR SzToLPCTSTR(char* szString);
//char* GetCurrentDir();
void WaitForProcessToAppear(LPCWSTR lpcszProc, DWORD dwDeley);
DWORD GetProcessIdByName(LPCWSTR lpcszProc);
BOOL InjectDll(DWORD dwPid, LPCWSTR szDllPath);
int main()
{
while (true)
{
std::wstring szProc, szDll;
std::wstring szDllPath;
std::wcout << L"Process: ";
std::wcin >> szProc;
std::wcout << L"DLL Injection: ";
std::wcin >> szDll;
WCHAR dir[MAX_PATH] = { 0 };
GetCurrentDirectoryW(MAX_PATH, dir);
szDllPath = dir;
szDllPath += L"\\";
szDllPath += szDll;
std::wcout << L"Waiting for process..." << std::endl;
WaitForProcessToAppear(szProc.c_str(), 100);
if (InjectDll(GetProcessIdByName(szProc.c_str()), szDllPath.c_str())) std::wcout << L"Injection succeeded!" << std::endl;
else std::wcout << L"Injection failed!" << std::endl;
std::wcout << L"\n";
}
return 0;
}
//char* GetCurrentDir()
//{
// char* szRet = (char*)malloc(MAX_PATH);
// _getcwd(szRet, MAX_PATH);
// return szRet;
//}
//LPCWSTR SzToLPCTSTR(char* szString)
//{
// LPTSTR lpszRet;
// size_t size = strlen(szString) + 1;
// lpszRet = (LPTSTR)malloc(MAX_PATH);
// mbstowcs_s(NULL, lpszRet, size, szString, _TRUNCATE);
// return lpszRet;
//}
void WaitForProcessToAppear(LPCWSTR lpcszProc, DWORD dwDeley)
{
HANDLE hSnap;
PROCESSENTRY32 peProc;
BOOL bAppeared = FALSE;
while (!bAppeared)
{
if ((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE)
{
peProc.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hSnap, &peProc))
while (Process32Next(hSnap, &peProc) && !bAppeared)
if (!lstrcmp(lpcszProc, peProc.szExeFile))
{
bAppeared = TRUE;
break;
}
}
CloseHandle(hSnap);
Sleep(dwDeley);
}
}
DWORD GetProcessIdByName(LPCWSTR lpcszProc)
{
HANDLE hSnap;
PROCESSENTRY32 peProc;
DWORD dwRet = -1;
if ((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE)
{
peProc.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hSnap, &peProc))
while (Process32Next(hSnap, &peProc))
if (!lstrcmp(lpcszProc, peProc.szExeFile))
{
dwRet = peProc.th32ProcessID;
break;
}
}
CloseHandle(hSnap);
return dwRet;
}
BOOL InjectDll(DWORD dwPid, LPCWSTR szDllPath)
{
DWORD dwMemSize;
HANDLE hProc;
LPVOID lpRemoteMem, lpLoadLibrary;
BOOL bRet = FALSE;
if ((hProc = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, dwPid)) != NULL)
{
dwMemSize = (wcslen(szDllPath) + 1) * sizeof(WCHAR);
if ((lpRemoteMem = VirtualAllocEx(hProc, NULL, dwMemSize, MEM_COMMIT, PAGE_READWRITE)) != NULL)
if (WriteProcessMemory(hProc, lpRemoteMem, (LPCVOID)szDllPath, dwMemSize, NULL))
{
lpLoadLibrary = GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "LoadLibraryW");
if (CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)lpLoadLibrary, lpRemoteMem, 0, NULL) != NULL)
bRet = TRUE;
}
}
CloseHandle(hProc);
return bRet;
}
Finally, according to the limitations in DllMain:
Call functions in User32.dll or Gdi32.dll. Some functions load
another DLL, which may not be initialized.
You cannot use MessageBox in DllMain, but you could use OutputDebugStringW instead to show a message, and use DebugView to check the debug string.
DLL:
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
OutputDebugStringW(L"Injected DLL_PROCESS_ATTACH by Matan Oshri");
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Or use Console API to pop up a console:
DWORD dwSize;
WCHAR string[] = L"Hello World";
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
AllocConsole();
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), string, 12, &dwSize, NULL);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
This program enumerate all handles and get their names.
For pID 4 OpenProcess gets error 5 with SeDebugPrivilege.
UAC off. Running from Admin.
Enable SeDebugPrivilege
BOOL EnableDebugPrivilege(BOOL bEnable)
{
HANDLE hToken = nullptr;
LUID luid;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) return FALSE;
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) return FALSE;
TOKEN_PRIVILEGES tokenPriv;
tokenPriv.PrivilegeCount = 1;
tokenPriv.Privileges[0].Luid = luid;
tokenPriv.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
if (!AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) return FALSE;
_tprintf(_T("Privileges error: %d\n", GetLastError()));
return TRUE;
}
Enumerate handles
DWORD EnumerateFileHandles(ULONG pid)
{
HINSTANCE hNtDll = LoadLibrary(_T("ntdll.dll"));
assert(hNtDll != NULL);
PFN_NTQUERYSYSTEMINFORMATION NtQuerySystemInformation =
(PFN_NTQUERYSYSTEMINFORMATION)GetProcAddress(hNtDll,
"NtQuerySystemInformation");
assert(NtQuerySystemInformation != NULL);
PFN_NTQUERYINFORMATIONFILE NtQueryInformationFile =
(PFN_NTQUERYINFORMATIONFILE)GetProcAddress(hNtDll,
"NtQueryInformationFile");
DWORD nSize = 4096, nReturn;
PSYSTEM_HANDLE_INFORMATION pSysHandleInfo = (PSYSTEM_HANDLE_INFORMATION)
HeapAlloc(GetProcessHeap(), 0, nSize);
while (NtQuerySystemInformation(SystemExtendedHandleInformation, pSysHandleInfo,
nSize, &nReturn) == STATUS_INFO_LENGTH_MISMATCH)
{
HeapFree(GetProcessHeap(), 0, pSysHandleInfo);
nSize += 4096;
pSysHandleInfo = (SYSTEM_HANDLE_INFORMATION*)HeapAlloc(
GetProcessHeap(), 0, nSize);
}
DWORD dwFiles = 0;
_tprintf(_T("Handles Number: %d\n"), pSysHandleInfo->NumberOfHandles);
for (ULONG i = 0; i < pSysHandleInfo->NumberOfHandles; i++)
{
PSYSTEM_HANDLE pHandle = &(pSysHandleInfo->Handles[i]);
if (pHandle->ProcessId == 4)
{
HANDLE hProcess = OpenProcess(
PROCESS_DUP_HANDLE, FALSE, pHandle->ProcessId);
if (hProcess == NULL)
{
_tprintf(_T("OpenProcess failed w/err 0x%08lx\n"), GetLastError());
continue;
}
HANDLE hCopy;
if (!DuplicateHandle(hProcess, (HANDLE)pHandle->Handle,
GetCurrentProcess(), &hCopy, MAXIMUM_ALLOWED, FALSE, 0))
continue;
TCHAR buf[MAX_PATH];
if (GetFinalPathNameByHandle(hCopy, buf, sizeof(buf), VOLUME_NAME_DOS))
wprintf(L"p%d:h%d:t%d:\t%s\n", pHandle->ProcessId, pHandle->Handle, pHandle->ObjectTypeNumber, buf);
CloseHandle(hProcess);
CloseHandle(hCopy);
}
}
HeapFree(GetProcessHeap(), 0, pSysHandleInfo);
return dwFiles;
}
On windows 7 x64 it's work fine.
But on Windows 10 x64 OpenProcess returns error 5 with SeDebugPrivilege.
How open system process(pID 4) on windows 10.
You can't open a handle for it as the documentation for OpenProcess specifically says it'll fail:
If the specified process is the Idle process or one of the CSRSS
processes, this function fails and the last error code is
ERROR_ACCESS_DENIED because their access restrictions prevent
user-level code from opening them.
If you want to get system process names, you could try to use CreateToolhelp32Snapshot() to get the snapshot of the process, then use Process32First() and Process32Next() to enumerate the all process.
Here is an example:
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <string>
#include <TlHelp32.h>
using namespace std;
int main()
{
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//get the snapshot
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
cout << "CreateToolhelp32Snapshot Error!" << endl;
return false;
}
BOOL bResult = Process32First(hProcessSnap, &pe32);
int num(0);
while(bResult)
{
cout << "[" << ++num << "] : " << "Process Name:"<< pe32.szExeFile << " " << "ProcessID:" << pe32.th32ProcessID << endl;
bResult = Process32Next(hProcessSnap, &pe32);
}
CloseHandle(hProcessSnap);
}
Hope it could help you!
//writing to mailslot
#include <windows.h>
#include <stdio.h>
LPTSTR SlotName = TEXT("\\\\.\\mailslot\\sample_mailslot");
BOOL WriteSlot(HANDLE hSlot, LPTSTR lpszMessage)
{
BOOL fResult;
DWORD cbWritten;
fResult = WriteFile(hSlot,
lpszMessage,
(DWORD) (lstrlen(lpszMessage)+1)*sizeof(TCHAR),
&cbWritten,
(LPOVERLAPPED) NULL);
if (!fResult)
{
printf("WriteFile failed with %d.\n", GetLastError());
return FALSE;
}
printf("Slot written to successfully.\n");
return TRUE;
}
int main()
{
HANDLE hFile;
hFile = CreateFile(SlotName,
GENERIC_WRITE,
FILE_SHARE_READ,
(LPSECURITY_ATTRIBUTES) NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("CreateFile failed with %d.\n", GetLastError());
return FALSE;
}
WriteSlot(hFile, TEXT("Message one for mailslot."));
WriteSlot(hFile, TEXT("Message two for mailslot."));
Sleep(5000);
WriteSlot(hFile, TEXT("Message three for mailslot."));
CloseHandle(hFile);
return TRUE;
}
//reading from mailslot
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
HANDLE hSlot;
LPTSTR SlotName = TEXT("\\\\.\\mailslot\\sample_mailslot");
BOOL ReadSlot()
{
DWORD cbMessage, cMessage, cbRead;
BOOL fResult;
LPTSTR lpszBuffer;
TCHAR achID[80];
DWORD cAllMessages;
HANDLE hEvent;
OVERLAPPED ov;
cbMessage = cMessage = cbRead = 0;
hEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("ExampleSlot"));
if( NULL == hEvent )
return FALSE;
ov.Offset = 0;
ov.OffsetHigh = 0;
ov.hEvent = hEvent;
fResult = GetMailslotInfo( hSlot, // mailslot handle
(LPDWORD) NULL, // no maximum message size
&cbMessage, // size of next message
&cMessage, // number of messages
(LPDWORD) NULL); // no read time-out
if (!fResult)
{
printf("GetMailslotInfo failed with %d.\n", GetLastError());
return FALSE;
}
if (cbMessage == MAILSLOT_NO_MESSAGE)
{
printf("Waiting for a message...\n");
return TRUE;
}
cAllMessages = cMessage;
while (cMessage != 0) // retrieve all messages
{
// Create a message-number string.
StringCchPrintf((LPTSTR) achID,
80,
TEXT("\nMessage #%d of %d\n"),
cAllMessages - cMessage + 1,
cAllMessages);
// Allocate memory for the message.
lpszBuffer = (LPTSTR) GlobalAlloc(GPTR,
lstrlen((LPTSTR) achID)*sizeof(TCHAR) + cbMessage);
if( NULL == lpszBuffer )
return FALSE;
lpszBuffer[0] = '\0';
fResult = ReadFile(hSlot,
lpszBuffer,
cbMessage,
&cbRead,
&ov);
if (!fResult)
{
printf("ReadFile failed with %d.\n", GetLastError());
GlobalFree((HGLOBAL) lpszBuffer);
return FALSE;
}
// Concatenate the message and the message-number string.
StringCbCat(lpszBuffer,
lstrlen((LPTSTR) achID)*sizeof(TCHAR)+cbMessage,
(LPTSTR) achID);
// Display the message.
_tprintf(TEXT("Contents of the mailslot: %s\n"), lpszBuffer);
GlobalFree((HGLOBAL) lpszBuffer);
fResult = GetMailslotInfo(hSlot, // mailslot handle
(LPDWORD) NULL, // no maximum message size
&cbMessage, // size of next message
&cMessage, // number of messages
(LPDWORD) NULL); // no read time-out
if (!fResult)
{
printf("GetMailslotInfo failed (%d)\n", GetLastError());
return FALSE;
}
}
CloseHandle(hEvent);
return TRUE;
}
BOOL WINAPI MakeSlot(LPTSTR lpszSlotName)
{
hSlot = CreateMailslot(lpszSlotName,
0, // no maximum message size
MAILSLOT_WAIT_FOREVER, // no time-out for operations
(LPSECURITY_ATTRIBUTES) NULL); // default security
if (hSlot == INVALID_HANDLE_VALUE)
{
printf("CreateMailslot failed with %d\n", GetLastError());
return FALSE;
}
return TRUE;
}
void main()
{
MakeSlot(SlotName);
while(TRUE)
{
ReadSlot();
Sleep(3000);
}
}
Go through the Visual Studio C++ Guided Tour on MSDN or watch this introductory video explaining how to create a basic Win32 application in C++. They should be enough of a starting point. From there on just browse the MSDN library to advance your knowledge or search for issues you encounter.