如何在C++中的另一个地址空间中调用函数

Jer*_*emy 5 c++ security

我知道这可能导致的线程问题及其危险,但我需要知道如何为我在学校做的安全项目这样做.我需要知道如何使用参数调用给定调用约定的远程地址空间中的函数 - 最好是恢复远程函数返回的数据,尽管我确实不需要它.

如果我可以在编译时从远程函数的函数原型获取细节,我将能够使这个方法工作.我需要知道参数有多大以及参数是否显式声明为指针(void*, char*, int*, etc...)

即如果我定义一个函数原型,如:

typedef void (__cdecl *testFunc_t)(int* pData);
Run Code Online (Sandbox Code Playgroud)

我需要在编译时至少获得参数的大小,如果可以的话,哪些是指针或不是.这里我们假设远程功能是一个stdcall_cdecl呼叫.

我使用的IDE是Microsoft Visual Studio 2007,以防该解决方案特定于特定产品.

这是我的计划:

  1. 使用CreateRemoteThread要调用的函数的原点在远程进程中创建一个线程,尽管我会在挂起状态下执行此操作.

  2. 我会设置堆栈,使得返回地址是在进程内部分配的代码存根的调用ExitThread(eax)- 因为这将使用函数的返回值退出线程 - 然后我将通过使用来恢复它GetExitCodeThread

  3. 我还会将函数调用的参数从我的本地堆栈复制到新创建的线程的参数 - 这是我需要知道函数参数是指针还是参数大小的地方.

  4. 恢复线程并等待它退出,此时我将返回调用者,线程退出代码.

我知道这应该在编译时可行但是编译器是否有一些方法可以用来做它,我不确定.我也知道所有这些数据都可以从编译代码后创建的PDB文件中轻松恢复,并且如果编译器执行优化,参数的大小可能会改变.我不需要被告知这是多么危险,因为我完全了解它,但这不是商业产品,而是我必须为学校做的一个小项目.

问题:如果我有一个函数原型,如typedef void(__ cdecl testFunc_t)(int pData);

无论如何我可以在编译时获得这个原型的参数的大小(即在上面的例子中,参数将总和为sizeof(int*)的总大小.例如,我有一个类似的函数:

template<typename T> unsigned long getPrototypeArgLength<T>()
{ 
   //would return size of arguments described in the prototype T 
} 

//when called as

getPrototypeArgLength<testFunc>()
Run Code Online (Sandbox Code Playgroud)

Jer*_*emy 1

好吧,我发现我可以使用 BOOST 库在编译时获取大量类型信息。具体来说,我正在使用 boost::function_traits 但是,如果您查看 boost 库,您会发现可以恢复相当多的信息。这是我编写的一些代码,用于演示如何获取函数原型的参数数量。

(实际上,我还没有测试下面的代码,它只是我从我制作和测试的另一个函数中拼凑而成的代码。)

template<typename T>
unsigned long getArgCount()
{
    return boost::function_traits<boost::remove_pointer<T>::type>::arity;
}

void (*pFunc)(int, int);

2 = getArgCount<BOOST_TYPEOF(pFunc)>();
Run Code Online (Sandbox Code Playgroud)