首页 > 其他分享 >[远程Call]32位远程多参数带返回调用

[远程Call]32位远程多参数带返回调用

时间:2023-08-25 21:55:42浏览次数:36  
标签:hMem 32 Call size shellcode 远程 hProcess

[远程Call]32位远程多参数带返回调用

引子

在Windows上可以使用CreateRemoteThread实现远程Call,但是有不带返回值且只能传递一个参数的限制。

解决思路

将多个参数利用VirtualAllocEx和WriteProcessMemory写入目标程序,再通过此方法注入一段shellcode,通过shellcode完成多参数的调用。

核心shellcode
push var_1
...
push var_n
mov eax,function_addr
/*
如果为 cdcel则需要平栈
add esp,count_param
*/
call eax
实现c++代码
#include <iostream>
#include <Windows.h>
#include <vector>
#include <thread>

using namespace std;

LPVOID RemoteNew(HANDLE hProcess, PUCHAR data,size_t size)
{
    auto hMem=VirtualAllocEx(hProcess, NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if (hMem == NULL)
    {
        return FALSE;
    }
    if (WriteProcessMemory(hProcess, hMem, data, size,NULL) == FALSE)
    {
        VirtualFreeEx(hProcess, hMem, 0, MEM_RELEASE);
        return FALSE;
    }
    return hMem;
}


BOOL RemoteCall(
    HANDLE hProcess,
    LPVOID remoteFuncAddr,
    vector<LPVOID> param,
    bool cdcelCall,
    bool waitRemoteThread 
)
{
    if (remoteFuncAddr == NULL)
        return FALSE;

    vector<UCHAR> shellcode;
    //push 结构

    for (int i = param.size() - 1; i >= 0; i--)//调用栈是个栈
    {
        if (((UINT)param[i]) <= 255) //小参数可以只传低位
            shellcode.push_back(106), shellcode.push_back((UCHAR)param[i]); //push byte
        else
            shellcode.push_back(104), shellcode.insert(shellcode.end(), (PUCHAR)&param[i], (PUCHAR)(&param[i] + 1)); //push dword
    }
    //把addr塞入寄存器
    shellcode.push_back(184); //mov
    shellcode.insert(shellcode.end(), (PUCHAR)&remoteFuncAddr, (PUCHAR)(&remoteFuncAddr + 1)); //eax,addr
    shellcode.push_back(255),shellcode.push_back(208);//call eax

  
    if (cdcelCall)
    {
        size_t paramSize = param.size() * sizeof(LPVOID);
        //cdcel是函数调用后平栈,stdcall是函数自己平
        shellcode.push_back(129), shellcode.push_back(196);//add esp
        shellcode.insert(shellcode.end(), (PUCHAR)&paramSize, (PUCHAR)(&paramSize + 1));
    }
    shellcode.push_back(195);//ret
    auto shellcodeAddr=RemoteNew(hProcess, shellcode.data(), shellcode.size() * sizeof(UCHAR));
    if (shellcodeAddr == NULL)
        return FALSE;
   
    auto hThread=CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)shellcodeAddr, NULL, NULL, NULL);
    if (hThread == NULL)
    {
        VirtualFreeEx(hProcess, shellcodeAddr, 0, MEM_RELEASE);
        return FALSE;
    }

    thread waiter([hThread, hProcess, shellcodeAddr] {
        WaitForSingleObject(hThread, INFINITE);
        VirtualFreeEx(hProcess, shellcodeAddr, 0, MEM_RELEASE);
        DWORD retCode;
        GetExitCodeThread(hThread, &retCode);
        cout <<"Ret: " << retCode << endl;
    });
    if (waitRemoteThread)
        waiter.join();
    else
        waiter.detach();

    return TRUE;
}

int add(int a, int b)
{
    return a + b;
}

int main()
{
    char a[] = "hello world";
    char b[] = "C++ YES";

    //-1是自己
    RemoteCall((HANDLE)-1, add, { (LPVOID)1,(LPVOID)3 }, true, true);

    auto p1 = RemoteNew((HANDLE)-1, (PUCHAR)a, sizeof(a));
    auto p2 = RemoteNew((HANDLE)-1, (PUCHAR)b, sizeof(b));
    RemoteCall((HANDLE)-1, MessageBoxA, { 0, p1,p2,(LPVOID)64 }, true, true);


    std::cout << "Hello World!\n";
    Sleep(-1);
}
实现缺陷
  1. 目前只能实现32位的远程调用,64位新增了内存的可执行权限,这样注入的shellcode没法执行。

  2. 返回值只能接受32位整数,其实实现64位整数和浮点的方法也不复杂,都可以用汇编把对应寄存器的值写到内存里,但是情况比较多,懒得写了。

标签:hMem,32,Call,size,shellcode,远程,hProcess
From: https://www.cnblogs.com/Icys/p/RemoteCall.html

相关文章

  • STM32深入学习3:DMA,串口通信和看门狗
    DMADMA直接存储器存取,用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。DMA1有7个通道,DMA2有5个通道,还有一个仲裁器来协调各个DMA请求的优先权。DMA的作用是实现数据的直接传输,从地址到地址的数据传输。DMA传输的相关参数:源地址,目标地址,数据传输量,传输模式......
  • Feign的远程调用
                ......
  • 远程连接linux开发
    远程连接linux开发#一般情况下开发环境 -win开发,linux上线有问题:有些模块win和linux不兼容-linux开发,linux上线 -ubuntu系统->台式机->ubuntu->ubuntu开发-mac系统,linux上线 -mac环境和linux很像#只有win机器,没有linux系统,项目要在linux系统下开发--->远......
  • python实现RPC(远程过程调用)
    python实现RPC(远程过程调用)#远程过程调用-1借助于rabbitmq可以跨语言-2SimpleXMLRPCServer内置的-3zerorpc-4grpc可以跨语言1.1SimpleXMLRPCServer自带的###服务端fromxmlrpc.serverimportSimpleXMLRPCServer#通信使用xml格式classRPCServer(object):......
  • 【MySQL 8.0】通过mysqlbinlog实现binlog文件的远程同步
    mysqlbinlog会伪装成一个slave,连接master请求指定的binlogfile,master接收到这个请求之后创建一个binlogdump线程推送binlog给伪装的slave。[mysql@node01~]$mysql-uroot-pabcd.1234-hnode01(root@node01)>createuserrepl@'%'identifiedby'repl';QueryOK,0ro......
  • 钡铼技术BL102 PLC网关教程:如何使用4G网络连接西门子PLC进行远程编程?
    1、打开网关配置软件,点击“搜索”,搜索局内网网关BL1022、搜索到的网关设备,选择要配置的设备,双击登录3、输入登录密码登录,默认是1234564、配置网关网口采集PLC,远程下载暂时只支持LAN口下PLC设备。示例S7-200SMART的IP地址是192.168.5.16。故点击LAN修改IP地址为:192.168.5.1,点击OK。......
  • 基于STM32设计的智能空调
    一、项目背景随着人们生活水平的不断提高,对居住环境的舒适度要求也越来越高。空调作为一种重要的家电设备,已经成为了现代家庭中必不可少的一部分。本文介绍了一种基于STM32的智能空调设计方案,可以自动地根据环境温度进行温度调节。二、设计思路2.1整体构架智能空调系统由温度检测......
  • windows远程桌面到ubuntu16.04
    环境ubuntu:16.04windows:windows10目标让windows可以使用RemoteDesktop客记端远程到ubuntu16.04安装事宜windowns无需安装ubuntu16.04需要安装xrdp和xfce4安装sudoaptinstallxrdpxfce4查看安装版本,发现默认安装的是xrdp0.6.1修改配置sudoechoxfce4-sessi......
  • STM32 使用内部晶振导致 Can 通讯异常
    1、问题背景STM32板间通讯,运行一段时间后Can通讯异常,MCU的Can总线外设停止工作2、问题原因STM32使用了内部晶振,仪器运行一段时间后板卡温度上升(散热设计不足),导致芯片时钟异常3、解决方法使用外部晶振,相对内部晶振,外部晶振更可靠,精度也更高。......
  • 并发问题和实现Callable接口
    并发1.初识并发问题//多个线程同时操作一个对象//买火车票//发现问题:多个线程操作同一个资源的情况下,线程不安全publicclassTestThread4implementsRunnable{  //票数  privateintticketNums=10;​  publicvoidrun(){    while(true){  ......