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
c552fb85
Commit
c552fb85
authored
Oct 01, 2014
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core tests: replace several classes in dynamic class loader, add additional checks
parent
8a4ec47b
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
139 additions
and
36 deletions
+139
-36
IntegrationTest.java
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
+64
-9
ClassFileManager.java
...c/test/java/jadx/tests/api/compiler/ClassFileManager.java
+48
-9
DynamicCompiler.java
...rc/test/java/jadx/tests/api/compiler/DynamicCompiler.java
+20
-8
TestSwitchOverEnum.java
...java/jadx/tests/integration/enums/TestSwitchOverEnum.java
+6
-8
TestBreakWithLabel.java
...java/jadx/tests/integration/loops/TestBreakWithLabel.java
+1
-2
No files found.
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
View file @
c552fb85
...
...
@@ -18,7 +18,9 @@ import jadx.tests.api.utils.TestUtils;
import
java.io.File
;
import
java.io.FileOutputStream
;
import
java.io.IOException
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Modifier
;
import
java.net.URISyntaxException
;
import
java.net.URL
;
import
java.util.ArrayList
;
...
...
@@ -71,8 +73,11 @@ public abstract class IntegrationTest extends TestUtils {
}
// don't unload class
System
.
out
.
println
(
cls
.
getCode
());
checkCode
(
cls
);
compile
(
cls
);
runAutoCheck
(
clsName
);
return
cls
;
}
...
...
@@ -102,9 +107,65 @@ public abstract class IntegrationTest extends TestUtils {
public
boolean
isFallbackMode
()
{
return
isFallback
;
}
@Override
public
boolean
isShowInconsistentCode
()
{
return
true
;
}
},
new
File
(
outDir
));
}
private
void
runAutoCheck
(
String
clsName
)
{
try
{
// run 'check' method from original class
Class
<?>
origCls
;
try
{
origCls
=
Class
.
forName
(
clsName
);
}
catch
(
ClassNotFoundException
e
)
{
// ignore
return
;
}
Method
checkMth
;
try
{
checkMth
=
origCls
.
getMethod
(
"check"
);
}
catch
(
NoSuchMethodException
e
)
{
// ignore
return
;
}
if
(!
checkMth
.
getReturnType
().
equals
(
void
.
class
)
||
!
Modifier
.
isPublic
(
checkMth
.
getModifiers
())
||
Modifier
.
isStatic
(
checkMth
.
getModifiers
()))
{
fail
(
"Wrong 'check' method"
);
return
;
}
try
{
checkMth
.
invoke
(
origCls
.
newInstance
());
}
catch
(
InvocationTargetException
ie
)
{
rethrow
(
"Java check failed"
,
ie
);
}
// run 'check' method from decompiled class
try
{
invoke
(
"check"
);
}
catch
(
InvocationTargetException
ie
)
{
rethrow
(
"Decompiled check failed"
,
ie
);
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
fail
(
"Auto check exception: "
+
e
.
getMessage
());
}
}
private
void
rethrow
(
String
msg
,
InvocationTargetException
ie
)
{
Throwable
cause
=
ie
.
getCause
();
if
(
cause
instanceof
AssertionError
)
{
System
.
err
.
println
(
msg
);
throw
((
AssertionError
)
cause
);
}
else
{
cause
.
printStackTrace
();
fail
(
msg
+
cause
.
getMessage
());
}
}
protected
MethodNode
getMethod
(
ClassNode
cls
,
String
method
)
{
for
(
MethodNode
mth
:
cls
.
getMethods
())
{
if
(
mth
.
getName
().
equals
(
method
))
{
...
...
@@ -133,7 +194,7 @@ public abstract class IntegrationTest extends TestUtils {
return
invoke
(
method
,
new
Class
[
0
]);
}
public
Object
invoke
(
String
method
,
Class
[]
types
,
Object
...
args
)
{
public
Object
invoke
(
String
method
,
Class
[]
types
,
Object
...
args
)
throws
Exception
{
Method
mth
=
getReflectMethod
(
method
,
types
);
return
invoke
(
mth
,
args
);
}
...
...
@@ -149,16 +210,10 @@ public abstract class IntegrationTest extends TestUtils {
return
null
;
}
public
Object
invoke
(
Method
mth
,
Object
...
args
)
{
public
Object
invoke
(
Method
mth
,
Object
...
args
)
throws
Exception
{
assertNotNull
(
"dynamicCompiler not ready"
,
dynamicCompiler
);
assertNotNull
(
"unknown method"
,
mth
);
try
{
return
dynamicCompiler
.
invoke
(
mth
,
args
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
fail
(
e
.
getMessage
());
}
return
null
;
return
dynamicCompiler
.
invoke
(
mth
,
args
);
}
public
File
getJarForClass
(
Class
<?>
cls
)
throws
IOException
{
...
...
jadx-core/src/test/java/jadx/tests/api/compiler/ClassFileManager.java
View file @
c552fb85
...
...
@@ -6,32 +6,71 @@ import javax.tools.JavaFileObject;
import
javax.tools.StandardJavaFileManager
;
import
java.io.IOException
;
import
java.security.SecureClassLoader
;
import
java.util.HashMap
;
import
java.util.Map
;
import
static
javax
.
tools
.
JavaFileObject
.
Kind
;
public
class
ClassFileManager
extends
ForwardingJavaFileManager
<
StandardJavaFileManager
>
{
private
JavaClassObject
jClsObject
;
private
DynamicClassLoader
classLoader
;
public
ClassFileManager
(
StandardJavaFileManager
standardManager
)
{
super
(
standardManager
);
classLoader
=
new
DynamicClassLoader
();
}
@Override
public
JavaFileObject
getJavaFileForOutput
(
Location
location
,
String
className
,
Kind
kind
,
FileObject
sibling
)
throws
IOException
{
jClsObject
=
new
JavaClassObject
(
className
,
kind
);
return
jClsObject
;
JavaClassObject
clsObject
=
new
JavaClassObject
(
className
,
kind
);
classLoader
.
getClsMap
().
put
(
className
,
clsObject
);
return
clsObject
;
}
@Override
public
ClassLoader
getClassLoader
(
Location
location
)
{
return
new
SecureClassLoader
()
{
@Override
protected
Class
<?>
findClass
(
String
name
)
throws
ClassNotFoundException
{
byte
[]
clsBytes
=
jClsObject
.
getBytes
();
return
super
.
defineClass
(
name
,
clsBytes
,
0
,
clsBytes
.
length
);
return
classLoader
;
}
private
class
DynamicClassLoader
extends
SecureClassLoader
{
private
final
Map
<
String
,
JavaClassObject
>
clsMap
=
new
HashMap
<
String
,
JavaClassObject
>();
private
final
Map
<
String
,
Class
>
clsCache
=
new
HashMap
<
String
,
Class
>();
@Override
protected
Class
<?>
findClass
(
String
name
)
throws
ClassNotFoundException
{
Class
<?>
cls
=
replaceClass
(
name
);
if
(
cls
!=
null
)
{
return
cls
;
}
return
super
.
findClass
(
name
);
}
public
Class
<?>
loadClass
(
String
name
)
throws
ClassNotFoundException
{
Class
<?>
cls
=
replaceClass
(
name
);
if
(
cls
!=
null
)
{
return
cls
;
}
};
return
super
.
loadClass
(
name
);
}
public
Class
<?>
replaceClass
(
String
name
)
throws
ClassNotFoundException
{
Class
cacheCls
=
clsCache
.
get
(
name
);
if
(
cacheCls
!=
null
)
{
return
cacheCls
;
}
JavaClassObject
clsObject
=
clsMap
.
get
(
name
);
if
(
clsObject
==
null
)
{
return
null
;
}
byte
[]
clsBytes
=
clsObject
.
getBytes
();
Class
<?>
cls
=
super
.
defineClass
(
name
,
clsBytes
,
0
,
clsBytes
.
length
);
clsCache
.
put
(
name
,
cls
);
return
cls
;
}
public
Map
<
String
,
JavaClassObject
>
getClsMap
()
{
return
clsMap
;
}
}
}
jadx-core/src/test/java/jadx/tests/api/compiler/DynamicCompiler.java
View file @
c552fb85
...
...
@@ -38,9 +38,13 @@ public class DynamicCompiler {
return
Boolean
.
TRUE
.
equals
(
compilerTask
.
call
());
}
private
ClassLoader
getClassLoader
()
{
return
fileManager
.
getClassLoader
(
null
);
}
private
void
makeInstance
()
throws
Exception
{
String
fullName
=
clsNode
.
getFullName
();
instance
=
fileManager
.
getClassLoader
(
null
).
loadClass
(
fullName
).
newInstance
();
instance
=
getClassLoader
(
).
loadClass
(
fullName
).
newInstance
();
if
(
instance
==
null
)
{
throw
new
NullPointerException
(
"Instantiation failed"
);
}
...
...
@@ -54,6 +58,9 @@ public class DynamicCompiler {
}
public
Method
getMethod
(
String
method
,
Class
[]
types
)
throws
Exception
{
for
(
Class
type
:
types
)
{
checkType
(
type
);
}
return
getInstance
().
getClass
().
getMethod
(
method
,
types
);
}
...
...
@@ -61,12 +68,17 @@ public class DynamicCompiler {
return
mth
.
invoke
(
getInstance
(),
args
);
}
public
Object
invoke
(
String
method
)
throws
Exception
{
return
invoke
(
method
,
new
Class
[
0
]);
}
public
Object
invoke
(
String
method
,
Class
[]
types
,
Object
...
args
)
throws
Exception
{
Method
mth
=
getMethod
(
method
,
types
);
return
invoke
(
mth
,
args
);
private
Class
<?>
checkType
(
Class
type
)
throws
ClassNotFoundException
{
if
(
type
.
isPrimitive
())
{
return
type
;
}
if
(
type
.
isArray
())
{
return
checkType
(
type
.
getComponentType
());
}
Class
<?>
decompiledCls
=
getClassLoader
().
loadClass
(
type
.
getName
());
if
(
type
!=
decompiledCls
)
{
throw
new
IllegalArgumentException
(
"Internal test class cannot be used in method invoke"
);
}
return
decompiledCls
;
}
}
jadx-core/src/test/java/jadx/tests/integration/enums/TestSwitchOverEnum.java
View file @
c552fb85
...
...
@@ -3,8 +3,6 @@ package jadx.tests.integration.enums;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.IntegrationTest
;
import
java.lang.reflect.Method
;
import
org.junit.Test
;
import
static
jadx
.
tests
.
api
.
utils
.
JadxMatchers
.
countString
;
...
...
@@ -27,19 +25,19 @@ public class TestSwitchOverEnum extends IntegrationTest {
return
0
;
}
public
void
check
()
{
assertEquals
(
1
,
testEnum
(
Count
.
ONE
));
assertEquals
(
2
,
testEnum
(
Count
.
TWO
));
assertEquals
(
0
,
testEnum
(
Count
.
THREE
));
}
@Test
public
void
test
()
{
ClassNode
cls
=
getClassNode
(
TestSwitchOverEnum
.
class
);
String
code
=
cls
.
getCode
().
toString
();
System
.
out
.
println
(
code
);
assertThat
(
code
,
countString
(
1
,
"synthetic"
));
assertThat
(
code
,
countString
(
2
,
"switch (c) {"
));
assertThat
(
code
,
countString
(
2
,
"case ONE:"
));
Method
mth
=
getReflectMethod
(
"testEnum"
,
Count
.
class
);
assertEquals
(
1
,
invoke
(
mth
,
Count
.
ONE
));
assertEquals
(
2
,
invoke
(
mth
,
Count
.
TWO
));
assertEquals
(
0
,
invoke
(
mth
,
Count
.
THREE
));
}
}
jadx-core/src/test/java/jadx/tests/integration/loops/TestBreakWithLabel.java
View file @
c552fb85
...
...
@@ -33,10 +33,9 @@ public class TestBreakWithLabel extends IntegrationTest {
}
@Test
public
void
test
()
{
public
void
test
()
throws
Exception
{
ClassNode
cls
=
getClassNode
(
TestCls
.
class
);
String
code
=
cls
.
getCode
().
toString
();
System
.
out
.
println
(
code
);
assertThat
(
code
,
containsOne
(
"loop0:"
));
assertThat
(
code
,
containsOne
(
"break loop0;"
));
...
...
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