C++ 远程线程在调用LoadLibrary时失败,出现错误87

C++ 远程线程在调用LoadLibrary时失败,出现错误87,c++,c,winapi,dll-injection,createremotethread,C++,C,Winapi,Dll Injection,Createremotethread,我试图创建一个远程线程,该线程将加载我编写的DLL,并从中运行函数。 DLL工作正常(已检查),但由于某种原因,远程线程失败,创建它的进程停止响应 我用ollyDebug试着看看出了什么问题,我注意到了两件事 我的字符串(dll名称和函数名称)被正确地传递到远程线程 LoadLibrary上的线程失败,lasterror代码为87“ERROR\u INVALID\u PARAMETER” 我最好的猜测是,不知何故,远程线程找不到LoadLibrary(这是因为链接器使用repspect to M

我试图创建一个远程线程,该线程将加载我编写的DLL,并从中运行函数。 DLL工作正常(已检查),但由于某种原因,远程线程失败,创建它的进程停止响应

我用ollyDebug试着看看出了什么问题,我注意到了两件事

  • 我的字符串(dll名称和函数名称)被正确地传递到远程线程
  • LoadLibrary上的线程失败,lasterror代码为87“ERROR\u INVALID\u PARAMETER”
  • 我最好的猜测是,不知何故,远程线程找不到LoadLibrary(这是因为链接器使用repspect to My Process完成的吗???,只是猜测而已…)

    我做错了什么

    这是远程功能的代码:

    static DWORD WINAPI SetRemoteHook (DATA *data)
    {
      HINSTANCE dll;
      HHOOK WINAPI hook;
      HOOK_PROC hookAdress;
    
      dll = LoadLibrary(data->dll);
    
      hookAdress = (HOOK_PROC) GetProcAddress(dll,data->func);
      if (hookAdress != NULL)
      {
        (hookAdress)(); 
      }
      return 1;
    }
    
    编辑:

    这是我将内存分配给远程进程的部分:

    typedef struct
    {
        char* dll;
        char* func;
    } DATA;
    
    char* dllName = "C:\\Windows\\System32\\cptnhook.dll";  
    char* funcName = "SetHook";
    char* targetPrgm = "mspaint.exe";
    Data lData;
    lData.dll = (char*) VirtualAllocEx( explorer, 0, sizeof(char)*strlen(dllName), MEM_COMMIT, PAGE_READWRITE );
    lData.func = (char*) VirtualAllocEx( explorer, 0, sizeof(char)*strlen(funcName), MEM_COMMIT, PAGE_READWRITE );
    WriteProcessMemory( explorer, lData.func, funcName, sizeof(char)*strlen(funcName), &v );
    WriteProcessMemory( explorer, lData.dll, dllName, sizeof(char)*strlen(dllName), &v );
    rDataP = (DATA*) VirtualAllocEx( explorer, 0, sizeof(DATA), MEM_COMMIT, PAGE_READWRITE );
    WriteProcessMemory( explorer, rDataP, &lData, sizeof(DATA), NULL );
    
    编辑: 看起来问题在于远程线程正在调用一个“垃圾”地址 而不是LoadLibrary基址。是否有可能与Visual studio链接 远程进程LoadLibrary地址错误

    编辑: 当我尝试运行与本地线程完全相同的代码(我在CreateRemoteThread中使用当前进程的句柄)时,整个过程运行得很好。这是什么原因造成的

    我应该添加调用函数代码吗?它似乎在尽自己的职责 代码正在远程线程中使用正确的参数执行

    代码是在VS2010下编译的

    数据是一个简单的结构,其名称为char*。(明确地在代码中编写字符串将导致指向我的原始进程的指针)


    我做错了什么?

    使用
    ERROR\u INVALID\u参数失败
    表示传递的参数有问题

    因此,我们应该看看
    data->dll
    ,它代表了唯一的参数

    在此处草签:

    lData.dll=VirtualAllocEx(浏览器,0,大小(字符)*(strlen(dllName)+1),MEM\u COMMIT,PAGE\u READWRITE)

    因此,让我们添加一个检查,检查引用的内存分配是否应该存储到
    lData.dll

    if (!lData.dll) {
      // do some error logging/handling/whatsoever
    }
    
    这样做之后,您可能检测到实现的调用失败,因为(MSDN for
    VirtualAllocEx()
    )的逐字记录:

    如果您试图提交尚未提交的页面,该函数将失败 保留的。产生的错误代码是错误\无效\地址

    因此,您可能希望按照建议修改相关调用的第四个参数(同样是MSDN中的逐字):

    要在一个步骤中保留和提交页面,请使用调用VirtualAllocEx 记住承诺,记住保留


    PS:对allocate
    lData.func
    ;-)的调用重复此练习

    使用
    错误\u无效\u参数失败
    表示传递的参数有问题

    因此,我们应该看看
    data->dll
    ,它代表了唯一的参数

    在此处草签:

    lData.dll=VirtualAllocEx(浏览器,0,大小(字符)*(strlen(dllName)+1),MEM\u COMMIT,PAGE\u READWRITE)

    因此,让我们添加一个检查,检查引用的内存分配是否应该存储到
    lData.dll

    if (!lData.dll) {
      // do some error logging/handling/whatsoever
    }
    
    这样做之后,您可能检测到实现的调用失败,因为(MSDN for
    VirtualAllocEx()
    )的逐字记录:

    如果您试图提交尚未提交的页面,该函数将失败 保留的。产生的错误代码是错误\无效\地址

    因此,您可能希望按照建议修改相关调用的第四个参数(同样是MSDN中的逐字):

    要在一个步骤中保留和提交页面,请使用调用VirtualAllocEx 记住承诺,记住保留


    PS:对allocate
    lData.func
    ;-)的调用重复此练习

    有可能LoadLibrary实际上是别名LoadLibraryW(取决于项目设置),后者是Unicode版本。无论何时使用带有“char”字符串而不是“TCHAR”字符串的Windows API,都应该显式使用ANSI版本名。这将防止在编写代码时出现调试麻烦,并且在将来您或其他人遇到项目转换为Unicode的情况时也会遇到调试麻烦

    因此,除了修复可怕的未终止字符串问题外,请确保使用:

    LoadLibraryA(data->dll);
    

    有可能LoadLibrary实际上是别名LoadLibraryW(取决于项目设置),这是Unicode版本。无论何时使用带有“char”字符串而不是“TCHAR”字符串的Windows API,都应该显式使用ANSI版本名。这将防止在编写代码时出现调试麻烦,并且在将来您或其他人遇到项目转换为Unicode的情况时也会遇到调试麻烦

    因此,除了修复可怕的未终止字符串问题外,请确保使用:

    LoadLibraryA(data->dll);
    

    您是否尝试使用具有显式dll路径的LoadLibrary?示例:LoadLibrary(“C:\\project\\my_app.dll”);只是为了确保参数被传递好的。我正在使用完整路径。(尽管它应该单独使用dll名称,因为exe和dll位于同一目录中)。我还应该提到LoadLibrary函数失败的事实也是一个猜测。(我可以看出,这是一个只有一个参数的函数,并且它是正确的路径,看起来像LoadLibrary…)如何将“数据”传递给远程线程?如何分配和填充“数据”所指的内存?使用VirtualAllocEx和WriteProcessMemory进行“数据”通信。它是一个指向结构的指针,该结构包含指向字符串的指针,该字符串具有我的dll名称和dll中的函数名称,这两个名称都是在远程线程进程内存中分配的。我编辑了这篇文章,其中包含了allocationClassic,但是由于一个bug,您忘记了同时复制字符串终止符。您是否尝试使用带有显式dll路径的LoadLibrary?示例:LoadLi