Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
gk0749
jadx
提交
57e3dd8f
J
jadx
项目概览
gk0749
/
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,体验更适合开发者的 AI 搜索 >>
未验证
提交
57e3dd8f
编写于
2月 20, 2022
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat(cli): improve single file mode (#1344)(#1384)
上级
a9bbadd6
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
120 addition
and
16 deletion
+120
-16
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
+16
-9
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
+12
-4
jadx-cli/src/main/java/jadx/cli/LogHelper.java
jadx-cli/src/main/java/jadx/cli/LogHelper.java
+1
-0
jadx-cli/src/main/java/jadx/cli/SingleClassMode.java
jadx-cli/src/main/java/jadx/cli/SingleClassMode.java
+87
-0
jadx-core/src/main/java/jadx/core/dex/visitors/SaveCode.java
jadx-core/src/main/java/jadx/core/dex/visitors/SaveCode.java
+4
-3
未找到文件。
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
浏览文件 @
57e3dd8f
...
...
@@ -32,23 +32,19 @@ public class JadxCLI {
public
static
int
execute
(
String
[]
args
)
{
JadxCLIArgs
jadxArgs
=
new
JadxCLIArgs
();
if
(
jadxArgs
.
processArgs
(
args
))
{
return
processAndSave
(
jadxArgs
.
toJadxArgs
()
);
return
processAndSave
(
jadxArgs
);
}
return
0
;
}
private
static
int
processAndSave
(
JadxArgs
jadxArgs
)
{
private
static
int
processAndSave
(
JadxCLIArgs
cliArgs
)
{
JadxArgs
jadxArgs
=
cliArgs
.
toJadxArgs
();
jadxArgs
.
setCodeCache
(
new
NoOpCodeCache
());
jadxArgs
.
setCodeWriterProvider
(
SimpleCodeWriter:
:
new
);
try
(
JadxDecompiler
jadx
=
new
JadxDecompiler
(
jadxArgs
))
{
jadx
.
load
();
if
(
LogHelper
.
getLogLevel
()
==
LogHelper
.
LogLevelEnum
.
QUIET
)
{
jadx
.
save
();
}
else
{
jadx
.
save
(
500
,
(
done
,
total
)
->
{
int
progress
=
(
int
)
(
done
*
100.0
/
total
);
System
.
out
.
printf
(
"INFO - progress: %d of %d (%d%%)\r"
,
done
,
total
,
progress
);
});
if
(!
SingleClassMode
.
process
(
jadx
,
cliArgs
))
{
save
(
jadx
);
}
int
errorsCount
=
jadx
.
getErrorsCount
();
if
(
errorsCount
!=
0
)
{
...
...
@@ -60,4 +56,15 @@ public class JadxCLI {
}
return
0
;
}
private
static
void
save
(
JadxDecompiler
jadx
)
{
if
(
LogHelper
.
getLogLevel
()
==
LogHelper
.
LogLevelEnum
.
QUIET
)
{
jadx
.
save
();
}
else
{
jadx
.
save
(
500
,
(
done
,
total
)
->
{
int
progress
=
(
int
)
(
done
*
100.0
/
total
);
System
.
out
.
printf
(
"INFO - progress: %d of %d (%d%%)\r"
,
done
,
total
,
progress
);
});
}
}
}
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
浏览文件 @
57e3dd8f
...
...
@@ -40,9 +40,12 @@ public class JadxCLIArgs {
@Parameter
(
names
=
{
"-s"
,
"--no-src"
},
description
=
"do not decompile source code"
)
protected
boolean
skipSources
=
false
;
@Parameter
(
names
=
{
"--single-class"
},
description
=
"decompile a single class"
)
@Parameter
(
names
=
{
"--single-class"
},
description
=
"decompile a single class
, can raw name or an alias
"
)
protected
String
singleClass
=
null
;
@Parameter
(
names
=
{
"--single-class-output"
},
description
=
"file or dir for write if decompile a single class"
)
protected
String
singleClassOutput
=
null
;
@Parameter
(
names
=
{
"--output-format"
},
description
=
"can be 'java' or 'json'"
)
protected
String
outputFormat
=
"java"
;
...
...
@@ -227,9 +230,6 @@ public class JadxCLIArgs {
args
.
setOutputFormat
(
JadxArgs
.
OutputFormatEnum
.
valueOf
(
outputFormat
.
toUpperCase
()));
args
.
setThreadsCount
(
threadsCount
);
args
.
setSkipSources
(
skipSources
);
if
(
singleClass
!=
null
)
{
args
.
setClassFilter
(
className
->
singleClass
.
equals
(
className
));
}
args
.
setSkipResources
(
skipResources
);
args
.
setFallbackMode
(
fallbackMode
);
args
.
setShowInconsistentCode
(
showInconsistentCode
);
...
...
@@ -279,6 +279,14 @@ public class JadxCLIArgs {
return
outDirRes
;
}
public
String
getSingleClass
()
{
return
singleClass
;
}
public
String
getSingleClassOutput
()
{
return
singleClassOutput
;
}
public
boolean
isSkipResources
()
{
return
skipResources
;
}
...
...
jadx-cli/src/main/java/jadx/cli/LogHelper.java
浏览文件 @
57e3dd8f
...
...
@@ -58,6 +58,7 @@ public class LogHelper {
// show progress for all levels except quiet
setLevelForClass
(
JadxCLI
.
class
,
Level
.
INFO
);
setLevelForClass
(
JadxDecompiler
.
class
,
Level
.
INFO
);
setLevelForClass
(
SingleClassMode
.
class
,
Level
.
INFO
);
}
}
...
...
jadx-cli/src/main/java/jadx/cli/SingleClassMode.java
0 → 100644
浏览文件 @
57e3dd8f
package
jadx.cli
;
import
java.io.File
;
import
java.util.List
;
import
java.util.stream.Collectors
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.api.ICodeInfo
;
import
jadx.api.JadxDecompiler
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.core.dex.visitors.SaveCode
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
jadx.core.utils.files.FileUtils
;
public
class
SingleClassMode
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
SingleClassMode
.
class
);
public
static
boolean
process
(
JadxDecompiler
jadx
,
JadxCLIArgs
cliArgs
)
{
String
singleClass
=
cliArgs
.
getSingleClass
();
String
singleClassOutput
=
cliArgs
.
getSingleClassOutput
();
if
(
singleClass
==
null
&&
singleClassOutput
==
null
)
{
return
false
;
}
ClassNode
clsForProcess
;
if
(
singleClass
!=
null
)
{
clsForProcess
=
jadx
.
getRoot
().
resolveClass
(
singleClass
);
if
(
clsForProcess
==
null
)
{
clsForProcess
=
jadx
.
getRoot
().
getClasses
().
stream
()
.
filter
(
cls
->
cls
.
getClassInfo
().
getAliasFullName
().
equals
(
singleClass
))
.
findFirst
().
orElse
(
null
);
}
if
(
clsForProcess
==
null
)
{
throw
new
JadxRuntimeException
(
"Input class not found: "
+
singleClass
);
}
if
(
clsForProcess
.
contains
(
AFlag
.
DONT_GENERATE
))
{
throw
new
JadxRuntimeException
(
"Input class can't be saved by currect jadx settings (marked as DONT_GENERATE)"
);
}
if
(
clsForProcess
.
isInner
())
{
clsForProcess
=
clsForProcess
.
getTopParentClass
();
LOG
.
warn
(
"Input class is inner, parent class will be saved: {}"
,
clsForProcess
.
getFullName
());
}
}
else
{
// singleClassOutput is set
// expect only one class to be loaded
List
<
ClassNode
>
classes
=
jadx
.
getRoot
().
getClasses
().
stream
()
.
filter
(
c
->
!
c
.
isInner
()
&&
!
c
.
contains
(
AFlag
.
DONT_GENERATE
))
.
collect
(
Collectors
.
toList
());
int
size
=
classes
.
size
();
if
(
size
==
1
)
{
clsForProcess
=
classes
.
get
(
0
);
}
else
{
throw
new
JadxRuntimeException
(
"Found "
+
size
+
" classes, single class output can't be used"
);
}
}
ICodeInfo
codeInfo
;
try
{
codeInfo
=
clsForProcess
.
decompile
();
}
catch
(
Exception
e
)
{
throw
new
JadxRuntimeException
(
"Class decompilation failed"
,
e
);
}
String
fileExt
=
SaveCode
.
getFileExtension
(
jadx
.
getRoot
());
File
out
;
if
(
singleClassOutput
==
null
)
{
out
=
new
File
(
jadx
.
getArgs
().
getOutDirSrc
(),
clsForProcess
.
getClassInfo
().
getAliasFullPath
()
+
fileExt
);
}
else
{
if
(
singleClassOutput
.
endsWith
(
fileExt
))
{
// treat as file name
out
=
new
File
(
singleClassOutput
);
}
else
{
// treat as directory
out
=
new
File
(
singleClassOutput
,
clsForProcess
.
getShortName
()
+
fileExt
);
}
}
File
resultOut
=
FileUtils
.
prepareFile
(
out
);
if
(
clsForProcess
.
getClassInfo
().
hasAlias
())
{
LOG
.
info
(
"Saving class '{}' (alias: '{}') to file '{}'"
,
clsForProcess
.
getClassInfo
().
getFullName
(),
clsForProcess
.
getFullName
(),
resultOut
.
getAbsolutePath
());
}
else
{
LOG
.
info
(
"Saving class '{}' to file '{}'"
,
clsForProcess
.
getFullName
(),
resultOut
.
getAbsolutePath
());
}
SaveCode
.
save
(
codeInfo
.
getCodeStr
(),
resultOut
);
return
true
;
}
}
jadx-core/src/main/java/jadx/core/dex/visitors/SaveCode.java
浏览文件 @
57e3dd8f
...
...
@@ -11,6 +11,7 @@ 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.dex.nodes.RootNode
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
jadx.core.utils.files.FileUtils
;
...
...
@@ -37,7 +38,7 @@ public class SaveCode {
if
(
cls
.
root
().
getArgs
().
isSkipFilesSave
())
{
return
;
}
String
fileName
=
cls
.
getClassInfo
().
getAliasFullPath
()
+
getFileExtension
(
cls
);
String
fileName
=
cls
.
getClassInfo
().
getAliasFullPath
()
+
getFileExtension
(
cls
.
root
()
);
save
(
codeStr
,
dir
,
fileName
);
}
...
...
@@ -61,8 +62,8 @@ public class SaveCode {
}
}
p
rivate
static
String
getFileExtension
(
ClassNode
cls
)
{
JadxArgs
.
OutputFormatEnum
outputFormat
=
cls
.
root
()
.
getArgs
().
getOutputFormat
();
p
ublic
static
String
getFileExtension
(
RootNode
root
)
{
JadxArgs
.
OutputFormatEnum
outputFormat
=
root
.
getArgs
().
getOutputFormat
();
switch
(
outputFormat
)
{
case
JAVA:
return
".java"
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录