上一篇,我们用模拟流程的方式,解决了跳转问题。

不过静态跳转,好歹事先是知道来龙去脉的。而动态跳转,只有运行时才知道要去哪。既然流程都是未知的,翻译从何谈起?

动态跳转,平时出现的多吗?非常多!除了 JMP 指令,还有一个更常用的,就是 RTS 指令。

它用于子流程的返回 —— 从栈上取出数据给程序计数器 PC,回到之前执行 JSR 指令的位置(相当于 call / return)。如果把栈上数据改了,那也是可以任意跳转的。

动态跳转很常用,因此必须得支持。

已有流程

动态跳转,理论上可以跳到任意位置,但事实上很少会乱跳。大多数时候,跳转的仍然是某个已有的流程。

比如 RTS 指令,跳转的就是之前执行 JSR 时的位置。(除非破坏了栈上的数据,跳到未知流程,但这是极小概率情况)

所以我们在翻译时,记录下每个 block_xxx 对应的原始位置:

addr_block_map = {
0x0600: block_0,
0x0612: block_1,
0x0618: block_2,
...
}

这样就可在运行时,通过「目标地址」查询对应的 JS 流程块。例如:

JMP ($00f0)

翻译成类似如下的 JS 代码:

pc = mem_read_uint16(0x00f0)
nextFn = addr_block_map[pc]

虽然 pc 的值不确定,但 addr_block_map[pc] 通常还是存在的。

使用这种方式,就能处理大多数情况下的「动态跳转」了!

未知流程

但是,总会有不存在的情况。最极端的,就是跳到栈内存上,将动态的数据当指令执行。。。这时,光靠翻译显然是做不到了。

不过,上一篇已给我们启示:如果翻译做不到,就用模拟凑合。现在完全无法翻译,那就 100% 模拟吧!

我们把模拟器、原始二进制指令,都打包在一起。运行过程中,一旦进入未知流程,就切换至模拟:

nextFn = addr_block_map[pc]

if (!nextFn) {       // 没有对应的流程,进入解释模式
nextFn = interpreter
return
}

模拟虽然很慢,但总比不支持好啊!

事实上,不必一直模拟下去,只要抓住机会,还是有可能翻身的:

function interpreter() {
do { // 解释模式
opcode = MEM[pc++] switch (opcode) {
case 0xA9: // LDA
...
case 0x85: // STA
...
case 0x4C: // JMP
pc = ...
nextFn = addr_block_map[pc]
}
} while(...)
}

一旦解释到「跳转指令」,并且跳到已有的 JS 流程上,这时就可以退出解释器,重回翻译模式了!

有了模拟器这个后备方案,我们总能活下去。并且大多数情况下,只是用来应急而已,不会模拟太久,因此性能损失不会太大。

到此,任意跳转的问题,就这样解决了。

结尾

前面提到,跳到栈上可以执行动态指令。事实上还有一种情况,不用跳转也可以,那就是:修改已有的指令。

下一篇,将讨论动态指令相关的问题。

机器指令翻译成 JavaScript —— No.4 动态跳转的更多相关文章

  1. 【探索】机器指令翻译成 JavaScript

    前言 前些时候研究脚本混淆时,打算先学一些「程序流程」相关的概念.为了不因太枯燥而放弃,决定想一个有趣的案例,可以边探索边学. 于是想了一个话题:尝试将机器指令 1:1 翻译 成 JavaScript ...

  2. 机器指令翻译成 JavaScript —— No.5 指令变化

    上一篇,我们通过内置解释器的方案,解决任意跳转的问题.同时,也提到另一个问题:如果指令发生变化,又该如何应对. 指令自改 如果指令加载到 RAM 中,那就和普通数据一样,也是可以随意修改的.然而,对应 ...

  3. 机器指令翻译成 JavaScript —— No.2 跳转处理

    上一篇,我们发现大多数 6502 指令都可以直接 1:1 翻译成 JS 代码,但除了「跳转指令」. 跳转指令,分无条件跳转.条件跳转.从另一个角度,也可分: 静态跳转:目标地址已知 动态跳转:目标地址 ...

  4. 机器指令翻译成 JavaScript —— No.7 过渡语言

    上一篇,我们决定使用 LLVM 来优化程序,并打算用 C 作为输入语言.现在我们来研究一下,将 6502 指令转换成 C 的可行性. 跳转支持 翻译成 C 语言,可比 JS 容易多了.因为 C 支持 ...

  5. 机器指令翻译成 JavaScript —— 终极目标

    上一篇,我们顺利将 6502 指令翻译成 C 代码,并演示了一个案例. 现在,我们来完成最后的目标 -- 转换成 JavaScript. 中间码输出 我们之所以选择 C,就是为了使用 LLVM.现在来 ...

  6. 机器指令翻译成 JavaScript —— No.3 流程分割

    上一篇 我们讨论了跳转指令,并实现「正跳转」的翻译,但最终困在「负跳转」上.而且,由于线程模型的差异,我们不能 1:1 的翻译,必须对流程进行一些改造. 当初之所以选择翻译,而不是模拟,就是出于性能考 ...

  7. 机器指令翻译成 JavaScript —— No.6 深度优化

    第一篇 中我们曾提到,JavaScript 最终还得经过浏览器来解析.因此可以把一些优化工作,交给脚本引擎来完成. 现代浏览器的优化能力确实很强,但是,运行时的优化终归是有限的.如果能在事先实现,则可 ...

  8. 四十年前的 6502 CPU 指令翻译成 JS 代码会是怎样

    去年折腾的一个东西,之前 blog 里也写过,不过那时边琢磨边写,所以比较杂乱,现在简单完整地讲解一下. 前言 当时看到一本虚拟机相关的书,正好又在想 JS 混淆相关的事,无意中冒出个问题:能不能把某 ...

  9. [书籍翻译] 《JavaScript并发编程》第一章 JavaScript并发简介

    > 本文是我翻译<JavaScript Concurrency>书籍的第一章,该书主要以Promises.Generator.Web workers等技术来讲解JavaScript并 ...

随机推荐

  1. 微信企业号 获取AccessToken

    目录 1. AccessToken介绍 2. 示例代码 1. AccessToken介绍 1.1 什么是AccessToken AccessToken即访问凭证,业务服务器每次主动调用企业号接口时需要 ...

  2. Javascript 的执行环境(execution context)和作用域(scope)及垃圾回收

    执行环境有全局执行环境和函数执行环境之分,每次进入一个新执行环境,都会创建一个搜索变量和函数的作用域链.函数的局部环境不仅有权访问函数作用于中的变量,而且可以访问其外部环境,直到全局环境.全局执行环境 ...

  3. H5单页面手势滑屏切换原理

    H5单页面手势滑屏切换是采用HTML5 触摸事件(Touch) 和 CSS3动画(Transform,Transition)来实现的,效果图如下所示,本文简单说一下其实现原理和主要思路. 1.实现原理 ...

  4. 用CIL写程序:你好,沃尔德

    前言: 项目紧赶慢赶总算在年前有了一些成绩,所以沉寂了几周之后,小匹夫也终于有时间写点东西了.以前匹夫写过一篇文章,对CIL做了一个简单地介绍,不过不知道各位看官看的是否过瘾,至少小匹夫觉得很不过瘾. ...

  5. ASP.NET是如何在IIS下工作的

    ASP.NET与IIS是紧密联系的,由于IIS6.0与IIS7.0的工作方式的不同,导致ASP.NET的工作原理也发生了相应的变化. IIS6(IIS7的经典模式)与IIS7的集成模式的不同 IIS6 ...

  6. Win10 IIS本地部署MVC网站时不能运行?

    异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 部署后出现这个错误: 打开文件目录后发现是可以看见目录的,静态页面也是可以打开的 ...

  7. ASP.NET MVC5+EF6+EasyUI 后台管理系统(71)-微信公众平台开发-公众号管理

    系列目录 思维导图 下面我们来看一个思维导图,这样就可以更快了解所需要的功能: 上一节我们利用了一个简单的代码例子,完成了与微信公众号的对话(给公众号发一条信息,并得到回复) 这一节将讲解公众号如何设 ...

  8. 从零开始编写自己的C#框架(25)——网站部署

    导航 1.关掉访问保护 2.发布网站 3.复制网站到服务器 4.添加新网站 5.设置网站访问权限 6.设置文件夹访问权限 7.控制可更新文件夹执行权限 8.设置“应用程序池”.net版本与模式 9.附 ...

  9. Kooboo CMS技术文档之二:Kooboo CMS的安装步骤

    在IIS上安装Kooboo CMS Kooboo CMS安装之后 安装的常见问题 1. 在IIS上安装Kooboo CMS Kooboo CMS部署到正式环境相当简单,安装过程是一个普通MVC站点在I ...

  10. vs15 preview5 离线安装包

    1.介绍 vs15是微软打造的新一代IDE,全新的安装方式.官网介绍如下(https://blogs.msdn.microsoft.com/visualstudio/2016/10/05/announ ...