首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >远程线程在调用LoadLibrary时失败,错误为87

远程线程在调用LoadLibrary时失败,错误为87
EN

Stack Overflow用户
提问于 2011-12-31 12:42:04
回答 2查看 4.4K关注 0票数 1

我正在尝试创建一个远程线程,它将加载我编写的DLL,并从它运行一个函数。DLL运行良好(选中),但由于某种原因,远程线程失败,创建它的进程停止响应。

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

"ERROR_INVALID_PARAMETER"将

  1. My字符串(dll名称和函数名)正确传递给远程线程
  2. 线程在LoadLibrary上失败,最后错误代码87

我最好的猜测是,远程线程不知怎么找不到LoadLibrary (这是因为链接器是在对我的进程进行回顾之后完成的吗??,只是猜测.)

我做错了什么?

这是远程函数的代码:

代码语言:javascript
运行
复制
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;
}

编辑:

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

代码语言:javascript
运行
复制
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链接远程进程LoadLibrary地址出错的可能性?

编辑:当我试图运行与本地线程相同的代码时(我在CreateRemoteThread中使用了当前进程的句柄),整个程序工作得很好。是什么导致了这一切?

我应该添加调用函数代码吗?当代码使用正确的参数在远程线程中执行时,它似乎在执行它的工作。

代码是在VS2010下编译的。

数据是一个简单的结构,带有char* 's到名称。(因为用代码明确地编写字符串会导致指向我的原始进程的指针)。

我做错了什么?

EN

回答 2

Stack Overflow用户

发布于 2012-01-02 08:40:45

ERROR_INVALID_PARAMETER失败表示传递的参数有问题。

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

它在这里初始化:

lData.dll = VirtualAllocEx(explorer, 0, sizeof(char) * (strlen(dllName) + 1), MEM_COMMIT, PAGE_READWRITE);

因此,让我们添加一个检查,作为引用的内存的分配是否真的成功地存储到lData.dll中。

代码语言:javascript
运行
复制
if (!lData.dll) {
  // do some error logging/handling/whatsoever
}

这样做后,您可能已经检测到已实现的调用失败是因为(从MSDN到VirtualAllocEx()):

如果尝试提交未保留的页,则

函数将失败。产生的错误代码是ERROR_INVALID_ADDRESS。

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

要在一步内预订和提交页面,使用MEM_COMMIT \ MEM_RESERVE调用VirtualAllocEx。

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

票数 1
EN

Stack Overflow用户

发布于 2012-01-06 03:17:24

LoadLibrary可能实际上正在别名LoadLibraryW (取决于项目设置),这是Unicode版本。当您使用带有"char“字符串而不是"TCHAR”的Windows时,应该显式地使用ANSI版本号。这将防止在编写代码时出现调试麻烦,并防止将来发生项目切换到Unicode时为您或其他人带来的麻烦。

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

代码语言:javascript
运行
复制
LoadLibraryA(data->dll);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8688137

复制
相关文章

相似问题

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