[远程Call]32位远程多参数带返回调用
[远程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)¶m[i], (PUCHAR)(¶m[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)¶mSize, (PUCHAR)(¶mSize + 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);
}
实现缺陷
目前只能实现32位的远程调用,64位新增了内存的可执行权限,这样注入的shellcode没法执行。
返回值只能接受32位整数,其实实现64位整数和浮点的方法也不复杂,都可以用汇编把对应寄存器的值写到内存里,但是情况比较多,懒得写了。
[远程Call]32位远程多参数带返回调用的更多相关文章
- VBA: 带参数带返回值的函数
Function pda(x) a = x If Len(a) = 1 Then ab = "00" & a ElseIf Len(a) = 2 Then ab = &qu ...
- 32位的Win7系统下安装64位的Sql Sever?
来自:http://zhidao.baidu.com/link?url=nQBoaLgoOyYCUdI7V4WZCMlTW3tKscdkOnLTIvlYtPpwoVhQkSahq44HeofBfzFT ...
- Linux:使用rpcgen实现64位程序调用32位库函数
摘要:本文介绍使用rpcgent实现64位程序调用32位库函数的方法,并给出样例代码. 我的问题 我的程序运行在64位Linux系统上,需要使用一个从外部获得的共享库中的函数,这个共享库是32位的,无 ...
- IOS是否存在32位和64位版本的区分
苹果于2013年9月推出了iPhone 5S新手机,采用的全新A7处理器其最大特色就是支持64位运算.其64位A7处理器的使用意味着iPhone性能会大有提高,性能和速度更加出色:而要到达到这样的性能 ...
- CLR调试报错“Visual Studio远程调试监视器 (MSVSMON.EXE) 的 64 位版本无法调试 32 位进程或 32 位转储。请改用 32 位版本”的解决
Win7 64位电脑上进行visual studio的数据库项目的CLR存储过程进行调试时,报错: ---------------------------Microsoft Visual Studio ...
- Visual Studio远程调试监视器(MSVSMON.EXE)的32位版本不能用于调试64位进程或64位转储
在VS2013中调试Silverlight项目时,提示:无法附加.Visual Studio远程调试监视器(MSVSMON.EXE)的32位版本不能用于调试64位进程或64位转储.请改用64位版本. ...
- 使用visual c++ 2005远程调试64位系统上32位与64位程序
一直都挺喜欢使用visual c++远程调试代码,它能展现给我们当时代码执行最真实的情景,今天有时间记录一下,以免以后忘了. 远程调试需要在被调试端安装服务器,对于visual c++ 2005来说调 ...
- mysql 远程连接不上,bind-address参数配置要求,以及怎么去使得mysql能够允许远程的客户端访问
刚安装了MySQL服务器,使用远程管理工具总是连接不上,因为知道mysql的默认端口是3306,于是使用telnet连接这个端口,(从这里可以学到telnet是可以这样用的) telnet 192.1 ...
- Photoshop做32位带Alpha通道的bmp图片
原文链接: http://blog.sina.com.cn/s/blog_65c0cae801016e5u.html 批量制作32位带Alpha通道的bmp图片,可以制作一个动作,内容可以如下: ...
- 论DATASNAP远程方法支持自定义对象作参数
论DATASNAP远程方法支持自定义对象作参数 DATASNAP远程方法已经可以支持自定义对象作参数,这是非常方便的功能. 1)自定义对象 type TMyInfo = class(TObject) ...
随机推荐
- 2021-08-24:合并石头的最低成本。有 N 堆石头排成一排,第 i 堆中有 stones[i] 块石头。每次移动(move)需要将连续的 K 堆石头合并为一堆,而这个移动的成本为这 K 堆石头的
2021-08-24:合并石头的最低成本.有 N 堆石头排成一排,第 i 堆中有 stones[i] 块石头.每次移动(move)需要将连续的 K 堆石头合并为一堆,而这个移动的成本为这 K 堆石头的 ...
- From Java To Kotlin:空安全、扩展、函数、Lambda很详细,这次终于懂了
From Java To Kotlin, 空安全.扩展.函数.Lambda 概述(Summarize) • Kotlin 是什么? • 可以做什么? • Android 官方开发语言从Java变为Ko ...
- Serverless冷扩机器在压测中被击穿问题
一.现象回顾 在今天ForceBot全链路压测中,有位同事负责的服务做Serverless扩容(负载达到50%之后自动扩容并上线接入流量)中,发现新扩容的机器被击穿,监控如下(关注2:40-3:15时 ...
- adb查看端口号,杀进程
1.先查看端口号占用的进程 netstat -ano | findstr 8000 2.在杀掉我们查出的进程15812 3.再次查看8000端口号的进程
- 百度飞桨(PaddlePaddle) - PP-OCRv3 文字检测识别系统 基于 Paddle Serving快速使用(服务化部署 - CentOS 7)
目录 Paddle Serving服务化部署实战 准备预测数据和部署环境 环境准备 安装 PaddlePaddle 2.0 安装 PaddleOCR 准备PaddleServing的运行环境, 模型转 ...
- 看懂java序列化,这篇就够了
前言 相信大家日常开发中,经常看到 Java 对象 "implements Serializable".那么,它到底有什么用呢?本文带你全方位的解读序列化与反序列化这一块知识点. ...
- C# - DTO 的字符串表达
第一阶段 重写 DTO 的 ToString() 方法.利用 Newtonsoft.Json 序列化 DTO 对象. 第二阶段 为 DTO 设置基类,重写基类的 ToString() 方法.利用 Sy ...
- AI 和 DevOps:实现高效软件交付的完美组合
AI 时代,DevOps 与 AI 共价结合.AI 由业务需求驱动,提高软件质量,而 DevOps 则从整体提升系统功能.DevOps 团队可以使用 AI 来进行测试.开发.监控.增强和系统发布.AI ...
- ArrayList 扩容机制
ArrayList 基本介绍 ArrayList实现了List接口.它可以存储包括null的任何类型的对象,允许重复元素.ArrayList在内部使用一个数组来存储元素,当元素数量超过数组容量时,Ar ...
- LaTeX 的学习笔记
摘自我的洛谷博客 该文章被打开的次数(包括洛谷平台): \(\LaTeX\) 中所有命令都以\开头,后面可以跟一个花括号,代表参数. \documentclass{} 指定了文章类型,有 articl ...