写入/读取受内存保护的进程的内存

时间:2014-09-29 21:06:28

标签: c++ windows memory token

我会尽力解释我的问题 我试图访问受内存保护的进程内存(Minesweeper) 我先把我的代码放在首位,然后我会解释我想要实现的目标。 (如果您阅读了所有内容并知道另一种方法,请发布)。

首先,getProcessHandle,一个返回名为procName的进程的打开句柄的函数 它完美无缺,我可以列出所有流程。

HANDLE getProcessHandle(const wchar_t *procName){
HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 procEnt;
procEnt.dwSize = sizeof(PROCESSENTRY32);
Process32First(snap, &procEnt);
printf("--Listando procesos...\n");
do{
    printf("Process name: %S \n", procEnt.szExeFile);
    if (!wcscmp(procName, procEnt.szExeFile)){
        printf("Encontrado %S.\n\n", procName);
        return OpenProcess(PROCESS_ALL_ACCESS, FALSE, procEnt.th32ProcessID);
    }
} while (Process32Next(snap, &procEnt));
printf("No se ha encontrado el proceso.");
CloseHandle(snap);
return NULL;

第二,getModule函数。它的工作应该是查找和枚举作为HANDLE传递的过程中的所有模块。

HMODULE getHModule(HANDLE procHandle, const wchar_t *procName){
HMODULE moduleHandle[1024];
DWORD bytesNeeded;
unsigned int i = 0;
if (EnumProcessModulesEx(procHandle, moduleHandle, sizeof(moduleHandle), &bytesNeeded, LIST_MODULES_ALL)){
    printf("--Modulos del proceso:\n");
    for (i = 0; i < (bytesNeeded / sizeof(HMODULE)); i++){
        TCHAR pathModule[1024];
        GetModuleBaseName(procHandle, moduleHandle[i], pathModule, sizeof(pathModule) / sizeof(TCHAR));
        if (!wcscmp(procName, pathModule)){
            printf("Encontrado modulo %S.", procName);
            return moduleHandle[i];
        }
        printf("Module %d: %S \n", i + 1, pathModule);
    }
    printf("No se ha encontrado el modulo.");
    return NULL;
}
else {
    printf("Error en EnumProcessModulesEx n: %ls", GetLastError());
}
return NULL;

问题来了。当我尝试枚举流程中的所有模块时,如果流程是一个正常的流程,我的意思是,一个不受内存保护的流程,它可以很好地工作。
问题是当进程受内存保护时 此时,我决定搜索,然后我发现了Privilege Tokens。它说如果我启动了SE_DEBUG_NAME令牌,我的过程可能会超过保护,所以,我已经完成了这个功能:

int privileges(){
HANDLE token;
TOKEN_PRIVILEGES tp;
DWORD siz = sizeof(TOKEN_PRIVILEGES);

if (OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &token) != 0){
    LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    if (AdjustTokenPrivileges(token, 0, &tp, siz, NULL ,NULL) != 0){
        cout << "--Conseguido acceso debug.\n";
        return TRUE;
    }
    else {
        cout << "fail adjust\n";
        return FALSE;
    }
}
else {
    cout << "fail if: " << GetLastError() << endl;
    cin.get();
    return FALSE;
}

&#34; main&#34;功能:

int _tmain(int argc, _TCHAR* argv[])
{
privileges();
wchar_t *processName = _T("calc.exe");
HANDLE hProc = getProcessHandle(processName);
  if (hProc){
      HMODULE hMod = getHModule(hProc, processName);
      cout << hMod;
  }
cin.get();
return 0;
}

我现在遇到的问题是,当我执行此函数privileges()时,它会返回ERROR_NO_TOKEN代码编号。
这里有人说我要更改OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &token)的{​​{1}},这不会导致任何问题,也不会导致该修复,我遇到的问题与OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)未执行相同。<登记/> 感谢您阅读所有文字,如果还有其他方法,请告诉我,我正在努力学习。

1 个答案:

答案 0 :(得分:0)

documentation for EnumProcessModulesEx说:

  

此功能主要用于64位应用程序。如果在WOW64下运行的32位应用程序调用该函数,则忽略dwFilterFlag选项,该函数提供与EnumProcessModules函数相同的结果。

转到documentation for EnumProcessModules,我们发现:

  

如果从WOW64上运行的32位应用程序调用此函数,则它只能枚举32位进程的模块。

因此,要处理64位进程,您的代码本身必须是64位。

文档仍在继续:

  

如果进程是64位进程,则此函数失败,最后一个错误代码为ERROR_PARTIAL_COPY(299)。

似乎这可能不正确,因为您收到了访问冲突异常。