[远程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位整数和浮点的方法也不复杂,都可以用汇编把对应寄存器的值写到内存里,但是情况比较多,懒得写了。

[远程Call]32位远程多参数带返回调用的更多相关文章

  1. VBA: 带参数带返回值的函数

    Function pda(x) a = x If Len(a) = 1 Then ab = "00" & a ElseIf Len(a) = 2 Then ab = &qu ...

  2. 32位的Win7系统下安装64位的Sql Sever?

    来自:http://zhidao.baidu.com/link?url=nQBoaLgoOyYCUdI7V4WZCMlTW3tKscdkOnLTIvlYtPpwoVhQkSahq44HeofBfzFT ...

  3. Linux:使用rpcgen实现64位程序调用32位库函数

    摘要:本文介绍使用rpcgent实现64位程序调用32位库函数的方法,并给出样例代码. 我的问题 我的程序运行在64位Linux系统上,需要使用一个从外部获得的共享库中的函数,这个共享库是32位的,无 ...

  4. IOS是否存在32位和64位版本的区分

    苹果于2013年9月推出了iPhone 5S新手机,采用的全新A7处理器其最大特色就是支持64位运算.其64位A7处理器的使用意味着iPhone性能会大有提高,性能和速度更加出色:而要到达到这样的性能 ...

  5. CLR调试报错“Visual Studio远程调试监视器 (MSVSMON.EXE) 的 64 位版本无法调试 32 位进程或 32 位转储。请改用 32 位版本”的解决

    Win7 64位电脑上进行visual studio的数据库项目的CLR存储过程进行调试时,报错: ---------------------------Microsoft Visual Studio ...

  6. Visual Studio远程调试监视器(MSVSMON.EXE)的32位版本不能用于调试64位进程或64位转储

    在VS2013中调试Silverlight项目时,提示:无法附加.Visual Studio远程调试监视器(MSVSMON.EXE)的32位版本不能用于调试64位进程或64位转储.请改用64位版本. ...

  7. 使用visual c++ 2005远程调试64位系统上32位与64位程序

    一直都挺喜欢使用visual c++远程调试代码,它能展现给我们当时代码执行最真实的情景,今天有时间记录一下,以免以后忘了. 远程调试需要在被调试端安装服务器,对于visual c++ 2005来说调 ...

  8. mysql 远程连接不上,bind-address参数配置要求,以及怎么去使得mysql能够允许远程的客户端访问

    刚安装了MySQL服务器,使用远程管理工具总是连接不上,因为知道mysql的默认端口是3306,于是使用telnet连接这个端口,(从这里可以学到telnet是可以这样用的) telnet 192.1 ...

  9. Photoshop做32位带Alpha通道的bmp图片

    原文链接: http://blog.sina.com.cn/s/blog_65c0cae801016e5u.html   批量制作32位带Alpha通道的bmp图片,可以制作一个动作,内容可以如下: ...

  10. 论DATASNAP远程方法支持自定义对象作参数

    论DATASNAP远程方法支持自定义对象作参数 DATASNAP远程方法已经可以支持自定义对象作参数,这是非常方便的功能. 1)自定义对象 type TMyInfo = class(TObject) ...

随机推荐

  1. 2021-08-24:合并石头的最低成本。有 N 堆石头排成一排,第 i 堆中有 stones[i] 块石头。每次移动(move)需要将连续的 K 堆石头合并为一堆,而这个移动的成本为这 K 堆石头的

    2021-08-24:合并石头的最低成本.有 N 堆石头排成一排,第 i 堆中有 stones[i] 块石头.每次移动(move)需要将连续的 K 堆石头合并为一堆,而这个移动的成本为这 K 堆石头的 ...

  2. From Java To Kotlin:空安全、扩展、函数、Lambda很详细,这次终于懂了

    From Java To Kotlin, 空安全.扩展.函数.Lambda 概述(Summarize) • Kotlin 是什么? • 可以做什么? • Android 官方开发语言从Java变为Ko ...

  3. Serverless冷扩机器在压测中被击穿问题

    一.现象回顾 在今天ForceBot全链路压测中,有位同事负责的服务做Serverless扩容(负载达到50%之后自动扩容并上线接入流量)中,发现新扩容的机器被击穿,监控如下(关注2:40-3:15时 ...

  4. adb查看端口号,杀进程

    1.先查看端口号占用的进程 netstat -ano | findstr 8000 2.在杀掉我们查出的进程15812 3.再次查看8000端口号的进程

  5. 百度飞桨(PaddlePaddle) - PP-OCRv3 文字检测识别系统 基于 Paddle Serving快速使用(服务化部署 - CentOS 7)

    目录 Paddle Serving服务化部署实战 准备预测数据和部署环境 环境准备 安装 PaddlePaddle 2.0 安装 PaddleOCR 准备PaddleServing的运行环境, 模型转 ...

  6. 看懂java序列化,这篇就够了

    前言 相信大家日常开发中,经常看到 Java 对象 "implements Serializable".那么,它到底有什么用呢?本文带你全方位的解读序列化与反序列化这一块知识点. ...

  7. C# - DTO 的字符串表达

    第一阶段 重写 DTO 的 ToString() 方法.利用 Newtonsoft.Json 序列化 DTO 对象. 第二阶段 为 DTO 设置基类,重写基类的 ToString() 方法.利用 Sy ...

  8. AI 和 DevOps:实现高效软件交付的完美组合

    AI 时代,DevOps 与 AI 共价结合.AI 由业务需求驱动,提高软件质量,而 DevOps 则从整体提升系统功能.DevOps 团队可以使用 AI 来进行测试.开发.监控.增强和系统发布.AI ...

  9. ArrayList 扩容机制

    ArrayList 基本介绍 ArrayList实现了List接口.它可以存储包括null的任何类型的对象,允许重复元素.ArrayList在内部使用一个数组来存储元素,当元素数量超过数组容量时,Ar ...

  10. LaTeX 的学习笔记

    摘自我的洛谷博客 该文章被打开的次数(包括洛谷平台): \(\LaTeX\) 中所有命令都以\开头,后面可以跟一个花括号,代表参数. \documentclass{} 指定了文章类型,有 articl ...