然后就是一些通用的函数了,注意这个 getFunc 就是获取函数名(或者说获取下一条指令)的函数,就是把原本文件的算法抄过来了,然后加上函数名映射。
protected function getFunc($eip)
{
$key = $this->getMemory($eip, 1);
$func = $this->getMemory($eip + 1, 2) . $this->getMemory($eip + 4, 2);
$func = str_repeat($key, 4) ^ $func;
$func = base64_decode('zb+8') . $func;
if (isset($this->fnm[$func])) { // function name map
$func = $this->fnm[$func];
} else {
throw new \Exception('Function not exists: $eip=' . $eip . ' func=' . $func);
}
if (ord($key ^ $this->getMemory($eip + 3, 1)) != 6) {
throw new \Exception('Instruction length is not 6');
}
return $func;
}
其他就是对每一个特殊指令进行单独操作,这个过程也很漫长。
然后我们就会得到反汇编的文件。

为了方便阅读,我有写了一个输出为文本文件的函数,我们之后分析起来比较方便。

然后想了想,我又加了一个功能,就是跳转列表,这个功能在我们分析的过程中还是非常重要的,因为程序不可能都是线性的,条件分支会给反编译带来麻烦,不规则的跳转更麻烦,我们之后要想办法消除这些跳转。

你要是自己实现反编译了,你就知道为什么不推荐使用 goto 语句了。
至此,我们的反编译器实现完成了。我们只用到了那个导出的 bin,完全脱离了原本的虚拟机。
反编译之后的指令,已经没有 1/2/4/6/12 位立即数的说法了,数字已经完全解码出来了,不用再考虑位数的问题了,可以说把指令集简化了。
之前说到了跳转很烦人,我们要想办法消除这些跳转,就是代码分块。
IDA 也有这个功能,这个功能好像还非常强大,只不过我还没想过破解过什么东西,还没学 IDA。
本来我是没有分块这一步骤的,直接反编译,但是后来发现跟踪跳转太麻烦了,所以就单独出来,先分块,然后再反编译。
分块的基础就是根据跳转,这套指令集只有两个跳转,jmp 和 jnz,这两个一个是 if 语句,一个是 if 的 stmts 块结束到 else 块结束出的跳转,一个是跳出 while 的条件,一个是继续循环的跳回指令。php语法基础
这里说的 stmts 与 else

if (cond)
stmts-block
else
else-block
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-67089-2.html
就是开战之时
中国发展迅速都是老百姓无形中的支持