Projects STRLCPY jadx Commits 066b5a89
🤬
  • core: refactor 'if' regions processing

  • Loading...
  • Skylot committed 1 decade ago
    066b5a89
    1 parent 4c4af792
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■ ■ ■
    jadx-core/src/main/java/jadx/core/dex/visitors/ConstInlinerVisitor.java
    skipped 10 lines
    11 11  import jadx.core.dex.nodes.InsnNode;
    12 12  import jadx.core.dex.nodes.MethodNode;
    13 13  import jadx.core.utils.BlockUtils;
     14 +import jadx.core.utils.InstructionRemover;
    14 15  import jadx.core.utils.exceptions.JadxException;
    15 16   
    16  -import java.util.Iterator;
    17 17  import java.util.List;
    18 18  import java.util.Set;
    19 19   
    skipped 5 lines
    25 25   return;
    26 26   }
    27 27   for (BlockNode block : mth.getBasicBlocks()) {
    28  - for (Iterator<InsnNode> it = block.getInstructions().iterator(); it.hasNext(); ) {
    29  - InsnNode insn = it.next();
     28 + InstructionRemover remover = new InstructionRemover(block.getInstructions());
     29 + for (InsnNode insn : block.getInstructions()) {
    30 30   if (checkInsn(mth, block, insn)) {
    31  - it.remove();
     31 + remover.add(insn);
    32 32   }
    33 33   }
     34 + remover.perform();
    34 35   }
    35 36   }
    36 37   
    skipped 16 lines
    53 54   private static boolean replaceConst(MethodNode mth, BlockNode block, InsnNode insn, long literal) {
    54 55   List<InsnArg> use = insn.getResult().getTypedVar().getUseList();
    55 56   int replaceCount = 0;
     57 + int assignCount = 0;
    56 58   for (InsnArg arg : use) {
    57 59   InsnNode useInsn = arg.getParentInsn();
    58 60   if (arg == insn.getResult() || useInsn == null) {
     61 + assignCount++;
    59 62   continue;
    60 63   }
    61 64   BlockNode useBlock = BlockUtils.getBlockByInsn(mth, useInsn);
    skipped 14 lines
    76 79   }
    77 80   }
    78 81   }
    79  - return replaceCount == use.size() - 1;
     82 + return replaceCount == use.size() - assignCount;
    80 83   }
    81 84   
    82 85   private static boolean registerReassignOnPath(BlockNode block, BlockNode useBlock, InsnNode assignInsn) {
    skipped 106 lines
  • ■ ■ ■ ■ ■ ■
    jadx-core/src/main/java/jadx/core/dex/visitors/regions/ProcessReturnInsns.java
    skipped 6 lines
    7 7  import jadx.core.dex.nodes.IRegion;
    8 8  import jadx.core.dex.nodes.InsnNode;
    9 9  import jadx.core.dex.nodes.MethodNode;
     10 +import jadx.core.dex.regions.IfRegion;
    10 11  import jadx.core.dex.regions.LoopRegion;
     12 +import jadx.core.dex.regions.SwitchRegion;
    11 13  import jadx.core.utils.RegionUtils;
    12 14   
    13 15  import java.util.List;
    skipped 38 lines
    52 54   private boolean noTrailInstructions(BlockNode block) {
    53 55   IContainer curContainer = block;
    54 56   for (IRegion region : regionStack) {
     57 + // ignore paths on other branches
     58 + if (region instanceof IfRegion
     59 + || region instanceof SwitchRegion) {
     60 + curContainer = region;
     61 + continue;
     62 + }
    55 63   List<IContainer> subBlocks = region.getSubBlocks();
    56 64   if (!subBlocks.isEmpty()) {
    57 65   ListIterator<IContainer> itSubBlock = subBlocks.listIterator(subBlocks.size());
    skipped 16 lines
  • ■ ■ ■ ■ ■ ■
    jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java
    skipped 460 lines
    461 461   }
    462 462   }
    463 463   
    464  - if (elseBlock != null) {
    465  - if (stack.containsExit(elseBlock)) {
    466  - elseBlock = null;
    467  - } else if (elseBlock.getAttributes().contains(AttributeFlag.RETURN)) {
    468  - out = elseBlock;
    469  - elseBlock = null;
    470  - }
     464 + if (elseBlock != null && stack.containsExit(elseBlock)) {
     465 + elseBlock = null;
    471 466   }
    472 467   
    473 468   stack.push(ifRegion);
    skipped 7 lines
    481 476   }
    482 477   
    483 478   private IfInfo mergeNestedIfNodes(BlockNode block, BlockNode bThen, BlockNode bElse, List<BlockNode> merged) {
     479 + IfInfo info = new IfInfo();
     480 + info.setIfnode(block);
     481 + info.setCondition(IfCondition.fromIfBlock(block));
     482 + info.setThenBlock(bThen);
     483 + info.setElseBlock(bElse);
     484 + return mergeNestedIfNodes(info, merged);
     485 + }
     486 + 
     487 + private IfInfo mergeNestedIfNodes(IfInfo info, List<BlockNode> merged) {
     488 + BlockNode bThen = info.getThenBlock();
     489 + BlockNode bElse = info.getElseBlock();
    484 490   if (bThen == bElse) {
    485 491   return null;
    486 492   }
    487 493   
    488  - boolean found;
    489  - IfCondition condition = IfCondition.fromIfBlock(block);
    490  - IfInfo result = null;
    491  - do {
    492  - found = false;
    493  - for (BlockNode succ : block.getSuccessors()) {
    494  - BlockNode nestedIfBlock = getIfNode(succ);
    495  - if (nestedIfBlock != null && nestedIfBlock != block) {
    496  - IfNode nestedIfInsn = (IfNode) nestedIfBlock.getInstructions().get(0);
    497  - BlockNode nbThen = nestedIfInsn.getThenBlock();
    498  - BlockNode nbElse = nestedIfInsn.getElseBlock();
    499  - 
    500  - boolean inverted = false;
    501  - IfCondition nestedCondition = IfCondition.fromIfNode(nestedIfInsn);
    502  - if (isPathExists(bElse, nestedIfBlock)) {
    503  - // else branch
    504  - if (!isEqualPaths(bThen, nbThen)) {
    505  - if (!isEqualPaths(bThen, nbElse)) {
    506  - // not connected conditions
    507  - break;
    508  - }
    509  - nestedIfInsn.invertCondition();
    510  - inverted = true;
    511  - }
    512  - condition = IfCondition.merge(Mode.OR, condition, nestedCondition);
    513  - } else {
    514  - // then branch
    515  - if (!isEqualPaths(bElse, nbElse)) {
    516  - if (!isEqualPaths(bElse, nbThen)) {
    517  - // not connected conditions
    518  - break;
    519  - }
    520  - nestedIfInsn.invertCondition();
    521  - inverted = true;
    522  - }
    523  - condition = IfCondition.merge(Mode.AND, condition, nestedCondition);
    524  - }
    525  - result = new IfInfo();
    526  - result.setCondition(condition);
    527  - nestedIfBlock.getAttributes().add(AttributeFlag.SKIP);
    528  - skipSimplePath(bThen);
    529  - 
    530  - if (merged != null) {
    531  - merged.add(nestedIfBlock);
    532  - }
     494 + BlockNode ifBlock = info.getIfnode();
     495 + BlockNode nestedIfBlock = getNextIfBlock(ifBlock);
     496 + if (nestedIfBlock == null) {
     497 + return null;
     498 + }
    533 499   
    534  - // set new blocks
    535  - result.setIfnode(nestedIfBlock);
    536  - result.setThenBlock(inverted ? nbElse : nbThen);
    537  - result.setElseBlock(inverted ? nbThen : nbElse);
     500 + IfNode nestedIfInsn = (IfNode) nestedIfBlock.getInstructions().get(0);
     501 + IfCondition nestedCondition = IfCondition.fromIfNode(nestedIfInsn);
     502 + BlockNode nbThen = nestedIfInsn.getThenBlock();
     503 + BlockNode nbElse = nestedIfInsn.getElseBlock();
    538 504   
    539  - found = true;
    540  - block = nestedIfBlock;
    541  - bThen = result.getThenBlock();
    542  - bElse = result.getElseBlock();
    543  - break;
     505 + IfCondition condition = info.getCondition();
     506 + boolean inverted = false;
     507 + if (isPathExists(bElse, nestedIfBlock)) {
     508 + // else branch
     509 + if (!isEqualPaths(bThen, nbThen)) {
     510 + if (!isEqualPaths(bThen, nbElse)) {
     511 + // not connected conditions
     512 + return null;
     513 + }
     514 + nestedIfInsn.invertCondition();
     515 + inverted = true;
     516 + }
     517 + condition = IfCondition.merge(Mode.OR, condition, nestedCondition);
     518 + } else {
     519 + // then branch
     520 + if (!isEqualPaths(bElse, nbElse)) {
     521 + if (!isEqualPaths(bElse, nbThen)) {
     522 + // not connected conditions
     523 + return null;
    544 524   }
     525 + nestedIfInsn.invertCondition();
     526 + inverted = true;
    545 527   }
    546  - } while (found);
     528 + condition = IfCondition.merge(Mode.AND, condition, nestedCondition);
     529 + }
     530 + if (merged != null) {
     531 + merged.add(nestedIfBlock);
     532 + }
     533 + nestedIfBlock.getAttributes().add(AttributeFlag.SKIP);
     534 + BlockNode blockToNestedIfBlock = BlockUtils.getNextBlockToPath(ifBlock, nestedIfBlock);
     535 + skipSimplePath(BlockUtils.selectOther(blockToNestedIfBlock, ifBlock.getCleanSuccessors()));
     536 + 
     537 + IfInfo result = new IfInfo();
     538 + result.setIfnode(nestedIfBlock);
     539 + result.setCondition(condition);
     540 + result.setThenBlock(inverted ? nbElse : nbThen);
     541 + result.setElseBlock(inverted ? nbThen : nbElse);
    547 542   
     543 + // search next nested if block
     544 + IfInfo next = mergeNestedIfNodes(result, merged);
     545 + if (next != null) {
     546 + return next;
     547 + }
    548 548   return result;
     549 + }
     550 + 
     551 + private BlockNode getNextIfBlock(BlockNode block) {
     552 + for (BlockNode succ : block.getSuccessors()) {
     553 + BlockNode nestedIfBlock = getIfNode(succ);
     554 + if (nestedIfBlock != null && nestedIfBlock != block) {
     555 + return nestedIfBlock;
     556 + }
     557 + }
     558 + return null;
    549 559   }
    550 560   
    551 561   private static BlockNode getIfNode(BlockNode block) {
    skipped 197 lines
  • ■ ■ ■ ■ ■ ■
    jadx-core/src/main/java/jadx/core/utils/BlockUtils.java
    skipped 131 lines
    132 132   }
    133 133   
    134 134   /**
     135 + * Return successor on path to 'pathEnd' block
     136 + */
     137 + public static BlockNode getNextBlockToPath(BlockNode block, BlockNode pathEnd) {
     138 + List<BlockNode> successors = block.getCleanSuccessors();
     139 + if (successors.contains(pathEnd)) {
     140 + return pathEnd;
     141 + }
     142 + Set<BlockNode> path = getAllPathsBlocks(block, pathEnd);
     143 + for (BlockNode s : successors) {
     144 + if (path.contains(s)) {
     145 + return s;
     146 + }
     147 + }
     148 + return null;
     149 + }
     150 + 
     151 + /**
    135 152   * Collect blocks from all possible execution paths from 'start' to 'end'
    136 153   */
    137 154   public static Set<BlockNode> getAllPathsBlocks(BlockNode start, BlockNode end) {
    skipped 97 lines
  • ■ ■ ■ ■ ■ ■
    jadx-core/src/main/java/jadx/core/utils/Utils.java
    skipped 34 lines
    35 35   case '/':
    36 36   case ';':
    37 37   case '$':
     38 + case ' ':
     39 + case ',':
    38 40   case '<':
    39  - case '[':
    40 41   sb.append('_');
    41 42   break;
    42 43   
    43  - case ']':
     44 + case '[':
    44 45   sb.append('A');
    45 46   break;
    46 47   
     48 + case ']':
    47 49   case '>':
    48  - case ',':
    49  - case ' ':
    50 50   case '?':
    51 51   case '*':
    52 52   break;
    skipped 57 lines
  • ■ ■ ■ ■ ■ ■
    jadx-core/src/test/java/jadx/api/InternalJadxTest.java
    1 1  package jadx.api;
    2 2   
    3 3  import jadx.core.Jadx;
    4  -import jadx.core.dex.attributes.AttributeFlag;
    5 4  import jadx.core.dex.nodes.ClassNode;
    6 5  import jadx.core.dex.nodes.MethodNode;
    7 6  import jadx.core.dex.visitors.DepthTraverser;
    skipped 12 lines
    20 19  import java.util.jar.JarOutputStream;
    21 20   
    22 21  import static junit.framework.Assert.assertEquals;
    23  -import static junit.framework.Assert.assertFalse;
    24 22  import static junit.framework.Assert.assertNotNull;
    25 23  import static junit.framework.Assert.fail;
     24 +import static org.hamcrest.CoreMatchers.containsString;
     25 +import static org.hamcrest.CoreMatchers.not;
     26 +import static org.junit.Assert.assertThat;
    26 27   
    27 28  public abstract class InternalJadxTest extends TestUtils {
    28 29   
    skipped 38 lines
    67 68   for (IDexTreeVisitor visitor : passes) {
    68 69   DepthTraverser.visit(visitor, cls);
    69 70   }
    70  - assertFalse(cls.getAttributes().contains(AttributeFlag.INCONSISTENT_CODE));
     71 + assertThat(cls.getCode().toString(), not(containsString("inconsistent")));
    71 72   return cls;
    72 73   } catch (Exception e) {
    73 74   e.printStackTrace();
    skipped 92 lines
Please wait...
Page is in error, reload to recover