Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
keyescgm
jadx
提交
54683e31
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,体验更适合开发者的 AI 搜索 >>
未验证
提交
54683e31
编写于
2月 21, 2022
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: plugin options, add verify checksum option for dex input (#1385)
上级
09335395
变更
24
隐藏空白更改
内联
并排
Showing
24 changed file
with
435 addition
and
25 deletion
+435
-25
README.md
README.md
+6
-0
jadx-cli/src/main/java/jadx/cli/JCommanderWrapper.java
jadx-cli/src/main/java/jadx/cli/JCommanderWrapper.java
+54
-3
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
+34
-2
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
+15
-1
jadx-core/src/main/java/jadx/api/JadxArgs.java
jadx-core/src/main/java/jadx/api/JadxArgs.java
+13
-0
jadx-core/src/main/java/jadx/api/JadxDecompiler.java
jadx-core/src/main/java/jadx/api/JadxDecompiler.java
+13
-0
jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
+4
-0
jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsWindow.java
...i/src/main/java/jadx/gui/settings/JadxSettingsWindow.java
+42
-0
jadx-gui/src/main/java/jadx/gui/utils/ui/DocumentUpdateListener.java
...c/main/java/jadx/gui/utils/ui/DocumentUpdateListener.java
+30
-0
jadx-gui/src/main/resources/i18n/Messages_de_DE.properties
jadx-gui/src/main/resources/i18n/Messages_de_DE.properties
+1
-0
jadx-gui/src/main/resources/i18n/Messages_en_US.properties
jadx-gui/src/main/resources/i18n/Messages_en_US.properties
+1
-0
jadx-gui/src/main/resources/i18n/Messages_es_ES.properties
jadx-gui/src/main/resources/i18n/Messages_es_ES.properties
+1
-0
jadx-gui/src/main/resources/i18n/Messages_ko_KR.properties
jadx-gui/src/main/resources/i18n/Messages_ko_KR.properties
+1
-0
jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties
jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties
+1
-0
jadx-gui/src/main/resources/i18n/Messages_zh_TW.properties
jadx-gui/src/main/resources/i18n/Messages_zh_TW.properties
+1
-0
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexFileLoader.java
...t/src/main/java/jadx/plugins/input/dex/DexFileLoader.java
+19
-9
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexInputOptions.java
...src/main/java/jadx/plugins/input/dex/DexInputOptions.java
+51
-0
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexInputPlugin.java
.../src/main/java/jadx/plugins/input/dex/DexInputPlugin.java
+23
-8
jadx-plugins/jadx-java-convert/src/main/java/jadx/plugins/input/javaconvert/JavaConvertPlugin.java
...ava/jadx/plugins/input/javaconvert/JavaConvertPlugin.java
+3
-1
jadx-plugins/jadx-plugins-api/src/main/java/jadx/api/plugins/JadxPluginManager.java
...api/src/main/java/jadx/api/plugins/JadxPluginManager.java
+34
-0
jadx-plugins/jadx-plugins-api/src/main/java/jadx/api/plugins/options/JadxPluginOptions.java
...main/java/jadx/api/plugins/options/JadxPluginOptions.java
+13
-0
jadx-plugins/jadx-plugins-api/src/main/java/jadx/api/plugins/options/OptionDescription.java
...main/java/jadx/api/plugins/options/OptionDescription.java
+25
-0
jadx-plugins/jadx-plugins-api/src/main/java/jadx/api/plugins/options/impl/JadxOptionDescription.java
.../jadx/api/plugins/options/impl/JadxOptionDescription.java
+47
-0
jadx-plugins/jadx-smali-input/src/main/java/jadx/plugins/input/smali/SmaliInputPlugin.java
.../main/java/jadx/plugins/input/smali/SmaliInputPlugin.java
+3
-1
未找到文件。
README.md
浏览文件 @
54683e31
...
...
@@ -123,11 +123,17 @@ options:
-q, --quiet - turn off output (set --log-level to QUIET)
--version - print jadx version
-h, --help - print this help
Plugin options (-P<name>=<value>):
1) dex-input (Load .dex and .apk files)
-Pdex-input.verify-checksum - Verify dex file checksum before load, values: [yes, no], default: yes
Examples:
jadx -d out classes.dex
jadx --rename-flags "none" classes.dex
jadx --rename-flags "valid, printable" classes.dex
jadx --log-level ERROR app.apk
jadx -Pdex-input.verify-checksum=no app.apk
```
These options also worked on jadx-gui running from command line and override options from preferences dialog
...
...
jadx-cli/src/main/java/jadx/cli/JCommanderWrapper.java
浏览文件 @
54683e31
...
...
@@ -17,6 +17,11 @@ import com.beust.jcommander.ParameterException;
import
com.beust.jcommander.Parameterized
;
import
jadx.api.JadxDecompiler
;
import
jadx.api.plugins.JadxPlugin
;
import
jadx.api.plugins.JadxPluginInfo
;
import
jadx.api.plugins.JadxPluginManager
;
import
jadx.api.plugins.options.JadxPluginOptions
;
import
jadx.api.plugins.options.OptionDescription
;
public
class
JCommanderWrapper
<
T
>
{
private
final
JCommander
jc
;
...
...
@@ -70,24 +75,25 @@ public class JCommanderWrapper<T> {
maxNamesLen
=
len
;
}
}
maxNamesLen
+=
3
;
JadxCLIArgs
args
=
(
JadxCLIArgs
)
jc
.
getObjects
().
get
(
0
);
for
(
Field
f
:
getFields
(
args
.
getClass
()))
{
String
name
=
f
.
getName
();
ParameterDescription
p
=
paramsMap
.
get
(
name
);
if
(
p
==
null
)
{
if
(
p
==
null
||
p
.
getParameter
().
hidden
()
)
{
continue
;
}
StringBuilder
opt
=
new
StringBuilder
();
opt
.
append
(
" "
).
append
(
p
.
getNames
());
String
description
=
p
.
getDescription
();
addSpaces
(
opt
,
maxNamesLen
-
opt
.
length
()
+
3
);
addSpaces
(
opt
,
maxNamesLen
-
opt
.
length
());
if
(
description
.
contains
(
"\n"
))
{
String
[]
lines
=
description
.
split
(
"\n"
);
opt
.
append
(
"- "
).
append
(
lines
[
0
]);
for
(
int
i
=
1
;
i
<
lines
.
length
;
i
++)
{
opt
.
append
(
'\n'
);
addSpaces
(
opt
,
maxNamesLen
+
5
);
addSpaces
(
opt
,
maxNamesLen
+
2
);
opt
.
append
(
lines
[
i
]);
}
}
else
{
...
...
@@ -99,11 +105,14 @@ public class JCommanderWrapper<T> {
}
out
.
println
(
opt
);
}
out
.
println
(
appendPluginOptions
(
maxNamesLen
));
out
.
println
();
out
.
println
(
"Examples:"
);
out
.
println
(
" jadx -d out classes.dex"
);
out
.
println
(
" jadx --rename-flags \"none\" classes.dex"
);
out
.
println
(
" jadx --rename-flags \"valid, printable\" classes.dex"
);
out
.
println
(
" jadx --log-level ERROR app.apk"
);
out
.
println
(
" jadx -Pdex-input.verify-checksum=no app.apk"
);
}
/**
...
...
@@ -145,4 +154,46 @@ public class JCommanderWrapper<T> {
str
.
append
(
' '
);
}
}
private
String
appendPluginOptions
(
int
maxNamesLen
)
{
StringBuilder
sb
=
new
StringBuilder
();
JadxPluginManager
pluginManager
=
new
JadxPluginManager
();
pluginManager
.
load
();
int
k
=
1
;
for
(
JadxPlugin
plugin
:
pluginManager
.
getAllPlugins
())
{
if
(
plugin
instanceof
JadxPluginOptions
)
{
if
(
appendPlugin
(((
JadxPluginOptions
)
plugin
),
sb
,
maxNamesLen
,
k
))
{
k
++;
}
}
}
if
(
sb
.
length
()
==
0
)
{
return
""
;
}
return
"\nPlugin options (-P<name>=<value>):"
+
sb
;
}
private
boolean
appendPlugin
(
JadxPluginOptions
plugin
,
StringBuilder
out
,
int
maxNamesLen
,
int
k
)
{
List
<
OptionDescription
>
descs
=
plugin
.
getOptionsDescriptions
();
if
(
descs
.
isEmpty
())
{
return
false
;
}
JadxPluginInfo
pluginInfo
=
plugin
.
getPluginInfo
();
out
.
append
(
"\n "
).
append
(
k
).
append
(
") "
);
out
.
append
(
pluginInfo
.
getPluginId
()).
append
(
" ("
).
append
(
pluginInfo
.
getDescription
()).
append
(
") "
);
for
(
OptionDescription
desc
:
descs
)
{
StringBuilder
opt
=
new
StringBuilder
();
opt
.
append
(
" -P"
).
append
(
desc
.
name
());
addSpaces
(
opt
,
maxNamesLen
-
opt
.
length
());
opt
.
append
(
"- "
).
append
(
desc
.
description
());
if
(!
desc
.
values
().
isEmpty
())
{
opt
.
append
(
", values: "
).
append
(
desc
.
values
());
}
if
(
desc
.
defaultValue
()
!=
null
)
{
opt
.
append
(
", default: "
).
append
(
desc
.
defaultValue
());
}
out
.
append
(
"\n"
).
append
(
opt
);
}
return
true
;
}
}
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
浏览文件 @
54683e31
...
...
@@ -7,6 +7,7 @@ import jadx.api.JadxArgs;
import
jadx.api.JadxDecompiler
;
import
jadx.api.impl.NoOpCodeCache
;
import
jadx.api.impl.SimpleCodeWriter
;
import
jadx.cli.LogHelper.LogLevelEnum
;
import
jadx.core.utils.exceptions.JadxArgsValidateException
;
import
jadx.core.utils.files.FileUtils
;
...
...
@@ -21,7 +22,7 @@ public class JadxCLI {
LOG
.
error
(
"Incorrect arguments: {}"
,
e
.
getMessage
());
result
=
1
;
}
catch
(
Exception
e
)
{
LOG
.
error
(
"
jadx error: {}"
,
e
.
getMessage
()
,
e
);
LOG
.
error
(
"
Process error:"
,
e
);
result
=
1
;
}
finally
{
FileUtils
.
deleteTempRootDir
();
...
...
@@ -38,11 +39,16 @@ public class JadxCLI {
}
private
static
int
processAndSave
(
JadxCLIArgs
cliArgs
)
{
setLogLevelsForLoadingStage
(
cliArgs
);
JadxArgs
jadxArgs
=
cliArgs
.
toJadxArgs
();
jadxArgs
.
setCodeCache
(
new
NoOpCodeCache
());
jadxArgs
.
setCodeWriterProvider
(
SimpleCodeWriter:
:
new
);
try
(
JadxDecompiler
jadx
=
new
JadxDecompiler
(
jadxArgs
))
{
jadx
.
load
();
if
(
checkForErrors
(
jadx
))
{
return
1
;
}
LogHelper
.
setLogLevelFromArgs
(
cliArgs
);
if
(!
SingleClassMode
.
process
(
jadx
,
cliArgs
))
{
save
(
jadx
);
}
...
...
@@ -57,8 +63,34 @@ public class JadxCLI {
return
0
;
}
private
static
void
setLogLevelsForLoadingStage
(
JadxCLIArgs
cliArgs
)
{
switch
(
cliArgs
.
getLogLevel
())
{
case
QUIET:
LogHelper
.
setLogLevelFromArgs
(
cliArgs
);
break
;
case
PROGRESS:
// show load errors
LogHelper
.
applyLogLevel
(
LogLevelEnum
.
ERROR
);
break
;
}
}
private
static
boolean
checkForErrors
(
JadxDecompiler
jadx
)
{
if
(
jadx
.
getRoot
().
getClasses
().
isEmpty
())
{
LOG
.
error
(
"Load failed! No classes for decompile!"
);
return
true
;
}
if
(
jadx
.
getErrorsCount
()
>
0
)
{
LOG
.
error
(
"Load with errors! Check log for details"
);
// continue processing
return
false
;
}
return
false
;
}
private
static
void
save
(
JadxDecompiler
jadx
)
{
if
(
LogHelper
.
getLogLevel
()
==
Log
Helper
.
Log
LevelEnum
.
QUIET
)
{
if
(
LogHelper
.
getLogLevel
()
==
LogLevelEnum
.
QUIET
)
{
jadx
.
save
();
}
else
{
jadx
.
save
(
500
,
(
done
,
total
)
->
{
...
...
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
浏览文件 @
54683e31
...
...
@@ -2,12 +2,15 @@ package jadx.cli;
import
java.util.ArrayList
;
import
java.util.EnumSet
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Locale
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
import
java.util.stream.Stream
;
import
com.beust.jcommander.DynamicParameter
;
import
com.beust.jcommander.IStringConverter
;
import
com.beust.jcommander.Parameter
;
...
...
@@ -177,6 +180,9 @@ public class JadxCLIArgs {
@Parameter
(
names
=
{
"-h"
,
"--help"
},
description
=
"print this help"
,
help
=
true
)
protected
boolean
printHelp
=
false
;
@DynamicParameter
(
names
=
"-P"
,
description
=
"Plugin options"
,
hidden
=
true
)
protected
Map
<
String
,
String
>
pluginOptions
=
new
HashMap
<>();
public
boolean
processArgs
(
String
[]
args
)
{
JCommanderWrapper
<
JadxCLIArgs
>
jcw
=
new
JCommanderWrapper
<>(
this
);
return
jcw
.
parse
(
args
)
&&
process
(
jcw
);
...
...
@@ -212,7 +218,6 @@ public class JadxCLIArgs {
if
(
threadsCount
<=
0
)
{
throw
new
JadxException
(
"Threads count must be positive, got: "
+
threadsCount
);
}
LogHelper
.
setLogLevelFromArgs
(
this
);
}
catch
(
JadxException
e
)
{
System
.
err
.
println
(
"ERROR: "
+
e
.
getMessage
());
jcw
.
printUsage
();
...
...
@@ -260,6 +265,7 @@ public class JadxCLIArgs {
args
.
setFsCaseSensitive
(
fsCaseSensitive
);
args
.
setCommentsLevel
(
commentsLevel
);
args
.
setUseDxInput
(
useDx
);
args
.
setPluginOptions
(
pluginOptions
);
return
args
;
}
...
...
@@ -411,6 +417,14 @@ public class JadxCLIArgs {
return
commentsLevel
;
}
public
LogHelper
.
LogLevelEnum
getLogLevel
()
{
return
logLevel
;
}
public
Map
<
String
,
String
>
getPluginOptions
()
{
return
pluginOptions
;
}
static
class
RenameConverter
implements
IStringConverter
<
Set
<
RenameEnum
>>
{
private
final
String
paramName
;
...
...
jadx-core/src/main/java/jadx/api/JadxArgs.java
浏览文件 @
54683e31
...
...
@@ -4,7 +4,9 @@ import java.io.File;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.EnumSet
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.function.Function
;
import
java.util.function.Predicate
;
...
...
@@ -100,6 +102,8 @@ public class JadxArgs {
*/
private
boolean
skipFilesSave
=
false
;
private
Map
<
String
,
String
>
pluginOptions
=
new
HashMap
<>();
public
JadxArgs
()
{
// use default options
}
...
...
@@ -474,6 +478,14 @@ public class JadxArgs {
this
.
skipFilesSave
=
skipFilesSave
;
}
public
Map
<
String
,
String
>
getPluginOptions
()
{
return
pluginOptions
;
}
public
void
setPluginOptions
(
Map
<
String
,
String
>
pluginOptions
)
{
this
.
pluginOptions
=
pluginOptions
;
}
@Override
public
String
toString
()
{
return
"JadxArgs{"
+
"inputFiles="
+
inputFiles
...
...
@@ -507,6 +519,7 @@ public class JadxArgs {
+
", codeCache="
+
codeCache
+
", codeWriter="
+
codeWriterProvider
.
apply
(
this
).
getClass
().
getSimpleName
()
+
", useDxInput="
+
useDxInput
+
", pluginOptions="
+
pluginOptions
+
'}'
;
}
}
jadx-core/src/main/java/jadx/api/JadxDecompiler.java
浏览文件 @
54683e31
...
...
@@ -30,6 +30,7 @@ import jadx.api.plugins.JadxPlugin;
import
jadx.api.plugins.JadxPluginManager
;
import
jadx.api.plugins.input.JadxInputPlugin
;
import
jadx.api.plugins.input.data.ILoadResult
;
import
jadx.api.plugins.options.JadxPluginOptions
;
import
jadx.core.Jadx
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.attributes.nodes.LineAttrNode
;
...
...
@@ -168,6 +169,18 @@ public final class JadxDecompiler implements Closeable {
LOG
.
debug
(
"Resolved plugins: {}"
,
Utils
.
collectionMap
(
pluginManager
.
getResolvedPlugins
(),
p
->
p
.
getPluginInfo
().
getPluginId
()));
}
Map
<
String
,
String
>
pluginOptions
=
args
.
getPluginOptions
();
if
(!
pluginOptions
.
isEmpty
())
{
LOG
.
debug
(
"Applying plugin options: {}"
,
pluginOptions
);
for
(
JadxPluginOptions
plugin
:
pluginManager
.
getPluginsWithOptions
())
{
try
{
plugin
.
setOptions
(
pluginOptions
);
}
catch
(
Exception
e
)
{
String
pluginId
=
plugin
.
getPluginInfo
().
getPluginId
();
throw
new
JadxRuntimeException
(
"Failed to apply options for plugin: "
+
pluginId
,
e
);
}
}
}
}
public
void
registerPlugin
(
JadxPlugin
plugin
)
{
...
...
jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
浏览文件 @
54683e31
...
...
@@ -582,6 +582,10 @@ public class JadxSettings extends JadxCLIArgs {
this
.
lineNumbersMode
=
lineNumbersMode
;
}
public
void
setPluginOptions
(
Map
<
String
,
String
>
pluginOptions
)
{
this
.
pluginOptions
=
pluginOptions
;
}
private
void
upgradeSettings
(
int
fromVersion
)
{
LOG
.
debug
(
"upgrade settings from version: {} to {}"
,
fromVersion
,
CURRENT_SETTINGS_VERSION
);
if
(
fromVersion
==
0
)
{
...
...
jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsWindow.java
浏览文件 @
54683e31
...
...
@@ -62,6 +62,11 @@ import jadx.api.CommentsLevel;
import
jadx.api.JadxArgs
;
import
jadx.api.JadxArgs.UseKotlinMethodsForVarNames
;
import
jadx.api.args.DeobfuscationMapFileMode
;
import
jadx.api.plugins.JadxPlugin
;
import
jadx.api.plugins.JadxPluginInfo
;
import
jadx.api.plugins.JadxPluginManager
;
import
jadx.api.plugins.options.JadxPluginOptions
;
import
jadx.api.plugins.options.OptionDescription
;
import
jadx.gui.ui.MainWindow
;
import
jadx.gui.ui.codearea.EditorTheme
;
import
jadx.gui.utils.FontUtils
;
...
...
@@ -69,6 +74,7 @@ import jadx.gui.utils.LafManager;
import
jadx.gui.utils.LangLocale
;
import
jadx.gui.utils.NLS
;
import
jadx.gui.utils.UiUtils
;
import
jadx.gui.utils.ui.DocumentUpdateListener
;
public
class
JadxSettingsWindow
extends
JDialog
{
private
static
final
long
serialVersionUID
=
-
1804570470377354148L
;
...
...
@@ -117,8 +123,11 @@ public class JadxSettingsWindow extends JDialog {
leftPanel
.
add
(
makeAppearanceGroup
());
leftPanel
.
add
(
makeOtherGroup
());
leftPanel
.
add
(
makeSearchResGroup
());
leftPanel
.
add
(
makePluginOptionsGroup
());
leftPanel
.
add
(
Box
.
createVerticalGlue
());
rightPanel
.
add
(
makeDecompilationGroup
());
rightPanel
.
add
(
Box
.
createVerticalGlue
());
JButton
saveBtn
=
new
JButton
(
NLS
.
str
(
"preferences.save"
));
saveBtn
.
addActionListener
(
event
->
{
...
...
@@ -550,6 +559,39 @@ public class JadxSettingsWindow extends JDialog {
return
other
;
}
private
SettingsGroup
makePluginOptionsGroup
()
{
SettingsGroup
pluginsGroup
=
new
SettingsGroup
(
NLS
.
str
(
"preferences.plugins"
));
JadxPluginManager
pluginManager
=
mainWindow
.
getWrapper
().
getDecompiler
().
getPluginManager
();
for
(
JadxPlugin
plugin
:
pluginManager
.
getAllPlugins
())
{
if
(!(
plugin
instanceof
JadxPluginOptions
))
{
continue
;
}
JadxPluginInfo
pluginInfo
=
plugin
.
getPluginInfo
();
JadxPluginOptions
optPlugin
=
(
JadxPluginOptions
)
plugin
;
for
(
OptionDescription
opt
:
optPlugin
.
getOptionsDescriptions
())
{
String
title
=
"["
+
pluginInfo
.
getPluginId
()
+
"] "
+
opt
.
description
();
if
(
opt
.
values
().
isEmpty
())
{
JTextField
textField
=
new
JTextField
();
textField
.
getDocument
().
addDocumentListener
(
new
DocumentUpdateListener
(
event
->
{
settings
.
getPluginOptions
().
put
(
opt
.
name
(),
textField
.
getText
());
needReload
();
}));
pluginsGroup
.
addRow
(
title
,
textField
);
}
else
{
String
curValue
=
settings
.
getPluginOptions
().
get
(
opt
.
name
());
JComboBox
<
String
>
combo
=
new
JComboBox
<>(
opt
.
values
().
toArray
(
new
String
[
0
]));
combo
.
setSelectedItem
(
curValue
!=
null
?
curValue
:
opt
.
defaultValue
());
combo
.
addActionListener
(
e
->
{
settings
.
getPluginOptions
().
put
(
opt
.
name
(),
((
String
)
combo
.
getSelectedItem
()));
needReload
();
});
pluginsGroup
.
addRow
(
title
,
combo
);
}
}
}
return
pluginsGroup
;
}
private
SettingsGroup
makeOtherGroup
()
{
JComboBox
<
LangLocale
>
languageCbx
=
new
JComboBox
<>(
NLS
.
getLangLocales
());
for
(
LangLocale
locale
:
NLS
.
getLangLocales
())
{
...
...
jadx-gui/src/main/java/jadx/gui/utils/ui/DocumentUpdateListener.java
0 → 100644
浏览文件 @
54683e31
package
jadx.gui.utils.ui
;
import
java.util.function.Consumer
;
import
javax.swing.event.DocumentEvent
;
import
javax.swing.event.DocumentListener
;
public
class
DocumentUpdateListener
implements
DocumentListener
{
private
final
Consumer
<
DocumentEvent
>
listener
;
public
DocumentUpdateListener
(
Consumer
<
DocumentEvent
>
listener
)
{
this
.
listener
=
listener
;
}
@Override
public
void
insertUpdate
(
DocumentEvent
event
)
{
this
.
listener
.
accept
(
event
);
}
@Override
public
void
removeUpdate
(
DocumentEvent
event
)
{
this
.
listener
.
accept
(
event
);
}
@Override
public
void
changedUpdate
(
DocumentEvent
event
)
{
this
.
listener
.
accept
(
event
);
}
}
jadx-gui/src/main/resources/i18n/Messages_de_DE.properties
浏览文件 @
54683e31
...
...
@@ -119,6 +119,7 @@ preferences.title=Einstellungen
preferences.deobfuscation
=
Deobfuskierung
preferences.appearance
=
Aussehen
preferences.decompile
=
Dekompilierung
#preferences.plugins=Plugins
preferences.project
=
Projekt
preferences.other
=
Andere
preferences.language
=
Sprache
...
...
jadx-gui/src/main/resources/i18n/Messages_en_US.properties
浏览文件 @
54683e31
...
...
@@ -119,6 +119,7 @@ preferences.title=Preferences
preferences.deobfuscation
=
Deobfuscation
preferences.appearance
=
Appearance
preferences.decompile
=
Decompilation
preferences.plugins
=
Plugins
preferences.project
=
Project
preferences.other
=
Other
preferences.language
=
Language
...
...
jadx-gui/src/main/resources/i18n/Messages_es_ES.properties
浏览文件 @
54683e31
...
...
@@ -119,6 +119,7 @@ preferences.title=Preferencias
preferences.deobfuscation
=
Desofuscación
#preferences.appearance=Appearance
preferences.decompile
=
Descompilación
#preferences.plugins=Plugins
#preferences.project=
preferences.other
=
Otros
preferences.language
=
Idioma
...
...
jadx-gui/src/main/resources/i18n/Messages_ko_KR.properties
浏览文件 @
54683e31
...
...
@@ -119,6 +119,7 @@ preferences.title=설정
preferences.deobfuscation
=
난독화 해제
preferences.appearance
=
외관
preferences.decompile
=
디컴파일
#preferences.plugins=Plugins
preferences.project
=
프로젝트
preferences.other
=
기타
preferences.language
=
언어
...
...
jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties
浏览文件 @
54683e31
...
...
@@ -119,6 +119,7 @@ preferences.title=首选项
preferences.deobfuscation
=
反混淆
preferences.appearance
=
界面
preferences.decompile
=
反编译
#preferences.plugins=Plugins
preferences.project
=
项目
preferences.other
=
其他
preferences.language
=
语言
...
...
jadx-gui/src/main/resources/i18n/Messages_zh_TW.properties
浏览文件 @
54683e31
...
...
@@ -119,6 +119,7 @@ preferences.title=選項
preferences.deobfuscation
=
去模糊化
preferences.appearance
=
外觀
preferences.decompile
=
反編譯
#preferences.plugins=Plugins
preferences.project
=
專案
preferences.other
=
其他
preferences.language
=
語言
...
...
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexFileLoader.java
浏览文件 @
54683e31
...
...
@@ -23,19 +23,27 @@ import jadx.plugins.input.dex.utils.DexCheckSum;
public
class
DexFileLoader
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
DexFileLoader
.
class
);
// sharing between all instances (can be used in other plugins) // TODO:
private
static
int
dexUniqId
=
1
;
public
static
List
<
DexReader
>
collectDexFiles
(
List
<
Path
>
pathsList
)
{
private
final
DexInputOptions
options
;
public
DexFileLoader
(
DexInputOptions
options
)
{
this
.
options
=
options
;
resetDexUniqId
();
}
public
List
<
DexReader
>
collectDexFiles
(
List
<
Path
>
pathsList
)
{
return
pathsList
.
stream
()
.
map
(
Path:
:
toFile
)
.
map
(
DexFileLoader
:
:
loadDexFromFile
)
.
map
(
this
::
loadDexFromFile
)
.
filter
(
list
->
!
list
.
isEmpty
())
.
flatMap
(
Collection:
:
stream
)
.
peek
(
dr
->
LOG
.
debug
(
"Loading dex: {}"
,
dr
))
.
collect
(
Collectors
.
toList
());
}
private
static
List
<
DexReader
>
loadDexFromFile
(
File
file
)
{
private
List
<
DexReader
>
loadDexFromFile
(
File
file
)
{
try
(
InputStream
inputStream
=
new
FileInputStream
(
file
))
{
return
checkFileMagic
(
file
,
inputStream
,
file
.
getAbsolutePath
());
}
catch
(
Exception
e
)
{
...
...
@@ -44,7 +52,7 @@ public class DexFileLoader {
}
}
private
static
List
<
DexReader
>
checkFileMagic
(
File
file
,
InputStream
inputStream
,
String
inputFileName
)
throws
IOException
{
private
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
];
in
.
mark
(
magic
.
length
);
...
...
@@ -54,7 +62,9 @@ public class DexFileLoader {
if
(
isStartWithBytes
(
magic
,
DexConsts
.
DEX_FILE_MAGIC
))
{
in
.
reset
();
byte
[]
content
=
readAllBytes
(
in
);
DexCheckSum
.
verify
(
content
);
if
(
options
.
isVerifyChecksum
())
{
DexCheckSum
.
verify
(
content
);
}
DexReader
dexReader
=
new
DexReader
(
getNextUniqId
(),
inputFileName
,
content
);
return
Collections
.
singletonList
(
dexReader
);
}
...
...
@@ -65,7 +75,7 @@ public class DexFileLoader {
}
}
private
static
List
<
DexReader
>
collectDexFromZip
(
File
file
)
{
private
List
<
DexReader
>
collectDexFromZip
(
File
file
)
{
List
<
DexReader
>
result
=
new
ArrayList
<>();
try
{
ZipSecurity
.
readZipEntries
(
file
,
(
entry
,
in
)
->
{
...
...
@@ -107,15 +117,15 @@ public class DexFileLoader {
return
buf
.
toByteArray
();
}
private
static
int
getNextUniqId
()
{
private
static
synchronized
int
getNextUniqId
()
{
dexUniqId
++;
if
(
dexUniqId
>=
0xFFFF
)
{
resetDexUniqId
()
;
dexUniqId
=
1
;
}
return
dexUniqId
;
}
p
ublic
static
void
resetDexUniqId
()
{
p
rivate
static
synchronized
void
resetDexUniqId
()
{
dexUniqId
=
1
;
}
}
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexInputOptions.java
0 → 100644
浏览文件 @
54683e31
package
jadx.plugins.input.dex
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.Locale
;
import
java.util.Map
;
import
jadx.api.plugins.options.OptionDescription
;
import
jadx.api.plugins.options.impl.JadxOptionDescription
;
public
class
DexInputOptions
{
private
static
final
String
VERIFY_CHECKSUM_OPT
=
DexInputPlugin
.
PLUGIN_ID
+
".verify-checksum"
;
private
boolean
verifyChecksum
=
true
;
public
void
apply
(
Map
<
String
,
String
>
options
)
{
verifyChecksum
=
getBooleanOption
(
options
,
VERIFY_CHECKSUM_OPT
,
true
);
}
public
List
<
OptionDescription
>
buildOptionsDescriptions
()
{
List
<
OptionDescription
>
list
=
new
ArrayList
<>(
1
);
list
.
add
(
new
JadxOptionDescription
(
VERIFY_CHECKSUM_OPT
,
"Verify dex file checksum before load"
,
"yes"
,
Arrays
.
asList
(
"yes"
,
"no"
)));
return
list
;
}
private
boolean
getBooleanOption
(
Map
<
String
,
String
>
options
,
String
key
,
boolean
defValue
)
{
String
val
=
options
.
get
(
key
);
if
(
val
==
null
)
{
return
defValue
;
}
String
valLower
=
val
.
toLowerCase
(
Locale
.
ROOT
);
if
(
valLower
.
equals
(
"yes"
)
||
valLower
.
equals
(
"true"
))
{
return
true
;
}
if
(
valLower
.
equals
(
"no"
)
||
valLower
.
equals
(
"false"
))
{
return
false
;
}
throw
new
IllegalArgumentException
(
"Unknown value '"
+
val
+
"' for option '"
+
key
+
"'"
+
", expect: 'yes' or 'no'"
);
}
public
boolean
isVerifyChecksum
()
{
return
verifyChecksum
;
}
}
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexInputPlugin.java
浏览文件 @
54683e31
...
...
@@ -3,33 +3,48 @@ package jadx.plugins.input.dex;
import
java.io.Closeable
;
import
java.nio.file.Path
;
import
java.util.List
;
import
java.util.Map
;
import
org.jetbrains.annotations.Nullable
;
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.api.plugins.options.JadxPluginOptions
;
import
jadx.api.plugins.options.OptionDescription
;
public
class
DexInputPlugin
implements
JadxInputPlugin
{
public
class
DexInputPlugin
implements
JadxInputPlugin
,
JadxPluginOptions
{
public
static
final
String
PLUGIN_ID
=
"dex-input"
;
public
DexInputPlugin
()
{
DexFileLoader
.
resetDexUniqId
();
}
private
final
DexInputOptions
options
=
new
DexInputOptions
();
private
final
DexFileLoader
loader
=
new
DexFileLoader
(
options
);
@Override
public
JadxPluginInfo
getPluginInfo
()
{
return
new
JadxPluginInfo
(
"dex-input"
,
"DexInput"
,
"Load .dex and .apk files"
);
return
new
JadxPluginInfo
(
PLUGIN_ID
,
"DexInput"
,
"Load .dex and .apk files"
);
}
@Override
public
ILoadResult
loadFiles
(
List
<
Path
>
input
)
{
return
load
Dex
Files
(
input
,
null
);
return
loadFiles
(
input
,
null
);
}
public
static
ILoadResult
loadDexFiles
(
List
<
Path
>
inputFiles
,
Closeable
closeable
)
{
List
<
DexReader
>
dexReaders
=
DexFileL
oader
.
collectDexFiles
(
inputFiles
);
public
ILoadResult
loadFiles
(
List
<
Path
>
inputFiles
,
@Nullable
Closeable
closeable
)
{
List
<
DexReader
>
dexReaders
=
l
oader
.
collectDexFiles
(
inputFiles
);
if
(
dexReaders
.
isEmpty
())
{
return
EmptyLoadResult
.
INSTANCE
;
}
return
new
DexLoadResult
(
dexReaders
,
closeable
);
}
@Override
public
void
setOptions
(
Map
<
String
,
String
>
options
)
{
this
.
options
.
apply
(
options
);
}
@Override
public
List
<
OptionDescription
>
getOptionsDescriptions
()
{
return
this
.
options
.
buildOptionsDescriptions
();
}
}
jadx-plugins/jadx-java-convert/src/main/java/jadx/plugins/input/javaconvert/JavaConvertPlugin.java
浏览文件 @
54683e31
...
...
@@ -11,6 +11,8 @@ import jadx.plugins.input.dex.DexInputPlugin;
public
class
JavaConvertPlugin
implements
JadxInputPlugin
{
private
final
DexInputPlugin
dexInput
=
new
DexInputPlugin
();
@Override
public
JadxPluginInfo
getPluginInfo
()
{
return
new
JadxPluginInfo
(
...
...
@@ -27,6 +29,6 @@ public class JavaConvertPlugin implements JadxInputPlugin {
result
.
close
();
return
EmptyLoadResult
.
INSTANCE
;
}
return
DexInputPlugin
.
loadDex
Files
(
result
.
getConverted
(),
result
);
return
dexInput
.
load
Files
(
result
.
getConverted
(),
result
);
}
}
jadx-plugins/jadx-plugins-api/src/main/java/jadx/api/plugins/JadxPluginManager.java
浏览文件 @
54683e31
...
...
@@ -16,6 +16,8 @@ import org.slf4j.Logger;
import
org.slf4j.LoggerFactory
;
import
jadx.api.plugins.input.JadxInputPlugin
;
import
jadx.api.plugins.options.JadxPluginOptions
;
import
jadx.api.plugins.options.OptionDescription
;
public
class
JadxPluginManager
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
JadxPluginManager
.
class
);
...
...
@@ -56,9 +58,34 @@ public class JadxPluginManager {
if
(!
allPlugins
.
add
(
pluginData
))
{
throw
new
IllegalArgumentException
(
"Duplicate plugin id: "
+
pluginData
+
", class "
+
plugin
.
getClass
());
}
if
(
plugin
instanceof
JadxPluginOptions
)
{
verifyOptions
(((
JadxPluginOptions
)
plugin
),
pluginData
.
getPluginId
());
}
return
pluginData
;
}
private
void
verifyOptions
(
JadxPluginOptions
plugin
,
String
pluginId
)
{
List
<
OptionDescription
>
descriptions
=
plugin
.
getOptionsDescriptions
();
if
(
descriptions
==
null
)
{
throw
new
IllegalArgumentException
(
"Null option descriptions in plugin id: "
+
pluginId
);
}
String
prefix
=
pluginId
+
'.'
;
descriptions
.
forEach
(
descObj
->
{
String
optName
=
descObj
.
name
();
if
(
optName
==
null
||
!
optName
.
startsWith
(
prefix
))
{
throw
new
IllegalArgumentException
(
"Plugin option name should start with plugin id: '"
+
prefix
+
"', option: "
+
optName
);
}
String
desc
=
descObj
.
description
();
if
(
desc
==
null
||
desc
.
isEmpty
())
{
throw
new
IllegalArgumentException
(
"Plugin option description not set, plugin: "
+
pluginId
);
}
List
<
String
>
values
=
descObj
.
values
();
if
(
values
==
null
)
{
throw
new
IllegalArgumentException
(
"Plugin option values is null, option: "
+
optName
+
", plugin: "
+
pluginId
);
}
});
}
public
boolean
unload
(
String
pluginId
)
{
boolean
result
=
allPlugins
.
removeIf
(
pd
->
{
String
id
=
pd
.
getPluginId
();
...
...
@@ -87,6 +114,13 @@ public class JadxPluginManager {
.
collect
(
Collectors
.
toList
());
}
public
List
<
JadxPluginOptions
>
getPluginsWithOptions
()
{
return
resolvedPlugins
.
stream
()
.
filter
(
JadxPluginOptions
.
class
::
isInstance
)
.
map
(
JadxPluginOptions
.
class
::
cast
)
.
collect
(
Collectors
.
toList
());
}
private
synchronized
void
resolve
()
{
Map
<
String
,
List
<
PluginData
>>
provides
=
allPlugins
.
stream
()
.
collect
(
Collectors
.
groupingBy
(
p
->
p
.
getInfo
().
getProvides
()));
...
...
jadx-plugins/jadx-plugins-api/src/main/java/jadx/api/plugins/options/JadxPluginOptions.java
0 → 100644
浏览文件 @
54683e31
package
jadx.api.plugins.options
;
import
java.util.List
;
import
java.util.Map
;
import
jadx.api.plugins.JadxPlugin
;
public
interface
JadxPluginOptions
extends
JadxPlugin
{
void
setOptions
(
Map
<
String
,
String
>
options
);
List
<
OptionDescription
>
getOptionsDescriptions
();
}
jadx-plugins/jadx-plugins-api/src/main/java/jadx/api/plugins/options/OptionDescription.java
0 → 100644
浏览文件 @
54683e31
package
jadx.api.plugins.options
;
import
java.util.List
;
import
org.jetbrains.annotations.Nullable
;
public
interface
OptionDescription
{
String
name
();
String
description
();
/**
* Possible values.
* Empty if not a limited set
*/
List
<
String
>
values
();
/**
* Default value.
* Null if required
*/
@Nullable
String
defaultValue
();
}
jadx-plugins/jadx-plugins-api/src/main/java/jadx/api/plugins/options/impl/JadxOptionDescription.java
0 → 100644
浏览文件 @
54683e31
package
jadx.api.plugins.options.impl
;
import
java.util.List
;
import
org.jetbrains.annotations.Nullable
;
import
jadx.api.plugins.options.OptionDescription
;
public
class
JadxOptionDescription
implements
OptionDescription
{
private
final
String
name
;
private
final
String
desc
;
private
final
String
defaultValue
;
private
final
List
<
String
>
values
;
public
JadxOptionDescription
(
String
name
,
String
desc
,
@Nullable
String
defaultValue
,
List
<
String
>
values
)
{
this
.
name
=
name
;
this
.
desc
=
desc
;
this
.
defaultValue
=
defaultValue
;
this
.
values
=
values
;
}
@Override
public
String
name
()
{
return
name
;
}
@Override
public
String
description
()
{
return
desc
;
}
@Override
public
@Nullable
String
defaultValue
()
{
return
defaultValue
;
}
@Override
public
List
<
String
>
values
()
{
return
values
;
}
@Override
public
String
toString
()
{
return
"OptionDescription{"
+
desc
+
", values="
+
values
+
'}'
;
}
}
jadx-plugins/jadx-smali-input/src/main/java/jadx/plugins/input/smali/SmaliInputPlugin.java
浏览文件 @
54683e31
...
...
@@ -11,6 +11,8 @@ import jadx.plugins.input.dex.DexInputPlugin;
public
class
SmaliInputPlugin
implements
JadxInputPlugin
{
private
final
DexInputPlugin
dexInput
=
new
DexInputPlugin
();
@Override
public
JadxPluginInfo
getPluginInfo
()
{
return
new
JadxPluginInfo
(
"smali-input"
,
"SmaliInput"
,
"Load .smali files"
);
...
...
@@ -22,6 +24,6 @@ public class SmaliInputPlugin implements JadxInputPlugin {
if
(!
convert
.
execute
(
input
))
{
return
EmptyLoadResult
.
INSTANCE
;
}
return
DexInputPlugin
.
loadDex
Files
(
convert
.
getDexFiles
(),
convert
);
return
dexInput
.
load
Files
(
convert
.
getDexFiles
(),
convert
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录