3 个版本
0.1.2 | 2022 年 11 月 14 日 |
---|---|
0.1.1 | 2022 年 11 月 9 日 |
0.1.0 | 2022 年 11 月 9 日 |
60 在 macOS 和 iOS API
在 hyperpom 中使用
125KB
1.5K SLoC
APPLEVISOR
苹果硅 Hypervisor 框架的 Rust 绑定
目录
此库可用于构建利用 Apple Silicon 上 Hypervisor
框架的 Rust 应用程序。它主要针对 Hyperpom 构建,但也可以用于更广泛的目的。
入门
自签名二进制文件和 Hypervisor 权限
为了能够访问 Hypervisor 框架,必须授予二进制可执行文件 hypervisor 权限。
证书链
要将此权限添加到您的项目,您首先需要一个证书链来签名您的二进制文件,可以通过以下说明创建。
- 打开 钥匙串访问 应用程序。
- 转到 钥匙串访问 > 证书助理 > 创建证书。
- 填写 名称 字段,此值将在以后用于标识我们要签名的证书,并将被称为
${CERT_NAME}
。 - 将 身份类型 设置为
Self-Signed Root
。 - 将 证书类型 设置为
Code Signing
。 - 单击 创建。
现在您可以使用以下命令对二进制文件进行签名并添加权限
codesign --entitlements entitlements.xml -s ${CERT_NAME} /path/to/binary
注意: entitlements.xml
文件位于 Applevisor 仓库的根目录。
编译流程
创建一个 Rust 项目,并在 Cargo.toml
中将 Applevisor 添加为依赖项。您可以从 crates.io ...
# Check which version is the latest, this part of the README might not be updated
# in future releases.
applevisor = "0.1.2"
... 或者直接从 GitHub 仓库 获取。
applevisor = { git="https://github.com/impalabs/applevisor", branch="master" }
在项目的根目录下创建一个名为 entitlements.txt
的文件,并添加以下内容
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.hypervisor</key>
<true/>
</dict>
</plist>
编写代码然后构建项目。
cargo build --release
对二进制文件进行签名并授权虚拟机权限。
codesign --entitlements entitlements.xml -s ${CERT_NAME} target/release/${PROJECT_NAME}
运行二进制文件。
target/release/${PROJECT_NAME}
文档
文档可在以下地址在线获取: https://docs.rs/applevisor
或者,您可以使用 cargo
生成文档。
cargo doc --open
示例
以下示例
- 为当前进程创建一个虚拟机;
- 创建一个虚拟 CPU;
- 启用虚拟机的调试功能,以便稍后使用断点;
- 创建 0x1000 字节的物理内存映射,并将其映射到地址 0x10000,具有读写执行权限;
- 在地址 0x10000 处写入指令
mov x0, #0x42; brk #0;
; - 设置 PC 为 0x10000;
- 启动 vCPU 并运行程序;
- 遇到断点时返回。
use applevisor::*;
fn main() {
// Creates a new virtual machine. There can be one, and only one, per process. Operations
// on the virtual machine remains possible as long as this object is valid.
let _vm = VirtualMachine::new().unwrap();
// Creates a new virtual CPU. This object abstracts operations that can be performed on
// CPUs, such as starting and stopping them, changing their registers, etc.
let vcpu = Vcpu::new().unwrap();
// Enables debug features for the hypervisor. This is optional, but it might be required
// for certain features to work, such as breakpoints.
assert!(vcpu.set_trap_debug_exceptions(true).is_ok());
assert!(vcpu.set_trap_debug_reg_accesses(true).is_ok());
// Creates a mapping object that represents a 0x10000-byte physical memory range.
let mut mem = Mapping::new(0x1000).unwrap();
// This mapping needs to be mapped to effectively allocate physical memory for the guest.
// Here we map the map the region at address 0x10000 and set the permissions to
// Read-Write-Execute.
assert_eq!(mem.map(0x10000, MemPerms::RWX), Ok(()));
// Writes a `mov x0, #0x42` instruction at address 0x10000.
assert_eq!(mem.write_dword(0x10000, 0xd2800840), Ok(4));
// Writes a `brk #0` instruction at address 0x10004.
assert_eq!(mem.write_dword(0x10004, 0xd4200000), Ok(4));
// Sets PC to 0x10000.
assert!(vcpu.set_reg(Reg::PC, 0x10000).is_ok());
// Starts the Vcpu. It will execute our mov and breakpoint instructions before stopping.
assert!(vcpu.run().is_ok());
// The *exit information* can be used to used to retrieve different pieces of
// information about the CPU exit status (e.g. exception type, fault address, etc.).
let _exit_info = vcpu.get_exit_info();
// If everything went as expected, the value in X0 is 0x42.
assert_eq!(vcpu.get_reg(Reg::X0), Ok(0x42));
}
您还可以查看 Hyperpom 项目的源代码,了解这些绑定在实际中的应用。
运行测试
要使用项目提供的 Makefile
运行测试,您首先需要安装 jq
。您可以使用 brew
来安装。
brew install jq
然后,您可以使用以下命令使用提供的 Makefile
运行测试
CERT_KEYCHAIN=${CERT_NAME} make tests