Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
keyescgm
jadx
提交
c47e9cdd
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,发现更多精彩内容 >>
提交
c47e9cdd
编写于
1月 04, 2021
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix: allow to load Spring Boot jar (#1066)
上级
8dd76420
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
139 addition
and
27 deletion
+139
-27
jadx-core/src/main/java/jadx/api/ResourcesLoader.java
jadx-core/src/main/java/jadx/api/ResourcesLoader.java
+4
-1
jadx-plugins/jadx-java-convert/src/main/java/jadx/plugins/input/javaconvert/AsmUtils.java
...rc/main/java/jadx/plugins/input/javaconvert/AsmUtils.java
+26
-0
jadx-plugins/jadx-java-convert/src/main/java/jadx/plugins/input/javaconvert/JavaConvertLoader.java
...ava/jadx/plugins/input/javaconvert/JavaConvertLoader.java
+88
-19
jadx-plugins/jadx-plugins-api/src/main/java/jadx/api/plugins/utils/ZipSecurity.java
...api/src/main/java/jadx/api/plugins/utils/ZipSecurity.java
+21
-7
未找到文件。
jadx-core/src/main/java/jadx/api/ResourcesLoader.java
浏览文件 @
c47e9cdd
...
...
@@ -128,7 +128,10 @@ public final class ResourcesLoader {
return
;
}
if
(
FileUtils
.
isZipFile
(
file
))
{
ZipSecurity
.
visitZipEntries
(
file
,
(
zipFile
,
entry
)
->
addEntry
(
list
,
file
,
entry
));
ZipSecurity
.
visitZipEntries
(
file
,
(
zipFile
,
entry
)
->
{
addEntry
(
list
,
file
,
entry
);
return
null
;
});
}
else
{
addResourceFile
(
list
,
file
);
}
...
...
jadx-plugins/jadx-java-convert/src/main/java/jadx/plugins/input/javaconvert/AsmUtils.java
0 → 100644
浏览文件 @
c47e9cdd
package
jadx.plugins.input.javaconvert
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
org.objectweb.asm.ClassReader
;
public
class
AsmUtils
{
public
static
String
getNameFromClassFile
(
Path
file
)
throws
IOException
{
try
(
InputStream
in
=
Files
.
newInputStream
(
file
))
{
return
getClassFullName
(
new
ClassReader
(
in
));
}
}
public
static
String
getNameFromClassFile
(
byte
[]
content
)
throws
IOException
{
return
getClassFullName
(
new
ClassReader
(
content
));
}
private
static
String
getClassFullName
(
ClassReader
classReader
)
{
return
classReader
.
getClassName
();
}
}
jadx-plugins/jadx-java-convert/src/main/java/jadx/plugins/input/javaconvert/JavaConvertLoader.java
浏览文件 @
c47e9cdd
package
jadx.plugins.input.javaconvert
;
import
java.io.B
ufferedIn
putStream
;
import
java.io.B
yteArrayOut
putStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
...
...
@@ -9,13 +9,14 @@ import java.nio.file.Files;
import
java.nio.file.LinkOption
;
import
java.nio.file.Path
;
import
java.nio.file.PathMatcher
;
import
java.nio.file.attribute.FileTime
;
import
java.util.List
;
import
java.util.Objects
;
import
java.util.jar.JarEntry
;
import
java.util.jar.JarOutputStream
;
import
java.util.stream.Collectors
;
import
java.util.stream.Stream
;
import
org.objectweb.asm.ClassReader
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -41,7 +42,7 @@ public class JavaConvertLoader {
try
{
convertJar
(
result
,
path
);
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Failed to convert file:
"
+
path
.
toAbsolutePath
(),
e
);
LOG
.
error
(
"Failed to convert file:
{}"
,
path
.
toAbsolutePath
(),
e
);
}
});
}
...
...
@@ -59,7 +60,7 @@ public class JavaConvertLoader {
Path
jarFile
=
Files
.
createTempFile
(
"jadx-"
,
".jar"
);
try
(
JarOutputStream
jo
=
new
JarOutputStream
(
Files
.
newOutputStream
(
jarFile
)))
{
for
(
Path
file
:
clsFiles
)
{
String
clsName
=
getNameFromClassFile
(
file
);
String
clsName
=
AsmUtils
.
getNameFromClassFile
(
file
);
if
(
clsName
==
null
||
!
ZipSecurity
.
isValidZipEntryName
(
clsName
))
{
throw
new
IOException
(
"Can't read class name from file: "
+
file
);
}
...
...
@@ -74,13 +75,6 @@ public class JavaConvertLoader {
}
}
public
static
String
getNameFromClassFile
(
Path
file
)
throws
IOException
{
try
(
InputStream
in
=
Files
.
newInputStream
(
file
))
{
ClassReader
classReader
=
new
ClassReader
(
in
);
return
classReader
.
getClassName
();
}
}
private
static
void
processAars
(
List
<
Path
>
input
,
ConvertResult
result
)
{
PathMatcher
aarMatcher
=
FileSystems
.
getDefault
().
getPathMatcher
(
"glob:**.aar"
);
input
.
stream
()
...
...
@@ -100,6 +94,68 @@ public class JavaConvertLoader {
}
private
static
void
convertJar
(
ConvertResult
result
,
Path
path
)
throws
Exception
{
if
(
repackAndConvertJar
(
result
,
path
))
{
return
;
}
convertSimpleJar
(
result
,
path
);
}
private
static
boolean
repackAndConvertJar
(
ConvertResult
result
,
Path
path
)
throws
Exception
{
// check if jar need a full repackage
Boolean
repackNeeded
=
ZipSecurity
.
visitZipEntries
(
path
.
toFile
(),
(
zipFile
,
zipEntry
)
->
{
String
entryName
=
zipEntry
.
getName
();
if
(
zipEntry
.
isDirectory
())
{
if
(
entryName
.
equals
(
"BOOT-INF/"
))
{
return
true
;
// Spring Boot jar
}
if
(
entryName
.
equals
(
"META-INF/versions/"
))
{
return
true
;
// exclude duplicated classes
}
}
if
(
entryName
.
endsWith
(
".jar"
))
{
return
true
;
// contains sub jars
}
if
(
entryName
.
endsWith
(
"module-info.class"
))
{
return
true
;
// need to exclude module files
}
return
null
;
});
if
(!
Objects
.
equals
(
repackNeeded
,
Boolean
.
TRUE
))
{
return
false
;
}
Path
jarFile
=
Files
.
createTempFile
(
"jadx-classes-"
,
".jar"
);
result
.
addTempPath
(
jarFile
);
try
(
JarOutputStream
jo
=
new
JarOutputStream
(
Files
.
newOutputStream
(
jarFile
)))
{
ZipSecurity
.
readZipEntries
(
path
.
toFile
(),
(
entry
,
in
)
->
{
try
{
String
entryName
=
entry
.
getName
();
if
(
entryName
.
endsWith
(
".class"
))
{
if
(
entryName
.
endsWith
(
"module-info.class"
)
||
entryName
.
startsWith
(
"META-INF/versions/"
))
{
return
;
}
byte
[]
clsFileContent
=
inputStreamToByteArray
(
in
);
String
clsName
=
AsmUtils
.
getNameFromClassFile
(
clsFileContent
);
if
(
clsName
==
null
||
!
ZipSecurity
.
isValidZipEntryName
(
clsName
))
{
throw
new
IOException
(
"Can't read class name from file: "
+
entryName
);
}
addJarEntry
(
jo
,
clsName
+
".class"
,
clsFileContent
,
entry
.
getLastModifiedTime
());
}
else
if
(
entryName
.
endsWith
(
".jar"
))
{
Path
tempJar
=
saveInputStreamToFile
(
in
,
".jar"
);
result
.
addTempPath
(
tempJar
);
convertJar
(
result
,
tempJar
);
}
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Failed to process jar entry: {} in {}"
,
entry
,
path
,
e
);
}
});
}
convertSimpleJar
(
result
,
jarFile
);
return
true
;
}
private
static
void
convertSimpleJar
(
ConvertResult
result
,
Path
path
)
throws
Exception
{
Path
tempDirectory
=
Files
.
createTempDirectory
(
"jadx-"
);
result
.
addTempPath
(
tempDirectory
);
...
...
@@ -119,18 +175,24 @@ public class JavaConvertLoader {
}
}
p
ublic
static
void
addFileToJar
(
JarOutputStream
jar
,
Path
source
,
String
entryName
)
throws
IOException
{
try
(
BufferedInputStream
in
=
new
BufferedInputStream
(
Files
.
newInputStream
(
source
)))
{
JarEntry
entry
=
new
JarEntry
(
entryName
);
entry
.
setTime
(
Files
.
getLastModifiedTime
(
source
,
LinkOption
.
NOFOLLOW_LINKS
).
toMillis
()
);
jar
.
putNextEntry
(
entry
);
p
rivate
static
void
addFileToJar
(
JarOutputStream
jar
,
Path
source
,
String
entryName
)
throws
IOException
{
byte
[]
fileContent
=
Files
.
readAllBytes
(
source
);
FileTime
lastModifiedTime
=
Files
.
getLastModifiedTime
(
source
,
LinkOption
.
NOFOLLOW_LINKS
);
addJarEntry
(
jar
,
entryName
,
fileContent
,
lastModifiedTime
);
}
copyStream
(
in
,
jar
);
jar
.
closeEntry
();
private
static
void
addJarEntry
(
JarOutputStream
jar
,
String
entryName
,
byte
[]
content
,
FileTime
modTime
)
throws
IOException
{
JarEntry
entry
=
new
JarEntry
(
entryName
);
if
(
modTime
!=
null
)
{
entry
.
setTime
(
modTime
.
toMillis
());
}
jar
.
putNextEntry
(
entry
);
jar
.
write
(
content
);
jar
.
closeEntry
();
}
p
ublic
static
void
copyStream
(
InputStream
input
,
OutputStream
output
)
throws
IOException
{
p
rivate
static
void
copyStream
(
InputStream
input
,
OutputStream
output
)
throws
IOException
{
byte
[]
buffer
=
new
byte
[
8
*
1024
];
while
(
true
)
{
int
count
=
input
.
read
(
buffer
);
...
...
@@ -141,6 +203,13 @@ public class JavaConvertLoader {
}
}
private
static
byte
[]
inputStreamToByteArray
(
InputStream
input
)
throws
IOException
{
try
(
ByteArrayOutputStream
output
=
new
ByteArrayOutputStream
())
{
copyStream
(
input
,
output
);
return
output
.
toByteArray
();
}
}
private
static
Path
saveInputStreamToFile
(
InputStream
in
,
String
suffix
)
throws
IOException
{
Path
tempJar
=
Files
.
createTempFile
(
"jadx-temp-"
,
suffix
);
try
(
OutputStream
out
=
Files
.
newOutputStream
(
tempJar
))
{
...
...
jadx-plugins/jadx-plugins-api/src/main/java/jadx/api/plugins/utils/ZipSecurity.java
浏览文件 @
c47e9cdd
...
...
@@ -6,9 +6,11 @@ import java.io.IOException;
import
java.io.InputStream
;
import
java.util.Enumeration
;
import
java.util.function.BiConsumer
;
import
java.util.function.BiFunction
;
import
java.util.zip.ZipEntry
;
import
java.util.zip.ZipFile
;
import
org.jetbrains.annotations.Nullable
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -86,14 +88,22 @@ public class ZipSecurity {
return
new
BufferedInputStream
(
limited
);
}
public
static
void
visitZipEntries
(
File
file
,
BiConsumer
<
ZipFile
,
ZipEntry
>
visitor
)
{
/**
* Visit valid entries in zip file.
* Return not null value from visitor to stop iteration.
*/
@Nullable
public
static
<
R
>
R
visitZipEntries
(
File
file
,
BiFunction
<
ZipFile
,
ZipEntry
,
R
>
visitor
)
{
try
(
ZipFile
zip
=
new
ZipFile
(
file
))
{
Enumeration
<?
extends
ZipEntry
>
entries
=
zip
.
entries
();
int
entriesProcessed
=
0
;
while
(
entries
.
hasMoreElements
())
{
ZipEntry
entry
=
entries
.
nextElement
();
if
(!
entry
.
isDirectory
()
&&
isValidZipEntry
(
entry
))
{
visitor
.
accept
(
zip
,
entry
);
if
(
isValidZipEntry
(
entry
))
{
R
result
=
visitor
.
apply
(
zip
,
entry
);
if
(
result
!=
null
)
{
return
result
;
}
entriesProcessed
++;
if
(
entriesProcessed
>
MAX_ENTRIES_COUNT
)
{
throw
new
IllegalStateException
(
"Zip entries count limit exceeded: "
+
MAX_ENTRIES_COUNT
...
...
@@ -104,15 +114,19 @@ public class ZipSecurity {
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
"Failed to process zip file: "
+
file
.
getAbsolutePath
(),
e
);
}
return
null
;
}
public
static
void
readZipEntries
(
File
file
,
BiConsumer
<
ZipEntry
,
InputStream
>
visitor
)
{
visitZipEntries
(
file
,
(
zip
,
entry
)
->
{
try
(
InputStream
in
=
getInputStreamForEntry
(
zip
,
entry
))
{
visitor
.
accept
(
entry
,
in
);
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
"Error process zip entry: "
+
entry
.
getName
());
if
(!
entry
.
isDirectory
())
{
try
(
InputStream
in
=
getInputStreamForEntry
(
zip
,
entry
))
{
visitor
.
accept
(
entry
,
in
);
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
"Error process zip entry: "
+
entry
.
getName
());
}
}
return
null
;
});
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录