首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >CreateRemoteThread - ERROR_ACCES_DENIED

CreateRemoteThread - ERROR_ACCES_DENIED
EN

Stack Overflow用户
提问于 2015-07-01 23:23:12
回答 2查看 934关注 0票数 2

我想我的代码现在终于可以工作了。唯一的问题是,由于某些原因,即使我用PROCESS_ALL_ACCESS打开了进程,CreateRemoteThread还是抛出了一个错误: ERROR_ACCESS_DENIED。

错误是用GetLastError检索到的,它会输出'5',翻译过来就是ERROR_ACCESS_DENIED。

代码语言:javascript
运行
复制
#include <iostream>
#include <windows.h>
#include <TlHelp32.h>

char* dllPath = "C:\\Users\\Kalist\\Desktop\\Projects\\DLL\\bin\\Debug\\DLL.dll";
char* ProcToInject = "calc.exe";

int main(){
    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof(PROCESSENTRY32);
    HANDLE procSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if(procSnap == INVALID_HANDLE_VALUE){
        std::cout << "Snapshot function failed" << std::endl;
    }

    DWORD procID = 0;
        if(Process32First(procSnap, &pe32)){
            do{
               if(!strcmp(pe32.szExeFile, ProcToInject)){
                    procID = pe32.th32ProcessID;
                    break;
               }
            }while(Process32Next(procSnap, &pe32));
        }
    CloseHandle(procSnap);

    if(procID != 0){

        HANDLE procAccess = OpenProcess(PROCESS_ALL_ACCESS, false, procID);
        if(procAccess == NULL){
            std::cout << "OpenProcess error: " << GetLastError() << std::endl;
        }

        LPVOID remoteString = (LPVOID)VirtualAllocEx(procAccess, NULL, strlen(dllPath)+1, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
        if(remoteString == NULL){
            std::cout << "VirtualAllocEx error: " << GetLastError() << std::endl;
        }

        bool memoryWritten = WriteProcessMemory(procAccess, (LPVOID)remoteString, dllPath, strlen(dllPath)+1, NULL);
        if(memoryWritten == 0){
            std::cout << "WriteProcessMemory error: " << GetLastError() << std::endl;
        }

        LPVOID getLibAdd = (LPVOID)GetProcAddress(GetModuleHandle("Kernel32.dll"), "LoadLibraryA");
        if(getLibAdd == NULL){
            std::cout << "GetProcAddress error: " << GetLastError() << std::endl;
        }

        HANDLE remoteThread = CreateRemoteThread(procAccess, NULL, 0, (LPTHREAD_START_ROUTINE)getLibAdd, (LPVOID)remoteString, 0, NULL);
        if(remoteThread == NULL){
            std::cout << "CreateRemoteThread error: " << GetLastError() << std::endl;
        }
        CloseHandle(procAccess);
    }else{
        std::cout << "Failed to retrieve procID" << std::endl;
    }
}
EN

回答 2

Stack Overflow用户

发布于 2015-07-01 23:27:00

当您尝试从32位进程调用CreateRemoteThread,但目标进程是64位进程时,您将收到此错误。我打赌这就是你要做的。

为了注入到一个64位的进程中,你需要你的注入进程也是64位的。显然,我相信你已经知道,你注入的DLL也必须是64位的。

无论如何,当您调用OpenProcess时,您不需要要求太多。我相信你所需要的就是:

代码语言:javascript
运行
复制
PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION 
  | PROCESS_VM_WRITE | PROCESS_VM_READ
票数 3
EN

Stack Overflow用户

发布于 2021-08-29 12:56:24

您编写的代码假设进程、运行代码、注入的动态链接库和calc.exe都是相同的位。

如果不满足这一点,则对CreateRemoteThread的调用将失败。这是由于lpStartAddress参数的限制。

以下报价来自CreateRemoteThread documentation

指向要由线程执行的LPTHREAD_START_ROUTINE类型的应用程序定义函数的指针,表示远程进程中线程的起始地址。该函数必须存在于远程进程中。有关详细信息,请参阅ThreadProc。

代码的假设是由于以下原因:

在比较x86和x64时,LoadLibraryA函数位于不同的rva,因为当您使用x86进程与x64进程时,加载的是不同的rva文件。将Kernel32.dll进程与x86进程进行比较时,也会在不同的基址加载不同的x64文件。你从GetProcAddr得到的地址是rva + dll base address

目前我正在编写一个注入器,它也将能够x86到x64,并且已经验证了,所有传递到CreateRemoteThread的地址都在目标进程的作用域中。此外,我还使用PROCESS_CREATE_THREAD | PROCESS_VM_WRITE | PROCESS_VM_READ| PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION打开了该进程。但是我仍然有这个问题。

这是因为,x86的指针长度是32位。不过,CreateRemoteThread的参数lpStartAddress是一个指针。这意味着,您永远无法调用x64目标的所有函数,因为函数指针将被封顶为32位。这反过来意味着,在x86目标进程中,您最多可以从x86进程调用x64可寻址区域内的所有函数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31165487

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档