Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
keyescgm
jadx
提交
c774ffc9
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,发现更多精彩内容 >>
未验证
提交
c774ffc9
编写于
1月 31, 2021
作者:
L
LBJ-the-GOAT
提交者:
GitHub
1月 30, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat(gui): search in resource files (#347) (#1032) (PR #1108)
Co-authored-by: tobias <tobias.hotmail.com>
上级
c93e7fb9
变更
19
隐藏空白更改
内联
并排
Showing
19 changed file
with
546 addition
and
23 deletion
+546
-23
jadx-core/src/main/java/jadx/core/utils/StringUtils.java
jadx-core/src/main/java/jadx/core/utils/StringUtils.java
+50
-0
jadx-gui/src/main/java/jadx/gui/jobs/IndexJob.java
jadx-gui/src/main/java/jadx/gui/jobs/IndexJob.java
+4
-5
jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
+32
-0
jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsWindow.java
...i/src/main/java/jadx/gui/settings/JadxSettingsWindow.java
+50
-0
jadx-gui/src/main/java/jadx/gui/treemodel/JResSearchNode.java
...-gui/src/main/java/jadx/gui/treemodel/JResSearchNode.java
+68
-0
jadx-gui/src/main/java/jadx/gui/ui/CommonSearchDialog.java
jadx-gui/src/main/java/jadx/gui/ui/CommonSearchDialog.java
+20
-3
jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
+4
-0
jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java
jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java
+5
-2
jadx-gui/src/main/java/jadx/gui/ui/codearea/CodePanel.java
jadx-gui/src/main/java/jadx/gui/ui/codearea/CodePanel.java
+19
-8
jadx-gui/src/main/java/jadx/gui/utils/CacheObject.java
jadx-gui/src/main/java/jadx/gui/utils/CacheObject.java
+22
-0
jadx-gui/src/main/java/jadx/gui/utils/search/CodeIndex.java
jadx-gui/src/main/java/jadx/gui/utils/search/CodeIndex.java
+1
-1
jadx-gui/src/main/java/jadx/gui/utils/search/ResourceIndex.java
...ui/src/main/java/jadx/gui/utils/search/ResourceIndex.java
+226
-0
jadx-gui/src/main/java/jadx/gui/utils/search/SimpleIndex.java
...-gui/src/main/java/jadx/gui/utils/search/SimpleIndex.java
+1
-1
jadx-gui/src/main/java/jadx/gui/utils/search/TextSearchIndex.java
.../src/main/java/jadx/gui/utils/search/TextSearchIndex.java
+14
-3
jadx-gui/src/main/resources/i18n/Messages_de_DE.properties
jadx-gui/src/main/resources/i18n/Messages_de_DE.properties
+6
-0
jadx-gui/src/main/resources/i18n/Messages_en_US.properties
jadx-gui/src/main/resources/i18n/Messages_en_US.properties
+6
-0
jadx-gui/src/main/resources/i18n/Messages_es_ES.properties
jadx-gui/src/main/resources/i18n/Messages_es_ES.properties
+6
-0
jadx-gui/src/main/resources/i18n/Messages_ko_KR.properties
jadx-gui/src/main/resources/i18n/Messages_ko_KR.properties
+6
-0
jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties
jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties
+6
-0
未找到文件。
jadx-core/src/main/java/jadx/core/utils/StringUtils.java
浏览文件 @
c774ffc9
...
...
@@ -256,6 +256,56 @@ public class StringUtils {
return
count
;
}
/**
* returns how many lines does it have between start to pos in content.
*/
public
static
int
countLinesByPos
(
String
content
,
int
pos
,
int
start
)
{
if
(
start
>=
pos
)
{
return
0
;
}
int
count
=
0
;
int
tempPos
=
start
;
do
{
tempPos
=
content
.
indexOf
(
"\n"
,
tempPos
);
if
(
tempPos
==
-
1
)
{
break
;
}
if
(
tempPos
>=
pos
)
{
break
;
}
count
+=
1
;
tempPos
+=
1
;
}
while
(
tempPos
<
content
.
length
());
return
count
;
}
/**
* returns lines that contain pos to end if end is not -1.
*/
public
static
String
getLine
(
String
content
,
int
pos
,
int
end
)
{
if
(
pos
>=
content
.
length
())
{
return
""
;
}
if
(
end
!=
-
1
)
{
if
(
end
>
content
.
length
())
{
end
=
content
.
length
()
-
1
;
}
}
else
{
end
=
pos
+
1
;
}
// get to line head
int
headPos
=
content
.
lastIndexOf
(
"\n"
,
pos
);
if
(
headPos
==
-
1
)
{
headPos
=
0
;
}
// get to line end
int
endPos
=
content
.
indexOf
(
"\n"
,
end
);
if
(
endPos
==
-
1
)
{
endPos
=
content
.
length
();
}
return
content
.
substring
(
headPos
,
endPos
);
}
public
static
boolean
isWhite
(
char
chr
)
{
return
WHITES
.
indexOf
(
chr
)
!=
-
1
;
}
...
...
jadx-gui/src/main/java/jadx/gui/jobs/IndexJob.java
浏览文件 @
c774ffc9
...
...
@@ -12,7 +12,6 @@ import jadx.gui.JadxWrapper;
import
jadx.gui.utils.CacheObject
;
import
jadx.gui.utils.CodeLinesInfo
;
import
jadx.gui.utils.CodeUsageInfo
;
import
jadx.gui.utils.JNodeCache
;
import
jadx.gui.utils.NLS
;
import
jadx.gui.utils.UiUtils
;
import
jadx.gui.utils.search.StringRef
;
...
...
@@ -30,12 +29,12 @@ public class IndexJob extends BackgroundJob {
@Override
protected
void
runJob
()
{
JNodeCache
nodeCache
=
cache
.
getNodeCache
(
);
TextSearchIndex
index
=
new
TextSearchIndex
(
nodeCache
);
CodeUsageInfo
usageInfo
=
new
CodeUsageInfo
(
nodeCache
);
TextSearchIndex
index
=
new
TextSearchIndex
(
cache
);
CodeUsageInfo
usageInfo
=
new
CodeUsageInfo
(
cache
.
getNodeCache
()
);
cache
.
setTextIndex
(
index
);
cache
.
setUsageInfo
(
usageInfo
);
addTask
(
index:
:
indexResource
);
for
(
final
JavaClass
cls
:
wrapper
.
getIncludedClasses
())
{
addTask
(()
->
indexCls
(
cache
,
cls
));
}
...
...
jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
浏览文件 @
c774ffc9
...
...
@@ -63,6 +63,10 @@ public class JadxSettings extends JadxCLIArgs {
private
Map
<
String
,
WindowLocation
>
windowPos
=
new
HashMap
<>();
private
int
mainWindowExtendedState
=
JFrame
.
NORMAL
;
private
boolean
codeAreaLineWrap
=
false
;
private
int
srhResourceSkipSize
=
1000
;
private
String
srhResourceFileExt
=
".xml|.html|.js|.json|.txt"
;
private
boolean
keepCommonDialogOpen
=
false
;
/**
* UI setting: the width of the tree showing the classes, resources, ...
*/
...
...
@@ -400,6 +404,30 @@ public class JadxSettings extends JadxCLIArgs {
return
this
.
codeAreaLineWrap
;
}
public
int
getSrhResourceSkipSize
()
{
return
srhResourceSkipSize
;
}
public
void
setSrhResourceSkipSize
(
int
size
)
{
srhResourceSkipSize
=
size
;
}
public
String
getSrhResourceFileExt
()
{
return
srhResourceFileExt
;
}
public
void
setSrhResourceFileExt
(
String
all
)
{
srhResourceFileExt
=
all
.
trim
();
}
public
void
setKeepCommonDialogOpen
(
boolean
yes
)
{
keepCommonDialogOpen
=
yes
;
}
public
boolean
getKeepCommonDialogOpen
()
{
return
keepCommonDialogOpen
;
}
private
void
upgradeSettings
(
int
fromVersion
)
{
LOG
.
debug
(
"upgrade settings from version: {} to {}"
,
fromVersion
,
CURRENT_SETTINGS_VERSION
);
if
(
fromVersion
==
0
)
{
...
...
@@ -454,6 +482,10 @@ public class JadxSettings extends JadxCLIArgs {
showHeapUsageBar
=
false
;
fromVersion
++;
}
if
(
fromVersion
==
10
)
{
srhResourceSkipSize
=
3
;
srhResourceFileExt
=
".xml|.html|.js|.json|.txt"
;
}
settingsVersion
=
CURRENT_SETTINGS_VERSION
;
sync
();
}
...
...
jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsWindow.java
浏览文件 @
c774ffc9
...
...
@@ -11,6 +11,10 @@ import java.util.Arrays;
import
java.util.Collection
;
import
javax.swing.*
;
import
javax.swing.event.ChangeEvent
;
import
javax.swing.event.ChangeListener
;
import
javax.swing.event.DocumentEvent
;
import
javax.swing.event.DocumentListener
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -74,6 +78,7 @@ public class JadxSettingsWindow extends JDialog {
leftPanel
.
add
(
makeProjectGroup
());
leftPanel
.
add
(
makeEditorGroup
());
leftPanel
.
add
(
makeOtherGroup
());
leftPanel
.
add
(
makeSearchResGroup
());
rightPanel
.
add
(
makeDecompilationGroup
());
...
...
@@ -474,6 +479,51 @@ public class JadxSettingsWindow extends JDialog {
return
group
;
}
private
SettingsGroup
makeSearchResGroup
()
{
SettingsGroup
group
=
new
SettingsGroup
(
NLS
.
str
(
"preferences.search_res_title"
));
int
prevSize
=
settings
.
getSrhResourceSkipSize
();
String
prevExts
=
settings
.
getSrhResourceFileExt
();
SpinnerNumberModel
sizeLimitModel
=
new
SpinnerNumberModel
(
prevSize
,
0
,
Integer
.
MAX_VALUE
,
1
);
JSpinner
spinner
=
new
JSpinner
(
sizeLimitModel
);
JTextField
fileExtField
=
new
JTextField
();
group
.
addRow
(
NLS
.
str
(
"preferences.res_skip_file"
),
spinner
);
group
.
addRow
(
NLS
.
str
(
"preferences.res_file_ext"
),
fileExtField
);
spinner
.
addChangeListener
(
new
ChangeListener
()
{
@Override
public
void
stateChanged
(
ChangeEvent
e
)
{
int
size
=
(
Integer
)
spinner
.
getValue
();
settings
.
setSrhResourceSkipSize
(
size
);
}
});
fileExtField
.
getDocument
().
addDocumentListener
(
new
DocumentListener
()
{
private
void
update
()
{
String
ext
=
fileExtField
.
getText
();
settings
.
setSrhResourceFileExt
(
ext
);
}
@Override
public
void
insertUpdate
(
DocumentEvent
e
)
{
update
();
}
@Override
public
void
removeUpdate
(
DocumentEvent
e
)
{
update
();
}
@Override
public
void
changedUpdate
(
DocumentEvent
e
)
{
update
();
}
});
fileExtField
.
setText
(
prevExts
);
return
group
;
}
private
void
needReload
()
{
needReload
=
true
;
}
...
...
jadx-gui/src/main/java/jadx/gui/treemodel/JResSearchNode.java
0 → 100644
浏览文件 @
c774ffc9
package
jadx.gui.treemodel
;
import
javax.swing.*
;
import
jadx.core.utils.StringUtils
;
public
class
JResSearchNode
extends
JNode
{
private
static
final
long
serialVersionUID
=
-
2222084945157778639L
;
private
final
transient
JResource
resNode
;
private
final
transient
String
text
;
private
final
transient
int
line
;
private
final
transient
int
pos
;
public
JResSearchNode
(
JResource
resNode
,
String
text
,
int
line
,
int
pos
)
{
this
.
pos
=
pos
;
this
.
text
=
text
;
this
.
line
=
line
;
this
.
resNode
=
resNode
;
}
public
JResource
getResNode
()
{
return
resNode
;
}
public
int
getPos
()
{
return
pos
;
}
@Override
public
String
makeDescString
()
{
return
text
;
}
@Override
public
JClass
getJParent
()
{
return
resNode
.
getJParent
();
}
@Override
public
int
getLine
()
{
return
line
;
}
@Override
public
String
makeLongStringHtml
()
{
return
getName
();
}
@Override
public
Icon
getIcon
()
{
return
resNode
.
getIcon
();
}
@Override
public
String
getName
()
{
return
resNode
.
getName
();
}
@Override
public
String
makeString
()
{
return
resNode
.
makeString
();
}
@Override
public
boolean
hasDescString
()
{
return
!
StringUtils
.
isEmpty
(
text
);
}
}
jadx-gui/src/main/java/jadx/gui/ui/CommonSearchDialog.java
浏览文件 @
c774ffc9
...
...
@@ -111,7 +111,10 @@ public abstract class CommonSearchDialog extends JDialog {
}
JumpPosition
jmpPos
;
JNode
node
=
(
JNode
)
resultsModel
.
getValueAt
(
selectedId
,
0
);
if
(
node
instanceof
CodeNode
)
{
if
(
node
instanceof
JResSearchNode
)
{
jmpPos
=
new
JumpPosition
(((
JResSearchNode
)
node
).
getResNode
(),
node
.
getLine
())
.
setPrecise
(((
JResSearchNode
)
node
).
getPos
());
}
else
if
(
node
instanceof
CodeNode
)
{
CodeNode
codeNode
=
(
CodeNode
)
node
;
jmpPos
=
new
JumpPosition
(
node
.
getRootClass
(),
node
.
getLine
(),
codeNode
.
getPos
());
if
(
codeNode
.
isPrecisePos
())
{
...
...
@@ -121,8 +124,9 @@ public abstract class CommonSearchDialog extends JDialog {
jmpPos
=
new
JumpPosition
(
node
.
getRootClass
(),
node
.
getLine
());
}
tabbedPane
.
codeJump
(
jmpPos
);
dispose
();
if
(!
mainWindow
.
getSettings
().
getKeepCommonDialogOpen
())
{
dispose
();
}
}
@Override
...
...
@@ -148,6 +152,15 @@ public abstract class CommonSearchDialog extends JDialog {
JPanel
buttonPane
=
new
JPanel
();
buttonPane
.
setLayout
(
new
BoxLayout
(
buttonPane
,
BoxLayout
.
LINE_AXIS
));
buttonPane
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
0
,
10
,
10
,
10
));
JCheckBox
cbKeepOpen
=
new
JCheckBox
(
NLS
.
str
(
"search_dialog.keep_open"
));
cbKeepOpen
.
setSelected
(
mainWindow
.
getSettings
().
getKeepCommonDialogOpen
());
cbKeepOpen
.
addActionListener
(
e
->
{
mainWindow
.
getSettings
().
setKeepCommonDialogOpen
(
cbKeepOpen
.
isSelected
());
mainWindow
.
getSettings
().
sync
();
});
buttonPane
.
add
(
cbKeepOpen
);
buttonPane
.
add
(
Box
.
createRigidArea
(
new
Dimension
(
15
,
0
)));
buttonPane
.
add
(
progressPane
);
buttonPane
.
add
(
Box
.
createRigidArea
(
new
Dimension
(
5
,
0
)));
buttonPane
.
add
(
Box
.
createHorizontalGlue
());
...
...
@@ -251,6 +264,10 @@ public abstract class CommonSearchDialog extends JDialog {
resultsInfoLabel
.
setText
(
statusText
);
}
protected
void
showSearchState
()
{
resultsInfoLabel
.
setText
(
NLS
.
str
(
"search_dialog.tip_searching"
));
}
protected
static
class
ResultsTable
extends
JTable
{
private
static
final
long
serialVersionUID
=
3901184054736618969L
;
private
final
transient
ResultsTableCellRenderer
renderer
;
...
...
jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
浏览文件 @
c774ffc9
...
...
@@ -445,6 +445,8 @@ public class MainWindow extends JFrame {
protected
void
resetCache
()
{
cacheObject
.
reset
();
// TODO: decompilation freezes sometime with several threads
this
.
cacheObject
.
setJRoot
(
treeRoot
);
this
.
cacheObject
.
setJadxSettings
(
settings
);
int
threadsCount
=
settings
.
getThreadsCount
();
cacheObject
.
setDecompileJob
(
new
DecompileJob
(
wrapper
,
threadsCount
));
cacheObject
.
setIndexJob
(
new
IndexJob
(
wrapper
,
cacheObject
,
threadsCount
));
...
...
@@ -563,6 +565,8 @@ public class MainWindow extends JFrame {
treeModel
.
setRoot
(
treeRoot
);
treeRoot
.
update
();
reloadTree
();
cacheObject
.
setJRoot
(
treeRoot
);
cacheObject
.
setJadxSettings
(
settings
);
}
private
void
clearTree
()
{
...
...
jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java
浏览文件 @
c774ffc9
...
...
@@ -39,7 +39,8 @@ public class SearchDialog extends CommonSearchDialog {
FIELD
,
CODE
,
IGNORE_CASE
,
USE_REGEX
USE_REGEX
,
Resource
}
private
transient
Set
<
SearchOptions
>
options
;
...
...
@@ -76,7 +77,6 @@ public class SearchDialog extends CommonSearchDialog {
if
(
lastSearch
!=
null
)
{
searchField
.
setText
(
lastSearch
);
searchField
.
selectAll
();
searchEmitter
.
emitSearch
();
}
searchField
.
requestFocus
();
}
...
...
@@ -91,6 +91,7 @@ public class SearchDialog extends CommonSearchDialog {
JCheckBox
caseChBox
=
makeOptionsCheckBox
(
NLS
.
str
(
"search_dialog.ignorecase"
),
SearchOptions
.
IGNORE_CASE
);
JCheckBox
regexChBox
=
makeOptionsCheckBox
(
NLS
.
str
(
"search_dialog.regex"
),
SearchOptions
.
USE_REGEX
);
JCheckBox
resChBox
=
makeOptionsCheckBox
(
NLS
.
str
(
"search_dialog.resource"
),
SearchOptions
.
Resource
);
JCheckBox
clsChBox
=
makeOptionsCheckBox
(
NLS
.
str
(
"search_dialog.class"
),
SearchOptions
.
CLASS
);
JCheckBox
mthChBox
=
makeOptionsCheckBox
(
NLS
.
str
(
"search_dialog.method"
),
SearchOptions
.
METHOD
);
JCheckBox
fldChBox
=
makeOptionsCheckBox
(
NLS
.
str
(
"search_dialog.field"
),
SearchOptions
.
FIELD
);
...
...
@@ -98,6 +99,7 @@ public class SearchDialog extends CommonSearchDialog {
JPanel
searchInPanel
=
new
JPanel
(
new
FlowLayout
(
FlowLayout
.
LEFT
));
searchInPanel
.
setBorder
(
BorderFactory
.
createTitledBorder
(
NLS
.
str
(
"search_dialog.search_in"
)));
searchInPanel
.
add
(
resChBox
);
searchInPanel
.
add
(
clsChBox
);
searchInPanel
.
add
(
mthChBox
);
searchInPanel
.
add
(
fldChBox
);
...
...
@@ -200,6 +202,7 @@ public class SearchDialog extends CommonSearchDialog {
if
(
index
==
null
)
{
return
Flowable
.
empty
();
}
showSearchState
();
return
index
.
buildSearch
(
text
,
options
);
}
...
...
jadx-gui/src/main/java/jadx/gui/ui/codearea/CodePanel.java
浏览文件 @
c774ffc9
...
...
@@ -149,10 +149,10 @@ public class CodePanel extends JPanel {
}
public
void
refresh
()
{
int
line
;
int
lineCount
;
int
line
=
0
;
int
tokenIndex
;
int
pos
=
codeArea
.
getCaretPosition
();
int
lineCount
=
codeArea
.
getLineCount
();
try
{
// after rename the change of document is undetectable, so
// use Token offset to calculate the new caret position.
...
...
@@ -161,10 +161,12 @@ public class CodePanel extends JPanel {
tokenIndex
=
getTokenIndexByOffset
(
token
,
pos
);
}
catch
(
BadLocationException
e
)
{
e
.
printStackTrace
();
tokenIndex
=
0
;
line
=
codeArea
.
getLineCount
()
-
1
;
tokenIndex
=
-
1
;
}
if
(
tokenIndex
==
-
1
)
{
refreshToViewport
();
return
;
}
lineCount
=
codeArea
.
getLineCount
();
codeArea
.
refresh
();
initLineNumbers
();
int
lineDiff
=
codeArea
.
getLineCount
()
-
lineCount
;
...
...
@@ -184,14 +186,23 @@ public class CodePanel extends JPanel {
});
}
private
void
refreshToViewport
()
{
JViewport
viewport
=
getCodeScrollPane
().
getViewport
();
Point
viewPosition
=
viewport
.
getViewPosition
();
codeArea
.
refresh
();
initLineNumbers
();
SwingUtilities
.
invokeLater
(()
->
{
viewport
.
setViewPosition
(
viewPosition
);
});
}
private
int
getTokenIndexByOffset
(
Token
token
,
int
offset
)
{
if
(
token
!=
null
)
{
int
index
=
1
;
while
(
token
.
getEndOffset
()
<
offset
)
{
token
=
token
.
getNextToken
();
if
(
token
==
null
)
{
index
=
0
;
break
;
return
-
1
;
}
index
++;
}
...
...
@@ -201,7 +212,7 @@ public class CodePanel extends JPanel {
}
private
int
getOffsetOfTokenByIndex
(
int
index
,
Token
token
)
{
if
(
token
!=
null
)
{
if
(
token
!=
null
&&
index
!=
-
1
)
{
for
(
int
i
=
0
;
i
<
index
;
i
++)
{
token
=
token
.
getNextToken
();
if
(
token
==
null
)
{
...
...
jadx-gui/src/main/java/jadx/gui/utils/CacheObject.java
浏览文件 @
c774ffc9
...
...
@@ -7,6 +7,8 @@ import org.jetbrains.annotations.Nullable;
import
jadx.gui.jobs.DecompileJob
;
import
jadx.gui.jobs.IndexJob
;
import
jadx.gui.settings.JadxSettings
;
import
jadx.gui.treemodel.JRoot
;
import
jadx.gui.ui.SearchDialog
;
import
jadx.gui.utils.search.TextSearchIndex
;
...
...
@@ -20,12 +22,16 @@ public class CacheObject {
private
String
lastSearch
;
private
JNodeCache
jNodeCache
;
private
Set
<
SearchDialog
.
SearchOptions
>
lastSearchOptions
;
private
JRoot
jRoot
;
private
JadxSettings
settings
;
public
CacheObject
()
{
reset
();
}
public
void
reset
()
{
jRoot
=
null
;
settings
=
null
;
decompileJob
=
null
;
indexJob
=
null
;
textIndex
=
null
;
...
...
@@ -89,4 +95,20 @@ public class CacheObject {
public
Set
<
SearchDialog
.
SearchOptions
>
getLastSearchOptions
()
{
return
lastSearchOptions
;
}
public
void
setJadxSettings
(
JadxSettings
settings
)
{
this
.
settings
=
settings
;
}
public
JadxSettings
getJadxSettings
()
{
return
this
.
settings
;
}
public
JRoot
getJRoot
()
{
return
jRoot
;
}
public
void
setJRoot
(
JRoot
jRoot
)
{
this
.
jRoot
=
jRoot
;
}
}
jadx-gui/src/main/java/jadx/gui/utils/search/CodeIndex.java
浏览文件 @
c774ffc9
...
...
@@ -47,7 +47,7 @@ public class CodeIndex {
}
LOG
.
debug
(
"Code search complete: {}, memory usage: {}"
,
searchSettings
.
getSearchString
(),
UiUtils
.
memoryInfo
());
emitter
.
onComplete
();
},
BackpressureStrategy
.
LATEST
);
},
BackpressureStrategy
.
BUFFER
);
}
public
int
size
()
{
...
...
jadx-gui/src/main/java/jadx/gui/utils/search/ResourceIndex.java
0 → 100644
浏览文件 @
c774ffc9
package
jadx.gui.utils.search
;
import
java.io.File
;
import
java.io.IOException
;
import
java.util.*
;
import
java.util.concurrent.*
;
import
java.util.zip.ZipEntry
;
import
java.util.zip.ZipFile
;
import
javax.swing.tree.TreeNode
;
import
io.reactivex.BackpressureStrategy
;
import
io.reactivex.Flowable
;
import
io.reactivex.FlowableEmitter
;
import
jadx.api.ResourceFile
;
import
jadx.api.ResourceType
;
import
jadx.core.utils.files.FileUtils
;
import
jadx.gui.treemodel.JResSearchNode
;
import
jadx.gui.treemodel.JResource
;
import
jadx.gui.utils.CacheObject
;
import
static
jadx
.
core
.
utils
.
StringUtils
.*;
public
class
ResourceIndex
{
private
final
List
<
JResource
>
resNodes
=
new
ArrayList
<>();
private
final
Set
<
String
>
extSet
=
new
HashSet
<>();
private
CacheObject
cache
;
private
String
fileExts
;
private
boolean
anyExt
;
private
int
sizeLimit
;
public
ResourceIndex
(
CacheObject
cache
)
{
this
.
cache
=
cache
;
}
private
void
search
(
final
JResource
resNode
,
FlowableEmitter
<
JResSearchNode
>
emitter
,
SearchSettings
searchSettings
)
{
int
pos
=
0
;
int
line
=
0
;
int
lastPos
=
0
;
int
lastLineOccurred
=
-
1
;
JResSearchNode
lastNode
=
null
;
int
searchStrLen
=
searchSettings
.
getSearchString
().
length
();
String
content
;
try
{
content
=
resNode
.
getContent
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
;
}
do
{
searchSettings
.
setStartPos
(
lastPos
);
pos
=
searchSettings
.
find
(
content
);
if
(
pos
>
-
1
)
{
line
+=
countLinesByPos
(
content
,
pos
,
lastPos
);
lastPos
=
pos
+
searchStrLen
;
String
lineText
=
getLine
(
content
,
pos
,
lastPos
);
if
(
lastLineOccurred
!=
line
)
{
lastLineOccurred
=
line
;
if
(
lastNode
!=
null
)
{
emitter
.
onNext
(
lastNode
);
}
lastNode
=
new
JResSearchNode
(
resNode
,
lineText
.
trim
(),
line
+
1
,
pos
);
}
}
else
{
if
(
lastNode
!=
null
)
{
// commit the final result node.
emitter
.
onNext
(
lastNode
);
}
break
;
}
}
while
(!
emitter
.
isCancelled
()
&&
lastPos
<
content
.
length
());
}
public
Flowable
<
JResSearchNode
>
search
(
SearchSettings
settings
)
{
refreshSettings
();
if
(
resNodes
.
size
()
==
0
)
{
return
Flowable
.
empty
();
}
return
Flowable
.
create
(
emitter
->
{
for
(
JResource
resNode
:
resNodes
)
{
if
(!
emitter
.
isCancelled
())
{
search
(
resNode
,
emitter
,
settings
);
}
}
emitter
.
onComplete
();
},
BackpressureStrategy
.
BUFFER
);
}
public
void
index
()
{
refreshSettings
();
}
private
void
clear
()
{
anyExt
=
false
;
sizeLimit
=
-
1
;
fileExts
=
""
;
extSet
.
clear
();
resNodes
.
clear
();
}
private
void
traverseTree
(
TreeNode
root
,
ZipFile
zip
)
{
for
(
int
i
=
0
;
i
<
root
.
getChildCount
();
i
++)
{
TreeNode
node
=
root
.
getChildAt
(
i
);
if
(
node
instanceof
JResource
)
{
JResource
resNode
=
(
JResource
)
node
;
try
{
resNode
.
loadNode
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
;
}
ResourceFile
resFile
=
resNode
.
getResFile
();
if
(
resFile
==
null
)
{
traverseTree
(
node
,
zip
);
}
else
{
if
(
resFile
.
getType
()
==
ResourceType
.
ARSC
&&
shouldSearchXML
())
{
resFile
.
loadContent
();
resNode
.
getFiles
().
forEach
(
t
->
traverseTree
(
t
,
null
));
}
else
{
filter
(
resNode
,
zip
);
}
}
}
}
}
private
boolean
shouldSearchXML
()
{
return
anyExt
||
fileExts
.
contains
(
".xml"
);
}
private
ZipFile
getZipFile
(
TreeNode
res
)
{
for
(
int
i
=
0
;
i
<
res
.
getChildCount
();
i
++)
{
TreeNode
node
=
res
.
getChildAt
(
i
);
if
(
node
instanceof
JResource
)
{
JResource
resNode
=
(
JResource
)
node
;
try
{
resNode
.
loadNode
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
null
;
}
ResourceFile
file
=
resNode
.
getResFile
();
if
(
file
==
null
)
{
ZipFile
zip
=
getZipFile
(
resNode
);
if
(
zip
!=
null
)
{
return
zip
;
}
}
else
{
File
zfile
=
file
.
getZipRef
().
getZipFile
();
if
(
FileUtils
.
isZipFile
(
zfile
))
{
try
{
return
new
ZipFile
(
zfile
);
}
catch
(
IOException
ignore
)
{
}
}
}
}
}
return
null
;
}
private
void
filter
(
JResource
resNode
,
ZipFile
zip
)
{
ResourceFile
resFile
=
resNode
.
getResFile
();
if
(
JResource
.
isSupportedForView
(
resFile
.
getType
()))
{
long
size
=
-
1
;
if
(
zip
!=
null
)
{
ZipEntry
entry
=
zip
.
getEntry
(
resFile
.
getOriginalName
());
if
(
entry
!=
null
)
{
size
=
entry
.
getSize
();
}
}
if
(
size
==
-
1
)
{
// resource from ARSC is unknown size
try
{
size
=
resNode
.
getContent
().
length
();
}
catch
(
Exception
ignore
)
{
return
;
}
}
if
(
size
<=
sizeLimit
)
{
if
(!
anyExt
)
{
for
(
String
ext
:
extSet
)
{
if
(
resFile
.
getOriginalName
().
endsWith
(
ext
))
{
resNodes
.
add
(
resNode
);
break
;
}
}
}
else
{
resNodes
.
add
(
resNode
);
}
}
}
}
private
void
refreshSettings
()
{
int
size
=
cache
.
getJadxSettings
().
getSrhResourceSkipSize
()
*
10240
;
if
(
size
!=
sizeLimit
||
!
cache
.
getJadxSettings
().
getSrhResourceFileExt
().
equals
(
fileExts
))
{
clear
();
sizeLimit
=
size
;
fileExts
=
cache
.
getJadxSettings
().
getSrhResourceFileExt
();
String
[]
exts
=
fileExts
.
split
(
"\\|"
);
for
(
String
ext
:
exts
)
{
ext
=
ext
.
trim
();
if
(!
ext
.
isEmpty
())
{
anyExt
=
ext
.
equals
(
"*"
);
if
(
anyExt
)
{
break
;
}
extSet
.
add
(
ext
);
}
}
ZipFile
zipFile
=
getZipFile
(
cache
.
getJRoot
());
traverseTree
(
cache
.
getJRoot
(),
zipFile
);
// reindex
try
{
if
(
zipFile
!=
null
)
{
zipFile
.
close
();
}
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
}
}
jadx-gui/src/main/java/jadx/gui/utils/search/SimpleIndex.java
浏览文件 @
c774ffc9
...
...
@@ -35,7 +35,7 @@ public class SimpleIndex {
}
}
emitter
.
onComplete
();
},
BackpressureStrategy
.
LATEST
);
},
BackpressureStrategy
.
BUFFER
);
}
public
int
size
()
{
...
...
jadx-gui/src/main/java/jadx/gui/utils/search/TextSearchIndex.java
浏览文件 @
c774ffc9
...
...
@@ -19,6 +19,7 @@ import jadx.core.codegen.CodeWriter;
import
jadx.gui.treemodel.CodeNode
;
import
jadx.gui.treemodel.JNode
;
import
jadx.gui.ui.SearchDialog
;
import
jadx.gui.utils.CacheObject
;
import
jadx.gui.utils.CodeLinesInfo
;
import
jadx.gui.utils.JNodeCache
;
import
jadx.gui.utils.UiUtils
;
...
...
@@ -28,6 +29,7 @@ import static jadx.gui.ui.SearchDialog.SearchOptions.CODE;
import
static
jadx
.
gui
.
ui
.
SearchDialog
.
SearchOptions
.
FIELD
;
import
static
jadx
.
gui
.
ui
.
SearchDialog
.
SearchOptions
.
IGNORE_CASE
;
import
static
jadx
.
gui
.
ui
.
SearchDialog
.
SearchOptions
.
METHOD
;
import
static
jadx
.
gui
.
ui
.
SearchDialog
.
SearchOptions
.
Resource
;
import
static
jadx
.
gui
.
ui
.
SearchDialog
.
SearchOptions
.
USE_REGEX
;
public
class
TextSearchIndex
{
...
...
@@ -40,11 +42,13 @@ public class TextSearchIndex {
private
final
SimpleIndex
mthSignaturesIndex
;
private
final
SimpleIndex
fldSignaturesIndex
;
private
final
CodeIndex
codeIndex
;
private
final
ResourceIndex
resIndex
;
private
final
List
<
JavaClass
>
skippedClasses
=
new
ArrayList
<>();
public
TextSearchIndex
(
JNodeCache
nodeCache
)
{
this
.
nodeCache
=
nodeCache
;
public
TextSearchIndex
(
CacheObject
cache
)
{
this
.
nodeCache
=
cache
.
getNodeCache
();
this
.
resIndex
=
new
ResourceIndex
(
cache
);
this
.
clsNamesIndex
=
new
SimpleIndex
();
this
.
mthSignaturesIndex
=
new
SimpleIndex
();
this
.
fldSignaturesIndex
=
new
SimpleIndex
();
...
...
@@ -85,6 +89,10 @@ public class TextSearchIndex {
}
}
public
void
indexResource
()
{
resIndex
.
index
();
}
public
void
remove
(
JavaClass
cls
)
{
this
.
clsNamesIndex
.
removeForCls
(
cls
);
this
.
mthSignaturesIndex
.
removeForCls
(
cls
);
...
...
@@ -121,6 +129,9 @@ public class TextSearchIndex {
result
=
Flowable
.
concat
(
result
,
searchInSkippedClasses
(
searchSettings
));
}
}
if
(
options
.
contains
(
Resource
))
{
result
=
Flowable
.
concat
(
result
,
resIndex
.
search
(
searchSettings
));
}
return
result
;
}
...
...
@@ -146,7 +157,7 @@ public class TextSearchIndex {
}
LOG
.
debug
(
"Skipped code search complete: {}, memory usage: {}"
,
searchSettings
.
getSearchString
(),
UiUtils
.
memoryInfo
());
emitter
.
onComplete
();
},
BackpressureStrategy
.
LATEST
);
},
BackpressureStrategy
.
BUFFER
);
}
private
int
searchNext
(
FlowableEmitter
<
CodeNode
>
emitter
,
JavaNode
javaClass
,
String
code
,
final
SearchSettings
searchSettings
)
{
...
...
jadx-gui/src/main/resources/i18n/Messages_de_DE.properties
浏览文件 @
c774ffc9
...
...
@@ -77,6 +77,9 @@ search_dialog.info_label=Zeige Ergebnisse %1$d bis %2$d von %3$d
search_dialog.col_node
=
Knoten
search_dialog.col_code
=
Code
search_dialog.regex
=
Regex
#search_dialog.resource=
#search_dialog.keep_open=
#search_dialog.tip_searching=
usage_dialog.title
=
Verwendungssuche
usage_dialog.label
=
Verwendung für:
...
...
@@ -132,6 +135,9 @@ preferences.rename=Umbenennen
preferences.rename_case
=
System unterscheidet zwischen Groß/Kleinschreibung
preferences.rename_valid
=
Ist eine gültige Kennung
preferences.rename_printable
=
Ist druckbar
#preferences.search_res_title=
#preferences.res_file_ext=
#preferences.res_skip_file=
msg.open_file
=
Bitte Datei öffnen
msg.saving_sources
=
Quellen speichern…
...
...
jadx-gui/src/main/resources/i18n/Messages_en_US.properties
浏览文件 @
c774ffc9
...
...
@@ -77,6 +77,9 @@ search_dialog.info_label=Showing results %1$d to %2$d of %3$d
search_dialog.col_node
=
Node
search_dialog.col_code
=
Code
search_dialog.regex
=
Regex
search_dialog.resource
=
Resource
search_dialog.keep_open
=
Keep open
search_dialog.tip_searching
=
Searching ...
usage_dialog.title
=
Usage search
usage_dialog.label
=
Usage for:
...
...
@@ -132,6 +135,9 @@ preferences.rename=Rename
preferences.rename_case
=
System case sensitivity
preferences.rename_valid
=
To be valid identifier
preferences.rename_printable
=
To be printable
preferences.search_res_title
=
Search Resource
preferences.res_file_ext
=
File Extensions (e.g. .xml|.html), * means all
preferences.res_skip_file
=
Skip files exceed (MB)
msg.open_file
=
Please open file
msg.saving_sources
=
Saving sources...
...
...
jadx-gui/src/main/resources/i18n/Messages_es_ES.properties
浏览文件 @
c774ffc9
...
...
@@ -77,6 +77,9 @@ search_dialog.info_label=Mostrando resultados %1$d a %2$d de %3$d
search_dialog.col_node
=
Nodo
search_dialog.col_code
=
Código
search_dialog.regex
=
Regex
#search_dialog.resource=
#search_dialog.keep_open=
#search_dialog.tip_searching=
usage_dialog.title
=
Usage search
usage_dialog.label
=
Usage for:
...
...
@@ -132,6 +135,9 @@ preferences.reset_title=Reestablecer preferencias
#preferences.rename_case=
#preferences.rename_valid=
#preferences.rename_printable=
#preferences.search_res_title=
#preferences.res_file_ext=
#preferences.res_skip_file=
msg.open_file
=
Por favor, abra un archivo
msg.saving_sources
=
Guardando fuente...
...
...
jadx-gui/src/main/resources/i18n/Messages_ko_KR.properties
浏览文件 @
c774ffc9
...
...
@@ -77,6 +77,9 @@ search_dialog.info_label=%3$d 중 %1$d-%2$d 결과 표시
search_dialog.col_node
=
노드
search_dialog.col_code
=
코드
search_dialog.regex
=
정규식
#search_dialog.resource=
#search_dialog.keep_open=
#search_dialog.tip_searching=
usage_dialog.title
=
사용 검색
usage_dialog.label
=
다음의 사용 검색 결과:
...
...
@@ -132,6 +135,9 @@ preferences.rename=이름 바꾸기
preferences.rename_case
=
시스템 대소문자 구분
preferences.rename_valid
=
유효한 식별자로 바꾸기
preferences.rename_printable
=
출력 가능하게 바꾸기
#preferences.search_res_title=
#preferences.res_file_ext=
#preferences.res_skip_file=
msg.open_file
=
파일을 여십시오
msg.saving_sources
=
소스 저장 중 ...
...
...
jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties
浏览文件 @
c774ffc9
...
...
@@ -77,6 +77,9 @@ search_dialog.info_label=显示了 %3$d 个结果中的第 %1$d 至第 %2$d 个
search_dialog.col_node
=
节点
search_dialog.col_code
=
代码
search_dialog.regex
=
正则表达式
#search_dialog.resource=
#search_dialog.keep_open=
#search_dialog.tip_searching=
usage_dialog.title
=
查找
usage_dialog.label
=
查找用例:
...
...
@@ -132,6 +135,9 @@ preferences.rename=重命名
preferences.rename_case
=
系统区分大小写
preferences.rename_valid
=
是有效的标识符
preferences.rename_printable
=
是可打印
#preferences.search_res_title=
#preferences.res_file_ext=
#preferences.res_skip_file=
msg.open_file
=
请打开文件
msg.saving_sources
=
正在导出源代码...
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录