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
7277ebb9
Commit
7277ebb9
authored
Nov 04, 2014
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: expand arrays for vararg arguments
parent
c18074f6
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
72 additions
and
34 deletions
+72
-34
InsnGen.java
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
+62
-27
DexNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/DexNode.java
+5
-0
TestInvokeInCatch.java
...java/jadx/tests/integration/invoke/TestInvokeInCatch.java
+1
-2
TestVarArg.java
...c/test/java/jadx/tests/integration/invoke/TestVarArg.java
+4
-5
No files found.
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
View file @
7277ebb9
...
...
@@ -49,6 +49,7 @@ import java.util.List;
import
java.util.Map
;
import
java.util.Set
;
import
org.jetbrains.annotations.Nullable
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -513,6 +514,13 @@ public class InsnGen {
}
private
void
fillArray
(
FillArrayNode
insn
,
CodeWriter
code
)
throws
CodegenException
{
String
filledArray
=
makeArrayElements
(
insn
);
code
.
add
(
"new "
);
useType
(
code
,
insn
.
getElementType
());
code
.
add
(
"[]{"
).
add
(
filledArray
).
add
(
'}'
);
}
private
String
makeArrayElements
(
FillArrayNode
insn
)
throws
CodegenException
{
ArgType
insnArrayType
=
insn
.
getResult
().
getType
();
ArgType
insnElementType
=
insnArrayType
.
getArrayElement
();
ArgType
elType
=
insn
.
getElementType
();
...
...
@@ -526,6 +534,8 @@ public class InsnGen {
LOG
.
warn
(
"Unknown array element type: {} in mth: {}"
,
elType
,
mth
);
elType
=
insnElementType
.
isTypeKnown
()
?
insnElementType
:
elType
.
selectFirst
();
}
insn
.
mergeElementType
(
elType
);
StringBuilder
str
=
new
StringBuilder
();
Object
data
=
insn
.
getData
();
switch
(
elType
.
getPrimitiveType
())
{
...
...
@@ -567,9 +577,7 @@ public class InsnGen {
}
int
len
=
str
.
length
();
str
.
delete
(
len
-
2
,
len
);
code
.
add
(
"new "
);
useType
(
code
,
elType
);
code
.
add
(
"[]{"
).
add
(
str
.
toString
()).
add
(
'}'
);
return
str
.
toString
();
}
private
void
makeConstructor
(
ConstructorInsn
insn
,
CodeWriter
code
)
...
...
@@ -613,7 +621,7 @@ public class InsnGen {
code
.
add
(
"new "
);
useClass
(
code
,
insn
.
getClassType
());
}
generateArguments
(
code
,
insn
,
0
,
mth
.
dex
().
resolveMethod
(
insn
.
getCallMth
()));
generate
Method
Arguments
(
code
,
insn
,
0
,
mth
.
dex
().
resolveMethod
(
insn
.
getCallMth
()));
}
private
void
makeInvoke
(
InvokeNode
insn
,
CodeWriter
code
)
throws
CodegenException
{
...
...
@@ -658,47 +666,74 @@ public class InsnGen {
code
.
attachAnnotation
(
callMthNode
);
}
code
.
add
(
callMth
.
getName
());
generateArguments
(
code
,
insn
,
k
,
callMthNode
);
generate
Method
Arguments
(
code
,
insn
,
k
,
callMthNode
);
}
private
void
generateArguments
(
CodeWriter
code
,
InsnNode
insn
,
int
k
,
MethodNode
callMth
)
throws
CodegenException
{
private
void
generateMethodArguments
(
CodeWriter
code
,
InsnNode
insn
,
int
startArgNum
,
@Nullable
MethodNode
callMth
)
throws
CodegenException
{
int
k
=
startArgNum
;
if
(
callMth
!=
null
&&
callMth
.
contains
(
AFlag
.
SKIP_FIRST_ARG
))
{
k
++;
}
int
argsCount
=
insn
.
getArgsCount
();
if
(
callMth
!=
null
&&
callMth
.
isArgsOverload
())
{
// add additional argument casts for overloaded methods
List
<
ArgType
>
originalType
=
callMth
.
getMethodInfo
().
getArgumentsTypes
();
int
origPos
=
0
;
code
.
add
(
'('
);
code
.
add
(
'('
);
if
(
k
<
argsCount
)
{
boolean
overloaded
=
callMth
!=
null
&&
callMth
.
isArgsOverload
();
for
(
int
i
=
k
;
i
<
argsCount
;
i
++)
{
InsnArg
arg
=
insn
.
getArg
(
i
);
ArgType
origType
=
originalType
.
get
(
origPos
);
if
(!
arg
.
getType
().
equals
(
origType
))
{
code
.
add
(
'('
);
useType
(
code
,
origType
);
code
.
add
(
") "
);
addArg
(
code
,
arg
,
true
);
}
else
{
addArg
(
code
,
arg
,
false
);
boolean
cast
=
overloaded
&&
processOverloadedArg
(
code
,
callMth
,
arg
,
i
-
startArgNum
);
if
(!
cast
&&
i
==
argsCount
-
1
&&
processVarArg
(
code
,
callMth
,
arg
))
{
continue
;
}
addArg
(
code
,
arg
,
false
);
if
(
i
<
argsCount
-
1
)
{
code
.
add
(
", "
);
}
origPos
++;
}
code
.
add
(
')'
);
}
else
{
}
code
.
add
(
')'
);
}
/**
* Add additional cast for overloaded method argument.
*/
private
boolean
processOverloadedArg
(
CodeWriter
code
,
MethodNode
callMth
,
InsnArg
arg
,
int
origPos
)
{
ArgType
origType
=
callMth
.
getMethodInfo
().
getArgumentsTypes
().
get
(
origPos
);
if
(!
arg
.
getType
().
equals
(
origType
))
{
code
.
add
(
'('
);
if
(
k
<
argsCount
)
{
addArg
(
code
,
insn
.
getArg
(
k
),
false
);
for
(
int
i
=
k
+
1
;
i
<
argsCount
;
i
++)
{
useType
(
code
,
origType
);
code
.
add
(
") "
);
return
true
;
}
return
false
;
}
/**
* Expand varArgs from filled array.
*/
private
boolean
processVarArg
(
CodeWriter
code
,
MethodNode
callMth
,
InsnArg
lastArg
)
throws
CodegenException
{
if
(
callMth
==
null
||
!
callMth
.
getAccessFlags
().
isVarArgs
())
{
return
false
;
}
if
(!
lastArg
.
getType
().
isArray
()
||
!
lastArg
.
isInsnWrap
())
{
return
false
;
}
InsnNode
insn
=
((
InsnWrapArg
)
lastArg
).
getWrapInsn
();
if
(
insn
.
getType
()
==
InsnType
.
FILLED_NEW_ARRAY
)
{
int
count
=
insn
.
getArgsCount
();
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
InsnArg
elemArg
=
insn
.
getArg
(
i
);
addArg
(
code
,
elemArg
,
false
);
if
(
i
<
count
-
1
)
{
code
.
add
(
", "
);
addArg
(
code
,
insn
.
getArg
(
i
),
false
);
}
}
code
.
add
(
')'
);
return
true
;
}
else
if
(
insn
.
getType
()
==
InsnType
.
FILL_ARRAY
)
{
code
.
add
(
makeArrayElements
((
FillArrayNode
)
insn
));
return
true
;
}
return
false
;
}
private
boolean
inlineMethod
(
MethodNode
callMthNode
,
InvokeNode
insn
,
CodeWriter
code
)
throws
CodegenException
{
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/DexNode.java
View file @
7277ebb9
...
...
@@ -13,6 +13,8 @@ import java.util.HashMap;
import
java.util.List
;
import
java.util.Map
;
import
org.jetbrains.annotations.Nullable
;
import
com.android.dex.ClassData
;
import
com.android.dex.ClassData.Method
;
import
com.android.dex.ClassDef
;
...
...
@@ -49,10 +51,12 @@ public class DexNode {
return
classes
;
}
@Nullable
public
ClassNode
resolveClass
(
ClassInfo
clsInfo
)
{
return
root
.
resolveClass
(
clsInfo
);
}
@Nullable
public
MethodNode
resolveMethod
(
MethodInfo
mth
)
{
ClassNode
cls
=
resolveClass
(
mth
.
getDeclClass
());
if
(
cls
!=
null
)
{
...
...
@@ -61,6 +65,7 @@ public class DexNode {
return
null
;
}
@Nullable
public
FieldNode
resolveField
(
FieldInfo
field
)
{
ClassNode
cls
=
resolveClass
(
field
.
getDeclClass
());
if
(
cls
!=
null
)
{
...
...
jadx-core/src/test/java/jadx/tests/integration/invoke/TestInvokeInCatch.java
View file @
7277ebb9
...
...
@@ -45,7 +45,6 @@ public class TestInvokeInCatch extends IntegrationTest {
assertThat
(
code
,
not
(
containsString
(
"return;"
)));
assertThat
(
code
,
containsOne
(
"} catch (IOException e) {"
));
assertThat
(
code
,
containsOne
(
"if (b == 1) {"
));
// assertThat(code, containsOne("log(TAG, \"Error: {}\", e.getMessage());"));
assertThat
(
code
,
containsOne
(
"log(TAG, \"Error: {}\", new String[]{e.getMessage()});"
));
assertThat
(
code
,
containsOne
(
"log(TAG, \"Error: {}\", e.getMessage());"
));
}
}
jadx-core/src/test/java/jadx/tests/integration/
annotations/TestVarArgAnnotation
.java
→
jadx-core/src/test/java/jadx/tests/integration/
invoke/TestVarArg
.java
View file @
7277ebb9
package
jadx
.
tests
.
integration
.
annotations
;
package
jadx
.
tests
.
integration
.
invoke
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.IntegrationTest
;
...
...
@@ -8,7 +8,7 @@ import org.junit.Test;
import
static
org
.
hamcrest
.
CoreMatchers
.
containsString
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
TestVarArg
Annotation
extends
IntegrationTest
{
public
class
TestVarArg
extends
IntegrationTest
{
public
static
class
TestCls
{
...
...
@@ -36,9 +36,8 @@ public class TestVarArgAnnotation extends IntegrationTest {
assertThat
(
code
,
containsString
(
"void test1(int... a) {"
));
assertThat
(
code
,
containsString
(
"void test2(int i, Object... a) {"
));
// TODO:
assertThat
(
code
,
containsString
(
"test1(new int[]{1, 2});"
));
assertThat
(
code
,
containsString
(
"test2(3, new Object[]{\"1\", Integer.valueOf(7)});"
));
assertThat
(
code
,
containsString
(
"test1(1, 2);"
));
assertThat
(
code
,
containsString
(
"test2(3, \"1\", Integer.valueOf(7));"
));
// negative case
assertThat
(
code
,
containsString
(
"void test3(int[] a) {"
));
...
...
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