Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: IfRegionMaker find the wrong outBlock #2385

Merged
merged 2 commits into from
Dec 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading