权限管理

查询权限

BOOL QueryPrivileges()
{
// 1. 获得本进程的令牌HANDLE hToken = NULL;if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))return false;// 2. 获取提升类型TOKEN_ELEVATION_TYPE ElevationType = TokenElevationTypeDefault;BOOL                 bIsAdmin = false;DWORD                dwSize = 0;
​
​if (GetTokenInformation(hToken, TokenElevationType, &ElevationType,sizeof(TOKEN_ELEVATION_TYPE), &dwSize)) {// 2.1 创建管理员组的对应SID
        BYTE adminSID[SECURITY_MAX_SID_SIZE];dwSize = sizeof(adminSID);CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, &adminSID, &dwSize);
​
​// 2.2 判断当前进程运行用户角色是否为管理员if (ElevationType == TokenElevationTypeLimited) {
​// a. 获取连接令牌的句柄HANDLE hUnfilteredToken = NULL;GetTokenInformation(hToken, TokenLinkedToken, (PVOID)&hUnfilteredToken,sizeof(HANDLE), &dwSize);
​// b. 检查这个原始的令牌是否包含管理员的SIDif (!CheckTokenMembership(hUnfilteredToken, &adminSID, &bIsAdmin))return false;CloseHandle(hUnfilteredToken);}else {bIsAdmin = IsUserAnAdmin();}CloseHandle(hToken);}// 3. 判断具体的权限状况BOOL bFullToken = false;switch (ElevationType) {case TokenElevationTypeDefault: /* 默认的用户或UAC被禁用 */if (IsUserAnAdmin())  bFullToken = true; // 默认用户有管理员权限else                  bFullToken = false;// 默认用户不是管理员组break;case TokenElevationTypeFull:    /* 已经成功提高进程权限 */if (IsUserAnAdmin())  bFullToken = true; //当前以管理员权限运行else                  bFullToken = false;//当前未以管理员权限运行break;case TokenElevationTypeLimited: /* 进程在以有限的权限运行 */if (bIsAdmin)  bFullToken = false;//用户有管理员权限,但进程权限有限else           bFullToken = false;//用户不是管理员组,且进程权限有限
    }
​// 4. 根据权限的不同控制按钮的显示if (!bFullToken)Button_SetElevationRequiredState(::GetDlgItem(m_hWnd, IDC_BUTTON1), !bFullToken);else::ShowWindow(::GetDlgItem(m_hWnd, IDC_BUTTON1), SW_HIDE);
}

管理员启动

void OnBnClickedButton1()
{
// 1. 隐藏当前窗口//ShowWindow(hWnd, SW_HIDE);this->ShowWindow(SW_HIDE);// 2. 获取当前程序路径WCHAR szApplication[MAX_PATH] = { 0 };DWORD cchLength = _countof(szApplication);QueryFullProcessImageName(GetCurrentProcess(), 0,szApplication, &cchLength);// 3. 以管理员权限重新打开进程SHELLEXECUTEINFO sei = { sizeof(SHELLEXECUTEINFO) };sei.lpVerb = L"runas";      // 请求提升权限sei.lpFile = szApplication; // 可执行文件路径sei.lpParameters = NULL;          // 不需要参数sei.nShow = SW_SHOWNORMAL; // 正常显示窗口if (ShellExecuteEx(&sei))exit(0);else::ShowWindow(m_hWnd, SW_SHOWNORMAL);
}

遍历权限

//遍历权限
void ShowPrviliges()
{
//获取进程令牌句柄
    HANDLE hToken;OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken);if (!hToken){printf("令牌获取失败\n");return;}//查询令牌中的权限
    DWORD dwSize;//第一次获取查询数据的大小
    GetTokenInformation(hToken,TokenPrivileges, NULL, NULL, &dwSize);//第二次根据上次获取的大小申请足够大的内存后,//将内存地址传进去获取想要的数据char* pBuf = new char[dwSize] {};GetTokenInformation(hToken,TokenPrivileges, pBuf, dwSize, &dwSize);//将内存中的内容用要查询数据结构体解析//这里事权限的结构体TOKEN_PRIVILEGES* pTp = (TOKEN_PRIVILEGES*)pBuf;
​//权限个数DWORD dwCount = pTp->PrivilegeCount;//指向权限数组首地址LUID_AND_ATTRIBUTES* pLaa = pTp->Privileges;//输出权限for (int i = 0; i < dwCount; i++, pLaa++){char szName[100] = {};DWORD dwLen = sizeof(szName);//查询此权限对应的字符串LookupPrivilegeNameA(0, &pLaa->Luid, szName, &dwLen);//状态,0:关闭,1:默认值,2:开启,3:默认开启 printf("[%s] -- 状态[%d]\n", szName, pLaa->Attributes);}delete pBuf;}

提升权限

BOOL EnableDebugPrivilege(BOOL fEnable){  BOOL fOk = FALSE;    HANDLE hToken;// 以修改权限的方式,打开进程的令牌if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES,&hToken)) {// 令牌权限结构体
        TOKEN_PRIVILEGES tp;tp.PrivilegeCount = 1;//获得LUIDLookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;//修改权限AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL); fOk = (GetLastError() == ERROR_SUCCESS);CloseHandle(hToken);}return(fOk);
}

内存管理

Windows提供了以下3种方式管理内存数据

  • 堆:适合用来管理大量的小型对象,使用堆管理方式可以非常方便的帮我们管理所需要的内存空间,而无需去 关心一些细节问题,但是堆管理方式的效率较低,堆内存的控制不够灵活

  • 虚拟内存:适合用于管理大型的对象数组或大型的结构数组,使用虚拟内存管理方式有丰富的内存管理接口, 可以使我们更加精确的控制内存数据

  • 文件映射:适合用于管理大型的数据流,以及在同一个机器上的不同进程间共享数据

堆使用

int main()
{//创建堆可增长的HANDLE heap = HeapCreate(0, 0, 0);//系统信息
    SYSTEM_INFO sys;GetSystemInfo(&sys);//申请5个页面大小堆LPVOID pBuff = HeapAlloc(heap, HEAP_ZERO_MEMORY, sys.dwPageSize * 5);//读写堆内存memcpy(pBuff, "hello", 6);printf("%s\n", pBuff);//释放堆
    HeapFree(heap, HEAP_NO_SERIALIZE, pBuff);//销毁堆
    HeapDestroy(heap);
​//系统的默认堆HANDLE hProcessHeap = GetProcessHeap();LPVOID pbuff2 = HeapAlloc(hProcessHeap, HEAP_ZERO_MEMORY,11 );//读写堆内存memcpy(pbuff2, "hello", 6);printf("%s\n", pbuff2);//不能使用DestroyHeap
    getchar();
}

虚拟内存

虚拟内存三种状态

空闲(free) : 进程不能访问这种页面,此页面还没有被分配 保留(reserve):这个页面被预定了。但是还未与物理内存映射,因此这里也是不能访问的 提交(commit): 内存已经被分配了,并且也与物理存储器映射了,进程已经可以访问这里

虚拟内存映射的三种方式:

private : 进程私有内存,不被其他进程所共享, 一般是堆,栈

mapped: 从别的内存映射而来

image : 从程序的PE映像映射而来,一般是映像的区段 虚拟内存的页面属性

READONLY :只读,只能从这个分页读取数据

READ_WRITE : 可读可写

EXECUTE : 可执行

EXECUTE_READ_WRITE : 可读可写可执行

WRITE_COPY : 写时拷贝 (用户不能使用)

使用虚拟内存

int main()
{//MEM_FREE    空闲,没有被使用//MEM_RESERVE 保留,没有与物理地址映射//MEM_COMMIT  提交,与物理地址进行映射
​//1.申请虚拟内存空间LPVOID pBuff = VirtualAlloc(0,  //预定的地址,申请空间从这个地址开始1,  //申请空间的大小,默认对齐4kbMEM_RESERVE | MEM_COMMIT,  //预定并提交PAGE_READWRITE           //可写可读
    );
​//VirtualAllocEx 在其它进程中申请空间
​//2.使用它memcpy(pBuff, "hello", 6);//3.释放内存VirtualFree(pBuff, 1, MEM_FREE);//VirtualFree 在其它进程中释放空间
​
​//修改内存分页属性char * pName = (char*)"hello";DWORD dwOldProtect;VirtualProtect(pName,          //修改的内存地址1,              //修改的大小,会分页对齐PAGE_READWRITE, //修改后的新属性&dwOldProtect); //修改前的原始属性
​pName[0] = 'x';//VirtualProtectEx 修改目标进程内存属性
}

文件映射

简单文操作

int main()
{//操纵一个文件,CreateFile,WriteFile,ReadFile
​//1. 文件映射 速度快,无需申请空间HANDLE hFile = CreateFile(L"1.txt",GENERIC_WRITE| GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
​//2.创建一个内存映射对象HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0x10, L"test");
​//3.将物理地址映射到虚拟地址SIZE_T Size = 10;LPVOID pFileBuff = MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, Size);
​//4.操作这段内存,写入数据memcpy(pFileBuff, "hello 15pb", 11);
​//5.刷新到文件FlushViewOfFile(pFileBuff, 10);
​//6.取消映射
    UnmapViewOfFile(pFileBuff);
​//7.关闭句柄
    CloseHandle(hFile);CloseHandle(hFileMap);
​}

进程通信

进程A

int main()
{//1.创建文件映射HANDLE hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE,   //创建文件映射 -1NULL,                   //文件安全属性PAGE_READWRITE,         //页面属性0, 0x0100,L"15pb");
​//2.物理地址转换虚拟内存地址LPVOID lpBuff = MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, 10);//3.写入数据memcpy(lpBuff, "hello15pb", 10);//4.等待读取system("pause");//5.释放文件映射
    UnmapViewOfFile(lpBuff);CloseHandle(hFileMap);std::cout << "Hello World!\n";
}

        

进程B

int main()
{ //1.打开文件映射 HANDLE hFileMap =  OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, L"15pb"); //2.将物理地址转换虚拟地址 LPVOID lPbuff = MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS,0,0,10); ///3.读写数据 printf("buff:%s\n", lPbuff); //4. 取消映射关系
 UnmapViewOfFile(lPbuff); CloseHandle(hFileMap); } 

 

遍历内存

int main()
{//1.遍历进程 内存状态DWORD Addres = 0, Size = 0;
​//保存内存信息MEMORY_BASIC_INFORMATION Basicinfo = {};
​//遍历进程所有分页,输出内容while (VirtualQuery((LPCVOID)Addres, &Basicinfo, sizeof(MEMORY_BASIC_INFORMATION))){Size = Basicinfo.RegionSize;printf("%08p  ", Basicinfo.BaseAddress);
​//当前状态switch (Basicinfo.State){case MEM_FREE:      printf("空闲\n"); break;case MEM_RESERVE:   printf("保留\n"); break;case MEM_COMMIT:    printf("提交\n"); break;default:printf("未知\n");break;}
​//如果是提交状态的内存区域,那么遍历所有块中的信息if (Basicinfo.State == MEM_COMMIT){//遍历所有基址是AddressLPVOID BaseBlockAddress = (LPVOID)Addres;DWORD BlockAddress = Addres;DWORD dwBlockSize = 0;
​// 遍历大内存块中的小内存块while (VirtualQuery((LPVOID)BlockAddress, &Basicinfo, sizeof(Basicinfo))){if (BaseBlockAddress != Basicinfo.AllocationBase){break;}printf("  %08X  ", BlockAddress);//查看内存状态,映射方式switch (Basicinfo.Type){case MEM_PRIVATE:   printf("私有  "); break;case MEM_MAPPED:    printf("映射  "); break;case MEM_IMAGE:     printf("镜像  "); break;default:printf("未知  ");break;}if (Basicinfo.Protect == 0)printf("---");else if (Basicinfo.Protect & PAGE_EXECUTE)printf("E--");else if (Basicinfo.Protect & PAGE_EXECUTE_READ)printf("ER-");else if (Basicinfo.Protect & PAGE_EXECUTE_READWRITE)printf("ERW");else if (Basicinfo.Protect & PAGE_READONLY)printf("-R-");else if (Basicinfo.Protect & PAGE_READWRITE)printf("-RW");else if (Basicinfo.Protect & PAGE_WRITECOPY)printf("WCOPY");else if (Basicinfo.Protect & PAGE_EXECUTE_WRITECOPY)printf("EWCOPY");printf("\n");//计算所有相同块大小dwBlockSize += Basicinfo.RegionSize;
​// 累加内存块的位置BlockAddress += Basicinfo.RegionSize;}//内有可能大小位空Size = dwBlockSize ? dwBlockSize : Basicinfo.RegionSize;}
//下一个区域内存信息
Addres += Size;}
​
}

转载于:https://www.cnblogs.com/ltyandy/p/11103542.html

PE基础5-权限提升-内存管理相关推荐

  1. 黑马程序员-iOS基础-Objective-C基础(六)内存管理

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 黑马程序员-iOS基础-Objective-C基础(六)内存管理 一.内存管理的必要性 移动设备 ...

  2. c语言基础学习08_关于内存管理的复习

    ============================================================================= 对于c语言来讲,内存管理是一个很重要的内容, ...

  3. .NET基础 (05)内存管理和垃圾回收

    内存管理和垃圾回收 1 简述.NET中堆栈和堆的特点和差异 2 执行string abc="aaa"+"bbb"+"ccc"共分配了多少内存 ...

  4. Linux Unix内存管理,简述:Unix/Linux内存管理

    一.底层结构 采用三层结构,实际使用中可以方便映射到两层或者三层结构,以适用不同的硬件结构.最下层的申请内存函数get_free_page.之上有三种类型的内存分配函数: 1.kmalloc类型.内核 ...

  5. 11 操作系统第三章 内存管理 内存的基本知识 内存管理 内存空间扩充 连续分配管理方式

    文章目录 1 内存概念 1.1 内存作用 1.2 逻辑地址VS物理地址 1.3 装入的三种方式 1.3.1 绝对装入 1.3.2 可重定位装入 1.3.3 动态重定位装入 1.4 链接的三种方式 1. ...

  6. Unreal3 window下内存管理实现详解

    Unreal3 window下内存管理实现详解 最近组里面同事加入了一个很牛叉的内存管理代码,勾起我对内存管理的强烈欲望,以前也做过内存管理,在没有遇到U3以前看了3,4种算法(C++游戏编程 这本书 ...

  7. Linux内存管理 brk(),mmap()系统调用源码分析2:brk()的内存释放流程

    Linux brk(),mmap()系统调用源码分析 brk()的内存释放流程 荣涛 2021年4月30日 内核版本:linux-5.10.13 注释版代码:https://github.com/Rt ...

  8. win32 24内存管理和文件操作

    Change the world by program 内存管理基础 Win32 中的内存管理是分层次的,系统提供了几组层次不同的函数来管理内存,它们是标准内存管理函数.堆管理函数.虚拟内存管理函数和 ...

  9. 内存与操作系统内存管理

    内存与操作系统内存管理 文章目录 内存与操作系统内存管理 一.内存的基础知识 二.内存管理 2.1 内存空间扩充 2.2 内存空间的分配与回收** Java.大数据开发学习要点(持续更新中-) 一.内 ...

最新文章

  1. 王者荣耀活动精选 Blink 第二弹来袭!
  2. IDEA中PlantUML的使用
  3. form表单用js提前执行函数若不成功则不提交_如何用Jmeter做接口自动化测试?跟着操作一次就明白了...
  4. Linux多线程同步——信号量
  5. 12c集群日志位置_Oracle 19C RAC 集群日志位置变化
  6. Java的二十三种设计模式(建造者模式(Builder))
  7. 修改服务器的AJP监听地址,修改服务器的AJP监听地址
  8. 爬虫提交form表单中含有(unable to decode value)解决方法
  9. COVID-19知识图谱问答系统(基于REFO)
  10. 关于silverlight打印功能
  11. XLSTransformer 导出Excel数据
  12. python使用selenium大麦网抢票
  13. WARN: Establishing SSL connection without server‘s identity verification
  14. Unity 异常记录日志功能
  15. 谷歌浏览器,退出时;调用退出的方法,vue
  16. thingsboard
  17. shell中初始化数组并遍历数组
  18. python 结合百度识图识别文字
  19. RHCE环境准备 | 介绍
  20. 分枝PEI修饰的PLGA纳米粒/载柚皮素的牛血清白蛋白修饰PLGA纳米粒/包封香豆素-6的PLGA纳米粒

热门文章

  1. 人月神话贯彻执行_《人月神话》读后感与读书笔记
  2. alphac测试和bata测试区别_康一康!接口测试与性能测试的区别瞧过来~
  3. AcWing 338. 计数问题(数位DP)
  4. AcWing 891. Nim游戏(nim博弈)
  5. 鳗鱼刺多怎么处理图像_图像二值化处理
  6. 2.C++深入理解 面向对象部分1
  7. LADRC的学习——用simulink搭建仿真模型
  8. 小学计算机知识题,小学信息技术基础知识试题
  9. REVerb三元抽取工具
  10. 父组件和子组件同是使用 beforeDestroy 钩子 保存同一份数据