Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
极致猎手
jadx
提交
15602848
J
jadx
项目概览
极致猎手
/
jadx
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jadx
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
15602848
编写于
8月 06, 2020
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
refactor: fix zip security in dex plugin, remove smali deps from jadx-core
上级
558a8673
变更
24
隐藏空白更改
内联
并排
Showing
24 changed file
with
152 addition
and
149 deletion
+152
-149
jadx-core/build.gradle
jadx-core/build.gradle
+0
-6
jadx-core/src/main/java/jadx/api/ResourceFile.java
jadx-core/src/main/java/jadx/api/ResourceFile.java
+1
-1
jadx-core/src/main/java/jadx/api/ResourcesLoader.java
jadx-core/src/main/java/jadx/api/ResourcesLoader.java
+1
-1
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/codegen/json/JsonCodeGen.java
...ore/src/main/java/jadx/core/codegen/json/JsonCodeGen.java
+1
-1
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
+20
-31
jadx-core/src/main/java/jadx/core/dex/nodes/FieldNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/FieldNode.java
+2
-3
jadx-core/src/main/java/jadx/core/dex/nodes/IDexNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/IDexNode.java
+1
-3
jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java
+2
-3
jadx-core/src/main/java/jadx/core/dex/visitors/SaveCode.java
jadx-core/src/main/java/jadx/core/dex/visitors/SaveCode.java
+1
-1
jadx-core/src/main/java/jadx/core/utils/ErrorsCounter.java
jadx-core/src/main/java/jadx/core/utils/ErrorsCounter.java
+1
-7
jadx-core/src/main/java/jadx/core/xmlgen/ResourcesSaver.java
jadx-core/src/main/java/jadx/core/xmlgen/ResourcesSaver.java
+1
-1
jadx-core/src/test/java/jadx/tests/external/BaseExternalTest.java
...e/src/test/java/jadx/tests/external/BaseExternalTest.java
+1
-1
jadx-gui/src/main/java/jadx/gui/ui/RenameDialog.java
jadx-gui/src/main/java/jadx/gui/ui/RenameDialog.java
+7
-9
jadx-plugins/jadx-dex-input/build.gradle
jadx-plugins/jadx-dex-input/build.gradle
+5
-1
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexFileLoader.java
...t/src/main/java/jadx/plugins/input/dex/DexFileLoader.java
+46
-28
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexLoadResult.java
...t/src/main/java/jadx/plugins/input/dex/DexLoadResult.java
+2
-8
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexReader.java
...input/src/main/java/jadx/plugins/input/dex/DexReader.java
+8
-31
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/sections/DexClassData.java
...in/java/jadx/plugins/input/dex/sections/DexClassData.java
+9
-4
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/utils/SmaliUtils.java
...rc/main/java/jadx/plugins/input/dex/utils/SmaliUtils.java
+33
-0
jadx-plugins/jadx-dex-input/src/test/java/jadx/plugins/input/dex/DexInputPluginTest.java
.../test/java/jadx/plugins/input/dex/DexInputPluginTest.java
+5
-2
jadx-plugins/jadx-dex-input/src/test/java/jadx/plugins/input/dex/utils/SmaliTestUtils.java
...est/java/jadx/plugins/input/dex/utils/SmaliTestUtils.java
+1
-1
jadx-plugins/jadx-plugins-api/src/main/java/jadx/api/plugins/input/data/IClassData.java
...src/main/java/jadx/api/plugins/input/data/IClassData.java
+2
-4
jadx-plugins/jadx-plugins-api/src/main/java/jadx/api/plugins/utils/ZipSecurity.java
...api/src/main/java/jadx/api/plugins/utils/ZipSecurity.java
+1
-1
未找到文件。
jadx-core/build.gradle
浏览文件 @
15602848
...
...
@@ -10,12 +10,6 @@ dependencies {
implementation
'com.google.code.gson:gson:2.8.6'
implementation
'org.smali:baksmali:2.4.0'
implementation
(
'org.smali:smali:2.4.0'
)
{
exclude
group:
'com.google.guava'
}
implementation
'com.google.guava:guava:29.0-jre'
testImplementation
'org.apache.commons:commons-lang3:3.10'
testRuntimeOnly
(
project
(
':jadx-plugins:jadx-dex-input'
))
...
...
jadx-core/src/main/java/jadx/api/ResourceFile.java
浏览文件 @
15602848
...
...
@@ -2,7 +2,7 @@ package jadx.api;
import
java.io.File
;
import
jadx.
core.utils.file
s.ZipSecurity
;
import
jadx.
api.plugins.util
s.ZipSecurity
;
import
jadx.core.xmlgen.ResContainer
;
public
class
ResourceFile
{
...
...
jadx-core/src/main/java/jadx/api/ResourcesLoader.java
浏览文件 @
15602848
...
...
@@ -17,12 +17,12 @@ import org.slf4j.LoggerFactory;
import
jadx.api.ResourceFile.ZipRef
;
import
jadx.api.impl.SimpleCodeInfo
;
import
jadx.api.plugins.utils.ZipSecurity
;
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
;
...
...
jadx-core/src/main/java/jadx/core/clsp/ClsSet.java
浏览文件 @
15602848
...
...
@@ -27,6 +27,7 @@ import org.jetbrains.annotations.Nullable;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.api.plugins.utils.ZipSecurity
;
import
jadx.core.dex.info.AccessInfo
;
import
jadx.core.dex.info.ClassInfo
;
import
jadx.core.dex.info.MethodInfo
;
...
...
@@ -37,7 +38,6 @@ import jadx.core.dex.nodes.RootNode;
import
jadx.core.utils.exceptions.DecodeException
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
jadx.core.utils.files.FileUtils
;
import
jadx.core.utils.files.ZipSecurity
;
import
static
jadx
.
core
.
utils
.
Utils
.
notEmpty
;
...
...
jadx-core/src/main/java/jadx/core/codegen/json/JsonCodeGen.java
浏览文件 @
15602848
...
...
@@ -68,7 +68,7 @@ public class JsonCodeGen {
JsonClass
jsonCls
=
new
JsonClass
();
jsonCls
.
setPkg
(
classInfo
.
getAliasPkg
());
jsonCls
.
setDex
(
cls
.
getInput
Path
().
toString
());
jsonCls
.
setDex
(
cls
.
getInput
FileName
());
jsonCls
.
setName
(
classInfo
.
getFullName
());
if
(
classInfo
.
hasAlias
())
{
jsonCls
.
setAlias
(
classInfo
.
getAliasFullName
());
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
浏览文件 @
15602848
package
jadx.core.dex.nodes
;
import
java.io.StringWriter
;
import
java.nio.file.Path
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashMap
;
...
...
@@ -39,7 +37,6 @@ import jadx.core.dex.instructions.args.ArgType;
import
jadx.core.dex.instructions.args.LiteralArg
;
import
jadx.core.dex.nodes.parser.SignatureParser
;
import
jadx.core.dex.visitors.ProcessAnonymous
;
import
jadx.core.utils.SmaliUtils
;
import
jadx.core.utils.Utils
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
...
...
@@ -50,10 +47,7 @@ public class ClassNode extends NotificationAttrNode implements ILoadable, ICodeN
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
ClassNode
.
class
);
private
final
RootNode
root
;
private
final
IClassData
cls
;
private
final
int
clsDefOffset
;
@Nullable
private
final
Path
inputPath
;
private
final
IClassData
clsData
;
private
final
ClassInfo
clsInfo
;
private
AccessInfo
accessFlags
;
...
...
@@ -86,11 +80,9 @@ public class ClassNode extends NotificationAttrNode implements ILoadable, ICodeN
public
ClassNode
(
RootNode
root
,
IClassData
cls
)
{
this
.
root
=
root
;
this
.
inputPath
=
cls
.
getInputPath
();
this
.
clsDefOffset
=
cls
.
getClassDefOffset
();
this
.
clsInfo
=
ClassInfo
.
fromType
(
root
,
ArgType
.
object
(
cls
.
getType
()));
initialLoad
(
cls
);
this
.
cls
=
cls
.
copy
();
// TODO: need only for rename feature
this
.
cls
Data
=
cls
.
copy
();
}
private
void
initialLoad
(
IClassData
cls
)
{
...
...
@@ -152,9 +144,7 @@ public class ClassNode extends NotificationAttrNode implements ILoadable, ICodeN
// Create empty class
private
ClassNode
(
RootNode
root
,
String
name
,
int
accessFlags
)
{
this
.
root
=
root
;
this
.
cls
=
null
;
this
.
inputPath
=
null
;
this
.
clsDefOffset
=
0
;
this
.
clsData
=
null
;
this
.
clsInfo
=
ClassInfo
.
fromName
(
root
,
name
);
this
.
interfaces
=
new
ArrayList
<>();
this
.
methods
=
new
ArrayList
<>();
...
...
@@ -299,13 +289,13 @@ public class ClassNode extends NotificationAttrNode implements ILoadable, ICodeN
}
public
void
deepUnload
()
{
if
(
cls
==
null
)
{
if
(
cls
Data
==
null
)
{
// manually added class
return
;
}
clearAttributes
();
root
().
getConstValues
().
removeForClass
(
this
);
initialLoad
(
cls
);
initialLoad
(
cls
Data
);
ProcessAnonymous
.
runForClass
(
this
);
for
(
ClassNode
innerClass
:
innerClasses
)
{
...
...
@@ -610,29 +600,28 @@ public class ClassNode extends NotificationAttrNode implements ILoadable, ICodeN
public
String
getSmali
()
{
if
(
smali
==
null
)
{
String
Writer
stringWriter
=
new
StringWriter
(
4096
);
getSmali
(
this
,
stringWriter
);
s
tringWriter
.
append
(
System
.
lineSeparator
());
String
Builder
sb
=
new
StringBuilder
(
);
getSmali
(
sb
);
s
b
.
append
(
System
.
lineSeparator
());
Set
<
ClassNode
>
allInlinedClasses
=
new
LinkedHashSet
<>();
getInnerAndInlinedClassesRecursive
(
allInlinedClasses
);
for
(
ClassNode
innerClass
:
allInlinedClasses
)
{
getSmali
(
innerClass
,
stringWriter
);
s
tringWriter
.
append
(
System
.
lineSeparator
());
innerClass
.
getSmali
(
sb
);
s
b
.
append
(
System
.
lineSeparator
());
}
smali
=
s
tringWriter
.
toString
();
smali
=
s
b
.
toString
();
}
return
smali
;
}
protected
static
boolean
getSmali
(
ClassNode
classNode
,
StringWriter
stringWriter
)
{
Path
inputPath
=
classNode
.
inputPath
;
if
(
inputPath
==
null
)
{
stringWriter
.
append
(
String
.
format
(
"###### Class %s is created by jadx"
,
classNode
.
getFullName
()));
return
false
;
protected
void
getSmali
(
StringBuilder
sb
)
{
if
(
this
.
clsData
==
null
)
{
sb
.
append
(
String
.
format
(
"###### Class %s is created by jadx"
,
getFullName
()));
return
;
}
s
tringWriter
.
append
(
String
.
format
(
"###### Class %s (%s)"
,
classNode
.
getFullName
(),
classNode
.
getRawName
()));
s
tringWriter
.
append
(
System
.
lineSeparator
());
return
SmaliUtils
.
getSmaliCode
(
inputPath
,
classNode
.
clsDefOffset
,
stringWriter
);
s
b
.
append
(
String
.
format
(
"###### Class %s (%s)"
,
getFullName
(),
getRawName
()));
s
b
.
append
(
System
.
lineSeparator
());
sb
.
append
(
this
.
clsData
.
getDisassembledCode
()
);
}
public
ProcessState
getState
()
{
...
...
@@ -668,8 +657,8 @@ public class ClassNode extends NotificationAttrNode implements ILoadable, ICodeN
}
@Override
public
Path
getInputPath
()
{
return
inputPath
;
public
String
getInputFileName
()
{
return
clsData
==
null
?
"synthetic"
:
clsData
.
getInputFileName
()
;
}
@Override
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/FieldNode.java
浏览文件 @
15602848
package
jadx.core.dex.nodes
;
import
java.nio.file.Path
;
import
java.util.Collections
;
import
java.util.List
;
...
...
@@ -88,8 +87,8 @@ public class FieldNode extends LineAttrNode implements ICodeNode {
}
@Override
public
Path
getInputPath
()
{
return
parentClass
.
getInput
Path
();
public
String
getInputFileName
()
{
return
parentClass
.
getInput
FileName
();
}
@Override
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/IDexNode.java
浏览文件 @
15602848
package
jadx.core.dex.nodes
;
import
java.nio.file.Path
;
public
interface
IDexNode
{
String
typeName
();
RootNode
root
();
Path
getInputPath
();
String
getInputFileName
();
}
jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java
浏览文件 @
15602848
package
jadx.core.dex.nodes
;
import
java.nio.file.Path
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
...
...
@@ -598,8 +597,8 @@ public class MethodNode extends NotificationAttrNode implements IMethodDetails,
}
@Override
public
Path
getInputPath
()
{
return
parentClass
.
getInput
Path
();
public
String
getInputFileName
()
{
return
parentClass
.
getInput
FileName
();
}
@Override
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/SaveCode.java
浏览文件 @
15602848
...
...
@@ -8,11 +8,11 @@ import org.slf4j.LoggerFactory;
import
jadx.api.ICodeInfo
;
import
jadx.api.JadxArgs
;
import
jadx.api.plugins.utils.ZipSecurity
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
jadx.core.utils.files.FileUtils
;
import
jadx.core.utils.files.ZipSecurity
;
public
class
SaveCode
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
SaveCode
.
class
);
...
...
jadx-core/src/main/java/jadx/core/utils/ErrorsCounter.java
浏览文件 @
15602848
package
jadx.core.utils
;
import
java.nio.file.Path
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashSet
;
...
...
@@ -37,12 +36,7 @@ public class ErrorsCounter {
}
public
static
String
formatMsg
(
IDexNode
node
,
String
msg
)
{
return
msg
+
" in "
+
node
.
typeName
()
+
": "
+
node
+
", file: "
+
getNodeFile
(
node
);
}
private
static
String
getNodeFile
(
IDexNode
node
)
{
Path
inputPath
=
node
.
getInputPath
();
return
inputPath
==
null
?
"synthetic"
:
inputPath
.
toString
();
return
msg
+
" in "
+
node
.
typeName
()
+
": "
+
node
+
", file: "
+
node
.
getInputFileName
();
}
private
synchronized
<
N
extends
IDexNode
&
IAttributeNode
>
String
addError
(
N
node
,
String
error
,
@Nullable
Throwable
e
)
{
...
...
jadx-core/src/main/java/jadx/core/xmlgen/ResourcesSaver.java
浏览文件 @
15602848
...
...
@@ -9,11 +9,11 @@ import org.slf4j.LoggerFactory;
import
jadx.api.ResourceFile
;
import
jadx.api.ResourcesLoader
;
import
jadx.api.plugins.utils.ZipSecurity
;
import
jadx.core.dex.visitors.SaveCode
;
import
jadx.core.utils.exceptions.JadxException
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
jadx.core.utils.files.FileUtils
;
import
jadx.core.utils.files.ZipSecurity
;
public
class
ResourcesSaver
implements
Runnable
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
ResourcesSaver
.
class
);
...
...
jadx-core/src/test/java/jadx/tests/external/BaseExternalTest.java
浏览文件 @
15602848
...
...
@@ -100,7 +100,7 @@ public abstract class BaseExternalTest extends IntegrationTest {
throw
new
JadxRuntimeException
(
"Class process failed"
,
e
);
}
LOG
.
info
(
"----------------------------------------------------------------"
);
LOG
.
info
(
"Print class: {}
, {}"
,
classNode
.
getFullName
(),
classNode
.
getInputPath
());
LOG
.
info
(
"Print class: {}
from: {}"
,
classNode
.
getFullName
(),
classNode
.
getInputFileName
());
if
(
mthPattern
!=
null
)
{
printMethods
(
classNode
,
mthPattern
);
}
else
{
...
...
jadx-gui/src/main/java/jadx/gui/ui/RenameDialog.java
浏览文件 @
15602848
...
...
@@ -132,26 +132,24 @@ public class RenameDialog extends JDialog {
return
String
.
format
(
"%s %s = %s"
,
type
,
id
,
renameText
);
}
private
boolean
writeDeobfMapFile
(
Path
deobfMapPath
,
List
<
String
>
deobfMap
)
throws
IOException
{
private
void
writeDeobfMapFile
(
Path
deobfMapPath
,
List
<
String
>
deobfMap
)
throws
IOException
{
if
(
deobfMapPath
==
null
)
{
LOG
.
error
(
"updateDeobfMapFile(): deobfMapPath is null!"
);
return
false
;
return
;
}
File
tmpFile
=
File
.
createTempFile
(
"deobf_tmp_"
,
".txt"
);
FileOutputStream
fileOut
=
new
FileOutputStream
(
tmpFile
);
for
(
String
entry
:
deobfMap
)
{
fileOut
.
write
(
entry
.
getBytes
());
fileOut
.
write
(
System
.
lineSeparator
().
getBytes
());
try
(
FileOutputStream
fileOut
=
new
FileOutputStream
(
tmpFile
))
{
for
(
String
entry
:
deobfMap
)
{
fileOut
.
write
(
entry
.
getBytes
());
fileOut
.
write
(
System
.
lineSeparator
().
getBytes
());
}
}
fileOut
.
close
();
File
oldMap
=
File
.
createTempFile
(
"deobf_bak_"
,
".txt"
);
Files
.
copy
(
deobfMapPath
,
oldMap
.
toPath
(),
StandardCopyOption
.
REPLACE_EXISTING
);
LOG
.
trace
(
"Copying "
+
tmpFile
.
toPath
()
+
" to "
+
deobfMapPath
);
Files
.
copy
(
tmpFile
.
toPath
(),
deobfMapPath
,
StandardCopyOption
.
REPLACE_EXISTING
);
Files
.
delete
(
oldMap
.
toPath
());
Files
.
delete
(
tmpFile
.
toPath
());
return
true
;
}
@NotNull
...
...
jadx-plugins/jadx-dex-input/build.gradle
浏览文件 @
15602848
...
...
@@ -5,5 +5,9 @@ plugins {
dependencies
{
api
(
project
(
":jadx-plugins:jadx-plugins-api"
))
testImplementation
(
'org.smali:smali:2.4.0'
)
// TODO: finish own smali printer
implementation
'org.smali:baksmali:2.4.0'
implementation
'com.google.guava:guava:29.0-jre'
// force latest version for smali
testImplementation
'org.smali:smali:2.4.0'
// compile smali files in tests
}
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexFileLoader.java
浏览文件 @
15602848
package
jadx.plugins.input.dex
;
import
java.io.BufferedInputStream
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.nio.file.FileSystem
;
import
java.nio.file.FileSystems
;
import
java.nio.file.FileVisitResult
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.nio.file.SimpleFileVisitor
;
import
java.nio.file.StandardOpenOption
;
import
java.nio.file.attribute.BasicFileAttributes
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.stream.Collectors
;
import
java.util.zip.ZipFile
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
com.google.common.io.ByteStreams
;
import
jadx.api.plugins.utils.ZipSecurity
;
import
jadx.plugins.input.dex.sections.DexConsts
;
public
class
DexFileLoader
{
...
...
@@ -26,43 +26,57 @@ public class DexFileLoader {
public
static
List
<
DexReader
>
collectDexFiles
(
List
<
Path
>
pathsList
)
{
return
pathsList
.
stream
()
.
map
(
path
->
loadDexFromPath
(
path
,
0
))
.
map
(
Path:
:
toFile
)
.
map
(
DexFileLoader:
:
loadDexFromFile
)
.
filter
(
list
->
!
list
.
isEmpty
())
.
flatMap
(
Collection:
:
stream
)
.
peek
(
dr
->
LOG
.
debug
(
"Loading dex: {}"
,
dr
))
.
collect
(
Collectors
.
toList
());
}
private
static
List
<
DexReader
>
loadDexFromPath
(
Path
path
,
int
depth
)
{
try
(
InputStream
inputStream
=
Files
.
newInputStream
(
path
,
StandardOpenOption
.
READ
))
{
private
static
List
<
DexReader
>
loadDexFromFile
(
File
file
)
{
try
(
InputStream
inputStream
=
new
FileInputStream
(
file
))
{
return
checkFileMagic
(
file
,
inputStream
,
file
.
getAbsolutePath
());
}
catch
(
Exception
e
)
{
LOG
.
error
(
"File open error: {}"
,
file
.
getAbsolutePath
(),
e
);
return
Collections
.
emptyList
();
}
}
private
static
List
<
DexReader
>
checkFileMagic
(
File
file
,
InputStream
inputStream
,
String
inputFileName
)
throws
IOException
{
try
(
InputStream
in
=
inputStream
.
markSupported
()
?
inputStream
:
new
BufferedInputStream
(
inputStream
))
{
byte
[]
magic
=
new
byte
[
DexConsts
.
MAX_MAGIC_SIZE
];
if
(
inputStream
.
read
(
magic
)
!=
magic
.
length
)
{
in
.
mark
(
magic
.
length
);
if
(
in
.
read
(
magic
)
!=
magic
.
length
)
{
return
Collections
.
emptyList
();
}
if
(
isStartWithBytes
(
magic
,
DexConsts
.
DEX_FILE_MAGIC
))
{
return
Collections
.
singletonList
(
new
DexReader
(
path
));
in
.
reset
();
DexReader
dexReader
=
new
DexReader
(
inputFileName
,
readAllBytes
(
in
));
return
Collections
.
singletonList
(
dexReader
);
}
if
(
depth
==
0
&&
isStartWithBytes
(
magic
,
DexConsts
.
ZIP_FILE_MAGIC
))
{
return
collectDexFromZip
(
path
,
depth
);
if
(
file
!=
null
&&
isStartWithBytes
(
magic
,
DexConsts
.
ZIP_FILE_MAGIC
))
{
return
collectDexFromZip
(
file
);
}
}
catch
(
Exception
e
)
{
LOG
.
error
(
"File open error: {}"
,
path
,
e
);
return
Collections
.
emptyList
();
}
return
Collections
.
emptyList
();
}
private
static
List
<
DexReader
>
collectDexFromZip
(
Path
path
,
int
depth
)
throws
IOException
{
private
static
List
<
DexReader
>
collectDexFromZip
(
File
file
)
{
List
<
DexReader
>
result
=
new
ArrayList
<>();
FileSystem
zip
=
FileSystems
.
newFileSystem
(
path
,
(
ClassLoader
)
null
);
for
(
Path
rootDir
:
zip
.
getRootDirectories
())
{
Files
.
walkFileTree
(
rootDir
,
new
SimpleFileVisitor
<
Path
>()
{
@Override
public
FileVisitResult
visitFile
(
Path
file
,
BasicFileAttributes
attrs
)
{
// TODO: add zip security checks
result
.
addAll
(
loadDexFromPath
(
file
,
depth
+
1
));
return
FileVisitResult
.
CONTINUE
;
}
});
try
(
ZipFile
zip
=
new
ZipFile
(
file
))
{
zip
.
stream
()
.
filter
(
entry
->
!
entry
.
isDirectory
())
.
filter
(
ZipSecurity:
:
isValidZipEntry
)
.
forEach
(
entry
->
{
try
(
InputStream
in
=
zip
.
getInputStream
(
entry
))
{
result
.
addAll
(
checkFileMagic
(
null
,
in
,
entry
.
getName
()));
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Failed to read zip entry: {}"
,
entry
,
e
);
}
});
}
catch
(
Exception
e
)
{
LOG
.
warn
(
"Failed to open zip file: {}"
,
file
.
getAbsolutePath
());
}
return
result
;
}
...
...
@@ -79,4 +93,8 @@ public class DexFileLoader {
}
return
true
;
}
private
static
byte
[]
readAllBytes
(
InputStream
in
)
throws
IOException
{
return
ByteStreams
.
toByteArray
(
in
);
}
}
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexLoadResult.java
浏览文件 @
15602848
...
...
@@ -16,11 +16,7 @@ public class DexLoadResult implements ILoadResult {
@Nullable
private
final
Closeable
closeable
;
public
DexLoadResult
(
List
<
DexReader
>
dexReaders
)
{
this
(
dexReaders
,
null
);
}
public
DexLoadResult
(
List
<
DexReader
>
dexReaders
,
Closeable
closeable
)
{
public
DexLoadResult
(
List
<
DexReader
>
dexReaders
,
@Nullable
Closeable
closeable
)
{
this
.
dexReaders
=
dexReaders
;
this
.
closeable
=
closeable
;
}
...
...
@@ -38,9 +34,7 @@ public class DexLoadResult implements ILoadResult {
@Override
public
void
close
()
throws
IOException
{
for
(
DexReader
dexReader
:
dexReaders
)
{
dexReader
.
close
();
}
dexReaders
.
clear
();
if
(
closeable
!=
null
)
{
closeable
.
close
();
}
...
...
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexReader.java
浏览文件 @
15602848
package
jadx.plugins.input.dex
;
import
java.io.Closeable
;
import
java.io.IOException
;
import
java.nio.ByteBuffer
;
import
java.nio.file.FileSystem
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.util.function.Consumer
;
import
jadx.api.plugins.input.data.IClassData
;
...
...
@@ -14,22 +9,18 @@ import jadx.plugins.input.dex.sections.DexHeader;
import
jadx.plugins.input.dex.sections.SectionReader
;
import
jadx.plugins.input.dex.sections.annotations.AnnotationsParser
;
public
class
DexReader
implements
Closeable
{
public
class
DexReader
{
private
final
Path
path
;
private
final
String
inputFileName
;
private
final
ByteBuffer
buf
;
private
final
DexHeader
header
;
public
DexReader
(
Path
path
)
throws
IOException
{
this
.
path
=
path
;
this
.
buf
=
ByteBuffer
.
wrap
(
Files
.
readAllBytes
(
path
)
);
public
DexReader
(
String
inputFileName
,
byte
[]
content
)
{
this
.
inputFileName
=
inputFileName
;
this
.
buf
=
ByteBuffer
.
wrap
(
content
);
this
.
header
=
new
DexHeader
(
new
SectionReader
(
this
,
0
));
}
public
String
getDexVersion
()
{
return
this
.
header
.
getVersion
();
}
public
void
visitClasses
(
Consumer
<
IClassData
>
consumer
)
{
int
count
=
header
.
getClassDefsSize
();
if
(
count
==
0
)
{
...
...
@@ -53,26 +44,12 @@ public class DexReader implements Closeable {
return
header
;
}
public
Path
getPath
()
{
return
path
;
}
public
String
getFullPath
()
{
StringBuilder
sb
=
new
StringBuilder
();
FileSystem
fileSystem
=
path
.
getFileSystem
();
if
(
fileSystem
.
getClass
().
getName
().
contains
(
"Zip"
))
{
sb
.
append
(
fileSystem
.
toString
()).
append
(
':'
);
}
sb
.
append
(
path
.
toAbsolutePath
());
return
sb
.
toString
();
}
@Override
public
void
close
()
throws
IOException
{
public
String
getInputFileName
()
{
return
inputFileName
;
}
@Override
public
String
toString
()
{
return
getFullPath
()
;
return
inputFileName
;
}
}
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/sections/DexClassData.java
浏览文件 @
15602848
package
jadx.plugins.input.dex.sections
;
import
java.nio.file.Path
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
...
...
@@ -15,6 +14,7 @@ import jadx.api.plugins.input.data.IMethodData;
import
jadx.api.plugins.input.data.annotations.EncodedValue
;
import
jadx.api.plugins.input.data.annotations.IAnnotation
;
import
jadx.plugins.input.dex.sections.annotations.AnnotationsParser
;
import
jadx.plugins.input.dex.utils.SmaliUtils
;
public
class
DexClassData
implements
IClassData
{
public
static
final
int
SIZE
=
8
*
4
;
...
...
@@ -71,8 +71,8 @@ public class DexClassData implements IClassData {
}
@Override
public
Path
getInputPath
()
{
return
in
.
getDexReader
().
get
Path
();
public
String
getInputFileName
()
{
return
in
.
getDexReader
().
get
InputFileName
();
}
public
int
getAnnotationsOff
()
{
...
...
@@ -186,11 +186,16 @@ public class DexClassData implements IClassData {
return
annotationsParser
.
readClassAnnotations
();
}
@Override
public
int
getClassDefOffset
()
{
return
in
.
pos
(
0
).
getAbsPos
();
}
@Override
public
String
getDisassembledCode
()
{
byte
[]
dexBuf
=
in
.
getDexReader
().
getBuf
().
array
();
return
SmaliUtils
.
getSmaliCode
(
dexBuf
,
getClassDefOffset
());
}
@Override
public
String
toString
()
{
return
getType
();
...
...
jadx-
core/src/main/java/jadx/core
/utils/SmaliUtils.java
→
jadx-
plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex
/utils/SmaliUtils.java
浏览文件 @
15602848
package
jadx.
core
.utils
;
package
jadx.
plugins.input.dex
.utils
;
import
java.io.BufferedInputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.PrintWriter
;
import
java.io.StringWriter
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
org.jf.baksmali.Adaptors.ClassDefinition
;
import
org.jf.baksmali.BaksmaliOptions
;
import
org.jf.dexlib2.dexbacked.DexBackedClassDef
;
import
org.jf.dexlib2.dexbacked.DexBackedDexFile
;
import
org.jf.smali.Smali
;
import
org.jf.smali.SmaliOptions
;
import
org.jf.util.IndentingWriter
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
// TODO: move smali dependencies out from jadx-core
public
class
SmaliUtils
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
SmaliUtils
.
class
);
public
static
void
assembleDex
(
String
outputDexFile
,
String
inputSmali
)
{
public
static
String
getSmaliCode
(
byte
[]
dexBuf
,
int
clsDefOffset
)
{
StringWriter
stringWriter
=
new
StringWriter
();
try
{
SmaliOptions
options
=
new
SmaliOptions
();
options
.
outputDexFile
=
outputDexFile
;
Smali
.
assemble
(
options
,
inputSmali
);
}
catch
(
Exception
e
)
{
throw
new
JadxRuntimeException
(
"Smali assemble error"
,
e
);
}
}
public
static
boolean
getSmaliCode
(
Path
path
,
int
clsDefOffset
,
StringWriter
stringWriter
)
{
if
(
clsDefOffset
==
0
)
{
return
false
;
}
try
(
InputStream
inputStream
=
new
BufferedInputStream
(
Files
.
newInputStream
(
path
)))
{
DexBackedDexFile
dexFile
=
DexBackedDexFile
.
fromInputStream
(
null
,
inputStream
);
DexBackedDexFile
dexFile
=
new
DexBackedDexFile
(
null
,
dexBuf
);
DexBackedClassDef
dexBackedClassDef
=
new
DexBackedClassDef
(
dexFile
,
clsDefOffset
,
0
);
getSmaliCode
(
dexBackedClassDef
,
stringWriter
);
return
true
;
ClassDefinition
classDefinition
=
new
ClassDefinition
(
new
BaksmaliOptions
(),
dexBackedClassDef
);
classDefinition
.
writeTo
(
new
IndentingWriter
(
stringWriter
))
;
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Error generating smali"
,
e
);
stringWriter
.
append
(
"Error generating smali code: "
);
stringWriter
.
append
(
e
.
getMessage
());
stringWriter
.
append
(
System
.
lineSeparator
());
stringWriter
.
append
(
Utils
.
getStackTrace
(
e
));
return
false
;
e
.
printStackTrace
(
new
PrintWriter
(
stringWriter
,
true
));
}
}
private
static
void
getSmaliCode
(
DexBackedClassDef
classDef
,
StringWriter
stringWriter
)
throws
IOException
{
ClassDefinition
classDefinition
=
new
ClassDefinition
(
new
BaksmaliOptions
(),
classDef
);
classDefinition
.
writeTo
(
new
IndentingWriter
(
stringWriter
));
return
stringWriter
.
toString
();
}
}
jadx-plugins/jadx-dex-input/src/test/java/jadx/plugins/input/dex/DexInputPluginTest.java
浏览文件 @
15602848
...
...
@@ -13,7 +13,7 @@ import jadx.api.plugins.input.data.AccessFlags;
import
jadx.api.plugins.input.data.AccessFlagsScope
;
import
jadx.api.plugins.input.data.ICodeReader
;
import
jadx.api.plugins.input.data.ILoadResult
;
import
jadx.plugins.input.dex.utils.SmaliUtils
;
import
jadx.plugins.input.dex.utils.Smali
Test
Utils
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
...
...
@@ -31,7 +31,7 @@ class DexInputPluginTest {
@Test
public
void
loadTestSmali
()
throws
Exception
{
processFile
(
SmaliUtils
.
compileSmaliFromResource
(
"samples/test.smali"
));
processFile
(
Smali
Test
Utils
.
compileSmaliFromResource
(
"samples/test.smali"
));
}
private
static
void
processFile
(
Path
sample
)
throws
IOException
{
...
...
@@ -65,6 +65,9 @@ class DexInputPluginTest {
System
.
out
.
println
(
mth
.
disassembleMethod
());
System
.
out
.
println
(
"---"
);
});
System
.
out
.
println
(
"----"
);
System
.
out
.
println
(
cls
.
getDisassembledCode
());
System
.
out
.
println
(
"----"
);
});
assertThat
(
count
.
get
()).
isGreaterThan
(
0
);
}
...
...
jadx-plugins/jadx-dex-input/src/test/java/jadx/plugins/input/dex/utils/SmaliUtils.java
→
jadx-plugins/jadx-dex-input/src/test/java/jadx/plugins/input/dex/utils/Smali
Test
Utils.java
浏览文件 @
15602848
...
...
@@ -10,7 +10,7 @@ import java.util.stream.Collectors;
import
org.jf.smali.Smali
;
import
org.jf.smali.SmaliOptions
;
public
class
SmaliUtils
{
public
class
Smali
Test
Utils
{
public
static
Path
compileSmaliFromResource
(
String
res
)
{
try
{
...
...
jadx-plugins/jadx-plugins-api/src/main/java/jadx/api/plugins/input/data/IClassData.java
浏览文件 @
15602848
package
jadx.api.plugins.input.data
;
import
java.nio.file.Path
;
import
java.util.List
;
import
java.util.function.Consumer
;
...
...
@@ -23,7 +22,7 @@ public interface IClassData {
String
getSourceFile
();
Path
getInputPath
();
String
getInputFileName
();
void
visitFieldsAndMethods
(
Consumer
<
IFieldData
>
fieldsConsumer
,
Consumer
<
IMethodData
>
mthConsumer
);
...
...
@@ -31,6 +30,5 @@ public interface IClassData {
List
<
IAnnotation
>
getAnnotations
();
// TODO: make api methods to get dissembled code
int
getClassDefOffset
();
String
getDisassembledCode
();
}
jadx-
core/src/main/java/jadx/core/utils/file
s/ZipSecurity.java
→
jadx-
plugins/jadx-plugins-api/src/main/java/jadx/api/plugins/util
s/ZipSecurity.java
浏览文件 @
15602848
package
jadx.
core.utils.file
s
;
package
jadx.
api.plugins.util
s
;
import
java.io.File
;
import
java.io.IOException
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录