win原理Day005.zip
UAC
// UACDlg.cpp : 实现文件//#include "stdafx.h"#include "UAC.h"#include "UACDlg.h"#include "afxdialogex.h"#ifdef _DEBUG#define new DEBUG_NEW#endif// 用于应用程序“关于”菜单项的 CAboutDlg 对话框class CAboutDlg : public CDialogEx{public:    CAboutDlg();// 对话框数据    enum { IDD = IDD_ABOUTBOX };    protected:    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持// 实现protected:    DECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD){}void CAboutDlg::DoDataExchange(CDataExchange* pDX){    CDialogEx::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)END_MESSAGE_MAP()// CUACDlg 对话框CUACDlg::CUACDlg(CWnd* pParent /*=NULL*/)    : CDialogEx(CUACDlg::IDD, pParent){    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void CUACDlg::DoDataExchange(CDataExchange* pDX){    CDialogEx::DoDataExchange(pDX);    DDX_Control(pDX, IDC_BUTTON1, m_Button);}BEGIN_MESSAGE_MAP(CUACDlg, CDialogEx)    ON_WM_SYSCOMMAND()    ON_WM_PAINT()    ON_WM_QUERYDRAGICON()    ON_BN_CLICKED(IDC_BUTTON1, &CUACDlg::OnBnClickedButton1)END_MESSAGE_MAP()// CUACDlg 消息处理程序BOOL CUACDlg::OnInitDialog(){    CDialogEx::OnInitDialog();    // 将“关于...”菜单项添加到系统菜单中。    // IDM_ABOUTBOX 必须在系统命令范围内。    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);    ASSERT(IDM_ABOUTBOX < 0xF000);    CMenu* pSysMenu = GetSystemMenu(FALSE);    if (pSysMenu != NULL)    {        BOOL bNameValid;        CString strAboutMenu;        bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);        ASSERT(bNameValid);        if (!strAboutMenu.IsEmpty())        {            pSysMenu->AppendMenu(MF_SEPARATOR);            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);        }    }    // 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动    //  执行此操作    SetIcon(m_hIcon, TRUE);            // 设置大图标    SetIcon(m_hIcon, FALSE);        // 设置小图标    // TODO:  在此添加额外的初始化代码    // 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. 检查这个原始的令牌是否包含管理员的SID            if (!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(m_Button.m_hWnd,        !bFullToken);    else        ::ShowWindow(m_Button.m_hWnd, SW_SHOW);    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE}void CUACDlg::OnSysCommand(UINT nID, LPARAM lParam){    if ((nID & 0xFFF0) == IDM_ABOUTBOX)    {        CAboutDlg dlgAbout;        dlgAbout.DoModal();    }    else    {        CDialogEx::OnSysCommand(nID, lParam);    }}// 如果向对话框添加最小化按钮,则需要下面的代码//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,//  这将由框架自动完成。void CUACDlg::OnPaint(){    if (IsIconic())    {        CPaintDC dc(this); // 用于绘制的设备上下文        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);        // 使图标在工作区矩形中居中        int cxIcon = GetSystemMetrics(SM_CXICON);        int cyIcon = GetSystemMetrics(SM_CYICON);        CRect rect;        GetClientRect(&rect);        int x = (rect.Width() - cxIcon + 1) / 2;        int y = (rect.Height() - cyIcon + 1) / 2;        // 绘制图标        dc.DrawIcon(x, y, m_hIcon);    }    else    {        CDialogEx::OnPaint();    }}//当用户拖动最小化窗口时系统调用此函数取得光标//显示。HCURSOR CUACDlg::OnQueryDragIcon(){    return static_cast<HCURSOR>(m_hIcon);}void CUACDlg::OnBnClickedButton1(){    // TODO:  在此添加控件通知处理程序代码    // 1. 隐藏当前窗口    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(SW_SHOWNORMAL);}
遍历权限
// win原理Day005.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <windows.h>BOOL EnableDebugPrivilege(BOOL fEnable){   //提升为调试权限    BOOL fOk = FALSE;    HANDLE hToken;    // 以修改权限的方式,打开进程的令牌    if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES,        &hToken)) {        // 令牌权限结构体        TOKEN_PRIVILEGES tp;        tp.PrivilegeCount = 1;        //获得LUID        LookupPrivilegeValue(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);}//遍历权限void ShowPrivilege(){    //打开访问令牌    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;    //pTp->Privileges:存储权限的数组    LUID_AND_ATTRIBUTES* pLaa = pTp->Privileges;    for (int i = 0; i < dwCount;i++,pLaa++)    {        char strName[100] = {};        DWORD dwLen = sizeof(strName);        LookupPrivilegeNameA(0, &pLaa->Luid, strName, &dwLen);        //pLaa->Attributes:0表示关闭,1表示默认开启,2:开启,3:默认开启        printf("权限:【%s】-状态:【%d】\n", strName, pLaa->Attributes);    }    //释放内存    delete pBuf;}int _tmain(int argc, _TCHAR* argv[]){    EnableDebugPrivilege(TRUE);    ShowPrivilege();    system("pause");    return 0;}
虚拟内存
// 虚拟内存.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <windows.h>void temp(){    //     DWORD dwPid;    //     scanf_s("%d", &dwPid);    //     HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);    //     //加强版,跨进程申请内存    //     LPVOID lpBuf = VirtualAllocEx(hProcess, NULL, 1, MEM_COMMIT, PAGE_READWRITE);    //     //     //memcpy(lpBuf, "hello world", sizeof("hello world"));    //     //printf("%s", lpBuf);    //     //跨进程写内存    //     DWORD dwWrite;    //     WriteProcessMemory(hProcess,    //         lpBuf, "hello world",    //         sizeof("hello world"), &dwWrite);    //     char szBuf[100] = {};    //     DWORD dwRead;    //     //跨进程读内存    //     ReadProcessMemory(hProcess,     //         lpBuf, szBuf,     //         sizeof(szBuf), &dwRead);    //     //     printf("%s", szBuf);}int _tmain(int argc, _TCHAR* argv[]){    //申请虚拟内存(本进程)    LPVOID lpBuf = VirtualAlloc(NULL,        1,         MEM_COMMIT,        PAGE_READONLY);    //memcpy(lpBuf, "hello world", sizeof("hello world"));    //printf("%s", lpBuf);    //修改内存属性    DWORD dwOld;    VirtualProtect(lpBuf, 1, PAGE_READWRITE, &dwOld);    memcpy(lpBuf, "hello world", sizeof("hello world"));    return 0;}
遍历虚拟内存
// 遍历虚拟内存.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <Windows.h>#include <list>using std::list;enum MEMORYSTATE {    e_stat_free = MEM_FREE,    e_stat_reserve = MEM_RESERVE,    e_stat_commit = MEM_COMMIT};enum MEMORYTYPE {    e_type_image = MEM_IMAGE,    e_type_mapped = MEM_MAPPED,    e_type_private = MEM_PRIVATE,};typedef struct VMINFO {    DWORD        address;    DWORD        size;    MEMORYSTATE state;}VMINFO;void queryVirtualMemoryStatue(HANDLE hProcess, list<VMINFO>* memoryStatue) {    MEMORY_BASIC_INFORMATION    mbi = { 0 };    VMINFO                        statue = { 0 };    DWORD                        dwAddress = 0;    DWORD                        dwSize = 0;    BOOL                        bRet = FALSE;    while (1) {        bRet = VirtualQueryEx(hProcess,            (LPCVOID)dwAddress,            &mbi,            sizeof(MEMORY_BASIC_INFORMATION));        if (bRet == FALSE)            break;        statue.address = dwAddress;        statue.state = (MEMORYSTATE)mbi.State;        dwSize = mbi.RegionSize;        // 输出内存状态,         // 内存状态用于描述虚拟内存有没有和物理存储器进行关联.        // 或是否被预定.        // free   : 闲置,没有预定,没有和物理存储器关联        // reserve: 保留,被预定,没有和物理存储器关联        // commit : 提交,已经和物理存储器关联        switch (statue.state) {        case e_stat_free:            printf("0x%08X : Free\n", statue.address);            break;        case e_stat_reserve:            printf("0x%08X : reserve\n", statue.address);            break;        case e_stat_commit:            printf("0x%08X : commit\n", statue.address);            break;        }        // 如果内存地址已经提交到物理内存,则遍历提交到的每一个内存块.        if (statue.state == e_stat_commit) {            dwSize = 0;            LPVOID    dwAllocationBase = mbi.AllocationBase;            DWORD    dwBlockAddress = (DWORD)dwAddress;            while (1) {                bRet = VirtualQueryEx(hProcess,                    (LPCVOID)dwBlockAddress,                    &mbi,                    sizeof(MEMORY_BASIC_INFORMATION));                if (bRet == FALSE) {                    break;                }                // 判断遍历出来的内存块是否是同一块.(看它们的分配的首地址是否相等.)                // 如果不是,则跳出循环.                if (mbi.AllocationBase != dwAllocationBase)                    break;                printf("\t0x%08X ", dwBlockAddress);                // 输出内存类型                // 内存类型表示虚拟内存是以何种方式和物理存储器进行关联                // image  : 是从影像文件中映射而来                // mapped : 内存映射                // private: 私有内存,其它进程无法访问.                switch (mbi.Type) {                case e_type_image:                    printf(" 类型: image   ");                    break;                case e_type_mapped:                    printf(" 类型: mapped  ");                    break;                case e_type_private:                    printf(" 类型: private ");                    break;                default:                    break;                }                // 输出内存分页属性                // 内存分页属性用于表示内存分页能够进行何种访问,如读,写,执行,写时拷贝.                if (mbi.Protect == 0)                    printf("---");                else if (mbi.Protect & PAGE_EXECUTE)                    printf("E--");                else if (mbi.Protect & PAGE_EXECUTE_READ)                    printf("ER-");                else if (mbi.Protect & PAGE_EXECUTE_READWRITE)                    printf("ERW");                else if (mbi.Protect & PAGE_READONLY)                    printf("-R-");                else if (mbi.Protect & PAGE_READWRITE)                    printf("-RW");                else if (mbi.Protect & PAGE_WRITECOPY)                    printf("WCOPY");                else if (mbi.Protect & PAGE_EXECUTE_WRITECOPY)                    printf("EWCOPY");                // 输出内存块的大小.                printf(" 大小:0x%X\n", mbi.RegionSize);                // 索引到下一个内存块                dwBlockAddress += mbi.RegionSize;                // 累加内存块的大小                dwSize += mbi.RegionSize;            }        }        statue.size = dwSize;        memoryStatue->push_back(statue);        // 遍历下一块虚拟内存.        dwAddress += dwSize;    }}int _tmain(int argc, _TCHAR* argv[]){    list<VMINFO> vmList;    queryVirtualMemoryStatue(GetCurrentProcess(), &vmList);    return 0;}
共享内存B
// 共享内存B.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <windows.h>int _tmain(int argc, _TCHAR* argv[]){    //打开文件映射对象    HANDLE hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, L"hello");    //关联虚拟内存    LPVOID lpBuf = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 16);    getchar();//暂停一下等待另一头把数据写入到共享内存中    printf("%s", lpBuf);//读取内存数据    //取消映射    UnmapViewOfFile(lpBuf);    //关闭句柄    CloseHandle(hMap);    system("pause");    return 0;}
堆
// 堆.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <windows.h>int _tmain(int argc, _TCHAR* argv[]){//     创建一个可增长的堆//         HANDLE  hHeap = HeapCreate(0, 0, 0);//         SYSTEM_INFO si;     //系统信息//         GetSystemInfo(&si); // 获取系统信息//         //在堆上分配3个页面大小的内存//         LPVOID lpMem = HeapAlloc(hHeap, //             HEAP_ZERO_MEMORY, //             3);//         HeapFree(hHeap, 0, lpMem);//         HeapDestroy(hHeap);    HANDLE      hHeap = GetProcessHeap(); // 获取默认堆    SYSTEM_INFO si;                       //系统信息    GetSystemInfo(&si);                   // 获取系统信息    //在堆上分配3个页面大小的内存    LPVOID lpMem = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, si.dwPageSize * 3);    HeapFree(hHeap, 0, lpMem);    HeapDestroy( hHeap );//默认堆是不能被销毁的    return 0;}
文件映射
// 文件映射.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <windows.h>//创建文件映射(关联文件)void FileMapToFile(char* pFilePath){    //获取文件句柄    HANDLE hFile = CreateFileA(pFilePath,        GENERIC_READ | GENERIC_WRITE, TRUE, NULL,        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);    if (hFile == INVALID_HANDLE_VALUE)    {        printf("文件打开失败\n");        return;    }    //创建文件映射对象    HANDLE hMap = CreateFileMapping(hFile, NULL,         PAGE_READWRITE, NULL,        NULL, NULL);    //关联虚拟内存    LPVOID lpBuf = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);    *(int*)lpBuf = 0x99999999;    //及时刷新到磁盘文件    FlushViewOfFile(lpBuf, 4);    //取消文件映射    UnmapViewOfFile(lpBuf);    //关闭文件映射对象句柄    CloseHandle(hMap);    CloseHandle(hFile);}//进程间通讯(共享内存)void ShareMemory(){    //创建文件映射对象    HANDLE hMap = CreateFileMapping(INVALID_HANDLE_VALUE,         NULL, PAGE_READWRITE,        0, 16, L"hello");    //与虚拟内存关联    LPVOID lpBuf = MapViewOfFile(hMap,         FILE_MAP_ALL_ACCESS,         0, 0,  //映射偏移量必须是系统内存分配粒度(64KB)的整数倍        16);    //写通讯数据    memcpy(lpBuf, "hello girl", sizeof("hello girl"));    //取消映射(如果不需要再通讯了,在执行)    //UnmapViewOfFile(lpBuf);    //CloseHandle(hMap);}int _tmain(int argc, _TCHAR* argv[]){    //FileMapToFile("123.exe");    ShareMemory();    system("pause");    return 0;}