1

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

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

  1. 我的字符串(dll 名称和函数名称)正确传递给远程线程
  2. 线程在 LoadLibrary 上失败,最后一个错误代码为 87“ERROR_INVALID_PARAMETER”

我最好的猜测是,远程线程找不到 LoadLibrary (这是因为链接器完成了对我的进程的repspect???,只是猜测......)

我究竟做错了什么?

这是远程功能的代码:

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下编译。

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

我究竟做错了什么?

4

2 回答 2

1

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

所以应该看看data->dll哪个代表唯一的参数。

它在这里初始化:

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

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

if (!lData.dll) {
  // do some error logging/handling/whatsoever
}

这样做后,您可能已经检测到调用已实现失败,因为(来自 MSDN 的逐字记录VirtualAllocEx()):

如果您尝试提交尚未保留的页面,则该功能将失败。生成的错误代码为 ERROR_INVALID_ADDRESS。

因此,您可能希望按照建议修改相关调用的第四个参数(再次从 MSDN 逐字记录):

要在一个步骤中保留和提交页面,请使用 MEM_COMMIT | 调用 VirtualAllocEx。MEM_RESERVE。

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

于 2012-01-02T08:40:45.477 回答
0

LoadLibrary 实际上可能是对 LoadLibraryW 的别名(取决于项目设置),它是 Unicode 版本。每当您使用带有“char”字符串而不是“TCHAR”的 Windows API 时,都应该明确地使用 ANSI 版本名称。这将避免在编写代码时出现调试麻烦,也可以在将来为您或其他人避免项目切换到 Unicode 的情况。

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

LoadLibraryA(data->dll);
于 2012-01-06T03:17:24.113 回答