win原理Day005.zip

UAC

  1. // UACDlg.cpp : 实现文件
  2. //
  3. #include "stdafx.h"
  4. #include "UAC.h"
  5. #include "UACDlg.h"
  6. #include "afxdialogex.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #endif
  10. // 用于应用程序“关于”菜单项的 CAboutDlg 对话框
  11. class CAboutDlg : public CDialogEx
  12. {
  13. public:
  14. CAboutDlg();
  15. // 对话框数据
  16. enum { IDD = IDD_ABOUTBOX };
  17. protected:
  18. virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
  19. // 实现
  20. protected:
  21. DECLARE_MESSAGE_MAP()
  22. };
  23. CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
  24. {
  25. }
  26. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  27. {
  28. CDialogEx::DoDataExchange(pDX);
  29. }
  30. BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
  31. END_MESSAGE_MAP()
  32. // CUACDlg 对话框
  33. CUACDlg::CUACDlg(CWnd* pParent /*=NULL*/)
  34. : CDialogEx(CUACDlg::IDD, pParent)
  35. {
  36. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  37. }
  38. void CUACDlg::DoDataExchange(CDataExchange* pDX)
  39. {
  40. CDialogEx::DoDataExchange(pDX);
  41. DDX_Control(pDX, IDC_BUTTON1, m_Button);
  42. }
  43. BEGIN_MESSAGE_MAP(CUACDlg, CDialogEx)
  44. ON_WM_SYSCOMMAND()
  45. ON_WM_PAINT()
  46. ON_WM_QUERYDRAGICON()
  47. ON_BN_CLICKED(IDC_BUTTON1, &CUACDlg::OnBnClickedButton1)
  48. END_MESSAGE_MAP()
  49. // CUACDlg 消息处理程序
  50. BOOL CUACDlg::OnInitDialog()
  51. {
  52. CDialogEx::OnInitDialog();
  53. // 将“关于...”菜单项添加到系统菜单中。
  54. // IDM_ABOUTBOX 必须在系统命令范围内。
  55. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  56. ASSERT(IDM_ABOUTBOX < 0xF000);
  57. CMenu* pSysMenu = GetSystemMenu(FALSE);
  58. if (pSysMenu != NULL)
  59. {
  60. BOOL bNameValid;
  61. CString strAboutMenu;
  62. bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
  63. ASSERT(bNameValid);
  64. if (!strAboutMenu.IsEmpty())
  65. {
  66. pSysMenu->AppendMenu(MF_SEPARATOR);
  67. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  68. }
  69. }
  70. // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
  71. // 执行此操作
  72. SetIcon(m_hIcon, TRUE); // 设置大图标
  73. SetIcon(m_hIcon, FALSE); // 设置小图标
  74. // TODO: 在此添加额外的初始化代码
  75. // 1. 获得本进程的令牌
  76. HANDLE hToken = NULL;
  77. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
  78. return false;
  79. // 2. 获取提升类型
  80. TOKEN_ELEVATION_TYPE ElevationType = TokenElevationTypeDefault;
  81. BOOL bIsAdmin = false;
  82. DWORD dwSize = 0;
  83. if (GetTokenInformation(hToken, TokenElevationType, &ElevationType,
  84. sizeof(TOKEN_ELEVATION_TYPE), &dwSize)) {
  85. // 2.1 创建管理员组的对应SID
  86. BYTE adminSID[SECURITY_MAX_SID_SIZE];
  87. dwSize = sizeof(adminSID);
  88. CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, &adminSID, &dwSize);
  89. // 2.2 判断当前进程运行用户角色是否为管理员
  90. if (ElevationType == TokenElevationTypeLimited) {
  91. // a. 获取连接令牌的句柄
  92. HANDLE hUnfilteredToken = NULL;
  93. GetTokenInformation(hToken, TokenLinkedToken, (PVOID)&hUnfilteredToken,
  94. sizeof(HANDLE), &dwSize);
  95. // b. 检查这个原始的令牌是否包含管理员的SID
  96. if (!CheckTokenMembership(hUnfilteredToken, &adminSID, &bIsAdmin))
  97. return false;
  98. CloseHandle(hUnfilteredToken);
  99. }
  100. else {
  101. bIsAdmin = IsUserAnAdmin();
  102. }
  103. CloseHandle(hToken);
  104. }
  105. // 3. 判断具体的权限状况
  106. BOOL bFullToken = false;
  107. switch (ElevationType) {
  108. case TokenElevationTypeDefault: /* 默认的用户或UAC被禁用 */
  109. if (IsUserAnAdmin()) bFullToken = true; // 默认用户有管理员权限
  110. else bFullToken = false;// 默认用户不是管理员组
  111. break;
  112. case TokenElevationTypeFull: /* 已经成功提高进程权限 */
  113. if (IsUserAnAdmin()) bFullToken = true; //当前以管理员权限运行
  114. else bFullToken = false;//当前未以管理员权限运行
  115. break;
  116. case TokenElevationTypeLimited: /* 进程在以有限的权限运行 */
  117. if (bIsAdmin) bFullToken = false;//用户有管理员权限,但进程权限有限
  118. else bFullToken = false;//用户不是管理员组,且进程权限有限
  119. }
  120. // 4. 根据权限的不同控制按钮的显示
  121. if (!bFullToken)
  122. Button_SetElevationRequiredState(m_Button.m_hWnd,
  123. !bFullToken);
  124. else
  125. ::ShowWindow(m_Button.m_hWnd, SW_SHOW);
  126. return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
  127. }
  128. void CUACDlg::OnSysCommand(UINT nID, LPARAM lParam)
  129. {
  130. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  131. {
  132. CAboutDlg dlgAbout;
  133. dlgAbout.DoModal();
  134. }
  135. else
  136. {
  137. CDialogEx::OnSysCommand(nID, lParam);
  138. }
  139. }
  140. // 如果向对话框添加最小化按钮,则需要下面的代码
  141. // 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
  142. // 这将由框架自动完成。
  143. void CUACDlg::OnPaint()
  144. {
  145. if (IsIconic())
  146. {
  147. CPaintDC dc(this); // 用于绘制的设备上下文
  148. SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
  149. // 使图标在工作区矩形中居中
  150. int cxIcon = GetSystemMetrics(SM_CXICON);
  151. int cyIcon = GetSystemMetrics(SM_CYICON);
  152. CRect rect;
  153. GetClientRect(&rect);
  154. int x = (rect.Width() - cxIcon + 1) / 2;
  155. int y = (rect.Height() - cyIcon + 1) / 2;
  156. // 绘制图标
  157. dc.DrawIcon(x, y, m_hIcon);
  158. }
  159. else
  160. {
  161. CDialogEx::OnPaint();
  162. }
  163. }
  164. //当用户拖动最小化窗口时系统调用此函数取得光标
  165. //显示。
  166. HCURSOR CUACDlg::OnQueryDragIcon()
  167. {
  168. return static_cast<HCURSOR>(m_hIcon);
  169. }
  170. void CUACDlg::OnBnClickedButton1()
  171. {
  172. // TODO: 在此添加控件通知处理程序代码
  173. // 1. 隐藏当前窗口
  174. ShowWindow(SW_HIDE);
  175. // 2. 获取当前程序路径
  176. WCHAR szApplication[MAX_PATH] = { 0 };
  177. DWORD cchLength = _countof(szApplication);
  178. QueryFullProcessImageName(GetCurrentProcess(), 0,
  179. szApplication, &cchLength);
  180. // 3. 以管理员权限重新打开进程
  181. SHELLEXECUTEINFO sei = { sizeof(SHELLEXECUTEINFO) };
  182. sei.lpVerb = L"runas"; // 请求提升权限
  183. sei.lpFile = szApplication; // 可执行文件路径
  184. sei.lpParameters = NULL; // 不需要参数
  185. sei.nShow = SW_SHOWNORMAL; // 正常显示窗口
  186. if (ShellExecuteEx(&sei))
  187. exit(0);
  188. else
  189. ShowWindow(SW_SHOWNORMAL);
  190. }

遍历权限

  1. // win原理Day005.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include <windows.h>
  5. BOOL EnableDebugPrivilege(BOOL fEnable){ //提升为调试权限
  6. BOOL fOk = FALSE; HANDLE hToken;
  7. // 以修改权限的方式,打开进程的令牌
  8. if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES,
  9. &hToken)) {
  10. // 令牌权限结构体
  11. TOKEN_PRIVILEGES tp;
  12. tp.PrivilegeCount = 1;
  13. //获得LUID
  14. LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
  15. tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;
  16. AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL); //修改权限
  17. fOk = (GetLastError() == ERROR_SUCCESS);
  18. CloseHandle(hToken);
  19. }
  20. return(fOk);
  21. }
  22. //遍历权限
  23. void ShowPrivilege()
  24. {
  25. //打开访问令牌
  26. HANDLE hToken;
  27. OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken);
  28. if (!hToken)
  29. {
  30. printf("令牌打开失败\n");
  31. return;
  32. }
  33. //查询令牌中的权限
  34. DWORD dwSize;
  35. //第一次调用是为了获取数据大小
  36. GetTokenInformation(hToken, TokenPrivileges, NULL, NULL, &dwSize);
  37. char* pBuf = new char[dwSize]{};
  38. //第二次调用就可以获取数据了
  39. GetTokenInformation(hToken, TokenPrivileges, pBuf, dwSize, &dwSize);
  40. TOKEN_PRIVILEGES* pTp = (TOKEN_PRIVILEGES*)pBuf;
  41. //权限个数
  42. DWORD dwCount = pTp->PrivilegeCount;
  43. //pTp->Privileges:存储权限的数组
  44. LUID_AND_ATTRIBUTES* pLaa = pTp->Privileges;
  45. for (int i = 0; i < dwCount;i++,pLaa++)
  46. {
  47. char strName[100] = {};
  48. DWORD dwLen = sizeof(strName);
  49. LookupPrivilegeNameA(0, &pLaa->Luid, strName, &dwLen);
  50. //pLaa->Attributes:0表示关闭,1表示默认开启,2:开启,3:默认开启
  51. printf("权限:【%s】-状态:【%d】\n", strName, pLaa->Attributes);
  52. }
  53. //释放内存
  54. delete pBuf;
  55. }
  56. int _tmain(int argc, _TCHAR* argv[])
  57. {
  58. EnableDebugPrivilege(TRUE);
  59. ShowPrivilege();
  60. system("pause");
  61. return 0;
  62. }

虚拟内存

  1. // 虚拟内存.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include <windows.h>
  5. void temp()
  6. {
  7. // DWORD dwPid;
  8. // scanf_s("%d", &dwPid);
  9. // HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
  10. // //加强版,跨进程申请内存
  11. // LPVOID lpBuf = VirtualAllocEx(hProcess, NULL, 1, MEM_COMMIT, PAGE_READWRITE);
  12. //
  13. // //memcpy(lpBuf, "hello world", sizeof("hello world"));
  14. // //printf("%s", lpBuf);
  15. // //跨进程写内存
  16. // DWORD dwWrite;
  17. // WriteProcessMemory(hProcess,
  18. // lpBuf, "hello world",
  19. // sizeof("hello world"), &dwWrite);
  20. // char szBuf[100] = {};
  21. // DWORD dwRead;
  22. // //跨进程读内存
  23. // ReadProcessMemory(hProcess,
  24. // lpBuf, szBuf,
  25. // sizeof(szBuf), &dwRead);
  26. //
  27. // printf("%s", szBuf);
  28. }
  29. int _tmain(int argc, _TCHAR* argv[])
  30. {
  31. //申请虚拟内存(本进程)
  32. LPVOID lpBuf = VirtualAlloc(NULL,
  33. 1,
  34. MEM_COMMIT,
  35. PAGE_READONLY);
  36. //memcpy(lpBuf, "hello world", sizeof("hello world"));
  37. //printf("%s", lpBuf);
  38. //修改内存属性
  39. DWORD dwOld;
  40. VirtualProtect(lpBuf, 1, PAGE_READWRITE, &dwOld);
  41. memcpy(lpBuf, "hello world", sizeof("hello world"));
  42. return 0;
  43. }

遍历虚拟内存

  1. // 遍历虚拟内存.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include <Windows.h>
  5. #include <list>
  6. using std::list;
  7. enum MEMORYSTATE {
  8. e_stat_free = MEM_FREE,
  9. e_stat_reserve = MEM_RESERVE,
  10. e_stat_commit = MEM_COMMIT
  11. };
  12. enum MEMORYTYPE {
  13. e_type_image = MEM_IMAGE,
  14. e_type_mapped = MEM_MAPPED,
  15. e_type_private = MEM_PRIVATE,
  16. };
  17. typedef struct VMINFO {
  18. DWORD address;
  19. DWORD size;
  20. MEMORYSTATE state;
  21. }VMINFO;
  22. void queryVirtualMemoryStatue(HANDLE hProcess, list<VMINFO>* memoryStatue) {
  23. MEMORY_BASIC_INFORMATION mbi = { 0 };
  24. VMINFO statue = { 0 };
  25. DWORD dwAddress = 0;
  26. DWORD dwSize = 0;
  27. BOOL bRet = FALSE;
  28. while (1) {
  29. bRet = VirtualQueryEx(hProcess,
  30. (LPCVOID)dwAddress,
  31. &mbi,
  32. sizeof(MEMORY_BASIC_INFORMATION));
  33. if (bRet == FALSE)
  34. break;
  35. statue.address = dwAddress;
  36. statue.state = (MEMORYSTATE)mbi.State;
  37. dwSize = mbi.RegionSize;
  38. // 输出内存状态,
  39. // 内存状态用于描述虚拟内存有没有和物理存储器进行关联.
  40. // 或是否被预定.
  41. // free : 闲置,没有预定,没有和物理存储器关联
  42. // reserve: 保留,被预定,没有和物理存储器关联
  43. // commit : 提交,已经和物理存储器关联
  44. switch (statue.state) {
  45. case e_stat_free:
  46. printf("0x%08X : Free\n", statue.address);
  47. break;
  48. case e_stat_reserve:
  49. printf("0x%08X : reserve\n", statue.address);
  50. break;
  51. case e_stat_commit:
  52. printf("0x%08X : commit\n", statue.address);
  53. break;
  54. }
  55. // 如果内存地址已经提交到物理内存,则遍历提交到的每一个内存块.
  56. if (statue.state == e_stat_commit) {
  57. dwSize = 0;
  58. LPVOID dwAllocationBase = mbi.AllocationBase;
  59. DWORD dwBlockAddress = (DWORD)dwAddress;
  60. while (1) {
  61. bRet = VirtualQueryEx(hProcess,
  62. (LPCVOID)dwBlockAddress,
  63. &mbi,
  64. sizeof(MEMORY_BASIC_INFORMATION));
  65. if (bRet == FALSE) {
  66. break;
  67. }
  68. // 判断遍历出来的内存块是否是同一块.(看它们的分配的首地址是否相等.)
  69. // 如果不是,则跳出循环.
  70. if (mbi.AllocationBase != dwAllocationBase)
  71. break;
  72. printf("\t0x%08X ", dwBlockAddress);
  73. // 输出内存类型
  74. // 内存类型表示虚拟内存是以何种方式和物理存储器进行关联
  75. // image : 是从影像文件中映射而来
  76. // mapped : 内存映射
  77. // private: 私有内存,其它进程无法访问.
  78. switch (mbi.Type) {
  79. case e_type_image:
  80. printf(" 类型: image ");
  81. break;
  82. case e_type_mapped:
  83. printf(" 类型: mapped ");
  84. break;
  85. case e_type_private:
  86. printf(" 类型: private ");
  87. break;
  88. default:
  89. break;
  90. }
  91. // 输出内存分页属性
  92. // 内存分页属性用于表示内存分页能够进行何种访问,如读,写,执行,写时拷贝.
  93. if (mbi.Protect == 0)
  94. printf("---");
  95. else if (mbi.Protect & PAGE_EXECUTE)
  96. printf("E--");
  97. else if (mbi.Protect & PAGE_EXECUTE_READ)
  98. printf("ER-");
  99. else if (mbi.Protect & PAGE_EXECUTE_READWRITE)
  100. printf("ERW");
  101. else if (mbi.Protect & PAGE_READONLY)
  102. printf("-R-");
  103. else if (mbi.Protect & PAGE_READWRITE)
  104. printf("-RW");
  105. else if (mbi.Protect & PAGE_WRITECOPY)
  106. printf("WCOPY");
  107. else if (mbi.Protect & PAGE_EXECUTE_WRITECOPY)
  108. printf("EWCOPY");
  109. // 输出内存块的大小.
  110. printf(" 大小:0x%X\n", mbi.RegionSize);
  111. // 索引到下一个内存块
  112. dwBlockAddress += mbi.RegionSize;
  113. // 累加内存块的大小
  114. dwSize += mbi.RegionSize;
  115. }
  116. }
  117. statue.size = dwSize;
  118. memoryStatue->push_back(statue);
  119. // 遍历下一块虚拟内存.
  120. dwAddress += dwSize;
  121. }
  122. }
  123. int _tmain(int argc, _TCHAR* argv[])
  124. {
  125. list<VMINFO> vmList;
  126. queryVirtualMemoryStatue(GetCurrentProcess(), &vmList);
  127. return 0;
  128. }

共享内存B

  1. // 共享内存B.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include <windows.h>
  5. int _tmain(int argc, _TCHAR* argv[])
  6. {
  7. //打开文件映射对象
  8. HANDLE hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, L"hello");
  9. //关联虚拟内存
  10. LPVOID lpBuf = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 16);
  11. getchar();//暂停一下等待另一头把数据写入到共享内存中
  12. printf("%s", lpBuf);//读取内存数据
  13. //取消映射
  14. UnmapViewOfFile(lpBuf);
  15. //关闭句柄
  16. CloseHandle(hMap);
  17. system("pause");
  18. return 0;
  19. }

  1. // 堆.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include <windows.h>
  5. int _tmain(int argc, _TCHAR* argv[])
  6. {
  7. // 创建一个可增长的堆
  8. // HANDLE hHeap = HeapCreate(0, 0, 0);
  9. // SYSTEM_INFO si; //系统信息
  10. // GetSystemInfo(&si); // 获取系统信息
  11. // //在堆上分配3个页面大小的内存
  12. // LPVOID lpMem = HeapAlloc(hHeap,
  13. // HEAP_ZERO_MEMORY,
  14. // 3);
  15. // HeapFree(hHeap, 0, lpMem);
  16. // HeapDestroy(hHeap);
  17. HANDLE hHeap = GetProcessHeap(); // 获取默认堆
  18. SYSTEM_INFO si; //系统信息
  19. GetSystemInfo(&si); // 获取系统信息
  20. //在堆上分配3个页面大小的内存
  21. LPVOID lpMem = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, si.dwPageSize * 3);
  22. HeapFree(hHeap, 0, lpMem);
  23. HeapDestroy( hHeap );//默认堆是不能被销毁的
  24. return 0;
  25. }

文件映射

  1. // 文件映射.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include <windows.h>
  5. //创建文件映射(关联文件)
  6. void FileMapToFile(char* pFilePath)
  7. {
  8. //获取文件句柄
  9. HANDLE hFile = CreateFileA(pFilePath,
  10. GENERIC_READ | GENERIC_WRITE, TRUE, NULL,
  11. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  12. if (hFile == INVALID_HANDLE_VALUE)
  13. {
  14. printf("文件打开失败\n");
  15. return;
  16. }
  17. //创建文件映射对象
  18. HANDLE hMap = CreateFileMapping(hFile, NULL,
  19. PAGE_READWRITE, NULL,
  20. NULL, NULL);
  21. //关联虚拟内存
  22. LPVOID lpBuf = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
  23. *(int*)lpBuf = 0x99999999;
  24. //及时刷新到磁盘文件
  25. FlushViewOfFile(lpBuf, 4);
  26. //取消文件映射
  27. UnmapViewOfFile(lpBuf);
  28. //关闭文件映射对象句柄
  29. CloseHandle(hMap);
  30. CloseHandle(hFile);
  31. }
  32. //进程间通讯(共享内存)
  33. void ShareMemory()
  34. {
  35. //创建文件映射对象
  36. HANDLE hMap = CreateFileMapping(INVALID_HANDLE_VALUE,
  37. NULL, PAGE_READWRITE,
  38. 0, 16, L"hello");
  39. //与虚拟内存关联
  40. LPVOID lpBuf = MapViewOfFile(hMap,
  41. FILE_MAP_ALL_ACCESS,
  42. 0, 0, //映射偏移量必须是系统内存分配粒度(64KB)的整数倍
  43. 16);
  44. //写通讯数据
  45. memcpy(lpBuf, "hello girl", sizeof("hello girl"));
  46. //取消映射(如果不需要再通讯了,在执行)
  47. //UnmapViewOfFile(lpBuf);
  48. //CloseHandle(hMap);
  49. }
  50. int _tmain(int argc, _TCHAR* argv[])
  51. {
  52. //FileMapToFile("123.exe");
  53. ShareMemory();
  54. system("pause");
  55. return 0;
  56. }