windows 显示进程地址空间

windows 显示进程地址空间

windows 显示进程地址空间


显示进程地址空间

/*
3-ProcessInfo.cpp
显示进程地址空间
*/



#include "..\\CommonFiles\\CmnHdr.h"
#include "..\\CommonFiles\\Toolhelp.h"

#include "resource.h"
#include <windowsx.h>
#include <stdarg.h>
#include <stdio.h>

#include <winternl.h> //用于windows内部声明
#include <AclAPI.h>	//用于ACL(访问控制器列表)管理
#include <Shlwapi.h> //用于windows shell strFormatKBSize.
#include <ShlObj.h> //为IsUserAnAdmin测试当前用户是否是管理员组的成员。
#include <AclAPI.h>	//用于ACL/ACE函数

#include <tchar.h>
#include <strsafe.h>


#pragma comment (lib,"shlwapi.lib")//shell 轻型使用工具函数库
#pragma comment (lib,"shell32.lib")

//
//NTQueryInformationProcess在winternl.h中定义
typedef NTSTATUS(CALLBACK* PFN_NTQUERYINFORMATIONPROCESS)(
	HANDLE ProcessHandle,
	PROCESSINFOCLASS ProcessInformationClass,
	PVOID ProcessInformation,
	ULONG ProcessInformationLength,
	PULONG ReturnLength OPTIONAL
	);

typedef struct
{
	DWORD Filler[4];
	DWORD InfoBlockAddress;
}__PEB;

typedef struct
{
	DWORD Filler[17];
	DWORD wszCmdLineAddress;
}__INFOBLOCK;


//
/*
PEB(process Environment Block)是一个未公开的结构体
typedef struct _PEB{
	BYTE Reserved1[2];//2字节
	BYTE BeingDegged; //1
	BYTE Reserved2[1];//1
	PVOID Reserved3[2]//2*4=8
	PPED_LDR_DATA Ldr; //4
	PRTL_USER_PROCESS_PARAMETERS ProcessParamters;
	BYTE Reserved4[104];
	PVOID Reserved5[52];
	PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
	BYTE Reserved6[128];
	PVOID Reserved7[1];
	ULONG SessionId;
	}PEB,*PPEB;

	typedef struct _RTL_USER_PROCESS_PARAMETERS{
	BYTE Reserved1[16];16字节
	PVOID Reserved2[10];
	UNICODE_STRING ImagePathName;
	UNICODE_STRING CommandLine;
	}RTL_USER_PROCESS_PARAMETERS,*PRTL_USER_PROCESS_PARAMETERS

}
*/


//全局变量
//指示由GetTokenInformation函数查询的令牌的提升类型
TOKEN_ELEVATION_TYPE s_elevationType = TokenElevationTypeDefault;
BOOL s_bIsAdmin = FALSE;//是否未管理员
const int s_cchAddress = sizeof(PVOID) * 2;


//函数原型
INT_PTR WINAPI	Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam);
BOOL Dlg_OnSize(HWND hwnd, UINT state, int cx, int cy);
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtrl, UINT codeNotify);
DWORD StartElevatedProcess(LPCTSTR szExecutable, LPCTSTR szCmdLine);
BOOL GetProcessElevation(TOKEN_ELEVATION_TYPE* pElevationType, BOOL* pIsAdmin);
VOID ShowModeleInfo(HWND hwnd, PCTSTR pszModulePath);
VOID ShowProcessInfo(HWND hwnd, DWORD dwProcessID);
VOID FormatSizeInKB(DWORD dwSize, DWORD nCharacters,LPTSTR szSize,size_t cchSize);

BOOL GetProcessOwner(DWORD PID, LPTSTR szOwner, DWORD cchSize);
BOOL GetProcessOwner(HANDLE hProcess, LPTSTR szOwner, size_t cchSize);
BOOL GetProcessCmdLine(DWORD PID, LPTSTR szCmdLine, DWORD Size);
BOOL GetProcessCmdLine(HANDLE hProcess, LPTSTR szCmdLine, DWORD Size);
NTSTATUS _NtQueryInformationProcess(HANDLE hProcess, PROCESSINFOCLASS pic,
	PVOID pPI, ULONG cbSize, PULONG pLength);

VOID Dlg_PopulateModuleList(HWND hwnd);
VOID Dlg_PopulateProcessList(HWND hwnd);
BOOL GetProcessIntegrityLevel(DWORD PID, PDWORD pIntegrityLevel,
	PDWORD pPolicy, PDWORD pResourceIntegrityLevel, PDWORD pResourcePolicy);
BOOL GetProcessIntegrityLevel(HANDLE hProcess, PDWORD pIntegrityLevel,
	PDWORD pPolicy, PDWORD pResourceIntegrityLevel, PDWORD pResourcePolicy);
void AddText(HWND hwnd, PCTSTR pszFormat, ...);
PVOID GetModulePreferredBaseAddr(DWORD dwProcessId, PVOID pvModuleRemote);

BOOL GetProcessOwner(HANDLE hProcess, LPTSTR szOwner, size_t cchSize) {

	// Sanity checks
	if ((szOwner == NULL) || (cchSize == 0))
		return(FALSE);

	// Default value
	szOwner[0] = TEXT('\0');

	// Gget process token
	HANDLE hToken = NULL;
	CToolhelp::EnablePrivilege(SE_TCB_NAME, TRUE);
	if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) {
		CToolhelp::EnablePrivilege(SE_TCB_NAME, FALSE);
		return(FALSE);
	}

	// Obtain the size of the user information in the token.
	DWORD cbti = 0;
	GetTokenInformation(hToken, TokenUser, NULL, 0, &cbti);

	// Call should have failed due to zero-length buffer.
	if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
		// Allocate buffer for user information in the token.
		PTOKEN_USER ptiUser =
			(PTOKEN_USER)HeapAlloc(GetProcessHeap(), 0, cbti);
		if (ptiUser != NULL) {
			// Retrieve the user information from the token.
			if (GetTokenInformation(hToken, TokenUser, ptiUser, cbti, &cbti)) {
				SID_NAME_USE   snu;
				TCHAR          szUser[MAX_PATH];
				DWORD          chUser = MAX_PATH;
				PDWORD         pcchUser = &chUser;
				TCHAR          szDomain[MAX_PATH];
				DWORD          chDomain = MAX_PATH;
				PDWORD         pcchDomain = &chDomain;

				// Retrieve user name and domain name based on user's SID.
				if (
					LookupAccountSid(
						NULL,
						ptiUser->User.Sid,
						szUser,
						pcchUser,
						szDomain,
						pcchDomain,
						&snu
					)
					) {
					// build the owner string as \\DomainName\UserName
					_tcscpy_s(szOwner, cchSize, TEXT("\\\\"));
					_tcscat_s(szOwner, cchSize, szDomain);
					_tcscat_s(szOwner, cchSize, TEXT("\\"));
					_tcscat_s(szOwner, cchSize, szUser);
				}
			}

			// Don't forget to free memory buffer
			HeapFree(GetProcessHeap(), 0, ptiUser);
		}
	}

	// Don't forget to free process token
	CloseHandle(hToken);

	// Restore privileges
	CToolhelp::EnablePrivilege(SE_TCB_NAME, TRUE);

	return(TRUE);
}


BOOL GetProcessOwner(DWORD PID, LPTSTR szOwner, DWORD cchSize) {

	// Sanity checks
	if ((PID <= 0) || (szOwner == NULL))
		return(FALSE);

	// Check if we can get information for this process
	HANDLE hProcess =
		OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, PID);
	if (hProcess == NULL)
		return(FALSE);

	BOOL bReturn = GetProcessOwner(hProcess, szOwner, cchSize);

	// Don't forget to release the process handle
	CloseHandle(hProcess);

	return(bReturn);
}

NTSTATUS _NtQueryInformationProcess(
	HANDLE hProcess,
	PROCESSINFOCLASS pic,
	PVOID pPI,
	ULONG cbSize,
	PULONG pLength
) {

	HMODULE hNtDll = LoadLibrary(TEXT("ntdll.dll"));
	if (hNtDll == NULL) {
		return(-1);
	}

	NTSTATUS lStatus = -1;  // error by default.

	// Note that function name is not UNICODE
	PFN_NTQUERYINFORMATIONPROCESS pfnNtQIP =
		(PFN_NTQUERYINFORMATIONPROCESS)GetProcAddress(
			hNtDll, "NtQueryInformationProcess");
	if (pfnNtQIP != NULL) {
		lStatus = pfnNtQIP(hProcess, pic, pPI, cbSize, pLength);
	}

	FreeLibrary(hNtDll);
	return(lStatus);
}



///
int WINAPI _tWinMain(HINSTANCE hInstanceExe, HINSTANCE, PTSTR pszCmdLine, int)
{
	//打开调试权限以运行应用程序查看服务应用
	CToolhelp::EnablePrivilege(SE_DEBUG_NAME, TRUE);
	//打开访问SACL权限--访问控制权限
	CToolhelp::EnablePrivilege(SE_SECURITY_NAME, TRUE);
	//显示主窗口
	DialogBox(hInstanceExe, MAKEINTRESOURCE(IDD_PROCESSINFO), NULL, Dlg_Proc);
	CToolhelp::EnablePrivilege(SE_SECURITY_NAME, FALSE);
	CToolhelp::EnablePrivilege(SE_DEBUG_NAME, FALSE);
	return (0);
}

INT_PTR WINAPI	Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
		chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog);
		chHANDLE_DLGMSG(hwnd, WM_SIZE, Dlg_OnSize);
		chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dlg_OnCommand);
	}
	return(FALSE);
}

BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
	chSETDLGICONS(hwnd, IDI_PROCESSINFO);

	//当提升权限或者禁用UAC时吗,管理员特权被设置为TRUE
	BOOL bCanReadSystemProcesses = FALSE;

	//显示是否正在运行“Filter Token”
	if (GetProcessElevation(&s_elevationType,&s_bIsAdmin))
	{
		//提升标题的前缀
		TCHAR szTitle[64];

		switch (s_elevationType)
		{
		//默认用户活禁用UAC
		case TokenElevationTypeDefault:
			if (IsUserAnAdmin())
			{
				_tcscpy_s(szTitle, _countof(szTitle), TEXT("Default Administrator"));
				bCanReadSystemProcesses = TRUE;
			}
			else
			{
				_tcscpy_s(szTitle, _countof(szTitle), TEXT("Default: "));
			}
			break;

			//进程权限被提升成功
		case TokenElevationTypeFull:
			if (IsUserAnAdmin())
			{
				_tcscpy_s(szTitle, _countof(szTitle), TEXT("Elevated Administorator"));
				bCanReadSystemProcesses = TRUE;
			}
			else
			{
				_tcscpy_s(szTitle, _countof(szTitle), TEXT("Elevated: "));
			}
			break;

			//进程运行与受限(筛选令牌)下
		case TokenElevationTypeLimited:
			if (s_bIsAdmin)
			{
				_tcscpy_s(szTitle, _countof(szTitle), TEXT("Filtered Administrator"));
			}
			else
			{
				_tcscpy_s(szTitle, _countof(szTitle), TEXT("Filtered: "));
			}
			break;
		}

		//根据提示类型更新对话框标题
		GetWindowText(hwnd, _tcschr(szTitle, TEXT('\0')),
			_countof(szTitle) - _tcslen(szTitle));
		SetWindowText(hwnd, szTitle);

		//增加“循牌”图标,以运行用户以提升的权限来运行程序
		if (!bCanReadSystemProcesses)
		{
			Button_SetElevationRequiredState(
				GetDlgItem(hwnd, IDC_BTN_SYSTEM_PROCESSES),
				!bCanReadSystemProcesses);
		}
		else
		{
			//已经提升权限则不不需要显示按钮
			ShowWindow(GetDlgItem(hwnd, IDC_BTN_SYSTEM_PROCESSES), SW_HIDE);

			//将组合列表框扩展到整个对话框的宽度
			MoveWindow(GetDlgItem(hwnd, IDC_BTN_SYSTEM_PROCESSES),
				0,0,0,0,FALSE);
		}
	}
	//隐藏“模块帮助”列表框
	ShowWindow(GetDlgItem(hwnd, IDC_MODULEHELP), SW_HIDE);

	//使输出窗口使用等宽字体
	SetWindowFont(GetDlgItem(hwnd, IDC_RESULTS),
		GetStockFont(ANSI_FIXED_FONT), FALSE);

	//默认下,显示运行中的进程
	Dlg_PopulateProcessList(hwnd);

	return (TRUE);
}

//
BOOL Dlg_OnSize(HWND hwnd, UINT state, int cx, int cy)
{
	RECT btnRect;
	HWND hwndCtrl = GetDlgItem(hwnd, IDC_BTN_SYSTEM_PROCESSES);
	GetClientRect(hwndCtrl, &btnRect);

	RECT rc;
	int n = LOWORD(GetDialogBaseUnits());//字体的宽度

	hwndCtrl = GetDlgItem(hwnd, IDC_PROCESSMODULELIST);
	GetClientRect(hwndCtrl, &rc);

	SetWindowPos(hwndCtrl, NULL,
		n + n + btnRect.right,//按钮宽度+一个字符宽度
		n,//y=一个字符的高度
		cx - n - n - n - btnRect.right,//Combox宽度,右边距留一字符宽度
		rc.bottom,
		SWP_NOZORDER);

	hwndCtrl = GetDlgItem(hwnd, IDC_RESULTS);
	SetWindowPos(hwndCtrl, NULL,
		n,
		n + rc.bottom + n,
		cx - n - n,
		cy - (n + rc.bottom + n) - n,
		SWP_NOZORDER);
	return 0;
}

//
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtrl, UINT codeNotify)
{
	static BOOL s_fProcesses = TRUE;

	switch (id)
	{
	case IDCANCEL:
		EndDialog(hwnd, id);
		break;

		//以管理员身份重启应用程序
	case IDC_BTN_SYSTEM_PROCESSES:
	{
		//case分支里面定义变量,要加大括号
		ShowWindow(hwnd, SW_HIDE);

		TCHAR szApplication[MAX_PATH];
		DWORD cchLength = _countof(szApplication);
		//获取进程的完整银蛇名称
		//第二个参为0表示使用win32路径格式,PROCESS_NAME_NATIVE,表示使用本地系统路径格式
		//第四个参数:返回字符串中字符的个数(不含\0)
		QueryFullProcessImageName(
			GetCurrentProcess(), 0, szApplication, &cchLength);
		DWORD dwStatus = StartElevatedProcess(szApplication, NULL);//手动提升权限
		if (dwStatus == S_OK)
		{
			//不需要极限在低特权下工作,退出本进程
			ExitProcess(0);
		}

		//否则,新进程如果启动失败,重新显示本进程的主窗口
		ShowWindow(hwnd, SW_SHOWNORMAL);
	}
		break;
		//Processes菜单
	case ID_PROCESSES:
		s_fProcesses = TRUE;
		//MF_BYCOMMAND:通过ID定位
		EnableMenuItem(GetMenu(hwnd), ID_VMMAP, MF_BYCOMMAND | MF_ENABLED);
		DrawMenuBar(hwnd);
		Dlg_PopulateProcessList(hwnd);
		break;
		//modules菜单项
	case ID_MODULES:
		EnableMenuItem(GetMenu(hwnd), ID_VMMAP,MF_BYCOMMAND|MF_GRAYED);
		DrawMenuBar(hwnd);
		s_fProcesses = FALSE;
		Dlg_PopulateModuleList(hwnd);
		break;

	case IDC_PROCESSMODULELIST:
		if (codeNotify == CBN_SELCHANGE)
		{
			DWORD dw = ComboBox_GetCurSel(hwndCtrl);
			if (s_fProcesses)
			{
				dw = (DWORD)ComboBox_GetItemData(hwndCtrl, dw);//process id
				ShowProcessInfo(GetDlgItem(hwnd, IDC_RESULTS), dw);
			}
			else
			{
				//完整路径的索引在helper listbox中
				dw = (DWORD)ComboBox_GetItemData(hwndCtrl, dw);
				TCHAR szModulePath[1024];
				ListBox_GetText(GetDlgItem(hwnd, IDC_MODULEHELP),
					dw, szModulePath);
				ShowModeleInfo(GetDlgItem(hwnd, IDC_RESULTS), szModulePath);
			}
		}
		break;
		//VMAP菜单0
	case ID_VMMAP:{
		TCHAR szCmdLine[32];
		//下拉列表框
		HWND hwndCB = GetDlgItem(hwnd, IDC_PROCESSMODULELIST);
		DWORD dwProcessId = (DWORD)
			ComboBox_GetItemData(hwndCB, ComboBox_GetCurSel(hwndCB));
		StringCchPrintf(szCmdLine, _countof(szCmdLine), TEXT("%d"),
			dwProcessId);

		DWORD dwStatus =
			StartElevatedProcess(TEXT("\"14-VMMap.exe\""), szCmdLine);
		//以管理员身份运行14-VMMap.exe程序时,会进行提升权限的询问,如果时用户拒绝
		//则显示下列消息框
		if (dwStatus == ERROR_CANCELLED)
		{
			chMB("Failed to run 14-VMMap.exe:you refused access.");
		}
		}
		break;
		
	}
}

//手动提升权限
DWORD StartElevatedProcess(LPCTSTR szExecutable, LPCTSTR szCmdLine)
{
	//初始化结构体
	SHELLEXECUTEINFO sei = { sizeof(SHELLEXECUTEINFO) };

	//请求管理员身份
	sei.lpVerb = TEXT("runas");//run administrator?

	//传入要提高权限的应用城项名
	sei.lpFile = szExecutable;

	//传入命令行参数
	sei.lpParameters = szCmdLine;

	//窗口正常显示,否则新启动的进程,七窗口将被隐藏
	sei.nShow = SW_SHOWNORMAL;

	ShellExecuteEx(&sei);
	return (GetLastError());
}

//获取令牌提升的类型机判断当前进程是否以管理员身份运行
BOOL GetProcessElevation(TOKEN_ELEVATION_TYPE* pElevationType, BOOL* pIsAdmin)
{
	HANDLE hToken = NULL;
	DWORD dwSize;

	//获取当前进程的Token 
	if (!OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY,&hToken))
	{
		return (FALSE);
	}

	BOOL bResult = FALSE;

	//获取提升类型
	if (GetTokenInformation(hToken,TokenElevationType,
		pElevationType,sizeof(TOKEN_ELEVATION_TYPE),&dwSize))
	{
		//创建管理员组的SID
		byte adminSID[SECURITY_MAX_SID_SIZE];
		dwSize = sizeof(adminSID);
		CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, &adminSID,
			&dwSize);
		//筛选令牌
		if (*pElevationType == TokenElevationTypeLimited)
		{
			//取地与筛选令牌关联的未筛选令牌
			HANDLE hUnfilTeredToken = NULL;
			GetTokenInformation(hToken, TokenLinkedToken, (void*)
				&hUnfilTeredToken, sizeof(HANDLE), &dwSize);

			//通过初始未被筛选的令牌判断是否包含管理员SID
			if (CheckTokenMembership(hUnfilTeredToken,&adminSID,pIsAdmin))
			{
				bResult = TRUE;
			}
			//关闭未筛选的令牌
			CloseHandle(hUnfilTeredToken);
		}
		else
		{
			//未筛选令牌
			*pIsAdmin = IsUserAnAdmin();
			bResult = TRUE;
		}
	}
	//关闭当前进程的令牌
	CloseHandle(hToken);
	return (bResult);
}

VOID ShowModeleInfo(HWND hwnd, PCTSTR pszModulePath)
{
	SetWindowText(hwnd, TEXT(" "));//Clear the output box 

	CToolhelp thProcesses(TH32CS_SNAPPROCESS);
	PROCESSENTRY32 pe = { sizeof(pe) };
	BOOL fOk = thProcesses.ProcessFirst(&pe);
	AddText(hwnd, TEXT("Pathname:%s\r\n\r\n"), pszModulePath);
	AddText(hwnd, TEXT("Process Informaton:\r\n"));
	AddText(hwnd, TEXT("    PID    %-*s Process\r\n"),
		s_cchAddress, TEXT("BaseAddr"));

	for (; fOk; fOk = thProcesses.ProcessNext(&pe))
	{
		CToolhelp thModules(TH32CS_SNAPMODULE, pe.th32ProcessID);
		MODULEENTRY32 me = { sizeof(me) };
		BOOL fOk = thModules.ModuleFirst(&me);
		for (;fOk;fOk = thModules.ModuleNext(&me))
		{
			if (_tcscmp(me.szExePath, pszModulePath) == 0)
			{
				AddText(hwnd, TEXT("    %08X  %p  %s\r\n"),
					pe.th32ProcessID, me.modBaseAddr, pe.szExeFile);
			}
		}
	}
}


void AddText(HWND hwnd, PCTSTR pszFormat, ...) 
{
	va_list argList;
	va_start(argList, pszFormat);

	TCHAR sz[20 * 1024];
	Edit_GetText(hwnd, sz, _countof(sz));
	_vstprintf_s(_tcschr(sz, TEXT('\0')), _countof(sz) - _tcslen(sz),
		pszFormat, argList);
	Edit_SetText(hwnd, sz);
	va_end(argList);
}

VOID ShowProcessInfo(HWND hwnd, DWORD dwProcessID) {

	SetWindowText(hwnd, TEXT(""));   // Clear the output box

	CToolhelp th(TH32CS_SNAPALL, dwProcessID);

	// Show Process details
	PROCESSENTRY32 pe = { sizeof(pe) };
	BOOL fOk = th.ProcessFirst(&pe);
	for (; fOk; fOk = th.ProcessNext(&pe)) {
		if (pe.th32ProcessID == dwProcessID) {
			TCHAR szCmdLine[1024];
			if (GetProcessCmdLine(dwProcessID, szCmdLine, _countof(szCmdLine))) {
				AddText(hwnd,
					TEXT("Command line: %s %s\r\n"), pe.szExeFile, szCmdLine);
			}
			else {
				AddText(hwnd, TEXT("Filename: %s\r\n"), pe.szExeFile);
			}
			AddText(hwnd, TEXT("   PID=%08X, ParentPID=%08X, ")
				TEXT("PriorityClass=%d, Threads=%d, Heaps=%d\r\n"),
				pe.th32ProcessID, pe.th32ParentProcessID,
				pe.pcPriClassBase, pe.cntThreads,
				th.HowManyHeaps());
			TCHAR szOwner[MAX_PATH + 1];
			if (GetProcessOwner(dwProcessID, szOwner, MAX_PATH)) {
				AddText(hwnd, TEXT("Owner: %s\r\n"), szOwner);
			}

			break;   // No need to continue looping
		}
	}


	// Show Modules in the Process
	// Number of characters to display an address
	AddText(hwnd, TEXT("\r\nModules Information:\r\n")
		TEXT("  Usage  %-*s(%-*s)  %10s  Module\r\n"),
		s_cchAddress, TEXT("BaseAddr"),
		s_cchAddress, TEXT("ImagAddr"), TEXT("Size"));

	MODULEENTRY32 me = { sizeof(me) };
	fOk = th.ModuleFirst(&me);
	for (; fOk; fOk = th.ModuleNext(&me)) {
		if (me.ProccntUsage == 65535) {
			// Module was implicitly loaded and cannot be unloaded
			AddText(hwnd, TEXT("  Fixed"));
		}
		else {
			AddText(hwnd, TEXT("  %5d"), me.ProccntUsage);
		}

		// Try to format the size in kb.
		TCHAR szFormattedSize[64];
		if (StrFormatKBSize(me.modBaseSize, szFormattedSize,
			_countof(szFormattedSize)) == NULL)
		{
			StringCchPrintf(szFormattedSize, _countof(szFormattedSize),
				TEXT("%10u"), me.modBaseSize);
		}

		PVOID pvPreferredBaseAddr =
			GetModulePreferredBaseAddr(pe.th32ProcessID, me.modBaseAddr);
		if (me.modBaseAddr == pvPreferredBaseAddr) {
			AddText(hwnd, TEXT("  %p %*s   %10s  %s\r\n"),
				me.modBaseAddr, s_cchAddress, TEXT(""),
				szFormattedSize, me.szExePath);
		}
		else {
			AddText(hwnd, TEXT("  %p(%p)  %10s  %s\r\n"),
				me.modBaseAddr, pvPreferredBaseAddr,
				szFormattedSize, me.szExePath);
		}
	}

	// Show threads in the process
	AddText(hwnd, TEXT("\r\nThread Information:\r\n")
		TEXT("      TID     Priority\r\n"));
	THREADENTRY32 te = { sizeof(te) };
	fOk = th.ThreadFirst(&te);
	for (; fOk; fOk = th.ThreadNext(&te)) {
		if (te.th32OwnerProcessID == dwProcessID) {
			int nPriority = te.tpBasePri + te.tpDeltaPri;
			if ((te.tpBasePri < 16) && (nPriority > 15)) nPriority = 15;
			if ((te.tpBasePri > 15) && (nPriority > 31)) nPriority = 31;
			if ((te.tpBasePri < 16) && (nPriority < 1)) nPriority = 1;
			if ((te.tpBasePri > 15) && (nPriority < 16)) nPriority = 16;
			AddText(hwnd, TEXT("   %08X       %2d\r\n"),
				te.th32ThreadID, nPriority);
		}
	}
}


BOOL GetProcessCmdLine(HANDLE hProcess, LPTSTR szCmdLine, DWORD Size) {

	// Sanity checks
	if ((hProcess == NULL) || (szCmdLine == NULL) || (Size == 0))
		return(FALSE);

	// 0. Get the Process Environment Block address
	int   iReturn = 1;
	DWORD dwSize;
	SIZE_T size;

	PROCESS_BASIC_INFORMATION  pbi;
	// The PEB was supposed to always be at address 0x7ffdf000 in XP...
	// ... but, here is the "right" way to get it now in Vista.
	iReturn =
		_NtQueryInformationProcess(
			hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), &dwSize);

	// NtQueryInformationProcess returns a negative value if it fails
	if (iReturn >= 0) {
		// 1. Find the Process Environment Block
		__PEB PEB;
		size = dwSize;
		if (!ReadProcessMemory(hProcess, pbi.PebBaseAddress, &PEB,
			sizeof(PEB), &size)) {
			// Call GetLastError() if you need to know why
			return(FALSE);
		}

		// 2. From this PEB, get the address of the block containing 
		// a pointer to the CmdLine
		__INFOBLOCK Block;
		if (!ReadProcessMemory(hProcess, (LPVOID)PEB.InfoBlockAddress,
			&Block, sizeof(Block), &size)) {
			// Call GetLastError() if you need to know why
			return(FALSE);
		}

		// 3. Get the CmdLine
		wchar_t wszCmdLine[MAX_PATH + 1];
		if (!ReadProcessMemory(hProcess, (LPVOID)Block.wszCmdLineAddress,
			wszCmdLine, MAX_PATH * sizeof(wchar_t), &size)) {
			// Call GetLastError() if you need to know why
			return(FALSE);
		}

		// 4. Skip the application pathname
		//    it can be empty, "c:\...\app.exe" or c:\...\app.exe
		wchar_t* pPos = wszCmdLine;
		if (*pPos != L'\0') {
			if (*pPos == L'"') {
				// Find the next " character
				pPos = wcschr(&pPos[1], L'"');
			}
			else {
				// Find the next SPACE character
				pPos = wcschr(&pPos[1], L' ');
			}

			// Skip it
			if (pPos != NULL)
				pPos++;
		}

		// Copy it back
		if (pPos != NULL) {
			if (*pPos != L'\0') {
#ifdef UNICODE
				// Both strings are in UNICODE.
				_tcscpy_s(szCmdLine, Size, pPos);
#else
				// from UNICODE to ANSI
				MultiByteToWideChar(CP_ACP, 0, szCmdLine, Size,
					pPos, wcslen(pPos));
#endif
			}
			else
				szCmdLine[0] = TEXT('\0');
		}
		else
			szCmdLine[0] = TEXT('\0');
	}
	else {
		return(FALSE);
	}

	return(TRUE);
}


BOOL GetProcessCmdLine(DWORD PID, LPTSTR szCmdLine, DWORD Size) {

	// Sanity checks
	if ((PID <= 0) || (szCmdLine == NULL))
		return(FALSE);

	// Check if we can get information for this process
	HANDLE hProcess =
		OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, PID);
	if (hProcess == NULL)
		return(FALSE);

	BOOL bReturn = GetProcessCmdLine(hProcess, szCmdLine, Size);

	// Don't forget to release the process handle
	CloseHandle(hProcess);

	return(bReturn);
}

VOID FormatSizeInKB(DWORD dwSize, DWORD nCharacters,
	LPTSTR szSize, size_t cchSize) {

	TCHAR szFormattedSize[64];
	if (StrFormatKBSize(dwSize, szFormattedSize,
		_countof(szFormattedSize)) == NULL) {
		StringCchPrintf(szFormattedSize, _countof(szFormattedSize), TEXT("%8u"), dwSize);
	}

	// Format to the right nCharacter width if needed.
	if (_tcslen(szFormattedSize) < nCharacters) {
		DWORD current = 0;
		for (current = 0;
			current < (nCharacters - _tcslen(szFormattedSize));
			current++) {
			szSize[current] = TEXT(' ');
		}
		szSize[current] = TEXT('\0');

		_tcscat_s(szSize, cchSize - current, szFormattedSize);
	}
}

VOID Dlg_PopulateProcessList(HWND hwnd) {

	HWND hwndList = GetDlgItem(hwnd, IDC_PROCESSMODULELIST);
	SetWindowRedraw(hwndList, FALSE);
	ComboBox_ResetContent(hwndList);

	CToolhelp thProcesses(TH32CS_SNAPPROCESS);
	PROCESSENTRY32 pe = { sizeof(pe) };
	BOOL fOk = thProcesses.ProcessFirst(&pe);
	for (; fOk; fOk = thProcesses.ProcessNext(&pe)) {
		TCHAR sz[1024];

		// Place the process name (without its path) & ID in the list
		PCTSTR pszExeFile = _tcsrchr(pe.szExeFile, TEXT('\\'));
		if (pszExeFile == NULL) {
			pszExeFile = pe.szExeFile;
		}
		else {
			pszExeFile++; // Skip over the slash
		}

		// Append the code/resource integrity level and policy
		DWORD dwCodeIntegrityLevel = 0;
		DWORD dwCodePolicy = TOKEN_MANDATORY_POLICY_OFF;
		DWORD dwResourcePolicy = 0;
		DWORD dwResourceIntegrityLevel = 0;
		TCHAR szCodeDetails[256];
		szCodeDetails[0] = TEXT('\0');
		TCHAR szResourceDetails[256];
		szResourceDetails[0] = TEXT('\0');
		if (GetProcessIntegrityLevel(pe.th32ProcessID, &dwCodeIntegrityLevel,
			&dwCodePolicy, &dwResourceIntegrityLevel, &dwResourcePolicy)) {
			switch (dwCodeIntegrityLevel) {
			case SECURITY_MANDATORY_LOW_RID:
				_tcscpy_s(szCodeDetails, _countof(szCodeDetails),
					TEXT("- Low "));
				break;

			case SECURITY_MANDATORY_MEDIUM_RID:
				_tcscpy_s(szCodeDetails, _countof(szCodeDetails),
					TEXT("- Medium "));
				break;

			case SECURITY_MANDATORY_HIGH_RID:
				_tcscpy_s(szCodeDetails, _countof(szCodeDetails),
					TEXT("- High "));
				break;

			case SECURITY_MANDATORY_SYSTEM_RID:
				_tcscpy_s(szCodeDetails, _countof(szCodeDetails),
					TEXT("- System "));
				break;

			default:
				_tcscpy_s(szCodeDetails, _countof(szCodeDetails),
					TEXT("- ??? "));
			}

			if (dwCodePolicy == TOKEN_MANDATORY_POLICY_OFF) { // = 0
				_tcscat_s(szCodeDetails,
					_countof(szCodeDetails), TEXT(" + no policy"));
			}
			else {
				if ((dwCodePolicy & TOKEN_MANDATORY_POLICY_VALID_MASK) == 0) {
					_tcscat_s(szCodeDetails, _countof(szCodeDetails),
						TEXT(" + ???"));
				}
				else {
					if ((dwCodePolicy & TOKEN_MANDATORY_POLICY_NO_WRITE_UP)
						== TOKEN_MANDATORY_POLICY_NO_WRITE_UP) {
						_tcscat_s(szCodeDetails, _countof(szCodeDetails),
							TEXT(" + no write-up"));
					}

					if ((dwCodePolicy & TOKEN_MANDATORY_POLICY_NEW_PROCESS_MIN)
						== TOKEN_MANDATORY_POLICY_NEW_PROCESS_MIN) {
						_tcscat_s(szCodeDetails, _countof(szCodeDetails),
							TEXT(" + new process min"));
					}
				}
			}

			switch (dwResourceIntegrityLevel) {
			case SECURITY_MANDATORY_LOW_RID:
				_tcscpy_s(szResourceDetails,
					_countof(szResourceDetails), TEXT("Low"));
				break;

			case SECURITY_MANDATORY_MEDIUM_RID:
				_tcscpy_s(szResourceDetails,
					_countof(szResourceDetails), TEXT("Medium"));
				break;

			case SECURITY_MANDATORY_HIGH_RID:
				_tcscpy_s(szResourceDetails,
					_countof(szResourceDetails), TEXT("High"));
				break;

			case SECURITY_MANDATORY_SYSTEM_RID:
				_tcscpy_s(szResourceDetails,
					_countof(szResourceDetails), TEXT("System"));
				break;

			case 0:
				_tcscpy_s(szResourceDetails,
					_countof(szResourceDetails), TEXT("Not set"));
				break;

			default:
				_tcscpy_s(szResourceDetails,
					_countof(szResourceDetails), TEXT("???"));
			}


			if (dwResourcePolicy == 0) { // = 0
				_tcscat_s(szResourceDetails,
					_countof(szResourceDetails), TEXT(" + 0 policy"));
			}
			else {
				if ((dwResourcePolicy & TOKEN_MANDATORY_POLICY_VALID_MASK) == 0) {
					_tcscat_s(szResourceDetails,
						_countof(szResourceDetails), TEXT(" + ???"));
				}
				else {
					if ((dwResourcePolicy & SYSTEM_MANDATORY_LABEL_NO_WRITE_UP)
						== SYSTEM_MANDATORY_LABEL_NO_WRITE_UP) {
						_tcscat_s(szResourceDetails,
							_countof(szResourceDetails),
							TEXT(" + no write-up"));
					}

					if ((dwResourcePolicy & SYSTEM_MANDATORY_LABEL_NO_READ_UP)
						== SYSTEM_MANDATORY_LABEL_NO_READ_UP) {
						_tcscat_s(szResourceDetails,
							_countof(szResourceDetails),
							TEXT(" + no read-up"));
					}
					if ((dwResourcePolicy & SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP)
						== SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP) {
						_tcscat_s(szResourceDetails,
							_countof(szResourceDetails),
							TEXT(" + no execute-up"));
					}
				}
			}
		}

		StringCchPrintf(sz, _countof(sz), TEXT("%s     (0x%08X)  %s    [%s]"),
			pszExeFile, pe.th32ProcessID, szCodeDetails, szResourceDetails);
		int n = ComboBox_AddString(hwndList, sz);

		// Associate the process ID with the added item
		ComboBox_SetItemData(hwndList, n, pe.th32ProcessID);
	}

	ComboBox_SetCurSel(hwndList, 0);  // Select the first entry

	// Simulate the user selecting this first item so that the
	// results pane shows something interesting
	FORWARD_WM_COMMAND(hwnd, IDC_PROCESSMODULELIST,
		hwndList, CBN_SELCHANGE, SendMessage);

	SetWindowRedraw(hwndList, TRUE);
	InvalidateRect(hwndList, NULL, FALSE);
}


///


VOID Dlg_PopulateModuleList(HWND hwnd) {

	HWND hwndModuleHelp = GetDlgItem(hwnd, IDC_MODULEHELP);
	ListBox_ResetContent(hwndModuleHelp);

	CToolhelp thProcesses(TH32CS_SNAPPROCESS);
	PROCESSENTRY32 pe = { sizeof(pe) };
	BOOL fOk = thProcesses.ProcessFirst(&pe);
	for (; fOk; fOk = thProcesses.ProcessNext(&pe)) {

		CToolhelp thModules(TH32CS_SNAPMODULE, pe.th32ProcessID);
		MODULEENTRY32 me = { sizeof(me) };
		BOOL fOk = thModules.ModuleFirst(&me);
		for (; fOk; fOk = thModules.ModuleNext(&me)) {
			int n = ListBox_FindStringExact(hwndModuleHelp, -1, me.szExePath);
			if (n == LB_ERR) {
				// This module hasn't been added before
				ListBox_AddString(hwndModuleHelp, me.szExePath);
			}
		}
	}

	HWND hwndList = GetDlgItem(hwnd, IDC_PROCESSMODULELIST);
	SetWindowRedraw(hwndList, FALSE);
	ComboBox_ResetContent(hwndList);
	int nNumModules = ListBox_GetCount(hwndModuleHelp);
	for (int i = 0; i < nNumModules; i++) {
		TCHAR sz[1024];
		ListBox_GetText(hwndModuleHelp, i, sz);
		// Place module name (without its path) in the list
		int nIndex = ComboBox_AddString(hwndList, _tcsrchr(sz, TEXT('\\')) + 1);
		// Associate the index of the full path with the added item
		ComboBox_SetItemData(hwndList, nIndex, i);
	}

	ComboBox_SetCurSel(hwndList, 0);  // Select the first entry

	// Simulate the user selecting this first item so that the
	// results pane shows something interesting
	FORWARD_WM_COMMAND(hwnd, IDC_PROCESSMODULELIST,
		hwndList, CBN_SELCHANGE, SendMessage);

	SetWindowRedraw(hwndList, TRUE);
	InvalidateRect(hwndList, NULL, FALSE);
}

BOOL GetProcessIntegrityLevel(HANDLE hProcess, PDWORD pIntegrityLevel,
	PDWORD pPolicy, PDWORD pResourceIntegrityLevel, PDWORD pResourcePolicy) {

	HANDLE hToken = NULL;
	if (!OpenProcessToken(hProcess, TOKEN_READ, &hToken)) {
		return(FALSE);
	}

	BOOL bReturn = FALSE;

	// First, compute the size of the buffer to get the Integrity level
	DWORD dwNeededSize = 0;
	if (!GetTokenInformation(
		hToken, TokenIntegrityLevel, NULL, 0, &dwNeededSize)) {

		PTOKEN_MANDATORY_LABEL pTokenInfo = NULL;
		if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
			// Second, allocate a memory block with the the required size 
			pTokenInfo = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, dwNeededSize);
			if (pTokenInfo != NULL) {
				// And finally, ask for the integrity level
				if (GetTokenInformation(hToken, TokenIntegrityLevel, pTokenInfo,
					dwNeededSize, &dwNeededSize)) {

					*pIntegrityLevel =
						*GetSidSubAuthority(
							pTokenInfo->Label.Sid,
							(*GetSidSubAuthorityCount(pTokenInfo->Label.Sid) - 1)
						);
					bReturn = TRUE;
				}

				// Don't forget to free the memory
				LocalFree(pTokenInfo);
			}
		}
	}

	// Try to get the policy if the integrity level was available
	if (bReturn) {
		*pPolicy = TOKEN_MANDATORY_POLICY_OFF;
		dwNeededSize = sizeof(DWORD);
		GetTokenInformation(hToken, TokenMandatoryPolicy, pPolicy,
			dwNeededSize, &dwNeededSize);
	}

	// Look for the resource policy
	*pResourceIntegrityLevel = 0; // 0 means none explicitely set
	*pResourcePolicy = 0;

	PACL pSACL = NULL;
	PSECURITY_DESCRIPTOR pSD = NULL;
	DWORD dwResult = ERROR_SUCCESS;

	// Look for the no-read-up/no-write-up policy in the SACL
	if (hToken != NULL) {
		dwResult =
			GetSecurityInfo(
				hProcess, SE_KERNEL_OBJECT,
				LABEL_SECURITY_INFORMATION,
				NULL, NULL, NULL,
				&pSACL, &pSD
			);
		if (dwResult == ERROR_SUCCESS) {
			if (pSACL != NULL) {
				SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
				if ((pSACL->AceCount > 0) && (GetAce(pSACL, 0, (PVOID*)&pACE))) {
					if (pACE != NULL) {
						SID* pSID = (SID*)(&pACE->SidStart);
						*pResourceIntegrityLevel = pSID->SubAuthority[0];
						*pResourcePolicy = pACE->Mask;
					}
				}
			}
		}

		// Cleanup memory allocated on our behalf
		if (pSD != NULL) LocalFree(pSD);
	}


	// Don't forget to close the token handle.
	CloseHandle(hToken);

	return(bReturn);
}

BOOL GetProcessIntegrityLevel(DWORD PID, PDWORD pIntegrityLevel,
	PDWORD pPolicy, PDWORD pResourceIntegrityLevel, PDWORD pResourcePolicy) {

	// Sanity checks
	if ((PID <= 0) || (pIntegrityLevel == NULL))
		return(FALSE);

	// Check if we can get information for this process
	HANDLE hProcess = OpenProcess(
		READ_CONTROL | PROCESS_QUERY_INFORMATION,
		FALSE, PID);

	if (hProcess == NULL)
		return(FALSE);

	BOOL bReturn = GetProcessIntegrityLevel(hProcess, pIntegrityLevel,
		pPolicy, pResourceIntegrityLevel, pResourcePolicy);

	// Don't forget to release the process handle
	CloseHandle(hProcess);

	return(bReturn);
}


PVOID GetModulePreferredBaseAddr(DWORD dwProcessId, PVOID pvModuleRemote) {

	PVOID pvModulePreferredBaseAddr = NULL;
	IMAGE_DOS_HEADER idh;
	IMAGE_NT_HEADERS inth;

	// Read the remote module's DOS header
	Toolhelp32ReadProcessMemory(dwProcessId,
		pvModuleRemote, &idh, sizeof(idh), NULL);

	// Verify the DOS image header
	if (idh.e_magic == IMAGE_DOS_SIGNATURE) {
		// Read the remote module's NT header
		Toolhelp32ReadProcessMemory(dwProcessId,
			(PBYTE)pvModuleRemote + idh.e_lfanew, &inth, sizeof(inth), NULL);

		// Verify the NT image header
		if (inth.Signature == IMAGE_NT_SIGNATURE) {
			// This is valid NT header, get the image's preferred base address
			pvModulePreferredBaseAddr = (PVOID)inth.OptionalHeader.ImageBase;
		}
	}
	return(pvModulePreferredBaseAddr);
}

  • 10
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值