Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
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
96e3e887
Commit
96e3e887
authored
Apr 21, 2013
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Inline 'access' synthetic methods
parent
87794d25
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
231 additions
and
3 deletions
+231
-3
Main.java
src/main/java/jadx/Main.java
+2
-0
ClassGen.java
src/main/java/jadx/codegen/ClassGen.java
+3
-0
InsnGen.java
src/main/java/jadx/codegen/InsnGen.java
+59
-1
AttributeType.java
src/main/java/jadx/dex/attributes/AttributeType.java
+1
-0
MethodInlineAttr.java
src/main/java/jadx/dex/attributes/MethodInlineAttr.java
+26
-0
MethodInfo.java
src/main/java/jadx/dex/info/MethodInfo.java
+22
-0
InsnType.java
src/main/java/jadx/dex/instructions/InsnType.java
+3
-0
ClassNode.java
src/main/java/jadx/dex/nodes/ClassNode.java
+10
-2
DexNode.java
src/main/java/jadx/dex/nodes/DexNode.java
+9
-0
MethodInlinerVisitor.java
src/main/java/jadx/dex/visitors/MethodInlinerVisitor.java
+55
-0
TestInner2.java
src/samples/java/jadx/samples/TestInner2.java
+41
-0
No files found.
src/main/java/jadx/Main.java
View file @
96e3e887
...
...
@@ -12,6 +12,7 @@ import jadx.dex.visitors.DotGraphVisitor;
import
jadx.dex.visitors.EnumVisitor
;
import
jadx.dex.visitors.FallbackModeVisitor
;
import
jadx.dex.visitors.IDexTreeVisitor
;
import
jadx.dex.visitors.MethodInlinerVisitor
;
import
jadx.dex.visitors.ModVisitor
;
import
jadx.dex.visitors.regions.CheckRegions
;
import
jadx.dex.visitors.regions.CleanRegions
;
...
...
@@ -113,6 +114,7 @@ public class Main {
if
(
args
.
isCFGOutput
())
passes
.
add
(
new
DotGraphVisitor
(
args
.
getOutDir
(),
true
));
passes
.
add
(
new
MethodInlinerVisitor
());
passes
.
add
(
new
ClassModifier
());
passes
.
add
(
new
CleanRegions
());
}
...
...
src/main/java/jadx/codegen/ClassGen.java
View file @
96e3e887
...
...
@@ -194,6 +194,9 @@ public class ClassGen {
CodeWriter
code
=
new
CodeWriter
(
clsCode
.
getIndent
()
+
1
);
for
(
Iterator
<
MethodNode
>
it
=
mthList
.
iterator
();
it
.
hasNext
();)
{
MethodNode
mth
=
it
.
next
();
if
(
mth
.
getAttributes
().
contains
(
AttributeFlag
.
DONT_GENERATE
))
continue
;
try
{
if
(
mth
.
getAccessFlags
().
isAbstract
()
||
mth
.
getAccessFlags
().
isNative
())
{
MethodGen
mthGen
=
new
MethodGen
(
this
,
mth
);
...
...
src/main/java/jadx/codegen/InsnGen.java
View file @
96e3e887
package
jadx
.
codegen
;
import
jadx.dex.attributes.AttributeType
;
import
jadx.dex.attributes.IAttribute
;
import
jadx.dex.attributes.MethodInlineAttr
;
import
jadx.dex.info.ClassInfo
;
import
jadx.dex.info.FieldInfo
;
import
jadx.dex.info.MethodInfo
;
...
...
@@ -27,7 +29,12 @@ import jadx.dex.nodes.RootNode;
import
jadx.utils.StringUtils
;
import
jadx.utils.exceptions.CodegenException
;
import
java.util.ArrayList
;
import
java.util.EnumSet
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map.Entry
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -324,6 +331,10 @@ public class InsnGen {
case
TERNARY:
break
;
case
ARGS:
code
.
add
(
arg
(
insn
.
getArg
(
0
)));
break
;
/* fallback mode instructions */
case
NOP:
state
.
add
(
InsnGenState
.
SKIP
);
...
...
@@ -462,6 +473,14 @@ public class InsnGen {
private
void
makeInvoke
(
InvokeNode
insn
,
CodeWriter
code
)
throws
CodegenException
{
MethodInfo
callMth
=
insn
.
getCallMth
();
// inline method if METHOD_INLINE attribute is attached
MethodNode
callMthNode
=
mth
.
dex
().
resolveMethod
(
callMth
);
if
(
callMthNode
!=
null
&&
callMthNode
.
getAttributes
().
contains
(
AttributeType
.
METHOD_INLINE
))
{
inlineMethod
(
callMthNode
,
insn
,
code
);
return
;
}
int
k
=
0
;
InvokeType
type
=
insn
.
getInvokeType
();
switch
(
type
)
{
...
...
@@ -488,6 +507,45 @@ public class InsnGen {
addArgs
(
code
,
insn
,
k
);
}
private
void
inlineMethod
(
MethodNode
callMthNode
,
InvokeNode
insn
,
CodeWriter
code
)
throws
CodegenException
{
IAttribute
mia
=
callMthNode
.
getAttributes
().
get
(
AttributeType
.
METHOD_INLINE
);
InsnNode
inl
=
((
MethodInlineAttr
)
mia
).
getInsn
();
if
(
callMthNode
.
getMethodInfo
().
getArgumentsTypes
().
isEmpty
())
{
makeInsn
(
inl
,
code
,
true
);
}
else
{
// remap args
InsnArg
[]
regs
=
new
InsnArg
[
callMthNode
.
getRegsCount
()];
List
<
RegisterArg
>
callArgs
=
callMthNode
.
getArguments
(
true
);
for
(
int
i
=
0
;
i
<
callArgs
.
size
();
i
++)
{
InsnArg
arg
=
insn
.
getArg
(
i
);
RegisterArg
callArg
=
callArgs
.
get
(
i
);
regs
[
callArg
.
getRegNum
()]
=
arg
;
}
// replace args
List
<
RegisterArg
>
inlArgs
=
new
ArrayList
<
RegisterArg
>();
inl
.
getRegisterArgs
(
inlArgs
);
Map
<
RegisterArg
,
InsnArg
>
toRevert
=
new
HashMap
<
RegisterArg
,
InsnArg
>();
for
(
RegisterArg
r
:
inlArgs
)
{
if
(
r
.
getRegNum
()
>=
regs
.
length
)
{
LOG
.
warn
(
"Unknown register number {} in method call: {}, {}"
,
r
,
callMthNode
,
mth
);
}
else
{
InsnArg
repl
=
regs
[
r
.
getRegNum
()];
if
(
repl
==
null
)
{
LOG
.
warn
(
"Not passed register {} in method call: {}, {}"
,
r
,
callMthNode
,
mth
);
}
else
{
inl
.
replaceArg
(
r
,
repl
);
toRevert
.
put
(
r
,
repl
);
}
}
}
makeInsn
(
inl
,
code
,
true
);
// revert changes
for
(
Entry
<
RegisterArg
,
InsnArg
>
e
:
toRevert
.
entrySet
())
{
inl
.
replaceArg
(
e
.
getValue
(),
e
.
getKey
());
}
}
}
private
void
addArgs
(
CodeWriter
code
,
InsnNode
insn
,
int
k
)
throws
CodegenException
{
code
.
add
(
'('
);
for
(
int
i
=
k
;
i
<
insn
.
getArgsCount
();
i
++)
{
...
...
@@ -495,7 +553,7 @@ public class InsnGen {
if
(
i
<
insn
.
getArgsCount
()
-
1
)
code
.
add
(
", "
);
}
code
.
add
(
")"
);
code
.
add
(
')'
);
}
private
void
makeArith
(
ArithNode
insn
,
CodeWriter
code
,
EnumSet
<
InsnGenState
>
state
)
throws
CodegenException
{
...
...
src/main/java/jadx/dex/attributes/AttributeType.java
View file @
96e3e887
...
...
@@ -21,6 +21,7 @@ public enum AttributeType {
// methods
JADX_ERROR
(
true
),
METHOD_INLINE
(
true
),
// classes
ENUM_CLASS
(
true
),
...
...
src/main/java/jadx/dex/attributes/MethodInlineAttr.java
0 → 100644
View file @
96e3e887
package
jadx
.
dex
.
attributes
;
import
jadx.dex.nodes.InsnNode
;
public
class
MethodInlineAttr
implements
IAttribute
{
private
final
InsnNode
insn
;
public
MethodInlineAttr
(
InsnNode
insn
)
{
this
.
insn
=
insn
;
}
public
InsnNode
getInsn
()
{
return
insn
;
}
@Override
public
AttributeType
getType
()
{
return
AttributeType
.
METHOD_INLINE
;
}
@Override
public
String
toString
()
{
return
"INLINE: "
+
insn
;
}
}
src/main/java/jadx/dex/info/MethodInfo.java
View file @
96e3e887
...
...
@@ -77,6 +77,28 @@ public final class MethodInfo {
}
@Override
public
int
hashCode
()
{
final
int
prime
=
31
;
int
result
=
1
;
result
=
prime
*
result
+
declClass
.
hashCode
();
result
=
prime
*
result
+
retType
.
hashCode
();
result
=
prime
*
result
+
shortId
.
hashCode
();
return
result
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
)
return
false
;
if
(
getClass
()
!=
obj
.
getClass
())
return
false
;
MethodInfo
other
=
(
MethodInfo
)
obj
;
if
(!
shortId
.
equals
(
other
.
shortId
))
return
false
;
if
(!
retType
.
equals
(
other
.
retType
))
return
false
;
if
(!
declClass
.
equals
(
other
.
declClass
))
return
false
;
return
true
;
}
@Override
public
String
toString
()
{
return
retType
+
" "
+
declClass
.
getFullName
()
+
"."
+
name
+
"("
+
Utils
.
listToString
(
args
)
+
")"
;
...
...
src/main/java/jadx/dex/instructions/InsnType.java
View file @
96e3e887
...
...
@@ -50,6 +50,9 @@ public enum InsnType {
CONSTRUCTOR
,
BREAK
,
CONTINUE
,
TERNARY
,
ARGS
,
// just generate arguments
NEW_MULTIDIM_ARRAY
// TODO: now multidimensional arrays created using Array.newInstance function
}
src/main/java/jadx/dex/nodes/ClassNode.java
View file @
96e3e887
...
...
@@ -239,7 +239,15 @@ public class ClassNode extends AttrNode implements ILoadable {
return
null
;
}
public
MethodNode
searchMethodById
(
String
shortId
)
{
public
MethodNode
searchMethod
(
MethodInfo
mth
)
{
for
(
MethodNode
m
:
methods
)
{
if
(
m
.
getMethodInfo
().
equals
(
mth
))
return
m
;
}
return
null
;
}
public
MethodNode
searchMethodByName
(
String
shortId
)
{
for
(
MethodNode
m
:
methods
)
{
if
(
m
.
getMethodInfo
().
getShortId
().
equals
(
shortId
))
return
m
;
...
...
@@ -248,7 +256,7 @@ public class ClassNode extends AttrNode implements ILoadable {
}
public
MethodNode
searchMethodById
(
int
id
)
{
return
searchMethodBy
Id
(
MethodInfo
.
fromDex
(
dex
,
id
).
getShortId
());
return
searchMethodBy
Name
(
MethodInfo
.
fromDex
(
dex
,
id
).
getShortId
());
}
public
List
<
ClassNode
>
getInnerClasses
()
{
...
...
src/main/java/jadx/dex/nodes/DexNode.java
View file @
96e3e887
package
jadx
.
dex
.
nodes
;
import
jadx.dex.info.ClassInfo
;
import
jadx.dex.info.MethodInfo
;
import
jadx.dex.instructions.args.ArgType
;
import
jadx.utils.exceptions.DecodeException
;
import
jadx.utils.files.InputFile
;
...
...
@@ -51,6 +52,14 @@ public class DexNode {
return
root
.
resolveClass
(
clsInfo
);
}
public
MethodNode
resolveMethod
(
MethodInfo
mth
)
{
ClassNode
cls
=
resolveClass
(
mth
.
getDeclClass
());
if
(
cls
!=
null
)
{
return
cls
.
searchMethod
(
mth
);
}
return
null
;
}
// DexBuffer wrappers
public
String
getString
(
int
index
)
{
...
...
src/main/java/jadx/dex/visitors/MethodInlinerVisitor.java
0 → 100644
View file @
96e3e887
package
jadx
.
dex
.
visitors
;
import
jadx.dex.attributes.AttributeFlag
;
import
jadx.dex.attributes.IAttribute
;
import
jadx.dex.attributes.MethodInlineAttr
;
import
jadx.dex.instructions.InsnType
;
import
jadx.dex.nodes.BlockNode
;
import
jadx.dex.nodes.InsnNode
;
import
jadx.dex.nodes.MethodNode
;
import
jadx.utils.exceptions.JadxException
;
public
class
MethodInlinerVisitor
extends
AbstractVisitor
{
@Override
public
void
visit
(
MethodNode
mth
)
throws
JadxException
{
if
(
mth
.
getAccessFlags
().
isSynthetic
()
&&
mth
.
getAccessFlags
().
isStatic
())
{
if
(
mth
.
getBasicBlocks
().
size
()
==
1
)
{
BlockNode
block
=
mth
.
getBasicBlocks
().
get
(
0
);
// synthetic field getter
if
(
block
.
getInstructions
().
size
()
==
1
)
{
InsnNode
insn
=
block
.
getInstructions
().
get
(
0
);
if
(
insn
.
getType
()
==
InsnType
.
RETURN
)
{
InsnNode
inl
=
new
InsnNode
(
InsnType
.
ARGS
,
1
);
inl
.
addArg
(
insn
.
getArg
(
0
));
addInlineAttr
(
mth
,
inl
);
return
;
}
}
// synthetic field setter
if
(
block
.
getInstructions
().
size
()
==
2
)
{
if
(
block
.
getInstructions
().
get
(
1
).
getType
()
==
InsnType
.
RETURN
)
{
InsnNode
insn
=
block
.
getInstructions
().
get
(
0
);
addInlineAttr
(
mth
,
insn
);
return
;
}
}
// synthetic method invoke
if
(
block
.
getInstructions
().
size
()
==
1
)
{
InsnNode
insn
=
block
.
getInstructions
().
get
(
0
);
addInlineAttr
(
mth
,
insn
);
return
;
}
}
}
}
private
static
void
addInlineAttr
(
MethodNode
mth
,
InsnNode
insn
)
{
IAttribute
attr
=
new
MethodInlineAttr
(
insn
);
mth
.
getAttributes
().
add
(
attr
);
mth
.
getAttributes
().
add
(
AttributeFlag
.
DONT_GENERATE
);
}
}
src/samples/java/jadx/samples/TestInner2.java
0 → 100644
View file @
96e3e887
package
jadx
.
samples
;
public
class
TestInner2
extends
AbstractTest
{
private
String
a
;
public
class
A
{
public
A
()
{
a
=
"a"
;
}
public
String
a
()
{
return
a
;
}
}
private
static
String
b
;
public
static
class
B
{
public
B
()
{
b
=
"b"
;
}
public
String
b
()
{
return
b
;
}
}
@Override
public
boolean
testRun
()
throws
Exception
{
assertTrue
((
new
A
()).
a
().
equals
(
"a"
));
assertTrue
(
a
.
equals
(
"a"
));
assertTrue
((
new
B
()).
b
().
equals
(
"b"
));
assertTrue
(
b
.
equals
(
"b"
));
return
true
;
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
new
TestInner2
().
testRun
();
}
}
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