b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

php语法基础 【原创】PHP魔方加密 手动反编译基于栈的指令(3)

电脑杂谈  发布时间:2018-02-08 12:09:56  来源:网络整理

有两种方法,一种是顺序搜索,另一种是跟踪搜索。

最开始我就是想的顺序搜索,遇到 jnz 和 jmp 都不跳转,只是记录他们的位置和相关信息,之后统一处理,顺序分析代码,之后再区分 stmts 块和 else 块。后来发现代码中有一些难点不太好实现。比如两个位置同时跳往同一处,到这里时,我需要同时组装两个 if 块,有时候两个 if 的代码块并不容易区分。

后来我就改用跟踪搜索了,先说 jnz,遇到 jnz 的话,代码分两支执行,遇到 jnz 就继续分,遇到 jmp 就直接跳转,直到两个代码会合(或者往回跳转),这样可以把原来混乱的 jnz 与 jmp 统一。

说到会合,说起来简单,做起来就要一定技巧了,这里又不能分成两个线程去做,怎么办呢?

简而言之就是,分为两个指令指针,一个指向正常执行的下一条指令,一个指向跳转之后的指令,然后总让小的指针往后执行,直到跳转指令或者相遇。

jnz a
......   <---- 指针 1
jmp b
a:
......   <---- 指针 2
jmp c
b:
......
jmp d
c:
......
d:
......
jnz a
......
jmp b
a:
......   <---- 指针 2
jmp c
b:
......   <---- 指针 1
jmp d
c:
......
d:
......
jnz a
......
jmp b
a:
......
jmp c
b:
......   <---- 指针 1
jmp d
c:
......   <---- 指针 2
d:
......
jnz a
......
jmp b
a:
......
jmp c
b:
......
jmp d
c:
......
d:
......   <---- 指针 1 & 指针 2

这就是大概的过程,我的代码实现中使用了 JumpException 这个东西,就是为了遇到跳转指令,直接停止指针的继续移动,重新判断移动哪个指针。

关键代码

/**
 * 条件分支语句
 * @param $jump_pointer
 * @param $next_pointer
 * home.php?mod=space&uid=155549 mixed
 * @throws \Exception
 */
protected function _jnz($jump_pointer, $next_pointer)
{
    if ($jump_pointer < $next_pointer) {
        throw new \Exception('jump pointer < next pointer');
    }

    // 备份 $asmTree
    $asmTreeElse = $asmTreeStmts = $asmTree = $this->asmTree;
    $asmTreePointer = count($this->asmTree);

    // 并分别走 stmts 块和 else 块
    ++$this->jnzStack;
    while ($jump_pointer != $next_pointer) {
        if (($jump_pointer > $next_pointer && $next_pointer > 0) || $jump_pointer < 0) {
            $this->asmTree = $asmTreeElse;
            try {
                $next_pointer = $this->dissect($next_pointer, $jump_pointer);
            } catch (JumpException $exception) {
                $next_pointer = $exception->jump_pointer;
            }
            $asmTreeElse = $this->asmTree;
        } else {
            $this->asmTree = $asmTreeStmts;
            try {
                $jump_pointer = $this->dissect($jump_pointer, $next_pointer);
            } catch (JumpException $exception) {
                $jump_pointer = $exception->jump_pointer;
            }
            $asmTreeStmts = $this->asmTree;
        }
    }
    --$this->jnzStack;

    // 检测循环
    $asmTreeStmtsLastOne = $asmTreeStmts[count($asmTreeStmts) - 1];
    $loop_begin = false;
    if ($asmTreeStmtsLastOne['asm'] == 'loop_end') {
        $loop_begin = $asmTreeStmtsLastOne['args']['begin'];
        array_pop($asmTreeStmts);
        $asmTreeElse[] = [
            'asm' => 'iter_break',
            'args' => [],
        ];
    }

    // 恢复 $asmTree
    $this->asmTree = $asmTree;

    // 构造 if 指令
    $this->asmTree[] = [
        'asm' => 'if               [esp]',
        'args' => [
            'stmts' => array_slice($asmTreeStmts, $asmTreePointer),
            'else' => array_slice($asmTreeElse, $asmTreePointer),
        ],
    ];

    // 构造 loop 指令
    if ($loop_begin !== false) {
        $loop_stmts = array_slice($this->asmTree, $loop_begin);
        $this->asmTree = array_slice($this->asmTree, 0, $loop_begin);
        $this->asmTree[] = [
            'asm' => 'loop',
            'args' => [
                'stmts' => $loop_stmts,
            ],
        ];
    }

    return $next_pointer;
}


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-67089-3.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    • 吴俊伯
      吴俊伯

      升級當天用了20來分鐘

      • 热依萨哈力瓦尔
        热依萨哈力瓦尔

        虽说吨位超过了

    热点图片
    拼命载入中...