Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
J
jadx
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open-source
jadx
Commits
cb23b657
Commit
cb23b657
authored
Apr 08, 2018
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: fix variable names propagation (#219)
parent
7a168148
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
225 additions
and
27 deletions
+225
-27
RegisterArg.java
...ain/java/jadx/core/dex/instructions/args/RegisterArg.java
+15
-0
DebugInfoParser.java
...main/java/jadx/core/dex/nodes/parser/DebugInfoParser.java
+12
-4
PrepareForCodeGen.java
...c/main/java/jadx/core/dex/visitors/PrepareForCodeGen.java
+1
-0
ProcessVariables.java
...java/jadx/core/dex/visitors/regions/ProcessVariables.java
+0
-1
SSATransform.java
...rc/main/java/jadx/core/dex/visitors/ssa/SSATransform.java
+14
-16
TypeInference.java
...a/jadx/core/dex/visitors/typeinference/TypeInference.java
+34
-2
TestConditions10.java
...a/jadx/tests/integration/conditions/TestConditions10.java
+1
-1
TestVariablesNames.java
.../jadx/tests/integration/debuginfo/TestVariablesNames.java
+52
-0
TestTryCatch7.java
...t/java/jadx/tests/integration/trycatch/TestTryCatch7.java
+4
-3
TestVariablesNames.smali
jadx-core/src/test/smali/debuginfo/TestVariablesNames.smali
+92
-0
No files found.
jadx-core/src/main/java/jadx/core/dex/instructions/args/RegisterArg.java
View file @
cb23b657
...
...
@@ -63,6 +63,21 @@ public class RegisterArg extends InsnArg implements Named {
return
n
.
equals
(((
Named
)
arg
).
getName
());
}
public
void
mergeName
(
InsnArg
arg
)
{
if
(
arg
instanceof
Named
)
{
Named
otherArg
=
(
Named
)
arg
;
String
otherName
=
otherArg
.
getName
();
String
name
=
getName
();
if
(!
Objects
.
equals
(
name
,
otherName
))
{
if
(
name
==
null
)
{
setName
(
otherName
);
}
else
if
(
otherName
==
null
)
{
otherArg
.
setName
(
name
);
}
}
}
}
@Override
public
void
setType
(
ArgType
type
)
{
if
(
sVar
!=
null
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/parser/DebugInfoParser.java
View file @
cb23b657
...
...
@@ -78,6 +78,8 @@ public class DebugInfoParser {
addrChange
(-
1
,
1
,
line
);
setLine
(
addr
,
line
);
boolean
varsInfoFound
=
false
;
int
c
=
section
.
readByte
()
&
0xFF
;
while
(
c
!=
DBG_END_SEQUENCE
)
{
switch
(
c
)
{
...
...
@@ -98,6 +100,7 @@ public class DebugInfoParser {
int
type
=
section
.
readUleb128
()
-
1
;
LocalVar
var
=
new
LocalVar
(
dex
,
regNum
,
nameId
,
type
,
DexNode
.
NO_INDEX
);
startVar
(
var
,
addr
,
line
);
varsInfoFound
=
true
;
break
;
}
case
DBG_START_LOCAL_EXTENDED:
{
...
...
@@ -107,6 +110,7 @@ public class DebugInfoParser {
int
sign
=
section
.
readUleb128
()
-
1
;
LocalVar
var
=
new
LocalVar
(
dex
,
regNum
,
nameId
,
type
,
sign
);
startVar
(
var
,
addr
,
line
);
varsInfoFound
=
true
;
break
;
}
case
DBG_RESTART_LOCAL:
{
...
...
@@ -118,6 +122,7 @@ public class DebugInfoParser {
}
var
.
start
(
addr
,
line
);
}
varsInfoFound
=
true
;
break
;
}
case
DBG_END_LOCAL:
{
...
...
@@ -127,6 +132,7 @@ public class DebugInfoParser {
var
.
end
(
addr
,
line
);
setVar
(
var
);
}
varsInfoFound
=
true
;
break
;
}
...
...
@@ -160,12 +166,14 @@ public class DebugInfoParser {
c
=
section
.
readByte
()
&
0xFF
;
}
if
(
varsInfoFound
)
{
for
(
LocalVar
var
:
locals
)
{
if
(
var
!=
null
&&
!
var
.
isEnd
())
{
var
.
end
(
mth
.
getCodeSize
()
-
1
,
line
);
setVar
(
var
);
}
}
}
setSourceLines
(
addr
,
insnByOffset
.
length
,
line
);
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/PrepareForCodeGen.java
View file @
cb23b657
...
...
@@ -142,6 +142,7 @@ public class PrepareForCodeGen extends AbstractVisitor {
}
if
(
replace
)
{
insn
.
add
(
AFlag
.
ARITH_ONEARG
);
insn
.
getResult
().
mergeName
(
arg
);
}
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/ProcessVariables.java
View file @
cb23b657
...
...
@@ -22,7 +22,6 @@ import jadx.core.utils.exceptions.JadxException;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.Iterator
;
import
java.util.LinkedHashMap
;
import
java.util.LinkedHashSet
;
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ssa/SSATransform.java
View file @
cb23b657
...
...
@@ -8,6 +8,7 @@ import jadx.core.dex.instructions.PhiInsn;
import
jadx.core.dex.instructions.args.InsnArg
;
import
jadx.core.dex.instructions.args.RegisterArg
;
import
jadx.core.dex.instructions.args.SSAVar
;
import
jadx.core.dex.instructions.args.VarName
;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.MethodNode
;
...
...
@@ -141,14 +142,7 @@ public class SSATransform extends AbstractVisitor {
PhiListAttr
phiList
=
enterBlock
.
get
(
AType
.
PHI_LIST
);
if
(
phiList
!=
null
)
{
for
(
PhiInsn
phiInsn
:
phiList
.
getList
())
{
int
regNum
=
phiInsn
.
getResult
().
getRegNum
();
SSAVar
var
=
vars
[
regNum
];
if
(
var
==
null
)
{
continue
;
}
RegisterArg
arg
=
phiInsn
.
bindArg
(
enterBlock
);
var
.
use
(
arg
);
var
.
setUsedInPhi
(
phiInsn
);
bindPhiArg
(
vars
,
enterBlock
,
phiInsn
);
}
}
}
...
...
@@ -183,21 +177,25 @@ public class SSATransform extends AbstractVisitor {
continue
;
}
for
(
PhiInsn
phiInsn
:
phiList
.
getList
())
{
bindPhiArg
(
vars
,
block
,
phiInsn
);
}
}
for
(
BlockNode
domOn
:
block
.
getDominatesOn
())
{
renameVar
(
mth
,
vars
,
vers
,
domOn
);
}
System
.
arraycopy
(
inputVars
,
0
,
vars
,
0
,
vars
.
length
);
}
private
static
void
bindPhiArg
(
SSAVar
[]
vars
,
BlockNode
block
,
PhiInsn
phiInsn
)
{
int
regNum
=
phiInsn
.
getResult
().
getRegNum
();
SSAVar
var
=
vars
[
regNum
];
if
(
var
==
null
)
{
continue
;
return
;
}
RegisterArg
arg
=
phiInsn
.
bindArg
(
block
);
var
.
use
(
arg
);
var
.
setUsedInPhi
(
phiInsn
);
}
}
for
(
BlockNode
domOn
:
block
.
getDominatesOn
())
{
renameVar
(
mth
,
vars
,
vers
,
domOn
);
}
System
.
arraycopy
(
inputVars
,
0
,
vars
,
0
,
vars
.
length
);
}
/**
* Fix last try/catch assign instruction
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeInference.java
View file @
cb23b657
package
jadx
.
core
.
dex
.
visitors
.
typeinference
;
import
java.util.List
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.nodes.PhiListAttr
;
import
jadx.core.dex.instructions.PhiInsn
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.dex.instructions.args.InsnArg
;
import
jadx.core.dex.instructions.args.RegisterArg
;
import
jadx.core.dex.instructions.args.SSAVar
;
import
jadx.core.dex.instructions.args.VarName
;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.DexNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.visitors.AbstractVisitor
;
import
jadx.core.utils.exceptions.JadxException
;
import
java.util.List
;
public
class
TypeInference
extends
AbstractVisitor
{
@Override
...
...
@@ -19,6 +23,8 @@ public class TypeInference extends AbstractVisitor {
if
(
mth
.
isNoCode
())
{
return
;
}
fixPhiVarNames
(
mth
);
DexNode
dex
=
mth
.
dex
();
for
(
SSAVar
var
:
mth
.
getSVars
())
{
// inference variable type
...
...
@@ -80,6 +86,32 @@ public class TypeInference extends AbstractVisitor {
}
}
private
static
void
fixPhiVarNames
(
MethodNode
mth
)
{
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
PhiListAttr
phiList
=
block
.
get
(
AType
.
PHI_LIST
);
if
(
phiList
==
null
)
{
continue
;
}
for
(
PhiInsn
phiInsn
:
phiList
.
getList
())
{
RegisterArg
resArg
=
phiInsn
.
getResult
();
int
argsCount
=
phiInsn
.
getArgsCount
();
for
(
int
i
=
0
;
i
<
argsCount
;
i
++)
{
RegisterArg
arg
=
phiInsn
.
getArg
(
i
);
arg
.
mergeName
(
resArg
);
}
VarName
varName
=
resArg
.
getSVar
().
getVarName
();
if
(
varName
==
null
)
{
varName
=
new
VarName
();
resArg
.
getSVar
().
setVarName
(
varName
);
}
for
(
int
i
=
0
;
i
<
argsCount
;
i
++)
{
RegisterArg
arg
=
phiInsn
.
getArg
(
i
);
arg
.
getSVar
().
setVarName
(
varName
);
}
}
}
}
private
static
String
processVarName
(
SSAVar
var
)
{
String
name
=
var
.
getAssign
().
getName
();
if
(
name
!=
null
)
{
...
...
jadx-core/src/test/java/jadx/tests/integration/conditions/TestConditions10.java
View file @
cb23b657
...
...
@@ -14,7 +14,7 @@ public class TestConditions10 extends IntegrationTest {
public
static
class
TestCls
{
public
void
test
(
boolean
a
,
int
b
)
throws
Exception
{
public
void
test
(
boolean
a
,
int
b
)
{
if
(
a
||
b
>
2
)
{
b
++;
}
...
...
jadx-core/src/test/java/jadx/tests/integration/debuginfo/TestVariablesNames.java
0 → 100644
View file @
cb23b657
package
jadx
.
tests
.
integration
.
debuginfo
;
import
org.junit.Test
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.IntegrationTest
;
import
jadx.tests.api.SmaliTest
;
import
static
jadx
.
tests
.
api
.
utils
.
JadxMatchers
.
containsLines
;
import
static
jadx
.
tests
.
api
.
utils
.
JadxMatchers
.
containsOne
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
TestVariablesNames
extends
SmaliTest
{
/*
public static class TestCls {
public void test(String s, int k) {
f1(s);
int i = k + 3;
String s2 = "i" + i;
f2(i, s2);
double d = i * 5;
String s3 = "d" + d;
f3(d, s3);
}
private void f1(String s) {
}
private void f2(int i, String i2) {
}
private void f3(double d, String d2) {
}
}
*/
/**
* Parameter register reused in variables assign with different types and names
* No variables names in debug info
*/
@Test
public
void
test
()
{
ClassNode
cls
=
getClassNodeFromSmaliWithPath
(
"debuginfo"
,
"TestVariablesNames"
);
String
code
=
cls
.
getCode
().
toString
();
// TODO: don't use current variables naming in tests
assertThat
(
code
,
containsOne
(
"f1(str);"
));
assertThat
(
code
,
containsOne
(
"f2(i2, \"i\" + i2);"
));
assertThat
(
code
,
containsOne
(
"f3(d, \"d\" + d);"
));
}
}
jadx-core/src/test/java/jadx/tests/integration/trycatch/TestTryCatch7.java
View file @
cb23b657
...
...
@@ -29,10 +29,11 @@ public class TestTryCatch7 extends IntegrationTest {
ClassNode
cls
=
getClassNode
(
TestCls
.
class
);
String
code
=
cls
.
getCode
().
toString
();
String
excVarName
=
"exception"
;
String
excVarName
=
"e"
;
String
catchExcVarName
=
"e2"
;
assertThat
(
code
,
containsOne
(
"Exception "
+
excVarName
+
" = new Exception();"
));
assertThat
(
code
,
containsOne
(
"} catch (Exception
e
) {"
));
assertThat
(
code
,
containsOne
(
excVarName
+
" =
e
;"
));
assertThat
(
code
,
containsOne
(
"} catch (Exception
"
+
catchExcVarName
+
"
) {"
));
assertThat
(
code
,
containsOne
(
excVarName
+
" =
"
+
catchExcVarName
+
"
;"
));
assertThat
(
code
,
containsOne
(
excVarName
+
".printStackTrace();"
));
assertThat
(
code
,
containsOne
(
"return "
+
excVarName
+
";"
));
}
...
...
jadx-core/src/test/smali/debuginfo/TestVariablesNames.smali
0 → 100644
View file @
cb23b657
.class public LTestVariablesNames;
.super Ljava/lang/Object;
.source "TestVariablesNames.java"
.method public test(Ljava/lang/String;I)V
.registers 10
.prologue
.line 17
invoke-direct {p0, p1}, LTestVariablesNames;->f1(Ljava/lang/String;)V
.line 18
add-int/lit8 p1, p2, 0x3
.line 19
new-instance v5, Ljava/lang/StringBuilder;
invoke-direct {v5}, Ljava/lang/StringBuilder;-><init>()V
const-string v6, "i"
invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v5
invoke-virtual {v5, p1}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
move-result-object v5
invoke-virtual {v5}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v3
.line 20
invoke-direct {p0, p1, v3}, LTestVariablesNames;->f2(ILjava/lang/String;)V
.line 21
mul-int/lit8 v5, p1, 0x5
int-to-double p1, v5
.line 22
new-instance v5, Ljava/lang/StringBuilder;
invoke-direct {v5}, Ljava/lang/StringBuilder;-><init>()V
const-string v6, "d"
invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v5
invoke-virtual {v5, p1, v1}, Ljava/lang/StringBuilder;->append(D)Ljava/lang/StringBuilder;
move-result-object v5
invoke-virtual {v5}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v4
.line 23
invoke-direct {p0, p1, v1, v4}, LTestVariablesNames;->f3(DLjava/lang/String;)V
.line 24
return-void
.end method
.method public constructor <init>()V
.registers 1
.prologue
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
.method private f1(Ljava/lang/String;)V
.registers 2
.prologue
return-void
.end method
.method private f2(ILjava/lang/String;)V
.registers 3
.prologue
return-void
.end method
.method private f3(DLjava/lang/String;)V
.registers 4
.prologue
return-void
.end method
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment