Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
J
jadx
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open-source
jadx
Commits
b09c7ba6
Commit
b09c7ba6
authored
Mar 31, 2019
by
Ahmed Ashour
Committed by
skylot
Mar 31, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(gui): support project (#526) (PR #543)
parent
ec66476a
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
640 additions
and
159 deletions
+640
-159
JadxCLIArgs.java
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
+0
-4
JadxGUI.java
jadx-gui/src/main/java/jadx/gui/JadxGUI.java
+1
-1
JadxWrapper.java
jadx-gui/src/main/java/jadx/gui/JadxWrapper.java
+17
-20
BackgroundWorker.java
jadx-gui/src/main/java/jadx/gui/jobs/BackgroundWorker.java
+1
-2
JadxProject.java
jadx-gui/src/main/java/jadx/gui/settings/JadxProject.java
+127
-0
JadxSettings.java
jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
+44
-19
JadxSettingsAdapter.java
.../src/main/java/jadx/gui/settings/JadxSettingsAdapter.java
+9
-3
JadxSettingsWindow.java
...i/src/main/java/jadx/gui/settings/JadxSettingsWindow.java
+24
-11
ApkSignature.java
jadx-gui/src/main/java/jadx/gui/treemodel/ApkSignature.java
+4
-4
CommonSearchDialog.java
jadx-gui/src/main/java/jadx/gui/ui/CommonSearchDialog.java
+4
-5
HeapUsageBar.java
jadx-gui/src/main/java/jadx/gui/ui/HeapUsageBar.java
+1
-3
MainDropTarget.java
jadx-gui/src/main/java/jadx/gui/ui/MainDropTarget.java
+1
-1
MainWindow.java
jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
+260
-61
NLS.java
jadx-gui/src/main/java/jadx/gui/utils/NLS.java
+5
-3
PathTypeAdapter.java
jadx-gui/src/main/java/jadx/gui/utils/PathTypeAdapter.java
+44
-0
Messages_en_US.properties
jadx-gui/src/main/resources/i18n/Messages_en_US.properties
+14
-5
Messages_es_ES.properties
jadx-gui/src/main/resources/i18n/Messages_es_ES.properties
+14
-5
Messages_zh_CN.properties
jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties
+14
-5
TestI18n.java
jadx-gui/src/test/java/jadx/gui/TestI18n.java
+56
-7
No files found.
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
View file @
b09c7ba6
...
...
@@ -231,10 +231,6 @@ public class JadxCLIArgs {
return
deobfuscationUseSourceNameAsAlias
;
}
public
boolean
escapeUnicode
()
{
return
escapeUnicode
;
}
public
boolean
isEscapeUnicode
()
{
return
escapeUnicode
;
}
...
...
jadx-gui/src/main/java/jadx/gui/JadxGUI.java
View file @
b09c7ba6
...
...
@@ -26,7 +26,7 @@ public class JadxGUI {
UIManager
.
setLookAndFeel
(
UIManager
.
getSystemLookAndFeelClassName
());
}
NLS
.
setLocale
(
settings
.
getLangLocale
());
SwingUtilities
.
invokeLater
(
new
MainWindow
(
settings
)::
open
);
SwingUtilities
.
invokeLater
(
new
MainWindow
(
settings
)::
init
);
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Error: {}"
,
e
.
getMessage
(),
e
);
System
.
exit
(
1
);
...
...
jadx-gui/src/main/java/jadx/gui/JadxWrapper.java
View file @
b09c7ba6
...
...
@@ -47,27 +47,24 @@ public class JadxWrapper {
}
public
void
saveAll
(
final
File
dir
,
final
ProgressMonitor
progressMonitor
)
{
Runnable
save
=
new
Runnable
()
{
@Override
public
void
run
()
{
try
{
decompiler
.
getArgs
().
setRootDir
(
dir
);
ThreadPoolExecutor
ex
=
(
ThreadPoolExecutor
)
decompiler
.
getSaveExecutor
();
ex
.
shutdown
();
while
(
ex
.
isTerminating
())
{
long
total
=
ex
.
getTaskCount
();
long
done
=
ex
.
getCompletedTaskCount
();
progressMonitor
.
setProgress
((
int
)
(
done
*
100.0
/
total
));
Thread
.
sleep
(
500
);
}
progressMonitor
.
close
();
LOG
.
info
(
"decompilation complete, freeing memory ..."
);
decompiler
.
getClasses
().
forEach
(
JavaClass:
:
unload
);
LOG
.
info
(
"done"
);
}
catch
(
InterruptedException
e
)
{
LOG
.
error
(
"Save interrupted"
,
e
);
Thread
.
currentThread
().
interrupt
();
Runnable
save
=
()
->
{
try
{
decompiler
.
getArgs
().
setRootDir
(
dir
);
ThreadPoolExecutor
ex
=
(
ThreadPoolExecutor
)
decompiler
.
getSaveExecutor
();
ex
.
shutdown
();
while
(
ex
.
isTerminating
())
{
long
total
=
ex
.
getTaskCount
();
long
done
=
ex
.
getCompletedTaskCount
();
progressMonitor
.
setProgress
((
int
)
(
done
*
100.0
/
total
));
Thread
.
sleep
(
500
);
}
progressMonitor
.
close
();
LOG
.
info
(
"decompilation complete, freeing memory ..."
);
decompiler
.
getClasses
().
forEach
(
JavaClass:
:
unload
);
LOG
.
info
(
"done"
);
}
catch
(
InterruptedException
e
)
{
LOG
.
error
(
"Save interrupted"
,
e
);
Thread
.
currentThread
().
interrupt
();
}
};
new
Thread
(
save
).
start
();
...
...
jadx-gui/src/main/java/jadx/gui/jobs/BackgroundWorker.java
View file @
b09c7ba6
...
...
@@ -58,8 +58,7 @@ public class BackgroundWorker extends SwingWorker<Void, Void> {
if
(
searchIndex
!=
null
&&
searchIndex
.
getSkippedCount
()
>
0
)
{
LOG
.
warn
(
"Indexing of some classes skipped, count: {}, low memory: {}"
,
searchIndex
.
getSkippedCount
(),
Utils
.
memoryInfo
());
String
msg
=
NLS
.
str
(
"message.indexingClassesSkipped"
);
msg
=
String
.
format
(
msg
,
searchIndex
.
getSkippedCount
());
String
msg
=
NLS
.
str
(
"message.indexingClassesSkipped"
,
searchIndex
.
getSkippedCount
());
JOptionPane
.
showMessageDialog
(
null
,
msg
);
}
}
catch
(
Exception
e
)
{
...
...
jadx-gui/src/main/java/jadx/gui/settings/JadxProject.java
0 → 100644
View file @
b09c7ba6
package
jadx
.
gui
.
settings
;
import
java.io.BufferedWriter
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.util.Arrays
;
import
java.util.List
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
com.google.gson.Gson
;
import
com.google.gson.GsonBuilder
;
import
jadx.gui.utils.PathTypeAdapter
;
public
class
JadxProject
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
JadxProject
.
class
);
private
static
final
int
CURRENT_SETTINGS_VERSION
=
0
;
public
static
final
String
PROJECT_EXTENSION
=
"jadx"
;
private
static
final
Gson
GSON
=
new
GsonBuilder
()
.
registerTypeHierarchyAdapter
(
Path
.
class
,
PathTypeAdapter
.
singleton
())
.
create
();
private
transient
JadxSettings
settings
;
private
transient
String
name
=
"New Project"
;
private
transient
Path
projectPath
;
private
List
<
Path
>
filesPath
;
private
transient
boolean
saved
;
private
transient
boolean
initial
=
true
;
private
int
projectVersion
=
0
;
public
JadxProject
(
JadxSettings
settings
)
{
this
.
settings
=
settings
;
}
public
Path
getProjectPath
()
{
return
projectPath
;
}
private
void
setProjectPath
(
Path
projectPath
)
{
this
.
projectPath
=
projectPath
;
if
(
projectVersion
!=
CURRENT_SETTINGS_VERSION
)
{
upgradeSettings
(
projectVersion
);
}
name
=
projectPath
.
getFileName
().
toString
();
name
=
name
.
substring
(
0
,
name
.
lastIndexOf
(
'.'
));
changed
();
}
public
Path
getFilePath
()
{
return
filesPath
==
null
?
null
:
filesPath
.
get
(
0
);
}
public
void
setFilePath
(
Path
filePath
)
{
if
(!
filePath
.
equals
(
getFilePath
()))
{
this
.
filesPath
=
Arrays
.
asList
(
filePath
);
changed
();
}
}
private
void
changed
()
{
if
(
settings
.
isAutoSaveProject
())
{
save
();
}
else
{
saved
=
false
;
}
initial
=
false
;
}
public
String
getName
()
{
return
name
;
}
public
boolean
isSaved
()
{
return
saved
;
}
public
boolean
isInitial
()
{
return
initial
;
}
public
void
saveAs
(
Path
path
)
{
setProjectPath
(
path
);
save
();
}
public
void
save
()
{
try
(
BufferedWriter
writer
=
Files
.
newBufferedWriter
(
getProjectPath
()))
{
writer
.
write
(
GSON
.
toJson
(
this
));
saved
=
true
;
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Error saving project"
,
e
);
}
}
public
static
JadxProject
from
(
Path
path
,
JadxSettings
settings
)
{
try
{
List
<
String
>
lines
=
Files
.
readAllLines
(
path
);
if
(!
lines
.
isEmpty
())
{
JadxProject
project
=
GSON
.
fromJson
(
lines
.
get
(
0
),
JadxProject
.
class
);
project
.
settings
=
settings
;
project
.
setProjectPath
(
path
);
project
.
saved
=
true
;
return
project
;
}
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Error loading project"
,
e
);
}
return
null
;
}
private
void
upgradeSettings
(
int
fromVersion
)
{
LOG
.
debug
(
"upgrade settings from version: {} to {}"
,
fromVersion
,
CURRENT_SETTINGS_VERSION
);
if
(
fromVersion
==
0
)
{
fromVersion
++;
}
projectVersion
=
CURRENT_SETTINGS_VERSION
;
save
();
}
}
jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
View file @
b09c7ba6
...
...
@@ -4,6 +4,8 @@ import java.awt.Font;
import
java.awt.GraphicsDevice
;
import
java.awt.GraphicsEnvironment
;
import
java.awt.Window
;
import
java.nio.file.Path
;
import
java.nio.file.Paths
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.HashMap
;
...
...
@@ -27,25 +29,27 @@ import jadx.gui.utils.Utils;
public
class
JadxSettings
extends
JadxCLIArgs
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
JadxSettings
.
class
);
private
static
final
String
USER_HOME
=
System
.
getProperty
(
"user.home"
);
private
static
final
int
RECENT_
FILE
S_COUNT
=
15
;
private
static
final
int
CURRENT_SETTINGS_VERSION
=
8
;
private
static
final
Path
USER_HOME
=
Paths
.
get
(
System
.
getProperty
(
"user.home"
)
);
private
static
final
int
RECENT_
PROJECT
S_COUNT
=
15
;
private
static
final
int
CURRENT_SETTINGS_VERSION
=
9
;
private
static
final
Font
DEFAULT_FONT
=
new
RSyntaxTextArea
().
getFont
();
static
final
Set
<
String
>
SKIP_FIELDS
=
new
HashSet
<>(
Arrays
.
asList
(
"files"
,
"input"
,
"outDir"
,
"outDirSrc"
,
"outDirRes"
,
"verbose"
,
"printVersion"
,
"printHelp"
));
private
String
lastOpenFilePath
=
USER_HOME
;
private
String
lastSaveFilePath
=
USER_HOME
;
private
Path
lastSaveProjectPath
=
USER_HOME
;
private
Path
lastOpenFilePath
=
USER_HOME
;
private
Path
lastSaveFilePath
=
USER_HOME
;
private
boolean
flattenPackage
=
false
;
private
boolean
checkForUpdates
=
false
;
private
List
<
String
>
recentFile
s
=
new
ArrayList
<>();
private
List
<
Path
>
recentProject
s
=
new
ArrayList
<>();
private
String
fontStr
=
""
;
private
String
editorThemePath
=
""
;
private
LangLocale
langLocale
=
NLS
.
defaultLocale
();
private
boolean
autoStartJobs
=
false
;
protected
String
excludedPackages
=
""
;
private
boolean
autoSaveProject
=
false
;
private
boolean
showHeapUsageBar
=
true
;
...
...
@@ -84,20 +88,29 @@ public class JadxSettings extends JadxCLIArgs {
}
}
public
String
getLastOpenFilePath
()
{
public
Path
getLastOpenFilePath
()
{
return
lastOpenFilePath
;
}
public
void
setLastOpenFilePath
(
String
lastOpenFilePath
)
{
public
void
setLastOpenFilePath
(
Path
lastOpenFilePath
)
{
this
.
lastOpenFilePath
=
lastOpenFilePath
;
partialSync
(
settings
->
settings
.
lastOpenFilePath
=
JadxSettings
.
this
.
lastOpenFilePath
);
}
public
String
getLastSaveFilePath
()
{
public
Path
getLastSaveProjectPath
()
{
return
lastSaveProjectPath
;
}
public
Path
getLastSaveFilePath
()
{
return
lastSaveFilePath
;
}
public
void
setLastSaveFilePath
(
String
lastSaveFilePath
)
{
public
void
setLastSaveProjectPath
(
Path
lastSaveProjectPath
)
{
this
.
lastSaveProjectPath
=
lastSaveProjectPath
;
partialSync
(
settings
->
settings
.
lastSaveProjectPath
=
JadxSettings
.
this
.
lastSaveProjectPath
);
}
public
void
setLastSaveFilePath
(
Path
lastSaveFilePath
)
{
this
.
lastSaveFilePath
=
lastSaveFilePath
;
partialSync
(
settings
->
settings
.
lastSaveFilePath
=
JadxSettings
.
this
.
lastSaveFilePath
);
}
...
...
@@ -120,18 +133,18 @@ public class JadxSettings extends JadxCLIArgs {
sync
();
}
public
Iterable
<
String
>
getRecentFile
s
()
{
return
recent
File
s
;
public
Iterable
<
Path
>
getRecentProject
s
()
{
return
recent
Project
s
;
}
public
void
addRecent
File
(
String
file
Path
)
{
recent
Files
.
remove
(
file
Path
);
recent
Files
.
add
(
0
,
file
Path
);
int
count
=
recent
File
s
.
size
();
if
(
count
>
RECENT_
FILE
S_COUNT
)
{
recent
Files
.
subList
(
RECENT_FILE
S_COUNT
,
count
).
clear
();
public
void
addRecent
Project
(
Path
project
Path
)
{
recent
Projects
.
remove
(
project
Path
);
recent
Projects
.
add
(
0
,
project
Path
);
int
count
=
recent
Project
s
.
size
();
if
(
count
>
RECENT_
PROJECT
S_COUNT
)
{
recent
Projects
.
subList
(
RECENT_PROJECT
S_COUNT
,
count
).
clear
();
}
partialSync
(
settings
->
settings
.
recent
Files
=
recentFile
s
);
partialSync
(
settings
->
settings
.
recent
Projects
=
recentProject
s
);
}
public
void
saveWindowPos
(
Window
window
)
{
...
...
@@ -265,6 +278,14 @@ public class JadxSettings extends JadxCLIArgs {
this
.
autoStartJobs
=
autoStartJobs
;
}
public
boolean
isAutoSaveProject
()
{
return
autoSaveProject
;
}
public
void
setAutoSaveProject
(
boolean
autoSaveProject
)
{
this
.
autoSaveProject
=
autoSaveProject
;
}
public
void
setExportAsGradleProject
(
boolean
exportAsGradleProject
)
{
this
.
exportAsGradleProject
=
exportAsGradleProject
;
}
...
...
@@ -343,6 +364,10 @@ public class JadxSettings extends JadxCLIArgs {
outDir
=
null
;
outDirSrc
=
null
;
outDirRes
=
null
;
fromVersion
++;
}
if
(
fromVersion
==
8
)
{
fromVersion
++;
}
settingsVersion
=
CURRENT_SETTINGS_VERSION
;
sync
();
...
...
jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsAdapter.java
View file @
b09c7ba6
package
jadx
.
gui
.
settings
;
import
java.lang.reflect.Modifier
;
import
java.nio.file.Path
;
import
java.util.prefs.Preferences
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
com.google.gson.ExclusionStrategy
;
import
com.google.gson.FieldAttributes
;
import
com.google.gson.Gson
;
import
com.google.gson.GsonBuilder
;
import
com.google.gson.InstanceCreator
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.gui.JadxGUI
;
import
jadx.gui.utils.PathTypeAdapter
;
public
class
JadxSettingsAdapter
{
...
...
@@ -34,7 +37,10 @@ public class JadxSettingsAdapter {
return
false
;
}
};
private
static
final
GsonBuilder
GSON_BUILDER
=
new
GsonBuilder
().
setExclusionStrategies
(
EXCLUDE_FIELDS
);
private
static
final
GsonBuilder
GSON_BUILDER
=
new
GsonBuilder
()
.
setExclusionStrategies
(
EXCLUDE_FIELDS
)
.
registerTypeHierarchyAdapter
(
Path
.
class
,
PathTypeAdapter
.
singleton
())
;
private
static
final
Gson
GSON
=
GSON_BUILDER
.
create
();
private
JadxSettingsAdapter
()
{
...
...
jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsWindow.java
View file @
b09c7ba6
...
...
@@ -52,6 +52,7 @@ public class JadxSettingsWindow extends JDialog {
panel
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
10
,
10
,
10
,
10
));
panel
.
add
(
makeDeobfuscationGroup
());
panel
.
add
(
makeDecompilationGroup
());
panel
.
add
(
makeProjectGroup
());
panel
.
add
(
makeEditorGroup
());
panel
.
add
(
makeOtherGroup
());
...
...
@@ -168,6 +169,18 @@ public class JadxSettingsWindow extends JDialog {
connectedComponents
.
forEach
(
comp
->
comp
.
setEnabled
(
enabled
));
}
private
SettingsGroup
makeProjectGroup
()
{
JCheckBox
autoSave
=
new
JCheckBox
();
autoSave
.
setSelected
(
settings
.
isAutoSaveProject
());
autoSave
.
addItemListener
(
e
->
settings
.
setAutoSaveProject
(
e
.
getStateChange
()
==
ItemEvent
.
SELECTED
));
SettingsGroup
group
=
new
SettingsGroup
(
NLS
.
str
(
"preferences.project"
));
group
.
addRow
(
NLS
.
str
(
"preferences.autoSave"
),
autoSave
);
return
group
;
}
private
SettingsGroup
makeEditorGroup
()
{
JButton
fontBtn
=
new
JButton
(
NLS
.
str
(
"preferences.select_font"
));
...
...
@@ -186,9 +199,9 @@ public class JadxSettingsWindow extends JDialog {
mainWindow
.
loadSettings
();
});
SettingsGroup
other
=
new
SettingsGroup
(
NLS
.
str
(
"preferences.editor"
));
JLabel
fontLabel
=
other
.
addRow
(
getFontLabelStr
(),
fontBtn
);
other
.
addRow
(
NLS
.
str
(
"preferences.theme"
),
themesCbx
);
SettingsGroup
group
=
new
SettingsGroup
(
NLS
.
str
(
"preferences.editor"
));
JLabel
fontLabel
=
group
.
addRow
(
getFontLabelStr
(),
fontBtn
);
group
.
addRow
(
NLS
.
str
(
"preferences.theme"
),
themesCbx
);
fontBtn
.
addMouseListener
(
new
MouseAdapter
()
{
@Override
...
...
@@ -205,7 +218,7 @@ public class JadxSettingsWindow extends JDialog {
}
}
});
return
other
;
return
group
;
}
private
String
getFontLabelStr
()
{
...
...
@@ -263,7 +276,7 @@ public class JadxSettingsWindow extends JDialog {
autoStartJobs
.
addItemListener
(
e
->
settings
.
setAutoStartJobs
(
e
.
getStateChange
()
==
ItemEvent
.
SELECTED
));
JCheckBox
escapeUnicode
=
new
JCheckBox
();
escapeUnicode
.
setSelected
(
settings
.
e
scapeUnicode
());
escapeUnicode
.
setSelected
(
settings
.
isE
scapeUnicode
());
escapeUnicode
.
addItemListener
(
e
->
{
settings
.
setEscapeUnicode
(
e
.
getStateChange
()
==
ItemEvent
.
SELECTED
);
needReload
();
...
...
@@ -333,12 +346,12 @@ public class JadxSettingsWindow extends JDialog {
needReload
();
});
SettingsGroup
other
=
new
SettingsGroup
(
NLS
.
str
(
"preferences.other"
));
other
.
addRow
(
NLS
.
str
(
"preferences.language"
),
languageCbx
);
other
.
addRow
(
NLS
.
str
(
"preferences.check_for_updates"
),
update
);
other
.
addRow
(
NLS
.
str
(
"preferences.cfg"
),
cfg
);
other
.
addRow
(
NLS
.
str
(
"preferences.raw_cfg"
),
rawCfg
);
return
other
;
SettingsGroup
group
=
new
SettingsGroup
(
NLS
.
str
(
"preferences.other"
));
group
.
addRow
(
NLS
.
str
(
"preferences.language"
),
languageCbx
);
group
.
addRow
(
NLS
.
str
(
"preferences.check_for_updates"
),
update
);
group
.
addRow
(
NLS
.
str
(
"preferences.cfg"
),
cfg
);
group
.
addRow
(
NLS
.
str
(
"preferences.raw_cfg"
),
rawCfg
);
return
group
;
}
private
void
needReload
()
{
...
...
jadx-gui/src/main/java/jadx/gui/treemodel/ApkSignature.java
View file @
b09c7ba6
...
...
@@ -77,15 +77,15 @@ public class ApkSignature extends JNode {
final
String
err
=
NLS
.
str
(
"apkSignature.errors"
);
final
String
warn
=
NLS
.
str
(
"apkSignature.warnings"
);
final
String
sigSucc
=
NLS
.
str
(
"apkSignature.signatureSuccess"
)
;
final
String
sigFail
=
NLS
.
str
(
"apkSignature.signatureFailed"
)
;
final
String
sigSucc
Key
=
"apkSignature.signatureSuccess"
;
final
String
sigFail
Key
=
"apkSignature.signatureFailed"
;
writeIssues
(
builder
,
err
,
result
.
getErrors
());
writeIssues
(
builder
,
warn
,
result
.
getWarnings
());
if
(!
result
.
getV1SchemeSigners
().
isEmpty
())
{
builder
.
append
(
"<h2>"
);
builder
.
escape
(
String
.
format
(
result
.
isVerifiedUsingV1Scheme
()
?
sigSucc
:
sigFail
,
1
));
builder
.
escape
(
NLS
.
str
(
result
.
isVerifiedUsingV1Scheme
()
?
sigSuccKey
:
sigFailKey
,
1
));
builder
.
append
(
"</h2>\n"
);
builder
.
append
(
"<blockquote>"
);
...
...
@@ -106,7 +106,7 @@ public class ApkSignature extends JNode {
}
if
(!
result
.
getV2SchemeSigners
().
isEmpty
())
{
builder
.
append
(
"<h2>"
);
builder
.
escape
(
String
.
format
(
result
.
isVerifiedUsingV2Scheme
()
?
sigSucc
:
sigFail
,
2
));
builder
.
escape
(
NLS
.
str
(
result
.
isVerifiedUsingV2Scheme
()
?
sigSuccKey
:
sigFailKey
,
2
));
builder
.
append
(
"</h2>\n"
);
builder
.
append
(
"<blockquote>"
);
...
...
jadx-gui/src/main/java/jadx/gui/ui/CommonSearchDialog.java
View file @
b09c7ba6
...
...
@@ -232,11 +232,10 @@ public abstract class CommonSearchDialog extends JDialog {
}
protected
void
updateProgressLabel
()
{
String
statusText
=
String
.
format
(
NLS
.
str
(
"search_dialog.info_label"
),
resultsModel
.
getDisplayedResultsStart
(),
resultsModel
.
getDisplayedResultsEnd
(),
resultsModel
.
getResultCount
()
String
statusText
=
NLS
.
str
(
"search_dialog.info_label"
,
resultsModel
.
getDisplayedResultsStart
(),
resultsModel
.
getDisplayedResultsEnd
(),
resultsModel
.
getResultCount
()
);
resultsInfoLabel
.
setText
(
statusText
);
}
...
...
jadx-gui/src/main/java/jadx/gui/ui/HeapUsageBar.java
View file @
b09c7ba6
...
...
@@ -25,11 +25,9 @@ public class HeapUsageBar extends JProgressBar implements ActionListener {
private
final
transient
Runtime
runtime
=
Runtime
.
getRuntime
();
private
final
transient
Timer
timer
;
private
final
String
textFormat
;
private
final
double
maxGB
;
public
HeapUsageBar
()
{
this
.
textFormat
=
NLS
.
str
(
"heapUsage.text"
);
setBorderPainted
(
false
);
setStringPainted
(
true
);
setValue
(
10
);
...
...
@@ -54,7 +52,7 @@ public class HeapUsageBar extends JProgressBar implements ActionListener {
long
used
=
runtime
.
totalMemory
()
-
runtime
.
freeMemory
();
int
usedKB
=
(
int
)
(
used
/
1024
);
setValue
(
usedKB
);
setString
(
String
.
format
(
textFormat
,
(
usedKB
/
TWO_TO_20
),
maxGB
));
setString
(
NLS
.
str
(
"heapUsage.text"
,
(
usedKB
/
TWO_TO_20
),
maxGB
));
if
((
used
+
Utils
.
MIN_FREE_MEMORY
)
>
runtime
.
maxMemory
())
{
setForeground
(
RED
);
...
...
jadx-gui/src/main/java/jadx/gui/ui/MainDropTarget.java
View file @
b09c7ba6
...
...
@@ -62,7 +62,7 @@ public class MainDropTarget implements DropTargetListener {
if
(!
transferData
.
isEmpty
())
{
dtde
.
dropComplete
(
true
);
// load first file
mainWindow
.
open
File
(
transferData
.
get
(
0
));
mainWindow
.
open
(
transferData
.
get
(
0
).
toPath
(
));
}
}
catch
(
Exception
e
)
{
LOG
.
error
(
"File drop operation failed"
,
e
);
...
...
jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
View file @
b09c7ba6
This diff is collapsed.
Click to expand it.
jadx-gui/src/main/java/jadx/gui/utils/NLS.java
View file @
b09c7ba6
...
...
@@ -61,12 +61,14 @@ public class NLS {
i18nMessagesMap
.
put
(
locale
,
bundle
);
}
public
static
String
str
(
String
key
)
{
public
static
String
str
(
String
key
,
Object
...
parameters
)
{
String
value
;
try
{
return
localizedMessagesMap
.
getString
(
key
);
value
=
localizedMessagesMap
.
getString
(
key
);
}
catch
(
MissingResourceException
e
)
{
return
fallbackMessagesMap
.
getString
(
key
);
// definitely exists
value
=
fallbackMessagesMap
.
getString
(
key
);
// definitely exists
}
return
String
.
format
(
value
,
parameters
);
}
public
static
String
str
(
String
key
,
LangLocale
locale
)
{
...
...
jadx-gui/src/main/java/jadx/gui/utils/PathTypeAdapter.java
0 → 100644
View file @
b09c7ba6
package
jadx
.
gui
.
utils
;
import
java.io.IOException
;
import
java.nio.file.Path
;
import
java.nio.file.Paths
;
import
com.google.gson.TypeAdapter
;
import
com.google.gson.stream.JsonReader
;
import
com.google.gson.stream.JsonToken
;
import
com.google.gson.stream.JsonWriter
;
public
class
PathTypeAdapter
{
private
static
TypeAdapter
<
Path
>
SINGLETON
;
public
static
TypeAdapter
<
Path
>
singleton
()
{
if
(
SINGLETON
==
null
)
{
SINGLETON
=
new
TypeAdapter
<
Path
>()
{
@Override
public
void
write
(
JsonWriter
out
,
Path
value
)
throws
IOException
{
if
(
value
==
null
)
{
out
.
nullValue
();
}
else
{
out
.
value
(
value
.
toAbsolutePath
().
toString
());
}
}
@Override
public
Path
read
(
JsonReader
in
)
throws
IOException
{
if
(
in
.
peek
()
==
JsonToken
.
NULL
)
{
in
.
nextNull
();
return
null
;
}
return
Paths
.
get
(
in
.
nextString
());
}
};
}
return
SINGLETON
;
}
private
PathTypeAdapter
()
{
}
}
jadx-gui/src/main/resources/i18n/Messages_en_US.properties
View file @
b09c7ba6
...
...
@@ -2,8 +2,8 @@ language.name=English
menu.file
=
File
menu.view
=
View
menu.recent_
files
=
Recent File
s
menu.no_recent_
files
=
No recent file
s
menu.recent_
projects
=
Recent project
s
menu.no_recent_
projects
=
No recent project
s
menu.preferences
=
Preferences
menu.sync
=
Sync with editor
menu.flatten
=
Show flatten packages
...
...
@@ -20,17 +20,18 @@ menu.update_label=New version %s available!
file.open_action
=
Open file...
file.open_title
=
Open file
file.new_project
=
New project
file.save_project
=
Save project
file.save_project_as
=
Save project as...
file.save_all
=
Save all
file.export_gradle
=
Save as gradle project
file.save_all_msg
=
Select directory for save decompiled sources
file.select
=
Select
file.exit
=
Exit
tree.sources_title
=
Source code
tree.resources_title
=
Resources
tree.loading
=
Loading...
search
=
Search
search.previous
=
Previous
search.next
=
Next
search.mark_all
=
Mark All
...
...
@@ -79,6 +80,7 @@ preferences.title=Preferences
preferences.deobfuscation
=
Deobfuscation
preferences.editor
=
Editor
preferences.decompile
=
Decompilation
preferences.project
=
Project
preferences.other
=
Other
preferences.language
=
Language
preferences.check_for_updates
=
Check for updates on startup
...
...
@@ -89,6 +91,7 @@ preferences.replaceConsts=Replace constants
preferences.respectBytecodeAccessModifiers
=
Respect bytecode access modifiers
preferences.useImports
=
Use import statements
preferences.skipResourcesDecode
=
Don't decode resources
preferences.autoSave
=
Auto save
preferences.threads
=
Processing threads count
preferences.excludedPackages
=
Excluded packages
preferences.excludedPackages.tooltip
=
List of space separated package names that will not be decompiled or indexed (saves RAM)
...
...
@@ -116,6 +119,8 @@ msg.saving_sources=Saving sources...
msg.language_changed_title
=
Language changed
msg.language_changed
=
New language will be displayed the next time application starts.
msg.index_not_initialized
=
Index not initialized, search will be disabled!
msg.project_error_title
=
Error
msg.project_error
=
Project could not be loaded
popup.undo
=
Undo
popup.redo
=
Redo
...
...
@@ -127,11 +132,15 @@ popup.select_all=Select All
popup.find_usage
=
Find Usage
popup.exclude
=
Exclude
confirm.save_as_title
=
Confirm Save as
confirm.save_as_message
=
%s already exists.
\n
Do you want to replace it?
confirm.not_saved_title
=
Save project
confirm.not_saved_message
=
Save the current project before opening the new one?
certificate.title
=
Certificate
certificate.cert_type
=
Type
certificate.serialSigVer
=
Version
certificate.serialNumber
=
Serial number
certificate.cert_issuer
=
Issuer
certificate.cert_subject
=
Subject
certificate.serialValidFrom
=
Valid from
certificate.serialValidUntil
=
Valid until
...
...
jadx-gui/src/main/resources/i18n/Messages_es_ES.properties
View file @
b09c7ba6
...
...
@@ -2,8 +2,8 @@ language.name=Español
menu.file
=
Archivo
menu.view
=
Vista
menu.recent_files
=
Archivos recientes
menu.no_recent_files
=
No hay archivos recientes
#menu.recent_projects=
#menu.no_recent_projects=
menu.preferences
=
Preferencias
menu.sync
=
Sincronizar con el editor
menu.flatten
=
Mostrar paquetes en vista plana
...
...
@@ -20,17 +20,18 @@ menu.update_label=¡Nueva versión %s disponible!
file.open_action
=
Abrir archivo...
file.open_title
=
Abrir archivo
#file.new_project=
#file.save_project=
#file.save_project_as=
file.save_all
=
Guardar todo
file.export_gradle
=
Guardar como proyecto Gradle
file.save_all_msg
=
Seleccionar carpeta para guardar fuentes descompiladas
file.select
=
Seleccionar
file.exit
=
Salir
tree.sources_title
=
Código fuente
tree.resources_title
=
Recursos
tree.loading
=
Cargando...
search
=
Buscar
search.previous
=
Anterior
search.next
=
Siguiente
search.mark_all
=
Marcar todo
...
...
@@ -79,6 +80,7 @@ preferences.title=Preferencias
preferences.deobfuscation
=
Desofuscación
preferences.editor
=
Editor
preferences.decompile
=
Descompilación
#preferences.project=
preferences.other
=
Otros
preferences.language
=
Idioma
preferences.check_for_updates
=
Buscar actualizaciones al iniciar
...
...
@@ -89,6 +91,7 @@ preferences.replaceConsts=Reemplazar constantes
#preferences.respectBytecodeAccessModifiers=
#preferences.useImports=
preferences.skipResourcesDecode
=
No descodificar recursos
#preferences.autoSave=
preferences.threads
=
Número de hilos a procesar
#preferences.excludedPackages=
#preferences.excludedPackages.tooltip=
...
...
@@ -116,6 +119,8 @@ msg.saving_sources=Guardando fuente...
msg.language_changed_title
=
Idioma cambiado
msg.language_changed
=
El nuevo idioma se mostrará la próxima vez que la aplicación se inicie.
msg.index_not_initialized
=
Índice no inicializado, ¡la bósqueda se desactivará!
#msg.project_error_title=
#msg.project_error=
popup.undo
=
Deshacer
popup.redo
=
Rehacer
...
...
@@ -127,11 +132,15 @@ popup.select_all=Seleccionar todo
#popup.find_usage=
#popup.exclude=
#confirm.save_as_title=
#confirm.save_as_message=
#confirm.not_saved_title=
#confirm.not_saved_message=
certificate.title
=
Certificado
certificate.cert_type
=
Tipo
certificate.serialSigVer
=
Versión
certificate.serialNumber
=
Número de serial
certificate.cert_issuer
=
Issuer
certificate.cert_subject
=
Subject
certificate.serialValidFrom
=
Válido desde
certificate.serialValidUntil
=
Válido hasta
...
...
jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties
View file @
b09c7ba6
...
...
@@ -2,8 +2,8 @@ language.name=中文(简体)
menu.file
=
文件
menu.view
=
视图
menu.recent_files
=
最近打开的文件
menu.no_recent_files
=
无最近打开的文件
#menu.recent_projects=
#menu.no_recent_projects=
menu.preferences
=
首选项
menu.sync
=
与编辑器同步
menu.flatten
=
展开显示代码包
...
...
@@ -20,17 +20,18 @@ menu.update_label=发现新版本 %s!
file.open_action
=
打开文件...
file.open_title
=
打开文件
#file.new_project=
#file.save_project=
#file.save_project_as=
file.save_all
=
全部保存
file.export_gradle
=
另存为 Gradle 项目
file.save_all_msg
=
选择反编译资源路径
file.select
=
选择
file.exit
=
退出
tree.sources_title
=
源代码
tree.resources_title
=
资源文件
tree.loading
=
稍等...
search
=
搜索
search.previous
=
上一个
search.next
=
下一个
search.mark_all
=
标记全部
...
...
@@ -79,6 +80,7 @@ preferences.title=首选项
preferences.deobfuscation
=
反混淆
preferences.editor
=
编辑器
preferences.decompile
=
反编译
#preferences.project=
preferences.other
=
其他
preferences.language
=
语言
preferences.check_for_updates
=
启动时检查更新
...
...
@@ -89,6 +91,7 @@ preferences.replaceConsts=替换常量
preferences.respectBytecodeAccessModifiers
=
遵守字节码访问修饰符
preferences.useImports
=
使用 import 语句
preferences.skipResourcesDecode
=
不反编译资源文件
#preferences.autoSave=
preferences.threads
=
并行线程数
preferences.excludedPackages
=
排除的包
preferences.excludedPackages.tooltip
=
将不被解压缩或索引的以空格分隔的包名称列表(节省 RAM)
...
...
@@ -116,6 +119,8 @@ msg.saving_sources=正在导出源代码...
msg.language_changed_title
=
语言已更改
msg.language_changed
=
在下次启动时将会显示新的语言。
msg.index_not_initialized
=
索引尚未初始化,无法进行搜索!
#msg.project_error_title=
#msg.project_error=
popup.undo
=
撤销
popup.redo
=
重做
...
...
@@ -127,11 +132,15 @@ popup.select_all=全选
popup.find_usage
=
查找用例
#popup.exclude=
#confirm.save_as_title=
#confirm.save_as_message=
#confirm.not_saved_title=
#confirm.not_saved_message=
certificate.title
=
证书
certificate.cert_type
=
类型
certificate.serialSigVer
=
版本
certificate.serialNumber
=
序列号
certificate.cert_issuer
=
颁发者
certificate.cert_subject
=
主题
certificate.serialValidFrom
=
有效期始
certificate.serialValidUntil
=
有效期至
...
...
jadx-gui/src/test/java/jadx/gui/TestI18n.java
View file @
b09c7ba6
package
jadx
.
gui
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
hamcrest
.
Matchers
.
empty
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertTrue
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
fail
;
import
java.io.IOException
;
import
java.io.Reader
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.nio.file.Paths
;
import
java.util.HashSet
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Properties
;
import
java.util.Set
;
import
org.junit.jupiter.api.Assertions
;
import
org.junit.jupiter.api.BeforeAll
;
import
org.junit.jupiter.api.Test
;
public
class
TestI18n
{
private
static
Path
guiJavaPath
;
private
static
Path
i18nPath
;
private
List
<
String
>
reference
;
private
String
referenceName
;
@BeforeAll
public
static
void
init
()
{
i18nPath
=
Paths
.
get
(
"src/main/resources/i18n"
);
assertTrue
(
Files
.
exists
(
i18nPath
));
guiJavaPath
=
Paths
.
get
(
"src/main/java"
);
assertTrue
(
Files
.
exists
(
guiJavaPath
));
}
@Test
public
void
filesExactlyMatch
()
throws
IOException
{
Path
path
=
Paths
.
get
(
"./src/main/resources/i18n"
);
assertTrue
(
Files
.
exists
(
path
));
Files
.
list
(
path
).
forEach
(
p
->
{
Files
.
list
(
i18nPath
).
forEach
(
p
->
{
List
<
String
>
lines
;
try
{
lines
=
Files
.
readAllLines
(
p
);
...
...
@@ -45,12 +64,12 @@ public class TestI18n {
if
(
p0
!=
-
1
)
{
String
prefix
=
line
.
substring
(
0
,
p0
+
1
);
if
(
i
>=
lines
.
size
()
||
!
trimComment
(
lines
.
get
(
i
)).
startsWith
(
prefix
))
{
fail
(
path
,
i
+
1
);
fail
Line
(
path
,
i
+
1
);
}
}
}
if
(
lines
.
size
()
!=
reference
.
size
())
{
fail
(
path
,
reference
.
size
());
fail
Line
(
path
,
reference
.
size
());
}
}
...
...
@@ -58,7 +77,37 @@ public class TestI18n {
return
string
.
startsWith
(
"#"
)
?
string
.
substring
(
1
)
:
string
;
}
private
void
fail
(
Path
path
,
int
line
)
{
Assertions
.
fail
(
"I18n files "
+
path
.
getFileName
()
+
" and "
+
referenceName
+
" differ in line "
+
line
);
private
void
failLine
(
Path
path
,
int
line
)
{
fail
(
"I18n files "
+
path
.
getFileName
()
+
" and "
+
referenceName
+
" differ in line "
+
line
);
}
@Test
public
void
keyIsUsed
()
throws
IOException
{
Properties
properties
=
new
Properties
();
try
(
Reader
reader
=
Files
.
newBufferedReader
(
i18nPath
.
resolve
(
"Messages_en_US.properties"
)))
{
properties
.
load
(
reader
);
}
Set
<
String
>
keys
=
new
HashSet
<>();
for
(
Object
key
:
properties
.
keySet
())
{
keys
.
add
(
"\""
+
key
+
'"'
);
}
Files
.
walk
(
guiJavaPath
).
filter
(
p
->
Files
.
isRegularFile
(
p
)).
forEach
(
p
->
{
try
{
List
<
String
>
lines
=
Files
.
readAllLines
(
p
);
for
(
String
line
:
lines
)
{
for
(
Iterator
<
String
>
it
=
keys
.
iterator
();
it
.
hasNext
();
)
{
if
(
line
.
contains
(
it
.
next
()))
{
it
.
remove
();
}
}
}
}
catch
(
IOException
e
)
{
throw
new
RuntimeException
(
e
);
}
});
assertThat
(
"keys not used"
,
keys
,
empty
());
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment