Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
keyescgm
jadx
提交
558a8673
J
jadx
项目概览
keyescgm
/
jadx
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jadx
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
558a8673
编写于
8月 05, 2020
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix: bring back smali files support (#961)
上级
bfd60b73
变更
28
隐藏空白更改
内联
并排
Showing
28 changed file
with
334 addition
and
75 deletion
+334
-75
.gitignore
.gitignore
+1
-0
build.gradle
build.gradle
+1
-1
jadx-cli/build.gradle
jadx-cli/build.gradle
+1
-0
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
+10
-5
jadx-cli/src/test/java/jadx/cli/TestInput.java
jadx-cli/src/test/java/jadx/cli/TestInput.java
+68
-0
jadx-cli/src/test/resources/samples/HelloWorld.smali
jadx-cli/src/test/resources/samples/HelloWorld.smali
+26
-0
jadx-cli/src/test/resources/samples/hello.dex
jadx-cli/src/test/resources/samples/hello.dex
+0
-0
jadx-core/build.gradle
jadx-core/build.gradle
+1
-0
jadx-core/src/main/java/jadx/api/JadxArgsValidator.java
jadx-core/src/main/java/jadx/api/JadxArgsValidator.java
+4
-7
jadx-core/src/main/java/jadx/api/JadxDecompiler.java
jadx-core/src/main/java/jadx/api/JadxDecompiler.java
+4
-1
jadx-core/src/main/java/jadx/api/ResourcesLoader.java
jadx-core/src/main/java/jadx/api/ResourcesLoader.java
+12
-8
jadx-core/src/main/java/jadx/core/clsp/ClsSet.java
jadx-core/src/main/java/jadx/core/clsp/ClsSet.java
+1
-1
jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java
+1
-0
jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java
jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java
+1
-1
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
+5
-6
jadx-core/src/test/java/jadx/tests/api/SmaliTest.java
jadx-core/src/test/java/jadx/tests/api/SmaliTest.java
+5
-28
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexFileLoader.java
...t/src/main/java/jadx/plugins/input/dex/DexFileLoader.java
+2
-1
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexInputPlugin.java
.../src/main/java/jadx/plugins/input/dex/DexInputPlugin.java
+11
-1
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexLoadResult.java
...t/src/main/java/jadx/plugins/input/dex/DexLoadResult.java
+18
-0
jadx-plugins/jadx-java-convert/src/main/java/jadx/plugins/input/javaconvert/ConvertResult.java
...in/java/jadx/plugins/input/javaconvert/ConvertResult.java
+4
-2
jadx-plugins/jadx-java-convert/src/main/java/jadx/plugins/input/javaconvert/JavaConvertPlugin.java
...ava/jadx/plugins/input/javaconvert/JavaConvertPlugin.java
+3
-13
jadx-plugins/jadx-plugins-api/src/main/java/jadx/api/plugins/input/data/ILoadResult.java
...rc/main/java/jadx/api/plugins/input/data/ILoadResult.java
+2
-0
jadx-plugins/jadx-plugins-api/src/main/java/jadx/api/plugins/input/data/impl/EmptyLoadResult.java
...ava/jadx/api/plugins/input/data/impl/EmptyLoadResult.java
+5
-0
jadx-plugins/jadx-smali-input/build.gradle
jadx-plugins/jadx-smali-input/build.gradle
+12
-0
jadx-plugins/jadx-smali-input/src/main/java/jadx/plugins/input/smali/SmaliConvert.java
.../src/main/java/jadx/plugins/input/smali/SmaliConvert.java
+107
-0
jadx-plugins/jadx-smali-input/src/main/java/jadx/plugins/input/smali/SmaliInputPlugin.java
.../main/java/jadx/plugins/input/smali/SmaliInputPlugin.java
+27
-0
jadx-plugins/jadx-smali-input/src/main/resources/META-INF/services/jadx.api.plugins.JadxPlugin
...n/resources/META-INF/services/jadx.api.plugins.JadxPlugin
+1
-0
settings.gradle
settings.gradle
+1
-0
未找到文件。
.gitignore
浏览文件 @
558a8673
...
...
@@ -26,6 +26,7 @@ node_modules/
jadx-output/
*-tmp/
**/tmp/
*.jobf
*.class
*.dump
...
...
build.gradle
浏览文件 @
558a8673
plugins
{
id
'org.sonarqube'
version
'3.0'
id
'com.github.ben-manes.versions'
version
'0.2
8
.0'
id
'com.github.ben-manes.versions'
version
'0.2
9
.0'
id
"com.diffplug.gradle.spotless"
version
"4.5.1"
}
...
...
jadx-cli/build.gradle
浏览文件 @
558a8673
...
...
@@ -6,6 +6,7 @@ dependencies {
implementation
(
project
(
':jadx-core'
))
runtimeOnly
(
project
(
':jadx-plugins:jadx-dex-input'
))
runtimeOnly
(
project
(
':jadx-plugins:jadx-smali-input'
))
runtimeOnly
(
project
(
':jadx-plugins:jadx-java-convert'
))
implementation
'com.beust:jcommander:1.78'
...
...
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
浏览文件 @
558a8673
...
...
@@ -15,10 +15,7 @@ public class JadxCLI {
public
static
void
main
(
String
[]
args
)
{
int
result
=
0
;
try
{
JadxCLIArgs
jadxArgs
=
new
JadxCLIArgs
();
if
(
jadxArgs
.
processArgs
(
args
))
{
result
=
processAndSave
(
jadxArgs
.
toJadxArgs
());
}
result
=
execute
(
args
);
}
catch
(
JadxArgsValidateException
e
)
{
LOG
.
error
(
"Incorrect arguments: {}"
,
e
.
getMessage
());
result
=
1
;
...
...
@@ -31,7 +28,15 @@ public class JadxCLI {
}
}
static
int
processAndSave
(
JadxArgs
jadxArgs
)
{
public
static
int
execute
(
String
[]
args
)
{
JadxCLIArgs
jadxArgs
=
new
JadxCLIArgs
();
if
(
jadxArgs
.
processArgs
(
args
))
{
return
processAndSave
(
jadxArgs
.
toJadxArgs
());
}
return
0
;
}
private
static
int
processAndSave
(
JadxArgs
jadxArgs
)
{
jadxArgs
.
setCodeCache
(
new
NoOpCodeCache
());
try
(
JadxDecompiler
jadx
=
new
JadxDecompiler
(
jadxArgs
))
{
jadx
.
load
();
...
...
jadx-cli/src/test/java/jadx/cli/TestInput.java
0 → 100644
浏览文件 @
558a8673
package
jadx.cli
;
import
java.io.IOException
;
import
java.net.URISyntaxException
;
import
java.net.URL
;
import
java.nio.file.Files
;
import
java.nio.file.LinkOption
;
import
java.nio.file.Path
;
import
java.nio.file.PathMatcher
;
import
java.util.List
;
import
java.util.stream.Collectors
;
import
java.util.stream.Stream
;
import
org.junit.jupiter.api.AfterAll
;
import
org.junit.jupiter.api.Test
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.core.utils.files.FileUtils
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
public
class
TestInput
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
TestInput
.
class
);
@Test
public
void
testDexInput
()
throws
Exception
{
decompile
(
"dex"
,
"samples/hello.dex"
);
}
@Test
public
void
testSmaliInput
()
throws
Exception
{
decompile
(
"smali"
,
"samples/HelloWorld.smali"
);
}
private
void
decompile
(
String
tmpDirName
,
String
inputSample
)
throws
URISyntaxException
,
IOException
{
StringBuilder
args
=
new
StringBuilder
();
Path
tempDir
=
FileUtils
.
createTempDir
(
tmpDirName
);
args
.
append
(
"-v "
);
args
.
append
(
"-d "
).
append
(
tempDir
.
toAbsolutePath
()).
append
(
' '
);
URL
resource
=
getClass
().
getClassLoader
().
getResource
(
inputSample
);
assertThat
(
resource
).
isNotNull
();
String
sampleFile
=
resource
.
toURI
().
getRawPath
();
args
.
append
(
sampleFile
);
int
result
=
JadxCLI
.
execute
(
args
.
toString
().
split
(
" "
));
assertThat
(
result
).
isEqualTo
(
0
);
List
<
Path
>
resultJavaFiles
=
collectJavaFilesInDir
(
tempDir
);
assertThat
(
resultJavaFiles
).
isNotEmpty
();
}
private
static
List
<
Path
>
collectJavaFilesInDir
(
Path
dir
)
throws
IOException
{
PathMatcher
matcher
=
dir
.
getFileSystem
().
getPathMatcher
(
"glob:**.java"
);
try
(
Stream
<
Path
>
pathStream
=
Files
.
walk
(
dir
))
{
return
pathStream
.
filter
(
p
->
Files
.
isRegularFile
(
p
,
LinkOption
.
NOFOLLOW_LINKS
))
.
peek
(
f
->
LOG
.
debug
(
"File in result dir: {}"
,
f
))
.
filter
(
matcher:
:
matches
)
.
collect
(
Collectors
.
toList
());
}
}
@AfterAll
public
static
void
cleanup
()
{
FileUtils
.
clearTempRootDir
();
}
}
jadx-cli/src/test/resources/samples/HelloWorld.smali
0 → 100644
浏览文件 @
558a8673
.class LHelloWorld;
.super Ljava/lang/Object;
.source "HelloWorld.java"
.method constructor <init>()V
.registers 1
.line 1
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
.method public static main([Ljava/lang/String;)V
.registers 2
.line 3
sget-object p0, Ljava/lang/System;->out:Ljava/io/PrintStream;
const-string v0, "Hello, World"
invoke-virtual {p0, v0}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
.line 4
return-void
.end method
jadx-cli/src/test/resources/samples/hello.dex
0 → 100644
浏览文件 @
558a8673
文件已添加
jadx-core/build.gradle
浏览文件 @
558a8673
...
...
@@ -19,6 +19,7 @@ dependencies {
testImplementation
'org.apache.commons:commons-lang3:3.10'
testRuntimeOnly
(
project
(
':jadx-plugins:jadx-dex-input'
))
testRuntimeOnly
(
project
(
':jadx-plugins:jadx-smali-input'
))
testRuntimeOnly
(
project
(
':jadx-plugins:jadx-java-convert'
))
}
...
...
jadx-core/src/main/java/jadx/api/JadxArgsValidator.java
浏览文件 @
558a8673
...
...
@@ -27,14 +27,11 @@ public class JadxArgsValidator {
if
(
inputFiles
.
isEmpty
())
{
throw
new
JadxArgsValidateException
(
"Please specify input file"
);
}
if
(
inputFiles
.
size
()
>
1
)
{
for
(
File
inputFile
:
inputFiles
)
{
String
fileName
=
inputFile
.
getName
();
if
(
fileName
.
startsWith
(
"--"
))
{
throw
new
JadxArgsValidateException
(
"Unknown argument: "
+
fileName
);
}
for
(
File
inputFile
:
inputFiles
)
{
String
fileName
=
inputFile
.
getName
();
if
(
fileName
.
startsWith
(
"--"
))
{
throw
new
JadxArgsValidateException
(
"Unknown argument: "
+
fileName
);
}
throw
new
JadxArgsValidateException
(
"Only one input file supported"
);
}
for
(
File
file
:
inputFiles
)
{
checkFile
(
file
);
...
...
jadx-core/src/main/java/jadx/api/JadxDecompiler.java
浏览文件 @
558a8673
...
...
@@ -108,7 +108,10 @@ public final class JadxDecompiler implements Closeable {
loadedInputs
.
clear
();
List
<
Path
>
inputPaths
=
Utils
.
collectionMap
(
args
.
getInputFiles
(),
File:
:
toPath
);
for
(
JadxInputPlugin
inputPlugin
:
pluginManager
.
getInputPlugins
())
{
loadedInputs
.
add
(
inputPlugin
.
loadFiles
(
inputPaths
));
ILoadResult
loadResult
=
inputPlugin
.
loadFiles
(
inputPaths
);
if
(
loadResult
!=
null
&&
!
loadResult
.
isEmpty
())
{
loadedInputs
.
add
(
loadResult
);
}
}
}
...
...
jadx-core/src/main/java/jadx/api/ResourcesLoader.java
浏览文件 @
558a8673
...
...
@@ -21,6 +21,7 @@ import jadx.core.codegen.CodeWriter;
import
jadx.core.utils.Utils
;
import
jadx.core.utils.android.Res9patchStreamDecoder
;
import
jadx.core.utils.exceptions.JadxException
;
import
jadx.core.utils.files.FileUtils
;
import
jadx.core.utils.files.ZipSecurity
;
import
jadx.core.xmlgen.ResContainer
;
import
jadx.core.xmlgen.ResTableParser
;
...
...
@@ -127,16 +128,19 @@ public final class ResourcesLoader {
if
(
file
==
null
)
{
return
;
}
try
(
ZipFile
zip
=
new
ZipFile
(
file
))
{
Enumeration
<?
extends
ZipEntry
>
entries
=
zip
.
entries
();
while
(
entries
.
hasMoreElements
())
{
ZipEntry
entry
=
entries
.
nextElement
();
if
(
ZipSecurity
.
isValidZipEntry
(
entry
))
{
addEntry
(
list
,
file
,
entry
);
if
(
FileUtils
.
isZipFile
(
file
))
{
try
(
ZipFile
zip
=
new
ZipFile
(
file
))
{
Enumeration
<?
extends
ZipEntry
>
entries
=
zip
.
entries
();
while
(
entries
.
hasMoreElements
())
{
ZipEntry
entry
=
entries
.
nextElement
();
if
(
ZipSecurity
.
isValidZipEntry
(
entry
))
{
addEntry
(
list
,
file
,
entry
);
}
}
}
catch
(
Exception
e
)
{
LOG
.
warn
(
"Failed to open zip file: {}"
,
file
.
getAbsolutePath
());
}
}
catch
(
Exception
e
)
{
LOG
.
debug
(
"Not a zip file: {}"
,
file
.
getAbsolutePath
());
}
else
{
addResourceFile
(
list
,
file
);
}
}
...
...
jadx-core/src/main/java/jadx/core/clsp/ClsSet.java
浏览文件 @
558a8673
...
...
@@ -87,7 +87,7 @@ public class ClsSet {
if
(
LOG
.
isDebugEnabled
())
{
long
time
=
System
.
currentTimeMillis
()
-
startTime
;
int
methodsCount
=
Stream
.
of
(
classes
).
mapToInt
(
clspClass
->
clspClass
.
getMethodsMap
().
size
()).
sum
();
LOG
.
debug
(
"
Load class set
in {}ms, classes: {}, methods: {}"
,
time
,
classes
.
length
,
methodsCount
);
LOG
.
debug
(
"
Clst file loaded
in {}ms, classes: {}, methods: {}"
,
time
,
classes
.
length
,
methodsCount
);
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java
浏览文件 @
558a8673
...
...
@@ -90,6 +90,7 @@ public class RootNode {
// sort classes by name, expect top classes before inner
classes
.
sort
(
Comparator
.
comparing
(
ClassNode:
:
getFullName
));
initInnerClasses
();
LOG
.
debug
(
"Classes loaded: {}"
,
classes
.
size
());
}
private
void
addDummyClass
(
IClassData
classData
,
Exception
exc
)
{
...
...
jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java
浏览文件 @
558a8673
...
...
@@ -222,7 +222,7 @@ public class FileUtils {
return
new
String
(
hexChars
);
}
p
rivate
static
boolean
isZipFile
(
File
file
)
{
p
ublic
static
boolean
isZipFile
(
File
file
)
{
try
(
InputStream
is
=
new
FileInputStream
(
file
))
{
byte
[]
headers
=
new
byte
[
4
];
int
read
=
is
.
read
(
headers
,
0
,
4
);
...
...
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
浏览文件 @
558a8673
...
...
@@ -104,7 +104,7 @@ public abstract class IntegrationTest extends TestUtils {
DebugChecks
.
checksEnabled
=
true
;
}
pr
ivate
JadxDecompiler
jadxDecompiler
;
pr
otected
JadxDecompiler
jadxDecompiler
;
@BeforeEach
public
void
init
()
{
...
...
@@ -142,7 +142,7 @@ public abstract class IntegrationTest extends TestUtils {
public
ClassNode
getClassNode
(
Class
<?>
clazz
)
{
try
{
File
jar
=
getJarForClass
(
clazz
);
return
getClassNodeFromFile
(
jar
,
clazz
.
getName
());
return
getClassNodeFromFile
s
(
Collections
.
singletonList
(
jar
)
,
clazz
.
getName
());
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
fail
(
e
.
getMessage
());
...
...
@@ -150,8 +150,8 @@ public abstract class IntegrationTest extends TestUtils {
return
null
;
}
public
ClassNode
getClassNodeFromFile
(
File
file
,
String
clsName
)
{
jadxDecompiler
=
loadFiles
(
Collections
.
singletonList
(
file
)
);
public
ClassNode
getClassNodeFromFile
s
(
List
<
File
>
files
,
String
clsName
)
{
jadxDecompiler
=
loadFiles
(
files
);
RootNode
root
=
JadxInternalAccess
.
getRoot
(
jadxDecompiler
);
ClassNode
cls
=
root
.
resolveClass
(
clsName
);
...
...
@@ -173,9 +173,8 @@ public abstract class IntegrationTest extends TestUtils {
}
protected
JadxDecompiler
loadFiles
(
List
<
File
>
inputFiles
)
{
JadxDecompiler
d
;
args
.
setInputFiles
(
inputFiles
);
d
=
new
JadxDecompiler
(
args
);
JadxDecompiler
d
=
new
JadxDecompiler
(
args
);
try
{
d
.
load
();
}
catch
(
Exception
e
)
{
...
...
jadx-core/src/test/java/jadx/tests/api/SmaliTest.java
浏览文件 @
558a8673
...
...
@@ -7,10 +7,7 @@ import java.util.stream.Collectors;
import
java.util.stream.Stream
;
import
org.jetbrains.annotations.Nullable
;
import
org.jf.smali.Smali
;
import
org.jf.smali.SmaliOptions
;
import
jadx.api.JadxDecompiler
;
import
jadx.api.JadxInternalAccess
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.core.dex.nodes.RootNode
;
...
...
@@ -26,9 +23,7 @@ public abstract class SmaliTest extends IntegrationTest {
protected
ClassNode
getClassNodeFromSmali
(
String
file
,
String
clsName
)
{
File
smaliFile
=
getSmaliFile
(
file
);
File
outDex
=
createTempFile
(
".dex"
);
compileSmali
(
outDex
,
Collections
.
singletonList
(
smaliFile
));
return
getClassNodeFromFile
(
outDex
,
clsName
);
return
getClassNodeFromFiles
(
Collections
.
singletonList
(
smaliFile
),
clsName
);
}
/**
...
...
@@ -51,9 +46,7 @@ public abstract class SmaliTest extends IntegrationTest {
}
protected
ClassNode
getClassNodeFromSmaliFiles
(
String
pkg
,
String
testName
,
String
clsName
)
{
File
outDex
=
createTempFile
(
".dex"
);
compileSmali
(
outDex
,
collectSmaliFiles
(
pkg
,
testName
));
return
getClassNodeFromFile
(
outDex
,
pkg
+
'.'
+
clsName
);
return
getClassNodeFromFiles
(
collectSmaliFiles
(
pkg
,
testName
),
pkg
+
'.'
+
clsName
);
}
protected
ClassNode
getClassNodeFromSmaliFiles
(
String
clsName
)
{
...
...
@@ -61,13 +54,10 @@ public abstract class SmaliTest extends IntegrationTest {
}
protected
List
<
ClassNode
>
loadFromSmaliFiles
()
{
File
outDex
=
createTempFile
(
".dex"
);
compileSmali
(
outDex
,
collectSmaliFiles
(
getTestPkg
(),
getTestName
()));
JadxDecompiler
d
=
loadFiles
(
Collections
.
singletonList
(
outDex
));
RootNode
root
=
JadxInternalAccess
.
getRoot
(
d
);
jadxDecompiler
=
loadFiles
(
collectSmaliFiles
(
getTestPkg
(),
getTestName
()));
RootNode
root
=
JadxInternalAccess
.
getRoot
(
jadxDecompiler
);
List
<
ClassNode
>
classes
=
root
.
getClasses
(
false
);
decompileAndCheck
(
d
,
classes
);
decompileAndCheck
(
jadxDecompiler
,
classes
);
return
classes
;
}
...
...
@@ -97,17 +87,4 @@ public abstract class SmaliTest extends IntegrationTest {
}
throw
new
AssertionError
(
"Smali file not found: "
+
smaliFile
.
getPath
());
}
private
static
boolean
compileSmali
(
File
output
,
List
<
File
>
inputFiles
)
{
try
{
SmaliOptions
options
=
new
SmaliOptions
();
options
.
outputDexFile
=
output
.
getAbsolutePath
();
options
.
verboseErrors
=
true
;
List
<
String
>
inputFileNames
=
inputFiles
.
stream
().
map
(
File:
:
getAbsolutePath
).
collect
(
Collectors
.
toList
());
Smali
.
assemble
(
options
,
inputFileNames
);
}
catch
(
Exception
e
)
{
throw
new
AssertionError
(
"Smali assemble error"
,
e
);
}
return
true
;
}
}
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexFileLoader.java
浏览文件 @
558a8673
...
...
@@ -26,7 +26,8 @@ public class DexFileLoader {
public
static
List
<
DexReader
>
collectDexFiles
(
List
<
Path
>
pathsList
)
{
return
pathsList
.
stream
()
.
map
((
Path
path
)
->
loadDexFromPath
(
path
,
0
))
.
map
(
path
->
loadDexFromPath
(
path
,
0
))
.
filter
(
list
->
!
list
.
isEmpty
())
.
flatMap
(
Collection:
:
stream
)
.
peek
(
dr
->
LOG
.
debug
(
"Loading dex: {}"
,
dr
))
.
collect
(
Collectors
.
toList
());
...
...
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexInputPlugin.java
浏览文件 @
558a8673
package
jadx.plugins.input.dex
;
import
java.io.Closeable
;
import
java.nio.file.Path
;
import
java.util.List
;
import
jadx.api.plugins.JadxPluginInfo
;
import
jadx.api.plugins.input.JadxInputPlugin
;
import
jadx.api.plugins.input.data.ILoadResult
;
import
jadx.api.plugins.input.data.impl.EmptyLoadResult
;
public
class
DexInputPlugin
implements
JadxInputPlugin
{
...
...
@@ -16,6 +18,14 @@ public class DexInputPlugin implements JadxInputPlugin {
@Override
public
ILoadResult
loadFiles
(
List
<
Path
>
input
)
{
return
new
DexLoadResult
(
DexFileLoader
.
collectDexFiles
(
input
));
return
loadDexFiles
(
input
,
null
);
}
public
static
ILoadResult
loadDexFiles
(
List
<
Path
>
inputFiles
,
Closeable
closeable
)
{
List
<
DexReader
>
dexReaders
=
DexFileLoader
.
collectDexFiles
(
inputFiles
);
if
(
dexReaders
.
isEmpty
())
{
return
EmptyLoadResult
.
INSTANCE
;
}
return
new
DexLoadResult
(
dexReaders
,
closeable
);
}
}
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexLoadResult.java
浏览文件 @
558a8673
package
jadx.plugins.input.dex
;
import
java.io.Closeable
;
import
java.io.IOException
;
import
java.util.List
;
import
java.util.function.Consumer
;
import
org.jetbrains.annotations.Nullable
;
import
jadx.api.plugins.input.data.IClassData
;
import
jadx.api.plugins.input.data.ILoadResult
;
import
jadx.api.plugins.input.data.IResourceData
;
public
class
DexLoadResult
implements
ILoadResult
{
private
final
List
<
DexReader
>
dexReaders
;
@Nullable
private
final
Closeable
closeable
;
public
DexLoadResult
(
List
<
DexReader
>
dexReaders
)
{
this
(
dexReaders
,
null
);
}
public
DexLoadResult
(
List
<
DexReader
>
dexReaders
,
Closeable
closeable
)
{
this
.
dexReaders
=
dexReaders
;
this
.
closeable
=
closeable
;
}
@Override
...
...
@@ -31,5 +41,13 @@ public class DexLoadResult implements ILoadResult {
for
(
DexReader
dexReader
:
dexReaders
)
{
dexReader
.
close
();
}
if
(
closeable
!=
null
)
{
closeable
.
close
();
}
}
@Override
public
boolean
isEmpty
()
{
return
dexReaders
.
isEmpty
();
}
}
jadx-plugins/jadx-java-convert/src/main/java/jadx/plugins/input/javaconvert/ConvertResult.java
浏览文件 @
558a8673
package
jadx.plugins.input.javaconvert
;
import
java.io.Closeable
;
import
java.io.File
;
import
java.io.IOException
;
import
java.nio.file.Files
;
...
...
@@ -12,7 +13,7 @@ import java.util.stream.Stream;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
class
ConvertResult
{
public
class
ConvertResult
implements
Closeable
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
ConvertResult
.
class
);
private
final
List
<
Path
>
converted
=
new
ArrayList
<>();
...
...
@@ -34,7 +35,8 @@ public class ConvertResult {
return
converted
.
isEmpty
();
}
public
void
deleteTemp
()
{
@Override
public
void
close
()
{
for
(
Path
tmpPath
:
tmpPaths
)
{
try
{
delete
(
tmpPath
);
...
...
jadx-plugins/jadx-java-convert/src/main/java/jadx/plugins/input/javaconvert/JavaConvertPlugin.java
浏览文件 @
558a8673
package
jadx.plugins.input.javaconvert
;
import
java.io.IOException
;
import
java.nio.file.Path
;
import
java.util.List
;
...
...
@@ -8,9 +7,7 @@ import jadx.api.plugins.JadxPluginInfo;
import
jadx.api.plugins.input.JadxInputPlugin
;
import
jadx.api.plugins.input.data.ILoadResult
;
import
jadx.api.plugins.input.data.impl.EmptyLoadResult
;
import
jadx.plugins.input.dex.DexFileLoader
;
import
jadx.plugins.input.dex.DexLoadResult
;
import
jadx.plugins.input.dex.DexReader
;
import
jadx.plugins.input.dex.DexInputPlugin
;
public
class
JavaConvertPlugin
implements
JadxInputPlugin
{
...
...
@@ -23,16 +20,9 @@ public class JavaConvertPlugin implements JadxInputPlugin {
public
ILoadResult
loadFiles
(
List
<
Path
>
input
)
{
ConvertResult
result
=
JavaConvertLoader
.
process
(
input
);
if
(
result
.
isEmpty
())
{
result
.
deleteTemp
();
result
.
close
();
return
EmptyLoadResult
.
INSTANCE
;
}
List
<
DexReader
>
dexReaders
=
DexFileLoader
.
collectDexFiles
(
result
.
getConverted
());
return
new
DexLoadResult
(
dexReaders
)
{
@Override
public
void
close
()
throws
IOException
{
super
.
close
();
result
.
deleteTemp
();
}
};
return
DexInputPlugin
.
loadDexFiles
(
result
.
getConverted
(),
result
);
}
}
jadx-plugins/jadx-plugins-api/src/main/java/jadx/api/plugins/input/data/ILoadResult.java
浏览文件 @
558a8673
...
...
@@ -7,4 +7,6 @@ public interface ILoadResult extends Closeable {
void
visitClasses
(
Consumer
<
IClassData
>
consumer
);
void
visitResources
(
Consumer
<
IResourceData
>
consumer
);
boolean
isEmpty
();
}
jadx-plugins/jadx-plugins-api/src/main/java/jadx/api/plugins/input/data/impl/EmptyLoadResult.java
浏览文件 @
558a8673
...
...
@@ -11,6 +11,11 @@ public class EmptyLoadResult implements ILoadResult {
public
static
final
EmptyLoadResult
INSTANCE
=
new
EmptyLoadResult
();
@Override
public
boolean
isEmpty
()
{
return
true
;
}
@Override
public
void
visitClasses
(
Consumer
<
IClassData
>
consumer
)
{
}
...
...
jadx-plugins/jadx-smali-input/build.gradle
0 → 100644
浏览文件 @
558a8673
plugins
{
id
'java-library'
}
dependencies
{
api
(
project
(
":jadx-plugins:jadx-plugins-api"
))
implementation
(
project
(
":jadx-plugins:jadx-dex-input"
))
implementation
'org.smali:smali:2.4.0'
implementation
'com.google.guava:guava:29.0-jre'
// force latest version for smali
}
jadx-plugins/jadx-smali-input/src/main/java/jadx/plugins/input/smali/SmaliConvert.java
0 → 100644
浏览文件 @
558a8673
package
jadx.plugins.input.smali
;
import
java.io.ByteArrayOutputStream
;
import
java.io.Closeable
;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
java.io.PrintStream
;
import
java.nio.file.FileSystems
;
import
java.nio.file.Files
;
import
java.nio.file.LinkOption
;
import
java.nio.file.Path
;
import
java.nio.file.PathMatcher
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.concurrent.Callable
;
import
java.util.stream.Collectors
;
import
org.jetbrains.annotations.Nullable
;
import
org.jf.smali.Smali
;
import
org.jf.smali.SmaliOptions
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
class
SmaliConvert
implements
Closeable
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
SmaliConvert
.
class
);
@Nullable
private
Path
tmpDex
;
public
boolean
execute
(
List
<
Path
>
input
)
{
List
<
Path
>
smaliFiles
=
filterSmaliFiles
(
input
);
if
(
smaliFiles
.
isEmpty
())
{
return
false
;
}
try
{
this
.
tmpDex
=
Files
.
createTempFile
(
"jadx-"
,
".dex"
);
boolean
result
=
compileSmali
(
tmpDex
,
smaliFiles
);
if
(
result
)
{
return
true
;
}
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Smali process error"
,
e
);
}
close
();
return
false
;
}
private
static
boolean
compileSmali
(
Path
output
,
List
<
Path
>
inputFiles
)
throws
IOException
{
SmaliOptions
options
=
new
SmaliOptions
();
options
.
outputDexFile
=
output
.
toAbsolutePath
().
toString
();
options
.
verboseErrors
=
true
;
List
<
String
>
inputFileNames
=
inputFiles
.
stream
()
.
map
(
p
->
p
.
toAbsolutePath
().
toString
())
.
distinct
()
.
collect
(
Collectors
.
toList
());
try
(
ByteArrayOutputStream
out
=
new
ByteArrayOutputStream
())
{
boolean
result
=
collectSystemErrors
(
out
,
()
->
Smali
.
assemble
(
options
,
inputFileNames
));
if
(!
result
)
{
LOG
.
error
(
"Smali compilation error:\n{}"
,
out
);
}
return
result
;
}
}
private
static
boolean
collectSystemErrors
(
OutputStream
out
,
Callable
<
Boolean
>
exec
)
{
PrintStream
systemErr
=
System
.
err
;
try
(
PrintStream
err
=
new
PrintStream
(
out
))
{
System
.
setErr
(
err
);
try
{
return
exec
.
call
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
(
err
);
return
false
;
}
}
finally
{
System
.
setErr
(
systemErr
);
}
}
private
List
<
Path
>
filterSmaliFiles
(
List
<
Path
>
input
)
{
PathMatcher
matcher
=
FileSystems
.
getDefault
().
getPathMatcher
(
"glob:**.smali"
);
return
input
.
stream
()
.
filter
(
p
->
Files
.
isRegularFile
(
p
,
LinkOption
.
NOFOLLOW_LINKS
))
.
filter
(
matcher:
:
matches
)
.
collect
(
Collectors
.
toList
());
}
public
List
<
Path
>
getDexFiles
()
{
if
(
tmpDex
==
null
)
{
return
Collections
.
emptyList
();
}
return
Collections
.
singletonList
(
tmpDex
);
}
@Override
public
void
close
()
{
try
{
if
(
tmpDex
!=
null
)
{
Files
.
deleteIfExists
(
tmpDex
);
}
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Failed to remove tmp dex file: {}"
,
tmpDex
,
e
);
}
}
}
jadx-plugins/jadx-smali-input/src/main/java/jadx/plugins/input/smali/SmaliInputPlugin.java
0 → 100644
浏览文件 @
558a8673
package
jadx.plugins.input.smali
;
import
java.nio.file.Path
;
import
java.util.List
;
import
jadx.api.plugins.JadxPluginInfo
;
import
jadx.api.plugins.input.JadxInputPlugin
;
import
jadx.api.plugins.input.data.ILoadResult
;
import
jadx.api.plugins.input.data.impl.EmptyLoadResult
;
import
jadx.plugins.input.dex.DexInputPlugin
;
public
class
SmaliInputPlugin
implements
JadxInputPlugin
{
@Override
public
JadxPluginInfo
getPluginInfo
()
{
return
new
JadxPluginInfo
(
"smali-input"
,
"SmaliInput"
,
"Load .smali files"
);
}
@Override
public
ILoadResult
loadFiles
(
List
<
Path
>
input
)
{
SmaliConvert
convert
=
new
SmaliConvert
();
if
(!
convert
.
execute
(
input
))
{
return
EmptyLoadResult
.
INSTANCE
;
}
return
DexInputPlugin
.
loadDexFiles
(
convert
.
getDexFiles
(),
convert
);
}
}
jadx-plugins/jadx-smali-input/src/main/resources/META-INF/services/jadx.api.plugins.JadxPlugin
0 → 100644
浏览文件 @
558a8673
jadx.plugins.input.smali.SmaliInputPlugin
settings.gradle
浏览文件 @
558a8673
...
...
@@ -7,4 +7,5 @@ include 'jadx-samples'
include
'jadx-plugins'
include
'jadx-plugins:jadx-plugins-api'
include
'jadx-plugins:jadx-dex-input'
include
'jadx-plugins:jadx-smali-input'
include
'jadx-plugins:jadx-java-convert'
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录