Changeset 799
- Timestamp:
- 04/26/2011 10:50:28 AM (2 years ago)
- Location:
- trunk
- Files:
-
- 2 modified
-
Decompiler.class.php (modified) (12 diffs)
-
decompilesample.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Decompiler.class.php
r796 r799 150 150 var $op2; 151 151 var $parent; 152 var $indent;153 152 154 153 function Decompiler_Binop($parent, $op1, $opc, $op2) … … 164 163 $opstr = $this->parent->binops[$this->opc]; 165 164 166 $op1 = foldToCode($this->op1, $indent); 167 if (is_a($this->op1, 'Decompiler_Binop') && $this->op1->opc != $this->opc) { 168 $op1 = "(" . str($op1, $indent) . ")"; 169 } 170 $op2 = foldToCode($this->op2, $indent); 171 if (is_a($this->op2, 'Decompiler_Binop') && $this->op2->opc != $this->opc && substr($opstr, -1) != '=') { 172 $op2 = "(" . str($op2, $indent) . ")"; 165 if (is_a($this->op1, 'Decompiler_TriOp') || is_a($this->op1, 'Decompiler_Binop') && $this->op1->opc != $this->opc) { 166 $op1 = "(" . str($this->op1, $indent) . ")"; 167 } 168 else { 169 $op1 = $this->op1; 170 } 171 172 if (is_a($this->op2, 'Decompiler_TriOp') || is_a($this->op2, 'Decompiler_Binop') && $this->op2->opc != $this->opc && substr($opstr, -1) != '=') { 173 $op2 = "(" . str($this->op2, $indent) . ")"; 174 } 175 else { 176 $op2 = $this->op2; 173 177 } 174 178 … … 177 181 } 178 182 179 return str($op1) . ' ' . $opstr . ' ' . str($op2); 183 return str($op1, $indent) . ' ' . $opstr . ' ' . str($op2, $indent); 184 } 185 } 186 // }}} 187 class Decompiler_TriOp extends Decompiler_Code // {{{ 188 { 189 var $condition; 190 var $trueValue; 191 var $falseValue; 192 193 function Decompiler_TriOp($condition, $trueValue, $falseValue) 194 { 195 $this->condition = $condition; 196 $this->trueValue = $trueValue; 197 $this->falseValue = $falseValue; 198 } 199 200 function toCode($indent) 201 { 202 $trueValue = $this->trueValue; 203 if (is_a($this->trueValue, 'Decompiler_TriOp')) { 204 $trueValue = "(" . str($trueValue, $indent) . ")"; 205 } 206 $falseValue = $this->falseValue; 207 if (is_a($this->falseValue, 'Decompiler_TriOp')) { 208 $falseValue = "(" . str($falseValue, $indent) . ")"; 209 } 210 211 return str($this->condition) . ' ? ' . str($trueValue) . ' : ' . str($falseValue); 180 212 } 181 213 } … … 486 518 XC_ASSIGN_BW_XOR => "^=", 487 519 XC_BOOL_XOR => "xor", 520 XC_JMP_SET => "?:", 488 521 ); 489 522 // }}} … … 707 740 $lastOp = &$opcodes[$last]; 708 741 742 // {{{ ?: excludign JMP_SET 743 if ($firstOp['opcode'] == XC_JMPZ && !empty($firstOp['jmpouts']) 744 && $last >= $first + 3 745 && $opcodes[$firstOp['jmpouts'][0] - 2]['opcode'] == XC_QM_ASSIGN 746 && $opcodes[$firstOp['jmpouts'][0] - 1]['opcode'] == XC_JMP && $opcodes[$firstOp['jmpouts'][0] - 1]['jmpouts'][0] == $last + 1 747 && $lastOp['opcode'] == XC_QM_ASSIGN 748 ) { 749 $trueFirst = $first + 1; 750 $trueLast = $firstOp['jmpouts'][0] - 2; 751 $falseFirst = $firstOp['jmpouts'][0]; 752 $falseLast = $last; 753 $this->removeJmpInfo($EX, $first); 754 755 $condition = $this->getOpVal($firstOp['op1'], $EX); 756 $this->recognizeAndDecompileClosedBlocks($EX, $trueFirst, $trueLast, $indent . INDENT); 757 $trueValue = $this->getOpVal($opcodes[$trueLast]['op1'], $EX, false, true); 758 $this->recognizeAndDecompileClosedBlocks($EX, $falseFirst, $falseLast, $indent . INDENT); 759 $falseValue = $this->getOpVal($opcodes[$falseLast]['op1'], $EX, false, true); 760 $T[$opcodes[$trueLast]['result']['var']] = new Decompiler_TriOp($condition, $trueValue, $falseValue); 761 return false; 762 } 763 // }}} 709 764 // {{{ try/catch 710 765 if (!empty($firstOp['jmpins']) && !empty($opcodes[$firstOp['jmpins'][0]]['isCatchBegin'])) { … … 974 1029 $this->decompileBasicBlock($EX, $starti, $blockFirst - 1, $indent); 975 1030 } 976 $this->decompileComplexBlock($EX, $blockFirst, $blockLast, $indent); 1031 if ($this->decompileComplexBlock($EX, $blockFirst, $blockLast, $indent) === false) { 1032 if ($EX['lastBlock'] == 'complex') { 1033 echo PHP_EOL; 1034 } 1035 $EX['lastBlock'] = null; 1036 } 977 1037 $starti = $blockLast + 1; 978 1038 $i = $starti; … … 1030 1090 case XC_JMPZ_EX: 1031 1091 case XC_JMPNZ_EX: 1032 case XC_JMP_SET:1092 // case XC_JMP_SET: 1033 1093 // case XC_FE_RESET: 1034 1094 case XC_FE_FETCH: … … 1111 1171 $EX['recvs'] = array(); 1112 1172 $EX['uses'] = array(); 1173 $EX['lastBlock'] = null; 1113 1174 1114 1175 $first = 0; … … 1274 1335 1275 1336 $resvar = null; 1337 unset($curResVar); 1338 if (array_key_exists($res['var'], $T)) { 1339 $curResVar = &$T[$res['var']]; 1340 } 1276 1341 if ((ZEND_ENGINE_2_4 ? ($res['op_type'] & EXT_TYPE_UNUSED) : ($res['EA.type'] & EXT_TYPE_UNUSED)) || $res['op_type'] == XC_IS_UNUSED) { 1277 1342 $istmpres = false; … … 1817 1882 $assoc = $this->getOpVal($op2, $EX); 1818 1883 if (isset($assoc)) { 1819 $ T[$res['var']]->value[] = array($assoc, $rvalue);1884 $curResVar->value[] = array($assoc, $rvalue); 1820 1885 } 1821 1886 else { 1822 $ T[$res['var']]->value[] = array(null, $rvalue);1887 $curResVar->value[] = array(null, $rvalue); 1823 1888 } 1824 1889 } … … 1842 1907 // }}} 1843 1908 case XC_QM_ASSIGN: // {{{ 1844 $resvar = $this->getOpVal($op1, $EX); 1909 if (isset($curResVar) && is_a($curResVar, 'Decompiler_Binop')) { 1910 $curResVar->op2 = $this->getOpVal($op1, $EX); 1911 } 1912 else { 1913 $resvar = $this->getOpVal($op1, $EX); 1914 } 1845 1915 break; 1846 1916 // }}} … … 1894 1964 break; 1895 1965 case XC_JMP_SET: // ?: 1896 $resvar = $this->getOpVal($op1, $EX); 1897 $op['cond'] = $resvar; 1898 $op['isjmp'] = true; 1966 $resvar = new Decompiler_Binop($this, $this->getOpVal($op1, $EX), XC_JMP_SET, null); 1899 1967 break; 1900 1968 case XC_JMPNZ: // while -
trunk/decompilesample.php
r797 r799 405 405 $this::__construct(); 406 406 $obj::__construct(); 407 408 407 $a = $b ?: $d; 409 408 $a = ($b ?: $d) + $c; 410 409 $a = f1() ?: f2(); 410 $a = $b ? $c : $d; 411 $a = ($b ? $c : $d) + $c; 412 $a = f1() ? f3() : f2(); 411 413 412 414 if ($b ?: $d) {

