witchan 发表于 2024-5-16 13:11

【iOS逆向与安全】iOS远程大师:通过H5后台远程查看和协助iPhone设备

# 前言

在移动设备测试和远程协助的过程中,能够远程查看和协助iPhone设备是一项非常实用的功能。为了解决这一需求,我开发了一款名为**iOS远程大师**的产品,允许用户通过H5后台界面查看和协助越狱或非越狱的iPhone设备。本文将详细介绍iOS远程大师的开发过程和技术实现。

---



# 一、技术实现

整个项目的核心技术包括H5前端界面、WebSocket通信、服务器转发和iPhone设备处理。下面将分步骤介绍每个部分的实现。



## 1. H5前端界面

在H5前端,我使用了vue框架来构建用户界面。用户通过这个界面可以实时查看iPhone的屏幕,并通过鼠标发送交互指令。

- **实时屏幕显示**:通过WebSocket连接,接收服务器转发的iPhone屏幕图像,并在H5页面上进行渲染。
- **用户指令捕获**:在div中监听用户的鼠标事件,并将这些事件转换为特定的指令格式。

### 横屏坐标转换

在前端实现中,处理横屏模式下的坐标转换至关重要。在 H5 后台将设备切换为横屏时,尽管你看到的界面已经是横屏了,但 iPhone 端实际仍然是竖屏,因此必须进行坐标转换,以确保点击事件能够在正确的位置被执行,并且保持显示的一致性。

```javascript
const convertCoordinates = (width, height, clickX, clickY) => {
const angle = rotateAngle.value % 360
if (angle === -90) {
    const rotatedX = height - clickX * Math.cos(angle * Math.PI / 180) + clickY * Math.sin(angle * Math.PI / 180)
    const rotatedY = -clickX * Math.sin(angle * Math.PI / 180) + clickY * Math.cos(angle * Math.PI / 180)
    clickX = rotatedX
    clickY = rotatedY
} else if (angle === -180) {
    const rotatedX = width - clickX
    const rotatedY = height - clickY
    clickX = rotatedX
    clickY = rotatedY
} else if (angle === -270) {
    const rotatedX = clickY
    const rotatedY = width - clickX
    clickX = rotatedX
    clickY = rotatedY
}
return { clickX, clickY }
}
```



## 2. WebSocket通信

前端和设备之间采用WebSocket进行实时通信,以确保低延迟的指令传输。

!(https://nas.witchan.com:5802/index.php/s/MHFmDB4tqXtdfqr/preview)

- **建立连接**:前端与后端建立WebSocket连接,确保双向通信的实现。
- **指令发送**:用户在前端页面上进行交互操作,前端将这些指令发送给后端,通过WebSocket进行传输。
- **指令转发**:后端接收到前端发送的指令后,根据指令内容识别目标设备,并将指令下发到对应的设备。
- **执行指令**:目标设备接收到后端发送的指令,并执行相应的操作。
- **结果回传**:设备执行完指令后,将执行结果发送给后端,后端再通过WebSocket将结果回传给前端,以供用户查看或处理。



## 3. iPhone设备处理命令

在iPhone设备端,我们区分越狱和不越狱设备的支持情况。

- **越狱设备**:支持iOS 12到14版本,通过私有API实现更深层次的操作。主要包括硬件触发和屏幕点击。

- **按键操作**:通过私有API直接触发iPhone的硬件功能,例如电源、Home键、音量+-等操作。
- **屏幕点击**:利用越狱权限,直接在屏幕坐标上模拟触摸事件。

按键操作的部分代码如下:

```
+ (void)sendHIDEventWithUsagePage:(uint16_t)usagePage usage:(uint16_t)usage down:(Boolean)down {
      uint64_t abTime = mach_absolute_time();
      IOHIDEventRef event = IOHIDEventCreateKeyboardEvent(kCFAllocatorDefault, abTime, usagePage, usage, down, 0);
      IOHIDEventSetIntegerValue(event,4, 1);
      IOHIDEventSetSenderID(event, senderID);
      postIOHIDEvent(event);
}

static void postIOHIDEvent(IOHIDEventRef event)
{
      static IOHIDEventSystemClientRef ioSystemClient = NULL;
      if (!ioSystemClient){
          ioSystemClient = IOHIDEventSystemClientCreate(kCFAllocatorDefault);
      }
      if (senderID != 0) {
          IOHIDEventSetSenderID(event, senderID);
      } else {
          return;
      }
      IOHIDEventSystemClientDispatchEvent(ioSystemClient, event);
}
```

具体的按键代码可参考:https://iphonedev.wiki/IOHIDFamily



屏幕点击的部分代码如下:

```
// 示例代码:使用私有API触发屏幕点击
void simulateTouch(CGFloat x, CGFloat y) {
      // 在实现模拟滑动过程中,滑动效果始终不理想,最终放弃。引用IOS13-SimulateTouch 项目来实现了屏幕的点击和滑动
      // 具体实现参考 IOS13-SimulateTouch 项目
      // https://github.com/xuan32546/IOS13-SimulateTouch
}
```

在这也要感谢微信群里的 **@福州-啊嘴** 在模拟滑动中提供的帮助



- **非越狱设备**:支持iOS 15及以上版本,利用(https://github.com/appium/WebDriverAgent)实现硬件的触发和屏幕的点击。

- **硬件触发**:通过XCUITest框架模拟按键操作。
- **屏幕点击**:使用XCUITest框架在指定坐标模拟点击。

按键操作的部分代码如下:

```objc
+ (void)sendHIDEventWithUsagePage:(uint16_t)usagePage usage:(uint16_t)usage down:(Boolean)down {
    if (usage == 0xe9) {
      [ pressButton:XCUIDeviceButtonVolumeUp];
    } else if (usage == 0xea) {
      [ pressButton:XCUIDeviceButtonVolumeDown];
    } else if (usage == 0x30 && down) {
      if (.fb_isScreenLocked) {
      [ fb_unlockScreen:nil];
      } else {
      [ fb_lockScreen:nil];
      }
    }
}

+ (void)simulateHome {
    [ pressButton:XCUIDeviceButtonHome];
}
```

屏幕点击的部分代码如下:

```
@interface XCUICoordinate ()

// 滑动事件
- (void)pressForDuration:(double)arg1 thenDragToCoordinate:(id)arg2;

// 点击事件
- (void)pressForDuration:(double)arg1;

@end


+ (void)simulateClick:(CGPoint)tapPoint {
      // 在 https://github.com/appium/WebDriverAgent 项目已经有现成封装好的代码,在这就直接拿来用了
      CGFloat x = tapPoint.x;
      CGFloat y = tapPoint.y;
      CGSize screenSize = ;
      double multiple = screenSize.width / remote_device_screen_width;
      x = x * multiple;
      y = y * multiple;
         
      FBRouteRequest *request = [ init];
      request.arguments = @{@"x": @(x), @"y": @(y), @"duration": @0.001};
      NSLog(@"witwit simulateClick =%@=", request.arguments);
      ;
}
```



# 二、具体功能

**iOS远程大师**主要实现了以下几个功能:

1. **实时屏幕显示**:用户可以在H5界面实时查看iPhone的屏幕。
2. **远程协助**:支持键盘输入、触屏操作等常见交互方式,以便对远程iPhone进行协助。
3. **多设备管理**:支持同时连接和管理多个iPhone设备。



# 三、遇到的问题及解决方案

在开发过程中,我也遇到了几个主要问题:

模拟滑动:在越狱机上的模块滑动效果始终不理想,竖滑正常,横滑始终反应,折腾了好久,最终放弃,直接引用了IOS13-SimulateTouch项目代码。
越狱设备socket连接偶尔断开 :在socket失去连接时,有重新建立连接,但还是有偶现的设备掉线线情况,后边有时间再处理。
设备兼容性:在越狱机上的12,13,14系统能正常运行,非越狱机15和16部分机型能正常运行。



# 总结

通过开发iOS远程大师,我们不仅实现了H5后台远程查看和协助iPhone的功能,还积累了丰富的经验和技术储备。希望这篇文章能对有类似需求和兴趣的开发者提供一些参考和启发,如你需要体验该项目,请联系我。

bachelor66 发表于 2024-5-16 15:51

这个不简单啊                                             

SZnA1 发表于 2024-5-16 13:20

很棒的教程

尹铭 发表于 2024-5-16 13:56

厉害很受用

jujiaomubiao 发表于 2024-5-16 15:17

给了很大启发,谢谢

echo2000 发表于 2024-5-16 15:22


给了很大启发,谢谢

dszq0612 发表于 2024-5-16 16:36

想体验,怎么联系呢???????????????????

鲨鱼V 发表于 2024-5-17 08:45


感谢分享

nitian0963 发表于 2024-5-17 09:27

感谢楼主,给了很大启发

uLY3M 发表于 2024-5-17 21:00

不错,分享给力
页: [1] 2
查看完整版本: 【iOS逆向与安全】iOS远程大师:通过H5后台远程查看和协助iPhone设备