Skip to content

Commit

Permalink
fix: IfRegionMaker find the wrong outBlock (PR #2385)
Browse files Browse the repository at this point in the history
* IfRegionMaker find wrong out block

* fix: test codes fail because of the previous commit
  • Loading branch information
ewt45 authored Dec 30, 2024
1 parent f4849d6 commit 84e211b
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ static IfInfo restructureIf(MethodNode mth, BlockNode block, IfInfo info) {
info.setOutBlock(null);
return info;
}
// init outblock, which will be used in isBadBranchBlock to compare with branch block
info.setOutBlock(BlockUtils.getPathCross(mth, thenBlock, elseBlock));
boolean badThen = isBadBranchBlock(info, thenBlock);
boolean badElse = isBadBranchBlock(info, elseBlock);
if (badThen && badElse) {
Expand All @@ -193,8 +195,6 @@ static IfInfo restructureIf(MethodNode mth, BlockNode block, IfInfo info) {
info = IfInfo.invert(info);
info = new IfInfo(info, elseBlock, null);
info.setOutBlock(thenBlock);
} else {
info.setOutBlock(BlockUtils.getPathCross(mth, thenBlock, elseBlock));
}
if (BlockUtils.isBackEdge(block, info.getOutBlock())) {
info.setOutBlock(null);
Expand All @@ -219,6 +219,10 @@ private static boolean isBadBranchBlock(IfInfo info, BlockNode block) {
}
}
}
// if branch block itself is outblock
if (info.getOutBlock() != null) {
return block == info.getOutBlock();
}
return !allPathsFromIf(block, info);
}

Expand Down
22 changes: 10 additions & 12 deletions jadx-core/src/main/java/jadx/core/utils/BlockUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -761,18 +761,22 @@ public static BlockNode getCommonDominator(MethodNode mth, List<BlockNode> block
/**
* Return common cross block for input set.
*
* @return null if cross is a method exit block.
* @return could be one of the giving blocks. null if cross is a method exit block.
*/
@Nullable
public static BlockNode getPathCross(MethodNode mth, Collection<BlockNode> blocks) {
BitSet domFrontBS = newBlocksBitSet(mth);
BitSet tmpBS = newBlocksBitSet(mth); // store block itself and its domFrontier
boolean first = true;
for (BlockNode b : blocks) {
tmpBS.clear();
tmpBS.set(b.getId());
tmpBS.or(b.getDomFrontier());
if (first) {
domFrontBS.or(b.getDomFrontier());
domFrontBS.or(tmpBS);
first = false;
} else {
domFrontBS.and(b.getDomFrontier());
domFrontBS.and(tmpBS);
}
}
domFrontBS.clear(mth.getExitBlock().getId());
Expand All @@ -790,7 +794,7 @@ public static BlockNode getPathCross(MethodNode mth, Collection<BlockNode> block
mth.getLoops().forEach(l -> excluded.set(l.getStart().getId()));
if (!mth.isNoExceptionHandlers()) {
// exclude exception handlers paths
mth.getExceptionHandlers().forEach(h -> mergeExcHandlerDomFrontier(mth, h, excluded));
mth.getExceptionHandlers().forEach(h -> addExcHandler(mth, h, excluded));
}
domFrontBS.andNot(excluded);
oneBlock = bitSetToOneBlock(mth, domFrontBS);
Expand All @@ -805,7 +809,6 @@ public static BlockNode getPathCross(MethodNode mth, Collection<BlockNode> block
BitSet domFrontier = block.getDomFrontier();
if (!domFrontier.isEmpty()) {
combinedDF.or(domFrontier);
combinedDF.clear(block.getId());
}
});
combinedDF.andNot(excluded);
Expand All @@ -827,18 +830,13 @@ public static BlockNode getPathCross(MethodNode mth, Collection<BlockNode> block
}
}

private static void mergeExcHandlerDomFrontier(MethodNode mth, ExceptionHandler handler, BitSet set) {
private static void addExcHandler(MethodNode mth, ExceptionHandler handler, BitSet set) {
BlockNode handlerBlock = handler.getHandlerBlock();
if (handlerBlock == null) {
mth.addDebugComment("Null handler block in: " + handler);
return;
}
BitSet domFrontier = handlerBlock.getDomFrontier();
if (domFrontier == null) {
mth.addDebugComment("Null dom frontier in handler: " + handler);
return;
}
set.or(domFrontier);
set.set(handlerBlock.getId());
}

public static BlockNode getPathCross(MethodNode mth, BlockNode b1, BlockNode b2) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package jadx.tests.integration.conditions;

import org.junit.jupiter.api.Test;

import jadx.tests.api.SmaliTest;

import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;

/**
* Issue #2384
*/
public class TestOutBlock extends SmaliTest {

@Test
public void test() {
allowWarnInCode();
disableCompilation();
assertThat(getClassNodeFromSmali())
.code()
.containsOne("setContentView");
}
}
149 changes: 149 additions & 0 deletions jadx-core/src/test/smali/conditions/TestOutBlock.smali
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
.class public Lconditions/TestOutBlock;
.super Lcom/eltechs/axs/activities/FrameworkActivity;


.method protected onCreate(Landroid/os/Bundle;)V
.registers 9

.line 98
invoke-super {p0, p1}, Lcom/eltechs/axs/activities/FrameworkActivity;->onCreate(Landroid/os/Bundle;)V

.line 101
invoke-virtual {p0}, Lconditions/TestOutBlock;->getApplicationState()Lcom/eltechs/axs/applicationState/ApplicationStateBase;

move-result-object p1

.line 102
invoke-interface {p1}, Lcom/eltechs/axs/applicationState/ApplicationStateBase;->getEnvironment()Lcom/eltechs/axs/environmentService/AXSEnvironment;

move-result-object v0

const-class v1, Lcom/eltechs/axs/environmentService/components/XServerComponent;

invoke-virtual {v0, v1}, Lcom/eltechs/axs/environmentService/AXSEnvironment;->getComponent(Ljava/lang/Class;)Lcom/eltechs/axs/environmentService/EnvironmentComponent;

move-result-object v0

check-cast v0, Lcom/eltechs/axs/environmentService/components/XServerComponent;

.line 103
invoke-virtual {p0}, Lconditions/TestOutBlock;->getIntent()Landroid/content/Intent;

move-result-object v1

const-string v2, "facadeclass"

invoke-virtual {v1, v2}, Landroid/content/Intent;->getSerializableExtra(Ljava/lang/String;)Ljava/io/Serializable;

move-result-object v1

check-cast v1, Ljava/lang/Class;

if-eqz v1, :cond_46

const/4 v2, 0x2

const/4 v3, 0x0

.line 108
:try_start_23
new-array v4, v2, [Ljava/lang/Class;

const-class v5, Lcom/eltechs/axs/xserver/XServer;

aput-object v5, v4, v3

const-class v5, Lcom/eltechs/axs/applicationState/ApplicationStateBase;

const/4 v6, 0x1

aput-object v5, v4, v6

invoke-virtual {v1, v4}, Ljava/lang/Class;->getDeclaredConstructor([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;

move-result-object v1

.line 109
new-array v2, v2, [Ljava/lang/Object;

invoke-virtual {v0}, Lcom/eltechs/axs/environmentService/components/XServerComponent;->getXServer()Lcom/eltechs/axs/xserver/XServer;

move-result-object v4

aput-object v4, v2, v3

aput-object p1, v2, v6

invoke-virtual {v1, v2}, Ljava/lang/reflect/Constructor;->newInstance([Ljava/lang/Object;)Ljava/lang/Object;

move-result-object v1

check-cast v1, Lcom/eltechs/axs/xserver/ViewFacade;
:try_end_42
.catch Ljava/lang/Exception; {:try_start_23 .. :try_end_42} :catch_43

goto :goto_47

.line 112
:catch_43
invoke-static {v3}, Lcom/eltechs/axs/helpers/Assert;->state(Z)V

:cond_46
const/4 v1, 0x0

.line 118
:goto_47
invoke-virtual {p0}, Lconditions/TestOutBlock;->getWindow()Landroid/view/Window;

move-result-object v2

const/16 v3, 0x80

invoke-virtual {v2, v3}, Landroid/view/Window;->addFlags(I)V

.line 120
invoke-virtual {p0}, Lconditions/TestOutBlock;->getWindow()Landroid/view/Window;

move-result-object v2

const/high16 v3, 0x400000

invoke-virtual {v2, v3}, Landroid/view/Window;->addFlags(I)V

.line 125
sget v2, Lcom/eltechs/axs/R$layout;->main:I

invoke-virtual {p0, v2}, Lconditions/TestOutBlock;->setContentView(I)V

.line 127
invoke-direct {p0}, Lconditions/TestOutBlock;->checkForSuddenDeath()Z

move-result v2

if-eqz v2, :cond_65

return-void

.line 135
:cond_65
new-instance v2, Lcom/eltechs/axs/widgets/viewOfXServer/ViewOfXServer;

invoke-virtual {v0}, Lcom/eltechs/axs/environmentService/components/XServerComponent;->getXServer()Lcom/eltechs/axs/xserver/XServer;

move-result-object v0

invoke-interface {p1}, Lcom/eltechs/axs/applicationState/ApplicationStateBase;->getXServerViewConfiguration()Lcom/eltechs/axs/configuration/XServerViewConfiguration;

move-result-object p1

invoke-direct {v2, p0, v0, v1, p1}, Lcom/eltechs/axs/widgets/viewOfXServer/ViewOfXServer;-><init>(Landroid/content/Context;Lcom/eltechs/axs/xserver/XServer;Lcom/eltechs/axs/xserver/ViewFacade;Lcom/eltechs/axs/configuration/XServerViewConfiguration;)V

iput-object v2, p0, Lconditions/TestOutBlock;->viewOfXServer:Lcom/eltechs/axs/widgets/viewOfXServer/ViewOfXServer;

.line 137
iget-object p1, p0, Lconditions/TestOutBlock;->periodicIabCheckTimer:Landroid/os/CountDownTimer;

invoke-virtual {p1}, Landroid/os/CountDownTimer;->start()Landroid/os/CountDownTimer;

return-void
.end method

0 comments on commit 84e211b

Please sign in to comment.