shanept / assembly-simulator
允许逐行执行编译后的汇编代码。提供访问寄存器和堆栈,以便轻松查询值。
0.1.0
2024-05-22 13:29 UTC
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.5
- phpunit/phpunit: ^10
README
AssemblySimulator项目提供了一种逐行执行编译后的汇编代码的方法,每次操作并提供访问寄存器和堆栈,以便轻松查询值。实现非常简单,我们只实现了几个基本指令。然而,该架构允许轻松扩展指令集,以满足您的项目需求。
模拟器
模拟器可以手动实例化,也可以通过模拟器工厂实例化。请注意,使用模拟器工厂并不限制您在创建模拟器后注册更多指令。以下两种方法等价:
<?php // METHOD 1: Using the factory. $simulator = SimulatorFactory::createSimulator(Simulator::PROTECTED_MODE); // METHOD 2: Manually creating the simulator. $simulator = new Simulator(Simulator::PROTECTED_MODE); // Instantiate default instruction set manually. $xor = new ExclusiveOr(); $lea = new LoadEffectiveAddress(); $mov = new Move(); $pop = new Pop(); $push = new Push(); // Link instruction set to simulator. $xor->setSimulator($simulator); $lea->setSimulator($simulator); $mov->setSimulator($simulator); $pop->setSimulator($simulator); $push->setSimulator($simulator);
模式
模拟器支持在真实模式、保护模式和长模式下运行。为了指定模拟器应运行的模式,请将其中一个模式常量提供给构造函数或setMode函数
- Simulator::REAL_MODE
- Simulator::PROTECTED_MODE
- Simulator::LONG_MODE
注意:如果您使用$simulator->setMode()函数设置模拟器模式,则在执行任何模拟之前必须先调用$simulator->reset()进行重置。请参阅模拟器重置部分。
重置模拟器
在某些情况下,您需要重置模拟器——就像按下电脑的重置开关一样。重置函数用于将模拟器恢复到更好的已知状态。这包括清除寄存器和堆栈。
注册自定义指令
为了使用模拟器,必须用您希望使用的指令集实例化它。这里提供了一个使用默认指令集的示例。请注意,如果您希望使用默认指令集使用模拟器,您可以直接使用模拟器工厂。
更多信息,请参阅自定义指令示例。
<?php $simulator = new Simulator(Simulator::PROTECTED_MODE); // Instantiate our instruction set. $exclusiveOr = new ExclusiveOr; $lea = new LoadEffectiveAddress; $mov = new Move; $pop = new Pop; $push = new Push; // Link our instruction set with the simulator. $exclusiveOr->setSimulator($simulator); $lea->setSimulator($simulator); $mov->setSimulator($simulator); $pop->setSimulator($simulator); $push->setSimulator($simulator);
代码缓冲区
在模拟之前,模拟器必须提供代码缓冲区以从中操作。这必须以二进制字符串的形式提供。
<?php $simulator = new Simulator(Simulator::PROTECTED_MODE); // Taken from PHP v8.3.7 Thread-Safe Windows "php8ts.dll" binary. $assemblyCode = "\x56" . // push esi "\x68\x18\xA7\x60\x10" . // push 0x1060A718 "\x6A\x0B" . // push 0xB "\x68\x98\x4D\x61\x10"; // push 0x10614D98 $simulator->setCodeBuffer($assemblyCode); // OR: Reads the same string from the php8ts.dll file. $fp = fopen("php8ts.dll", "rb"); fseek($fp, 4782677); $assemblyCode = fread($fp, 13); fclose($fp); $simulator->setCodeBuffer($assemblyCode); // The simulator can now run. $simulator->simulate();
示例
更多信息,请参阅示例目录下的示例。
- examples/getCdeclFunctionCallParameters.php - 如何使用模拟器的基本示例。
- examples/registeringCustomInstruction.php - 如何构建和使用自定义指令的示例。
- examples/registeringCustomInstructionWithFactory.php - 如上所述,使用模拟器工厂。
- examples/myCustomInstruction.php - 自定义指令如何实现的示例。