Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
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
229d78f1
Commit
229d78f1
authored
Mar 14, 2015
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gui: add preferences dialog
parent
f770e4ef
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
665 additions
and
142 deletions
+665
-142
JadxCLIArgs.java
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
+1
-1
Deobfuscator.java
jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java
+2
-1
JadxGUI.java
jadx-gui/src/main/java/jadx/gui/JadxGUI.java
+6
-16
JadxSettings.java
jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
+129
-0
JadxSettingsAdapter.java
.../src/main/java/jadx/gui/settings/JadxSettingsAdapter.java
+88
-0
JadxSettingsWindow.java
...i/src/main/java/jadx/gui/settings/JadxSettingsWindow.java
+259
-0
MainWindow.java
jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
+148
-28
SearchDialog.java
jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java
+1
-1
TabbedPane.java
jadx-gui/src/main/java/jadx/gui/ui/TabbedPane.java
+8
-4
JadxPreferences.java
jadx-gui/src/main/java/jadx/gui/utils/JadxPreferences.java
+0
-87
OverlayIcon.java
jadx-gui/src/main/java/jadx/gui/utils/OverlayIcon.java
+4
-4
Messages_en_US.properties
jadx-gui/src/main/resources/i18n/Messages_en_US.properties
+19
-0
lock_edit.png
jadx-gui/src/main/resources/icons-16/lock_edit.png
+0
-0
No files found.
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
View file @
229d78f1
...
...
@@ -18,7 +18,7 @@ import com.beust.jcommander.Parameter;
import
com.beust.jcommander.ParameterDescription
;
import
com.beust.jcommander.ParameterException
;
public
final
class
JadxCLIArgs
implements
IJadxArgs
{
public
class
JadxCLIArgs
implements
IJadxArgs
{
@Parameter
(
description
=
"<input file> (.dex, .apk, .jar or .class)"
)
protected
List
<
String
>
files
;
...
...
jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java
View file @
229d78f1
...
...
@@ -55,7 +55,7 @@ public class Deobfuscator {
}
public
void
execute
()
{
if
(
deobfMapFile
.
exists
())
{
if
(
deobfMapFile
.
exists
()
&&
!
args
.
isDeobfuscationForceSave
()
)
{
try
{
load
();
}
catch
(
IOException
e
)
{
...
...
@@ -295,6 +295,7 @@ public class Deobfuscator {
if
(!
deobfMapFile
.
exists
())
{
return
;
}
LOG
.
info
(
"Loading obfuscation map from: {}"
,
deobfMapFile
.
getAbsoluteFile
());
List
<
String
>
lines
=
FileUtils
.
readLines
(
deobfMapFile
,
MAP_FILE_CHARSET
);
for
(
String
l
:
lines
)
{
l
=
l
.
trim
();
...
...
jadx-gui/src/main/java/jadx/gui/JadxGUI.java
View file @
229d78f1
package
jadx
.
gui
;
import
jadx.cli.JadxCLIArgs
;
import
jadx.gui.settings.JadxSettings
;
import
jadx.gui.settings.JadxSettingsAdapter
;
import
jadx.gui.ui.MainWindow
;
import
javax.swing.SwingUtilities
;
import
javax.swing.UIManager
;
import
javax.swing.WindowConstants
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -15,26 +15,16 @@ public class JadxGUI {
public
static
void
main
(
String
[]
args
)
{
try
{
final
JadxCLIArgs
jadxArgs
=
new
JadxCLIArgs
();
final
JadxSettings
jadxArgs
=
JadxSettingsAdapter
.
load
();
// overwrite loaded settings by command line arguments
if
(!
jadxArgs
.
processArgs
(
args
))
{
return
;
}
UIManager
.
setLookAndFeel
(
UIManager
.
getSystemLookAndFeelClassName
());
SwingUtilities
.
invokeLater
(
new
Runnable
()
{
public
void
run
()
{
JadxWrapper
wrapper
=
new
JadxWrapper
(
jadxArgs
);
MainWindow
window
=
new
MainWindow
(
wrapper
);
window
.
pack
();
window
.
setLocationAndPosition
();
window
.
setVisible
(
true
);
window
.
setLocationRelativeTo
(
null
);
window
.
setDefaultCloseOperation
(
WindowConstants
.
DISPOSE_ON_CLOSE
);
if
(
jadxArgs
.
getInput
().
isEmpty
())
{
window
.
openFile
();
}
else
{
window
.
openFile
(
jadxArgs
.
getInput
().
get
(
0
));
}
MainWindow
window
=
new
MainWindow
(
jadxArgs
);
window
.
open
();
}
});
}
catch
(
Throwable
e
)
{
...
...
jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
0 → 100644
View file @
229d78f1
package
jadx
.
gui
.
settings
;
import
jadx.cli.JadxCLIArgs
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Set
;
public
class
JadxSettings
extends
JadxCLIArgs
{
private
static
final
String
USER_HOME
=
System
.
getProperty
(
"user.home"
);
private
static
final
int
RECENT_FILES_COUNT
=
15
;
static
final
Set
<
String
>
SKIP_FIELDS
=
new
HashSet
<
String
>(
Arrays
.
asList
(
"files"
,
"input"
,
"outputDir"
,
"printHelp"
));
private
String
lastOpenFilePath
=
USER_HOME
;
private
String
lastSaveFilePath
=
USER_HOME
;
private
boolean
flattenPackage
=
false
;
private
boolean
checkForUpdates
=
true
;
private
List
<
String
>
recentFiles
=
new
ArrayList
<
String
>();
public
void
sync
()
{
JadxSettingsAdapter
.
store
(
this
);
}
public
String
getLastOpenFilePath
()
{
return
lastOpenFilePath
;
}
public
void
setLastOpenFilePath
(
String
lastOpenFilePath
)
{
this
.
lastOpenFilePath
=
lastOpenFilePath
;
sync
();
}
public
String
getLastSaveFilePath
()
{
return
lastSaveFilePath
;
}
public
void
setLastSaveFilePath
(
String
lastSaveFilePath
)
{
this
.
lastSaveFilePath
=
lastSaveFilePath
;
sync
();
}
public
boolean
isFlattenPackage
()
{
return
flattenPackage
;
}
public
void
setFlattenPackage
(
boolean
flattenPackage
)
{
this
.
flattenPackage
=
flattenPackage
;
sync
();
}
public
boolean
isCheckForUpdates
()
{
return
checkForUpdates
;
}
public
void
setCheckForUpdates
(
boolean
checkForUpdates
)
{
this
.
checkForUpdates
=
checkForUpdates
;
sync
();
}
public
Iterable
<
String
>
getRecentFiles
()
{
return
recentFiles
;
}
public
void
addRecentFile
(
String
filePath
)
{
if
(
recentFiles
.
contains
(
filePath
))
{
return
;
}
recentFiles
.
add
(
filePath
);
int
count
=
recentFiles
.
size
();
if
(
count
>
RECENT_FILES_COUNT
)
{
recentFiles
.
subList
(
0
,
count
-
RECENT_FILES_COUNT
).
clear
();
}
sync
();
}
public
void
setThreadsCount
(
int
threadsCount
)
{
this
.
threadsCount
=
threadsCount
;
}
public
void
setFallbackMode
(
boolean
fallbackMode
)
{
this
.
fallbackMode
=
fallbackMode
;
}
public
void
setSkipResources
(
boolean
skipResources
)
{
this
.
skipResources
=
skipResources
;
}
public
void
setSkipSources
(
boolean
skipSources
)
{
this
.
skipSources
=
skipSources
;
}
public
void
setShowInconsistentCode
(
boolean
showInconsistentCode
)
{
this
.
showInconsistentCode
=
showInconsistentCode
;
}
public
void
setCfgOutput
(
boolean
cfgOutput
)
{
this
.
cfgOutput
=
cfgOutput
;
}
public
void
setRawCfgOutput
(
boolean
rawCfgOutput
)
{
this
.
rawCfgOutput
=
rawCfgOutput
;
}
public
void
setVerbose
(
boolean
verbose
)
{
this
.
verbose
=
verbose
;
}
public
void
setDeobfuscationOn
(
boolean
deobfuscationOn
)
{
this
.
deobfuscationOn
=
deobfuscationOn
;
}
public
void
setDeobfuscationMinLength
(
int
deobfuscationMinLength
)
{
this
.
deobfuscationMinLength
=
deobfuscationMinLength
;
}
public
void
setDeobfuscationMaxLength
(
int
deobfuscationMaxLength
)
{
this
.
deobfuscationMaxLength
=
deobfuscationMaxLength
;
}
public
void
setDeobfuscationForceSave
(
boolean
deobfuscationForceSave
)
{
this
.
deobfuscationForceSave
=
deobfuscationForceSave
;
}
}
jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsAdapter.java
0 → 100644
View file @
229d78f1
package
jadx
.
gui
.
settings
;
import
jadx.gui.JadxGUI
;
import
java.lang.reflect.Type
;
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
;
public
class
JadxSettingsAdapter
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
JadxSettingsAdapter
.
class
);
private
static
final
String
JADX_GUI_KEY
=
"jadx.gui.settings"
;
private
static
final
Preferences
PREFS
=
Preferences
.
userNodeForPackage
(
JadxGUI
.
class
);
private
static
ExclusionStrategy
EXCLUDE_FIELDS
=
new
ExclusionStrategy
()
{
@Override
public
boolean
shouldSkipField
(
FieldAttributes
f
)
{
return
JadxSettings
.
SKIP_FIELDS
.
contains
(
f
.
getName
());
}
@Override
public
boolean
shouldSkipClass
(
Class
<?>
clazz
)
{
return
false
;
}
};
private
static
final
GsonBuilder
GSON_BUILDER
=
new
GsonBuilder
().
setExclusionStrategies
(
EXCLUDE_FIELDS
);
private
static
final
Gson
GSON
=
GSON_BUILDER
.
create
();
private
JadxSettingsAdapter
()
{
}
public
static
JadxSettings
load
()
{
try
{
String
jsonSettings
=
PREFS
.
get
(
JADX_GUI_KEY
,
""
);
JadxSettings
settings
=
fromString
(
jsonSettings
);
if
(
settings
==
null
)
{
return
new
JadxSettings
();
}
LOG
.
info
(
"Loaded settings: {}"
,
makeString
(
settings
));
return
settings
;
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Error load settings"
,
e
);
return
new
JadxSettings
();
}
}
public
static
void
store
(
JadxSettings
settings
)
{
try
{
String
jsonSettings
=
makeString
(
settings
);
LOG
.
debug
(
"Saving settings: {}"
,
jsonSettings
);
PREFS
.
put
(
JADX_GUI_KEY
,
jsonSettings
);
PREFS
.
sync
();
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Error store settings"
,
e
);
}
}
public
static
JadxSettings
fromString
(
String
jsonSettings
)
{
return
GSON
.
fromJson
(
jsonSettings
,
JadxSettings
.
class
);
}
public
static
String
makeString
(
JadxSettings
settings
)
{
return
GSON
.
toJson
(
settings
);
}
public
static
void
fill
(
JadxSettings
settings
,
String
jsonStr
)
{
populate
(
GSON_BUILDER
,
jsonStr
,
JadxSettings
.
class
,
settings
);
}
private
static
<
T
>
void
populate
(
GsonBuilder
builder
,
String
json
,
Class
<
T
>
type
,
final
T
into
)
{
builder
.
registerTypeAdapter
(
type
,
new
InstanceCreator
<
T
>()
{
@Override
public
T
createInstance
(
Type
t
)
{
return
into
;
}
}).
create
().
fromJson
(
json
,
type
);
}
}
jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsWindow.java
0 → 100644
View file @
229d78f1
package
jadx
.
gui
.
settings
;
import
jadx.gui.ui.MainWindow
;
import
jadx.gui.utils.NLS
;
import
javax.swing.BorderFactory
;
import
javax.swing.Box
;
import
javax.swing.BoxLayout
;
import
javax.swing.JButton
;
import
javax.swing.JCheckBox
;
import
javax.swing.JComponent
;
import
javax.swing.JDialog
;
import
javax.swing.JLabel
;
import
javax.swing.JPanel
;
import
javax.swing.JSpinner
;
import
javax.swing.SwingConstants
;
import
javax.swing.WindowConstants
;
import
javax.swing.event.ChangeEvent
;
import
javax.swing.event.ChangeListener
;
import
java.awt.BorderLayout
;
import
java.awt.Container
;
import
java.awt.Dimension
;
import
java.awt.GridBagConstraints
;
import
java.awt.GridBagLayout
;
import
java.awt.GridLayout
;
import
java.awt.Insets
;
import
java.awt.event.ActionEvent
;
import
java.awt.event.ActionListener
;
import
java.awt.event.ItemEvent
;
import
java.awt.event.ItemListener
;
public
class
JadxSettingsWindow
extends
JDialog
{
private
static
final
long
serialVersionUID
=
-
1804570470377354148L
;
private
final
MainWindow
mainWindow
;
private
final
JadxSettings
settings
;
private
final
String
startSettings
;
private
boolean
needReload
=
false
;
public
JadxSettingsWindow
(
MainWindow
mainWindow
,
JadxSettings
settings
)
{
this
.
mainWindow
=
mainWindow
;
this
.
settings
=
settings
;
this
.
startSettings
=
JadxSettingsAdapter
.
makeString
(
settings
);
initUI
();
}
private
void
initUI
()
{
JPanel
panel
=
new
JPanel
();
panel
.
setLayout
(
new
GridLayout
(
0
,
1
,
10
,
5
));
panel
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
10
,
10
,
10
,
10
));
panel
.
add
(
makeDeobfuscationGroup
());
panel
.
add
(
makeOtherGroup
());
JButton
saveBtn
=
new
JButton
(
NLS
.
str
(
"preferences.save"
));
saveBtn
.
addActionListener
(
new
ActionListener
()
{
public
void
actionPerformed
(
ActionEvent
event
)
{
settings
.
sync
();
if
(
needReload
)
{
mainWindow
.
reOpenFile
();
}
dispose
();
}
});
JButton
cancelButton
=
new
JButton
(
NLS
.
str
(
"preferences.cancel"
));
cancelButton
.
addActionListener
(
new
ActionListener
()
{
public
void
actionPerformed
(
ActionEvent
event
)
{
JadxSettingsAdapter
.
fill
(
settings
,
startSettings
);
dispose
();
}
});
JPanel
buttonPane
=
new
JPanel
();
buttonPane
.
setLayout
(
new
BoxLayout
(
buttonPane
,
BoxLayout
.
LINE_AXIS
));
buttonPane
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
0
,
10
,
10
,
10
));
buttonPane
.
add
(
Box
.
createHorizontalGlue
());
buttonPane
.
add
(
saveBtn
);
buttonPane
.
add
(
Box
.
createRigidArea
(
new
Dimension
(
10
,
0
)));
buttonPane
.
add
(
cancelButton
);
Container
contentPane
=
getContentPane
();
contentPane
.
add
(
panel
,
BorderLayout
.
CENTER
);
contentPane
.
add
(
buttonPane
,
BorderLayout
.
PAGE_END
);
getRootPane
().
setDefaultButton
(
saveBtn
);
setTitle
(
NLS
.
str
(
"preferences.title"
));
setSize
(
400
,
550
);
setLocationRelativeTo
(
null
);
setDefaultCloseOperation
(
WindowConstants
.
DISPOSE_ON_CLOSE
);
setModalityType
(
ModalityType
.
APPLICATION_MODAL
);
pack
();
}
private
SettingsGroup
makeDeobfuscationGroup
()
{
JCheckBox
deobfOn
=
new
JCheckBox
();
deobfOn
.
setSelected
(
settings
.
isDeobfuscationOn
());
deobfOn
.
addItemListener
(
new
ItemListener
()
{
public
void
itemStateChanged
(
ItemEvent
e
)
{
settings
.
setDeobfuscationOn
(
e
.
getStateChange
()
==
ItemEvent
.
SELECTED
);
needReload
();
}
});
JCheckBox
deobfForce
=
new
JCheckBox
();
deobfForce
.
setSelected
(
settings
.
isDeobfuscationForceSave
());
deobfForce
.
addItemListener
(
new
ItemListener
()
{
public
void
itemStateChanged
(
ItemEvent
e
)
{
settings
.
setDeobfuscationForceSave
(
e
.
getStateChange
()
==
ItemEvent
.
SELECTED
);
needReload
();
}
});
final
JSpinner
minLen
=
new
JSpinner
();
minLen
.
setValue
(
settings
.
getDeobfuscationMinLength
());
minLen
.
addChangeListener
(
new
ChangeListener
()
{
@Override
public
void
stateChanged
(
ChangeEvent
e
)
{
settings
.
setDeobfuscationMinLength
((
Integer
)
minLen
.
getValue
());
needReload
();
}
});
final
JSpinner
maxLen
=
new
JSpinner
();
maxLen
.
setValue
(
settings
.
getDeobfuscationMaxLength
());
maxLen
.
addChangeListener
(
new
ChangeListener
()
{
@Override
public
void
stateChanged
(
ChangeEvent
e
)
{
settings
.
setDeobfuscationMaxLength
((
Integer
)
maxLen
.
getValue
());
needReload
();
}
});
SettingsGroup
deobfGroup
=
new
SettingsGroup
(
NLS
.
str
(
"preferences.deobfuscation"
));
deobfGroup
.
addRow
(
NLS
.
str
(
"preferences.deobfuscation_on"
),
deobfOn
);
deobfGroup
.
addRow
(
NLS
.
str
(
"preferences.deobfuscation_force"
),
deobfForce
);
deobfGroup
.
addRow
(
NLS
.
str
(
"preferences.deobfuscation_min_len"
),
minLen
);
deobfGroup
.
addRow
(
NLS
.
str
(
"preferences.deobfuscation_max_len"
),
maxLen
);
deobfGroup
.
end
();
return
deobfGroup
;
}
private
SettingsGroup
makeOtherGroup
()
{
JCheckBox
update
=
new
JCheckBox
();
update
.
setSelected
(
settings
.
isCheckForUpdates
());
update
.
addItemListener
(
new
ItemListener
()
{
public
void
itemStateChanged
(
ItemEvent
e
)
{
settings
.
setCheckForUpdates
(
e
.
getStateChange
()
==
ItemEvent
.
SELECTED
);
}
});
JCheckBox
fallback
=
new
JCheckBox
();
fallback
.
setSelected
(
settings
.
isFallbackMode
());
fallback
.
addItemListener
(
new
ItemListener
()
{
public
void
itemStateChanged
(
ItemEvent
e
)
{
settings
.
setFallbackMode
(
e
.
getStateChange
()
==
ItemEvent
.
SELECTED
);
needReload
();
}
});
JCheckBox
showInconsistentCode
=
new
JCheckBox
();
showInconsistentCode
.
setSelected
(
settings
.
isShowInconsistentCode
());
showInconsistentCode
.
addItemListener
(
new
ItemListener
()
{
public
void
itemStateChanged
(
ItemEvent
e
)
{
settings
.
setShowInconsistentCode
(
e
.
getStateChange
()
==
ItemEvent
.
SELECTED
);
needReload
();
}
});
JCheckBox
resourceDecode
=
new
JCheckBox
();
resourceDecode
.
setSelected
(
settings
.
isSkipResources
());
resourceDecode
.
addItemListener
(
new
ItemListener
()
{
public
void
itemStateChanged
(
ItemEvent
e
)
{
settings
.
setSkipResources
(
e
.
getStateChange
()
==
ItemEvent
.
SELECTED
);
needReload
();
}
});
final
JSpinner
threadsCount
=
new
JSpinner
();
threadsCount
.
setValue
(
settings
.
getThreadsCount
());
threadsCount
.
addChangeListener
(
new
ChangeListener
()
{
@Override
public
void
stateChanged
(
ChangeEvent
e
)
{
settings
.
setThreadsCount
((
Integer
)
threadsCount
.
getValue
());
}
});
JCheckBox
cfg
=
new
JCheckBox
();
cfg
.
setSelected
(
settings
.
isCFGOutput
());
cfg
.
addItemListener
(
new
ItemListener
()
{
public
void
itemStateChanged
(
ItemEvent
e
)
{
settings
.
setCfgOutput
(
e
.
getStateChange
()
==
ItemEvent
.
SELECTED
);
needReload
();
}
});
JCheckBox
rawCfg
=
new
JCheckBox
();
rawCfg
.
setSelected
(
settings
.
isRawCFGOutput
());
rawCfg
.
addItemListener
(
new
ItemListener
()
{
public
void
itemStateChanged
(
ItemEvent
e
)
{
settings
.
setRawCfgOutput
(
e
.
getStateChange
()
==
ItemEvent
.
SELECTED
);
needReload
();
}
});
SettingsGroup
other
=
new
SettingsGroup
(
NLS
.
str
(
"preferences.other"
));
other
.
addRow
(
NLS
.
str
(
"preferences.check_for_updates"
),
update
);
other
.
addRow
(
NLS
.
str
(
"preferences.threads"
),
threadsCount
);
other
.
addRow
(
NLS
.
str
(
"preferences.fallback"
),
fallback
);
other
.
addRow
(
NLS
.
str
(
"preferences.showInconsistentCode"
),
showInconsistentCode
);
other
.
addRow
(
NLS
.
str
(
"preferences.skipResourcesDecode"
),
resourceDecode
);
other
.
addRow
(
NLS
.
str
(
"preferences.cfg"
),
cfg
);
other
.
addRow
(
NLS
.
str
(
"preferences.raw_cfg"
),
rawCfg
);
return
other
;
}
private
void
needReload
()
{
needReload
=
true
;
}
private
static
class
SettingsGroup
extends
JPanel
{
private
static
final
long
serialVersionUID
=
-
6487309975896192544L
;
private
final
GridBagConstraints
c
;
private
int
row
;
public
SettingsGroup
(
String
title
)
{
setBorder
(
BorderFactory
.
createTitledBorder
(
title
));
setLayout
(
new
GridBagLayout
());
c
=
new
GridBagConstraints
();
c
.
insets
=
new
Insets
(
5
,
5
,
5
,
5
);
c
.
weighty
=
1.0
;
}
public
void
addRow
(
String
label
,
JComponent
comp
)
{
c
.
gridy
=
row
++;
JLabel
jLabel
=
new
JLabel
(
label
);
jLabel
.
setLabelFor
(
comp
);
jLabel
.
setHorizontalAlignment
(
SwingConstants
.
LEFT
);
c
.
gridx
=
0
;
c
.
gridwidth
=
1
;
c
.
anchor
=
GridBagConstraints
.
LINE_START
;
c
.
weightx
=
0.8
;
c
.
fill
=
GridBagConstraints
.
NONE
;
add
(
jLabel
,
c
);
c
.
gridx
=
1
;
c
.
gridwidth
=
GridBagConstraints
.
REMAINDER
;
c
.
anchor
=
GridBagConstraints
.
CENTER
;
c
.
weightx
=
0.2
;
c
.
fill
=
GridBagConstraints
.
HORIZONTAL
;
add
(
comp
,
c
);
}
public
void
end
()
{
add
(
Box
.
createVerticalGlue
());
}
}
}
jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
View file @
229d78f1
package
jadx
.
gui
.
ui
;
import
jadx.gui.JadxWrapper
;
import
jadx.gui.settings.JadxSettings
;
import
jadx.gui.settings.JadxSettingsWindow
;
import
jadx.gui.treemodel.JClass
;
import
jadx.gui.treemodel.JNode
;
import
jadx.gui.treemodel.JResource
;
...
...
@@ -8,7 +10,6 @@ import jadx.gui.treemodel.JRoot;
import
jadx.gui.update.JadxUpdate
;
import
jadx.gui.update.JadxUpdate.IUpdateCallback
;
import
jadx.gui.update.data.Release
;
import
jadx.gui.utils.JadxPreferences
;
import
jadx.gui.utils.Link
;
import
jadx.gui.utils.NLS
;
import
jadx.gui.utils.Position
;
...
...
@@ -31,6 +32,9 @@ import javax.swing.JToolBar;
import
javax.swing.JTree
;
import
javax.swing.ProgressMonitor
;
import
javax.swing.SwingUtilities
;
import
javax.swing.WindowConstants
;
import
javax.swing.event.MenuEvent
;
import
javax.swing.event.MenuListener
;
import
javax.swing.event.TreeExpansionEvent
;
import
javax.swing.event.TreeWillExpandListener
;
import
javax.swing.filechooser.FileNameExtensionFilter
;
...
...
@@ -53,6 +57,7 @@ import java.awt.event.KeyEvent;
import
java.awt.event.MouseAdapter
;
import
java.awt.event.MouseEvent
;
import
java.io.File
;
import
java.util.Arrays
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -76,8 +81,11 @@ public class MainWindow extends JFrame {
private
static
final
ImageIcon
ICON_FIND
=
Utils
.
openIcon
(
"magnifier"
);
private
static
final
ImageIcon
ICON_BACK
=
Utils
.
openIcon
(
"icon_back"
);
private
static
final
ImageIcon
ICON_FORWARD
=
Utils
.
openIcon
(
"icon_forward"
);
private
static
final
ImageIcon
ICON_PREF
=
Utils
.
openIcon
(
"wrench"
);
private
static
final
ImageIcon
ICON_DEOBF
=
Utils
.
openIcon
(
"lock_edit"
);
private
final
JadxWrapper
wrapper
;
private
final
JadxSettings
settings
;
private
JPanel
mainPanel
;
...
...
@@ -88,19 +96,37 @@ public class MainWindow extends JFrame {
private
JCheckBoxMenuItem
flatPkgMenuItem
;
private
JToggleButton
flatPkgButton
;
private
JToggleButton
deobfToggleBtn
;
private
boolean
isFlattenPackage
;
private
Link
updateLink
;
public
MainWindow
(
JadxWrapper
wrapper
)
{
this
.
wrapper
=
wrapper
;
public
MainWindow
(
JadxSettings
settings
)
{
this
.
wrapper
=
new
JadxWrapper
(
settings
);
this
.
settings
=
settings
;
initUI
();
initMenuAndToolbar
();
checkForUpdate
();
}
public
void
open
()
{
pack
();
setLocationAndPosition
();
setVisible
(
true
);
setLocationRelativeTo
(
null
);
setDefaultCloseOperation
(
WindowConstants
.
DISPOSE_ON_CLOSE
);
if
(
settings
.
getInput
().
isEmpty
())
{
openFile
();
}
else
{
openFile
(
settings
.
getInput
().
get
(
0
));
}
}
private
void
checkForUpdate
()
{
// TODO: add option for disable update checks
if
(!
settings
.
isCheckForUpdates
())
{
return
;
}
JadxUpdate
.
check
(
new
IUpdateCallback
()
{
@Override
public
void
onUpdate
(
final
Release
r
)
{
...
...
@@ -118,38 +144,50 @@ public class MainWindow extends JFrame {
public
void
openFile
()
{
JFileChooser
fileChooser
=
new
JFileChooser
();
fileChooser
.
setAcceptAllFileFilterUsed
(
true
);
fileChooser
.
setFileFilter
(
new
FileNameExtensionFilter
(
"supported files"
,
"dex"
,
"apk"
,
"jar"
));
String
[]
exts
=
{
"apk"
,
"dex"
,
"jar"
,
"class"
,
"zip"
};
String
description
=
"supported files: "
+
Arrays
.
toString
(
exts
).
replace
(
'['
,
'('
).
replace
(
']'
,
')'
);
fileChooser
.
setFileFilter
(
new
FileNameExtensionFilter
(
description
,
exts
));
fileChooser
.
setToolTipText
(
NLS
.
str
(
"file.open"
));
String
currentDirectory
=
JadxPreference
s
.
getLastOpenFilePath
();
String
currentDirectory
=
setting
s
.
getLastOpenFilePath
();
if
(!
currentDirectory
.
isEmpty
())
{
fileChooser
.
setCurrentDirectory
(
new
File
(
currentDirectory
));
}
int
ret
=
fileChooser
.
showDialog
(
mainPanel
,
NLS
.
str
(
"file.open"
));
if
(
ret
==
JFileChooser
.
APPROVE_OPTION
)
{
JadxPreferences
.
pu
tLastOpenFilePath
(
fileChooser
.
getCurrentDirectory
().
getPath
());
settings
.
se
tLastOpenFilePath
(
fileChooser
.
getCurrentDirectory
().
getPath
());
openFile
(
fileChooser
.
getSelectedFile
());
}
}
public
void
openFile
(
File
file
)
{
wrapper
.
openFile
(
file
);
deobfToggleBtn
.
setSelected
(
settings
.
isDeobfuscationOn
());
settings
.
addRecentFile
(
file
.
getAbsolutePath
());
initTree
();
setTitle
(
DEFAULT_TITLE
+
" - "
+
file
.
getName
());
}
public
void
reOpenFile
()
{
File
openedFile
=
wrapper
.
getOpenFile
();
if
(
openedFile
!=
null
)
{
tabbedPane
.
closeAllTabs
();
openFile
(
openedFile
);
}
}
private
void
saveAllAction
()
{
JFileChooser
fileChooser
=
new
JFileChooser
();
fileChooser
.
setFileSelectionMode
(
JFileChooser
.
DIRECTORIES_ONLY
);
fileChooser
.
setToolTipText
(
NLS
.
str
(
"file.save_all_msg"
));
String
currentDirectory
=
JadxPreference
s
.
getLastSaveFilePath
();
String
currentDirectory
=
setting
s
.
getLastSaveFilePath
();
if
(!
currentDirectory
.
isEmpty
())
{
fileChooser
.
setCurrentDirectory
(
new
File
(
currentDirectory
));
}
int
ret
=
fileChooser
.
showDialog
(
mainPanel
,
NLS
.
str
(
"file.select"
));
if
(
ret
==
JFileChooser
.
APPROVE_OPTION
)
{
JadxPreferences
.
pu
tLastSaveFilePath
(
fileChooser
.
getCurrentDirectory
().
getPath
());
settings
.
se
tLastSaveFilePath
(
fileChooser
.
getCurrentDirectory
().
getPath
());
ProgressMonitor
progressMonitor
=
new
ProgressMonitor
(
mainPanel
,
NLS
.
str
(
"msg.saving_sources"
),
""
,
0
,
100
);
progressMonitor
.
setMillisToPopup
(
500
);
wrapper
.
saveAll
(
fileChooser
.
getSelectedFile
(),
progressMonitor
);
...
...
@@ -174,7 +212,7 @@ public class MainWindow extends JFrame {
private
void
setFlattenPackage
(
boolean
value
)
{
isFlattenPackage
=
value
;
JadxPreferences
.
pu
tFlattenPackage
(
isFlattenPackage
);
settings
.
se
tFlattenPackage
(
isFlattenPackage
);
flatPkgButton
.
setSelected
(
isFlattenPackage
);
flatPkgMenuItem
.
setState
(
isFlattenPackage
);
...
...
@@ -265,15 +303,35 @@ public class MainWindow extends JFrame {
}
});
JMenu
recentFiles
=
new
JMenu
(
NLS
.
str
(
"menu.recent_files"
));
recentFiles
.
addMenuListener
(
new
RecentFilesMenuListener
(
recentFiles
));
JMenuItem
preferences
=
new
JMenuItem
(
NLS
.
str
(
"menu.preferences"
),
ICON_PREF
);
ActionListener
prefAction
=
new
ActionListener
()
{
public
void
actionPerformed
(
ActionEvent
event
)
{
final
JadxSettingsWindow
dialog
=
new
JadxSettingsWindow
(
MainWindow
.
this
,
settings
);
SwingUtilities
.
invokeLater
(
new
Runnable
()
{
public
void
run
()
{
dialog
.
setVisible
(
true
);
}
});
}
};
preferences
.
addActionListener
(
prefAction
);
file
.
add
(
open
);
file
.
add
(
saveAll
);
file
.
addSeparator
();
file
.
add
(
recentFiles
);
file
.
addSeparator
();
file
.
add
(
preferences
);
file
.
addSeparator
();
file
.
add
(
exit
);
JMenu
view
=
new
JMenu
(
NLS
.
str
(
"menu.view"
));
view
.
setMnemonic
(
KeyEvent
.
VK_V
);
isFlattenPackage
=
JadxPreferences
.
get
FlattenPackage
();
isFlattenPackage
=
settings
.
is
FlattenPackage
();
flatPkgMenuItem
=
new
JCheckBoxMenuItem
(
NLS
.
str
(
"menu.flatten"
),
ICON_FLAT_PKG
);
view
.
add
(
flatPkgMenuItem
);
...
...
@@ -334,13 +392,9 @@ public class MainWindow extends JFrame {
menuBar
.
add
(
help
);
setJMenuBar
(
menuBar
);
JToolBar
toolbar
=
new
JToolBar
();
toolbar
.
setFloatable
(
false
);
final
JButton
openButton
=
new
JButton
(
ICON_OPEN
);
openButton
.
addActionListener
(
new
OpenListener
());
openButton
.
setToolTipText
(
NLS
.
str
(
"file.open"
));
toolbar
.
add
(
openButton
);
final
JButton
saveAllButton
=
new
JButton
(
ICON_SAVE_ALL
);
saveAllButton
.
addActionListener
(
new
ActionListener
()
{
...
...
@@ -350,9 +404,6 @@ public class MainWindow extends JFrame {
}
});
saveAllButton
.
setToolTipText
(
NLS
.
str
(
"file.save_all"
));
toolbar
.
add
(
saveAllButton
);
toolbar
.
addSeparator
();
final
JButton
syncButton
=
new
JButton
(
ICON_SYNC
);
syncButton
.
addActionListener
(
new
ActionListener
()
{
...
...
@@ -362,7 +413,6 @@ public class MainWindow extends JFrame {
}
});
syncButton
.
setToolTipText
(
NLS
.
str
(
"menu.sync"
));
toolbar
.
add
(
syncButton
);
flatPkgButton
=
new
JToggleButton
(
ICON_FLAT_PKG
);
flatPkgButton
.
setSelected
(
isFlattenPackage
);
...
...
@@ -376,20 +426,14 @@ public class MainWindow extends JFrame {
flatPkgMenuItem
.
addActionListener
(
flatPkgAction
);
flatPkgButton
.
setToolTipText
(
NLS
.
str
(
"menu.flatten"
));
toolbar
.
add
(
flatPkgButton
);
toolbar
.
addSeparator
();
final
JButton
searchButton
=
new
JButton
(
ICON_SEARCH
);
searchButton
.
addActionListener
(
searchAction
);
searchButton
.
setToolTipText
(
NLS
.
str
(
"menu.search"
));
toolbar
.
add
(
searchButton
);
final
JButton
findButton
=
new
JButton
(
ICON_FIND
);
findButton
.
addActionListener
(
findAction
);
findButton
.
setToolTipText
(
NLS
.
str
(
"menu.find_in_file"
));
toolbar
.
add
(
findButton
);
toolbar
.
addSeparator
();
final
JButton
backButton
=
new
JButton
(
ICON_BACK
);
backButton
.
addActionListener
(
new
ActionListener
()
{
...
...
@@ -399,7 +443,6 @@ public class MainWindow extends JFrame {
}
});
backButton
.
setToolTipText
(
NLS
.
str
(
"nav.back"
));
toolbar
.
add
(
backButton
);
final
JButton
forwardButton
=
new
JButton
(
ICON_FORWARD
);
forwardButton
.
addActionListener
(
new
ActionListener
()
{
...
...
@@ -409,11 +452,52 @@ public class MainWindow extends JFrame {
}
});
forwardButton
.
setToolTipText
(
NLS
.
str
(
"nav.forward"
));
toolbar
.
add
(
forwardButton
);
toolbar
.
add
(
Box
.
createHorizontalGlue
());
final
JButton
prefButton
=
new
JButton
(
ICON_PREF
);
prefButton
.
addActionListener
(
prefAction
);
prefButton
.
setToolTipText
(
NLS
.
str
(
"menu.preferences"
));
deobfToggleBtn
=
new
JToggleButton
(
ICON_DEOBF
);
deobfToggleBtn
.
setSelected
(
settings
.
isDeobfuscationOn
());
deobfToggleBtn
.
setToolTipText
(
NLS
.
str
(
"preferences.deobfuscation"
));
deobfToggleBtn
.
addActionListener
(
new
ActionListener
()
{
@Override
public
void
actionPerformed
(
ActionEvent
e
)
{
settings
.
setDeobfuscationOn
(
deobfToggleBtn
.
isSelected
());
settings
.
sync
();
reOpenFile
();
}
});
updateLink
=
new
Link
(
""
,
JadxUpdate
.
JADX_RELEASES_URL
);
updateLink
.
setVisible
(
false
);
JToolBar
toolbar
=
new
JToolBar
();
toolbar
.
setFloatable
(
false
);
toolbar
.
add
(
openButton
);
toolbar
.
add
(
saveAllButton
);
toolbar
.
addSeparator
();
toolbar
.
add
(
syncButton
);
toolbar
.
add
(
flatPkgButton
);
toolbar
.
addSeparator
();
toolbar
.
add
(
searchButton
);
toolbar
.
add
(
findButton
);
toolbar
.
addSeparator
();
toolbar
.
add
(
backButton
);
toolbar
.
add
(
forwardButton
);
toolbar
.
addSeparator
();
toolbar
.
add
(
deobfToggleBtn
);
toolbar
.
addSeparator
();
toolbar
.
add
(
prefButton
);
toolbar
.
addSeparator
();
toolbar
.
add
(
Box
.
createHorizontalGlue
());
toolbar
.
add
(
updateLink
);
mainPanel
.
add
(
toolbar
,
BorderLayout
.
NORTH
);
...
...
@@ -495,4 +579,40 @@ public class MainWindow extends JFrame {
openFile
();
}
}
private
class
RecentFilesMenuListener
implements
MenuListener
{
private
final
JMenu
recentFiles
;
public
RecentFilesMenuListener
(
JMenu
recentFiles
)
{
this
.
recentFiles
=
recentFiles
;
}
@Override
public
void
menuSelected
(
MenuEvent
e
)
{
recentFiles
.
removeAll
();
File
openFile
=
wrapper
.
getOpenFile
();
String
currentFile
=
openFile
==
null
?
""
:
openFile
.
getAbsolutePath
();
for
(
final
String
file
:
settings
.
getRecentFiles
())
{
if
(
file
.
equals
(
currentFile
))
{
continue
;
}
JMenuItem
menuItem
=
new
JMenuItem
(
file
);
recentFiles
.
add
(
menuItem
);
menuItem
.
addActionListener
(
new
ActionListener
()
{
@Override
public
void
actionPerformed
(
ActionEvent
e
)
{
openFile
(
new
File
(
file
));
}
});
}
}
@Override
public
void
menuDeselected
(
MenuEvent
e
)
{
}
@Override
public
void
menuCanceled
(
MenuEvent
e
)
{
}
}
}
jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java
View file @
229d78f1
...
...
@@ -299,7 +299,7 @@ public class SearchDialog extends JDialog {
buttonPane
.
setLayout
(
new
BoxLayout
(
buttonPane
,
BoxLayout
.
LINE_AXIS
));
buttonPane
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
0
,
10
,
10
,
10
));
buttonPane
.
add
(
busyBar
);
search
Pane
.
add
(
Box
.
createRigidArea
(
new
Dimension
(
5
,
0
)));
button
Pane
.
add
(
Box
.
createRigidArea
(
new
Dimension
(
5
,
0
)));
buttonPane
.
add
(
Box
.
createHorizontalGlue
());
buttonPane
.
add
(
openBtn
);
buttonPane
.
add
(
Box
.
createRigidArea
(
new
Dimension
(
10
,
0
)));
...
...
jadx-gui/src/main/java/jadx/gui/ui/TabbedPane.java
View file @
229d78f1
...
...
@@ -200,10 +200,7 @@ class TabbedPane extends JTabbedPane {
closeAll
.
addActionListener
(
new
ActionListener
()
{
@Override
public
void
actionPerformed
(
ActionEvent
e
)
{
List
<
ContentPanel
>
contentPanels
=
new
ArrayList
<
ContentPanel
>(
openTabs
.
values
());
for
(
ContentPanel
panel
:
contentPanels
)
{
closeCodePanel
(
panel
);
}
closeAllTabs
();
}
});
menu
.
add
(
closeAll
);
...
...
@@ -230,4 +227,11 @@ class TabbedPane extends JTabbedPane {
}
return
menu
;
}
public
void
closeAllTabs
()
{
List
<
ContentPanel
>
contentPanels
=
new
ArrayList
<
ContentPanel
>(
openTabs
.
values
());
for
(
ContentPanel
panel
:
contentPanels
)
{
closeCodePanel
(
panel
);
}
}
}
jadx-gui/src/main/java/jadx/gui/utils/JadxPreferences.java
deleted
100644 → 0
View file @
f770e4ef
package
jadx
.
gui
.
utils
;
import
java.util.prefs.Preferences
;
public
class
JadxPreferences
{
private
static
final
String
KEY_LAST_OPEN_FILE_PATH
=
"lastOpenFilePath"
;
private
static
final
String
KEY_LAST_SAVE_FILE_PATH
=
"lastSaveFilePath"
;
private
static
final
String
KEY_FLATTEN_PACKAGE
=
"flattenPackage"
;
private
static
Preferences
prefs
=
null
;
public
static
String
getLastOpenFilePath
()
{
String
result
=
""
;
try
{
result
=
getPreferences
().
get
(
KEY_LAST_OPEN_FILE_PATH
,
""
);
if
(
result
.
isEmpty
())
{
result
=
System
.
getProperty
(
"user.home"
);
}
}
catch
(
Exception
anyEx
)
{
/* do nothing, no preferences */
}
return
result
;
}
public
static
void
putLastOpenFilePath
(
String
path
)
{
try
{
Preferences
prefs
=
getPreferences
();
prefs
.
put
(
KEY_LAST_OPEN_FILE_PATH
,
path
);
prefs
.
sync
();
}
catch
(
Exception
anyEx
)
{
/* do nothing, no preferences */
}
}
public
static
String
getLastSaveFilePath
()
{
String
result
=
""
;
try
{
result
=
getPreferences
().
get
(
KEY_LAST_SAVE_FILE_PATH
,
""
);
if
(
result
.
isEmpty
())
{
result
=
getLastOpenFilePath
();
}
}
catch
(
Exception
anyEx
)
{
/* do nothing, no preferences */
}
return
result
;
}
public
static
void
putLastSaveFilePath
(
String
path
)
{
try
{
Preferences
prefs
=
getPreferences
();
prefs
.
put
(
KEY_LAST_SAVE_FILE_PATH
,
path
);
prefs
.
sync
();
}
catch
(
Exception
anyEx
)
{
/* do nothing, no preferences */
}
}
public
static
boolean
getFlattenPackage
()
{
boolean
result
=
false
;
try
{
Preferences
prefs
=
getPreferences
();
result
=
prefs
.
getBoolean
(
KEY_FLATTEN_PACKAGE
,
false
);
}
catch
(
Exception
anyEx
)
{
/* do nothing, no preferences */
}
return
result
;
}
public
static
void
putFlattenPackage
(
boolean
value
)
{
try
{
Preferences
prefs
=
getPreferences
();
prefs
.
putBoolean
(
KEY_FLATTEN_PACKAGE
,
value
);
prefs
.
sync
();
}
catch
(
Exception
anyEx
)
{
/* do nothing, no preferences */
}
}
private
static
Preferences
getPreferences
()
{
if
(
prefs
==
null
)
{
prefs
=
Preferences
.
userRoot
();
}
return
prefs
;
}
}
jadx-gui/src/main/java/jadx/gui/utils/OverlayIcon.java
View file @
229d78f1
...
...
@@ -42,10 +42,10 @@ public class OverlayIcon implements Icon {
icon
.
paintIcon
(
c
,
g
,
x
,
y
);
int
k
=
0
;
for
(
Icon
i
con
:
icons
)
{
int
dx
=
(
int
)
(
OVERLAY_POS
[
k
++]
*
(
w
-
i
con
.
getIconWidth
()));
int
dy
=
(
int
)
(
OVERLAY_POS
[
k
++]
*
(
h
-
i
con
.
getIconHeight
()));
i
con
.
paintIcon
(
c
,
g
,
x
+
dx
,
y
+
dy
);
for
(
Icon
subI
con
:
icons
)
{
int
dx
=
(
int
)
(
OVERLAY_POS
[
k
++]
*
(
w
-
subI
con
.
getIconWidth
()));
int
dy
=
(
int
)
(
OVERLAY_POS
[
k
++]
*
(
h
-
subI
con
.
getIconHeight
()));
subI
con
.
paintIcon
(
c
,
g
,
x
+
dx
,
y
+
dy
);
}
}
...
...
jadx-gui/src/main/resources/i18n/Messages_en_US.properties
View file @
229d78f1
menu.file
=
File
menu.view
=
View
menu.recent_files
=
Recent Files
menu.preferences
=
Preferences
menu.sync
=
Sync with editor
menu.flatten
=
Show flatten packages
menu.navigation
=
Navigation
...
...
@@ -43,5 +45,22 @@ search_dialog.method=Method
search_dialog.field
=
Field
search_dialog.code
=
Code
preferences.title
=
Preferences
preferences.deobfuscation
=
Deobfuscation
preferences.other
=
Other
preferences.check_for_updates
=
Check for updates on startup
preferences.fallback
=
Fallback (simple dump)
preferences.showInconsistentCode
=
Show inconsistent code
preferences.skipResourcesDecode
=
Don't decode resources
preferences.threads
=
Processing threads count
preferences.cfg
=
Generate methods CFG graphs (in 'dot' format)
preferences.raw_cfg
=
Generate RAW CFG graphs
preferences.deobfuscation_on
=
Enable deobfuscation
preferences.deobfuscation_force
=
Force rewrite deobfuscation map file
preferences.deobfuscation_min_len
=
Minimum name length
preferences.deobfuscation_max_len
=
Maximum name length
preferences.save
=
Save
preferences.cancel
=
Cancel
msg.open_file
=
Please open file
msg.saving_sources
=
Saving sources
jadx-gui/src/main/resources/icons-16/lock_edit.png
0 → 100644
View file @
229d78f1
861 Bytes
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