我們要修改一個進程的訪問令牌,首先要獲得進程訪問令牌的句柄,這可以通過OpenProcessToken得到,函數(shù)的原型如下:
OpenProcessToken 得到進程的令牌句柄
BOOL OpenProcessToken(
HANDLE ProcessHandle, //要修改訪問權(quán)限的進程句柄
DWORD DesiredAccess, //指定你要進行的操作類型,TOKEN_ADJUST_PRIVILEGES表示你下面將要進行“修改令牌的訪問權(quán)限”的操作。
PHANDLE TokenHandle //返回的訪問令牌指針
);
AdjustTokenPrivileges的原型如下:
BOOL AdjustTokenPrivileges(
HANDLE TokenHandle, // 訪問令牌的句柄
BOOL DisableAllPrivileges, // 是進行權(quán)限修改還是除能(Disable)所有權(quán)限
PTOKEN_PRIVILEGES NewState, // 指明要修改的權(quán)限,是一個指向TOKEN_PRIVILEGES結(jié)構(gòu)的指針,該結(jié)構(gòu)包含一個數(shù)組,數(shù)據(jù)組的每個項指明了權(quán)限的類型和要進行的操作
DWORD BufferLength, // 結(jié)構(gòu)PreviousState的長度,如果PreviousState為空,該參數(shù)應(yīng)為NULL
PTOKEN_PRIVILEGES PreviousState, // 也是一個指向TOKEN_PRIVILEGES結(jié)構(gòu)的指針,存放修改前的訪問權(quán)限的信息,可空
PDWORD ReturnLength // 實際PreviousState結(jié)構(gòu)返回的大小
);
TOKEN_PRIVILEGES 這個結(jié)構(gòu),其聲明如下:
typedef struct _TOKEN_PRIVILEGES {
DWORD PrivilegeCount; //數(shù)組原素的個數(shù)
LUID_AND_ATTRIBUTES Privileges[]; //一個LUID_AND_ATTRIBUTES類型的數(shù)組
} TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;
再來看一下LUID_AND_ATTRIBUTES這個結(jié)構(gòu)的內(nèi)容,聲明如下:
typedef struct _LUID_AND_ATTRIBUTES {
LUID Luid; //指權(quán)限的類型
DWORD Attributes; //指明了我們要進行的操作類型
} LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <Tlhelp32.h>
// 提升權(quán)限
BOOL EnableDebugPrivilege() {
HANDLE hToken;
BOOL fOK = FALSE;
//1. 獲取進程訪問令牌的句柄
if (OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)){
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
//2. 查詢進程的權(quán)限 LookupPrivilegeValue
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
//3. 對這個訪問令牌進行修改 AdjustTokenPrivileges
AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
fOK = (GetLastError() == ERROR_SUCCESS);
CloseHandle(hToken);
}
return fOK;
}
//獲取進程ID
int GetProcessID(WCHAR * szProcessName){
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (INVALID_HANDLE_VALUE == hSnapshot){
return 0;
}
PROCESSENTRY32 pi;
pi.dwSize = sizeof(PROCESSENTRY32); //第一次使用必須初始化成員
BOOL bRet = Process32First(hSnapshot, &pi);
while (bRet){
/*
循環(huán)遍歷添加自己的額外代碼
*/
//判斷進程名是否一致,返回0代表一致
int flag = wcscmp(pi.szExeFile, szProcessName);
if (flag==0)
{
printf("EQUAL");
return pi.th32ProcessID;//進程一致,返回進程ID
}
bRet = Process32Next(hSnapshot, &pi);
}
return 0;
}
//修改內(nèi)存中的靜態(tài)地址
int main() {
//目標是鎖定陽光的數(shù)量
//WriteProcessMemory Windows系統(tǒng)API 1.進程句柄 2.地址(基址,靜態(tài)地址) 3.值(值得地址) 4.寫入的數(shù)據(jù)寬度 5.寫入的寬度(傳出的,SIZE_T地址)
//OpenProcess 權(quán)限,是否繼承句柄,進程ID(PID),
//手動輸入進程ID,下一節(jié)我們自動獲取ID了 26452
//判斷ID是否合法
//循環(huán)修改目標值
int procId = GetProcessID(L"PlantsVsZombies.exe");
if (procId){
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procId);
if (hProcess == NULL){
printf("open process fail;\n");
system("pause");
}else{
int nValue = 5000;
SIZE_T dwByte = 0;
LPVOID lpAddr = (LPVOID)0x0FE56CD0;
while (true){
bool flag = WriteProcessMemory(hProcess, lpAddr, &nValue, 4, &dwByte);
if (flag != true){
printf("write process memory fail;\n");
system("pause");
}
}
}
}
return 0;
}
提升權(quán)限
如果上述代碼提升權(quán)限還不夠用,進行如下設(shè)置
