【问题标题】:Calling a function remotely setting EAX and ECX调用函数远程设置 EAX 和 ECX
【发布时间】:2015-01-03 12:05:47
【问题描述】:

我试图在运行时和远程启动驻留在另一个程序中的函数。

使用 ollydbg 我得到了函数地址,我使用 CreateRemoteThread 来启动这个函数,它实际上运行了这个函数,但是它接收了两个参数,没有这些参数,程序就会崩溃。

问题是这个函数从 EAX 和 ECX 获取参数/参数,在它被调用之前被推送到这个函数(这两个值都是从 1 到 576 的矩阵坐标~~)

Createremotethread 不适用于插入参数,我尝试使用 struct 来使用多个 (2) 参数,但寄存器中的值不会改变。

如何通过从另一个不同的程序启动并设置这两个寄存器来使此功能在另一个程序上运行?

这是我在 0x01003084 中调用线程执行此函数的代码

    struct tagRemoteThreadParams //didnt worked
    {
        int Param1;
        int Param2;
    } RemoteThreadParams, *PRemoteThreadParams;


    RemoteThreadParams.Param1 = 0x00000001;//didnt worked
    RemoteThreadParams.Param2 = 0x00000001;//didnt worked


    int address=0x010038B1; // 0x01003084   --  0x01002FE0 -- 0x01003512  //Some addresses

    RedrawWindow(Find,NULL,NULL,RDW_ERASE|RDW_INVALIDATE|RDW_INTERNALPAINT|RDW_FRAME); //my program stuff

    DWORD rc;

    //this is where i call the function
    CreateRemoteThread(hProcess,NULL,NULL,(LPTHREAD_START_ROUTINE)address,&RemoteThreadParams,0,&rc);

    rc = WaitForSingleObject( hProcess, 30000 ); 
    CloseHandle(hProcess);
    VirtualFreeEx(hProcess, (LPVOID)address, 0, MEM_RELEASE | MEM_DECOMMIT);

请记住,我不想使用 DLL 注入(这不是我要搜索的内容),我实际上只想用一个代码来实现。 谢谢。

【问题讨论】:

  • 直接处理寄存器是操作系统/目标特定的??您是否错过了指定缩小范围的标签?
  • 这是在 Windows,IA32 中
  • 许多编译器允许在 C/C++ 代码中嵌入汇编指令,但不同编译器之间的语法差异很大。你用的是什么编译器?您是否已经阅读过文档?
  • CreateRemoteThread 仅允许您调用接受单个 LPVOID 参数的函数(如 ThreadProc)。考虑到您正在释放包含该函数的页面这一事实:您是自己注入该函数吗?如果是这样:更改签名以使其符合 ThreadProc。如果不是:也许您可以先注入一个辅助函数(使用 ThreadProc 的签名),在调用实际目标之前将结构的成员(作为 LPVOID 传递)推送到堆栈上。
  • @Paulo1205 我正在使用 g++,是的,我要更改的寄存器是另一个程序,而不是我正在编写的程序,因此只有在我将代码注入到其他程序

标签: c++ windows multithreading memory reverse-engineering


【解决方案1】:

您唯一的解决方案实际上是将代码注入到正确设置寄存器的另一个进程中,然后调用您要调用的函数。 CreateRemoteThread 具有严格的调用约定,因此您不能强制它在输入时具有特定的寄存器值。

另一种选择是在 Windows 中使用debug functionality 来更改寄存器内容,但这需要您在正确的位置[在正确的线程中]停止代码并在继续之前设置寄存器。这很棘手,大多数应用程序(假设我们正在计算游戏等)都有保护措施,以防止调试功能“弄乱”它们的状态。

【讨论】:

    【解决方案2】:

    好吧,您不能将该函数作为CreateRemoteThread 的线程过程传递,因为该函数没有正确的签名。因此,您需要传递一个具有正确签名的函数。

    一种非常常见的方法是传递LoadLibrary 的地址。您需要提供自己的 DLL。然后,该 DLL 的 DllMain 可以创建一个调用您的函数的新线程。

    但是您说您不想涉及另一个 DLL。所以在我看来,这留下了一种选择。在目标进程的虚拟地址空间中分配一些内存。使该内存具有可执行保护。将带有CreateRemoteThread 正确签名的线程过程写入该内存。最后,在这个线程过程中,调用所需的函数。

    【讨论】:

      猜你喜欢
      • 2023-03-29
      • 2018-08-25
      • 1970-01-01
      • 2017-04-05
      • 1970-01-01
      • 1970-01-01
      • 2021-07-25
      • 2015-01-21
      • 2011-08-31
      相关资源
      最近更新 更多