代码的远程调用

代码的远程调用涉及到以下技术难点

1.代码的拷贝:


    
    
DWORD CodeSize  =   0 ;
DWORD CodeStart 
=   0 ;
_asm
{
   mov eax, _end
   sub eax, _begin
   mov CodeSize, eax    mov eax, _begin
   mov CodeStart, eax
   jmp _end
_begin:
   
//此处是具体的功能代码
_end:
 }
 

// 计算要分配的空间  
DWORD ToAllocateSize  =  CodeSize  +   sizeof ( int );

// 分配空间
LPVOID RemotePointer  =  VirtualAllocEx( RemoteProcess, NULL, ToAllocateSize, MEM_COMMIT  |  MEM_RESERVE, PAGE_EXECUTE_READWRITE);     

// 拷贝代码
WriteProcessMemory(RemoteProcess, RemotePointer, reinterpret_cast < char *> (CodeStart), CodeSize, NULL);   
// 释放分配的空间
VirtualFreeEx(RemoteProcess, RemotePointer, CodeSize, MEM_DECOMMIT);
VirtualFreeEx(RemoteProcess, RemotePointer, 
0 , MEM_RELEASE);

2.参数的传递:参数传递的难点在于定位,在上面的基础上面继续完成参数的传递

 

int  Param1  =  GetTickCount();               // 用于测试的参数,此处用GetTickCount来赋值是表明此值不是常量,所以需要传递给调用的代码
DWORD CodeSize  =   0 ;
DWORD CodeStart 
=   0 ;
_asm
{
   mov eax, _end
   sub eax, _begin
   mov CodeSize, eax    mov eax, _begin
   mov CodeStart, eax
   jmp _end
_begin:
//注意,下面是使用传递过来的数据
   
//获取重定位信息
   call delta
delta:  pop ebp
   mov eax, offset delta
   sub ebp, eax  
//完成重定位,得到_end的真实地址,_end之后跟的是数据
   mov ebx, _end
   add ebx, ebp
//上面的步骤执行完了之后,ebx里面就是_end的实际位置了,在这里也就是指向Param1了

_end:
}
   
// 计算要分配的空间  
DWORD ToAllocateSize  =  CodeSize  +   sizeof ( int );

// 分配空间
LPVOID RemotePointer  =  VirtualAllocEx( RemoteProcess, NULL, ToAllocateSize, MEM_COMMIT  |  MEM_RESERVE, PAGE_EXECUTE_READWRITE);
// 拷贝代码
WriteProcessMemory(RemoteProcess, RemotePointer, reinterpret_cast < char *> (CodeStart), CodeSize, NULL);
// 接着前面的代码拷贝数据
WriteProcessMemory(RemoteProcess, RemotePointer  +  CodeSize, reinterpret_cast < char *> ( & Param1),  sizeof ( int ), NULL);

// 释放分配的空间
VirtualFreeEx(RemoteProcess, RemotePointer, CodeSize, MEM_DECOMMIT);
VirtualFreeEx(RemoteProcess, RemotePointer, 
0 , MEM_RELEASE);

 

3.调用:调用实在是再简单不过的事情了,上面的代码完成之后,可以使用你可以想到的调用方式,目前有实际意思的是远程线程以及网络调用

   远程线程的方法:

 

int  Param1  =  GetTickCount();               // 用于测试的参数,此处用GetTickCount来赋值是表明此值不是常量,所以需要传递给调用的代码
DWORD CodeSize  =   0 ;
DWORD CodeStart 
=   0 ;
_asm
{
   mov eax, _end
   sub eax, _begin
   mov CodeSize, eax    mov eax, _begin
   mov CodeStart, eax
   jmp _end
_begin:
//注意,下面是使用传递过来的数据
   
//获取重定位信息
   call delta
delta:  pop ebp
   mov eax, offset delta
   sub ebp, eax   
//完成重定位,得到_end的真实地址,_end之后跟的是数据
   mov ebx, _end
   add ebx, ebp
//上面的步骤执行完了之后,ebx里面就是_end的实际位置了,在这里也就是指向Param1了

_end:
}
   
// 计算要分配的空间  
DWORD ToAllocateSize  =  CodeSize  +   sizeof ( int );

// 分配空间
LPVOID RemotePointer  =  VirtualAllocEx( RemoteProcess, NULL, ToAllocateSize, MEM_COMMIT  |  MEM_RESERVE, PAGE_EXECUTE_READWRITE);
// 拷贝代码
WriteProcessMemory(RemoteProcess, RemotePointer, reinterpret_cast < char *> (CodeStart), CodeSize, NULL);
// 接着前面的代码拷贝数据
WriteProcessMemory(RemoteProcess, RemotePointer  +  CodeSize, reinterpret_cast < char *> ( & Param1),  sizeof ( int ), NULL); 

// 远程调用
HANDLE RemoteThread  =  CreateRemoteThread( RemoteProcess, NULL,  0 , reinterpret_cast < PTHREAD_START_ROUTINE > (RemotePointer),  0 0 , NULL);
WaitForSingleObject(RemoteThread, INFINITE);  

// 释放分配的空间
VirtualFreeEx(RemoteProcess, RemotePointer, CodeSize, MEM_DECOMMIT);
VirtualFreeEx(RemoteProcess, RemotePointer, 
0 , MEM_RELEASE);

 

    网络调用可以把上述的代码进行修改之后,通过网络传输之后,由接受放负责调用
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Akka 远程调用的实现基于 Akka Remoting 模块。以下是一个简单的示例: 首先,需要在项目中添加 Akka Remoting 依赖: ```xml <dependency> <groupId>com.typesafe.akka</groupId> <artifactId>akka-remote_2.11</artifactId> <version>2.5.9</version> </dependency> ``` 然后,定义一个远程 Actor,它可以通过网络接收和处理消息: ```java import akka.actor.AbstractActor; import akka.event.Logging; import akka.event.LoggingAdapter; public class RemoteActor extends AbstractActor { private LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this); @Override public Receive createReceive() { return receiveBuilder() .match(String.class, message -> { log.info("Received message: {}", message); getSender().tell("Hello from remote actor", getSelf()); }) .build(); } } ``` 接下来,在本地 Actor 中创建一个远程 Actor 的引用,并向其发送消息: ```java import akka.actor.ActorRef; import akka.actor.ActorSystem; import akka.actor.Props; import akka.pattern.Patterns; import scala.concurrent.Await; import scala.concurrent.duration.Duration; import java.util.concurrent.TimeUnit; public class LocalActor { public static void main(String[] args) throws Exception { ActorSystem system = ActorSystem.create("MySystem"); // 创建远程 Actor 的引用 ActorRef remoteActor = system.actorOf(Props.create(RemoteActor.class), "remoteActor"); // 向远程 Actor 发送消息,并等待其回复 String message = "Hello from local actor"; Object response = Patterns.ask(remoteActor, message, 5000).toCompletableFuture().get(5000, TimeUnit.MILLISECONDS); System.out.println("Received response: " + response); system.terminate(); } } ``` 在上面的代码中,我们使用 `Patterns.ask` 方法向远程 Actor 发送一条消息,并等待其回复。该方法返回一个 `Future` 对象,我们可以使用 `toCompletableFuture()` 方法将其转换为 Java 8 的 `CompletableFuture` 对象,从而方便地使用 `get` 方法等待结果。 以上就是一个简单的 Akka 远程调用的示例。在实际应用中,还需要配置 Akka Remoting 的一些参数,例如远程 Actor 的地址、端口等。具体配置方法可以参考 Akka 官方文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值