如何判定指令长度
现在来解答前面遗留的一个问题。
上面这个算法能够工作的一个重要前提是:
我们得知道,给末尾字节 1后,有没有影响指令的长度。
要判断某个字节是不是关键字节,就得知道这个字节的内容变化,会不会影响到指令长度,所以如果无法判断长度有没有变化,那上面的算法就无从谈起了。
所以如何知道长度有没有变化呢?报告中用到了一个非常巧妙的方法。
假设我们要评估下面这一串数据,前面开头到底多少个字节是一条完整指令。
可能第一个字节0F就是一条指令。
也可能前面两个字节0F 6A是一条指令。
还可能前面五个字节0F 6A 60 6A 79 6D是一条指令。
到底是什么情况,我们不知道,让我们用程序来尝试推导出来。
准备两个连续的内存页面,前面一个拥有可执行的权限,后面一个不能执行。
记住:当CPU发现指令位于不可执行的页面中时,它会抛异常!
现在,在内存中这样放置上面的数据流:第一个字节放在第一个页面的末尾位置,后面在字节放在第二个不可执行的页面上。
然后JMP到这条指令的地址,尝试去执行它,CPU中的译码器开始译码: