Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b4d9663be | ||
|
|
1e6e664137 | ||
|
|
e9512807e4 | ||
|
|
6b6caf3303 | ||
|
|
fa08199f43 | ||
|
|
f2cf3ed7ed | ||
|
|
51db05bb23 | ||
|
|
2a69d7ee3a | ||
|
|
64279006d2 | ||
|
|
f3fe8f1f08 | ||
|
|
1b5581a255 | ||
|
|
db360dd6d3 | ||
|
|
521aefc5e4 | ||
|
|
e97fc30c61 | ||
|
|
f89a6ffc02 | ||
|
|
8698122bc0 | ||
|
|
d39bb2c21d | ||
|
|
6bcadd4b72 | ||
|
|
f5913b36eb | ||
|
|
9eda7c7137 | ||
|
|
2967120d3f | ||
|
|
f5c574cf64 | ||
|
|
7be0680637 | ||
|
|
4688eab951 | ||
|
|
b2b08d7509 | ||
|
|
de1d39d8c7 | ||
|
|
7735ffaf5f | ||
|
|
e60eea24a6 | ||
|
|
ccaa70ac41 | ||
|
|
c7021f35d3 | ||
|
|
bf666cfbbb | ||
|
|
5221578aed | ||
|
|
743de1881a | ||
|
|
efc9f079f2 | ||
|
|
153e0f8fc4 | ||
|
|
88f0f480cd | ||
|
|
2284734b85 | ||
|
|
211784ae69 | ||
|
|
01c3263d9d | ||
|
|
e564cfa4fd | ||
|
|
27994a07b3 | ||
|
|
af5a48b80e | ||
|
|
7ebc3fed78 | ||
|
|
1419b3961f | ||
|
|
be2e7de8e3 | ||
|
|
5bc13a6272 | ||
|
|
305d2fe4cf | ||
|
|
1e64bc0c05 | ||
|
|
c0c7396fa2 | ||
|
|
11d4795f3b | ||
|
|
1f64a78c54 | ||
|
|
9f8c7a3dbf | ||
|
|
5b96cbf3ca | ||
|
|
5c6fe552b2 | ||
|
|
c05f417fcb | ||
|
|
7a730bce9a | ||
|
|
6453c3ef9f | ||
|
|
b5a895cc3b | ||
|
|
785023b9b3 | ||
|
|
2c081c18ca | ||
|
|
a090bed5b9 | ||
|
|
cc24f31bca | ||
|
|
185eba3290 | ||
|
|
59369651b3 | ||
|
|
d0e917dc0e | ||
|
|
f1b1278092 | ||
|
|
3b1ceb1c4d | ||
|
|
6c7c6218c6 | ||
|
|
88f08af1c9 | ||
|
|
854bd468b7 | ||
|
|
61ec84ac18 | ||
|
|
0c7f4db3d0 | ||
|
|
0a154acaa6 | ||
|
|
3670a4b5b2 | ||
|
|
dba7165058 | ||
|
|
b1c2770175 | ||
|
|
26759c1b41 | ||
|
|
94a57b0bfb | ||
|
|
9ec7a26112 | ||
|
|
6b52baf740 | ||
|
|
5aa9c50aed | ||
|
|
c1d833704a | ||
|
|
9efbc4670c | ||
|
|
5d73465949 | ||
|
|
1dc396a97d | ||
|
|
9ba4fafe85 | ||
|
|
fe5b45000c | ||
|
|
2b1aed2038 | ||
|
|
cf2abdb318 | ||
|
|
5e10777cf3 | ||
|
|
eddd40ba3c | ||
|
|
a410416b35 | ||
|
|
f5849b4113 | ||
|
|
4b81e9dcd7 | ||
|
|
2780f3cfd3 | ||
|
|
ff6034a8bf | ||
|
|
2770981072 | ||
|
|
347b101a64 | ||
|
|
8f385ab4e5 | ||
|
|
82490ef6e4 | ||
|
|
154ca0a4f7 | ||
|
|
76aea8e7e1 | ||
|
|
aa9053dd26 | ||
|
|
0fd0bf0747 | ||
|
|
6f5d62e7dd | ||
|
|
ad9f17e7ca | ||
|
|
74a48500bc | ||
|
|
01b5e89d86 | ||
|
|
1c5b19e674 | ||
|
|
5ba09b8586 | ||
|
|
434ec4f3ea | ||
|
|
ad77a4600f | ||
|
|
41f436aa6a | ||
|
|
fa58912e33 | ||
|
|
97dca359cc | ||
|
|
97bdad44dc | ||
|
|
1eafdabb17 | ||
|
|
8a22594745 | ||
|
|
ab6b51cde3 | ||
|
|
76952aa408 | ||
|
|
f09023c08c | ||
|
|
2f6460bfab | ||
|
|
0589bd7f96 | ||
|
|
f357f400b0 | ||
|
|
ccbbad4765 | ||
|
|
8d72dbce55 | ||
|
|
7e36b2b1b6 | ||
|
|
ad7b7fa57b | ||
|
|
ee91eb34d4 | ||
|
|
45098358a6 | ||
|
|
14d843c138 | ||
|
|
86af2a4cf2 | ||
|
|
195e4a4392 | ||
|
|
9f64d3f28e | ||
|
|
addeaa2309 | ||
|
|
422f4b07b4 | ||
|
|
c15a3e2a49 | ||
|
|
3d7e682b9b | ||
|
|
008e0e34e6 | ||
|
|
e8f4e135a4 | ||
|
|
33df6dcec3 | ||
|
|
9ebab409ac | ||
|
|
419b54e0c1 | ||
|
|
d7d07c47bc | ||
|
|
53b207ce68 | ||
|
|
bf5c780d34 | ||
|
|
3c5c9654f3 | ||
|
|
fd1e3a7016 | ||
|
|
31a1203122 | ||
|
|
e58a28f168 | ||
|
|
604d2b542a | ||
|
|
8ba6574b0c | ||
|
|
bfba4e838d | ||
|
|
79a2767fae | ||
|
|
768fbe237b | ||
|
|
6c8b195d00 | ||
|
|
49b54e5b5d | ||
|
|
0974d525ea | ||
|
|
465cf40df7 | ||
|
|
7c7bf0f04b | ||
|
|
2eb886f750 | ||
|
|
b9422fe192 | ||
|
|
00627e83c3 | ||
|
|
b9bbbb1229 | ||
|
|
ce22b5878c | ||
|
|
71a8db3fda | ||
|
|
af786dc874 | ||
|
|
441606e2f4 | ||
|
|
72c14ecd87 | ||
|
|
7d624ab6e4 | ||
|
|
a107bd7443 | ||
|
|
34c3419d3c | ||
|
|
915d27345b | ||
|
|
3dafd0ce78 | ||
|
|
1713b651f2 | ||
|
|
07f60a902f | ||
|
|
6f2e5dfc44 | ||
|
|
9a4d376681 | ||
|
|
41858793c8 | ||
|
|
a816bf6b1a | ||
|
|
b7143d87b4 | ||
|
|
5e2e33db4c | ||
|
|
6c2a85aac8 | ||
|
|
ced621bfda | ||
|
|
6cc996db47 | ||
|
|
5feb20ec83 | ||
|
|
7b69406cf0 | ||
|
|
5934226a69 | ||
|
|
36df8cf2e2 | ||
|
|
7351cc453d | ||
|
|
1832888bcf | ||
|
|
c3de15d278 | ||
|
|
296063e231 | ||
|
|
e1711582ec | ||
|
|
a140e1b386 | ||
|
|
5d67bc28ea | ||
|
|
629eeb4176 | ||
|
|
29563f3f03 | ||
|
|
a5e98926af | ||
|
|
a47c67d797 | ||
|
|
3d67eac402 | ||
|
|
a5eea419d8 | ||
|
|
1b62051543 | ||
|
|
774ba4dd86 | ||
|
|
aa1f0eb5c1 | ||
|
|
93d5f8eda6 | ||
|
|
b6ac112d10 | ||
|
|
da2f6e79d3 | ||
|
|
db9c0effba | ||
|
|
764cf05571 | ||
|
|
bed468679f | ||
|
|
6b6994cf1e | ||
|
|
8d940ce7e1 | ||
|
|
b5d8182780 | ||
|
|
64f2bfa15b | ||
|
|
5d6a014157 | ||
|
|
dc51d5fe16 | ||
|
|
b091a0902e | ||
|
|
e30f47f5de | ||
|
|
469f520b30 | ||
|
|
5ed77ef1bb | ||
|
|
37288d81a7 | ||
|
|
e6d52eed44 | ||
|
|
9b23f42a0a | ||
|
|
78bae22fb2 | ||
|
|
667aaff62d | ||
|
|
8a51ef8524 | ||
|
|
56bd22f4e3 | ||
|
|
2abcacb722 | ||
|
|
a727f93d0e | ||
|
|
272f0da513 | ||
|
|
64fecfbebb | ||
|
|
869998b58a | ||
|
|
f0cef8e4f5 | ||
|
|
2b47060190 | ||
|
|
eaba7bbdad | ||
|
|
beae7d7551 | ||
|
|
d7970177f3 | ||
|
|
cd7a2d08ca | ||
|
|
c3409ab251 | ||
|
|
18ac71a371 | ||
|
|
8ccd7d9dd5 | ||
|
|
c15b35c74f | ||
|
|
272a9da194 | ||
|
|
2cd5d0109c | ||
|
|
8b48ce96e1 | ||
|
|
108c605897 | ||
|
|
70be993cfd | ||
|
|
09d7d62632 | ||
|
|
534dfde000 | ||
|
|
75e4afe5ce | ||
|
|
c0eeba3cfc | ||
|
|
0976bf2aa8 | ||
|
|
b658b2bbc2 | ||
|
|
d934619abe | ||
|
|
d68207b59e | ||
|
|
672acd902b | ||
|
|
9735074c7c | ||
|
|
3b89622ba8 | ||
|
|
77be9b82c1 | ||
|
|
620ac0081f | ||
|
|
1a0a486c71 | ||
|
|
3feb7b2a93 | ||
|
|
d4ca777cbd | ||
|
|
9101519e26 | ||
|
|
1896d7ffec | ||
|
|
5871f6ea1c | ||
|
|
d7fe9272b8 | ||
|
|
40ee584fcf | ||
|
|
93a24b3ad0 | ||
|
|
661d273ab7 | ||
|
|
3aee0c3548 | ||
|
|
dd60c551cd | ||
|
|
1c984ae94b | ||
|
|
ddac25ee39 | ||
|
|
2fe18dead5 | ||
|
|
b16408049b | ||
|
|
110fa13b1d | ||
|
|
d911376774 | ||
|
|
3a246798b8 | ||
|
|
0de3f90b6c | ||
|
|
4c7e23e0a6 | ||
|
|
9b6bce7e58 | ||
|
|
9e3f9f6345 | ||
|
|
a1356fbdd9 | ||
|
|
d33a8dc7a2 | ||
|
|
e1b5e909c4 | ||
|
|
cbf7bc6a3d | ||
|
|
1ae192e48e | ||
|
|
0dc095ff71 | ||
|
|
e5277f39a1 | ||
|
|
e5444aa9e6 | ||
|
|
bbaa1abfe5 | ||
|
|
a101ba7167 | ||
|
|
33b32edb4a | ||
|
|
ecc7d05a05 | ||
|
|
3efbbc85ab | ||
|
|
7a3e617585 | ||
|
|
6767934906 | ||
|
|
85f757efb9 | ||
|
|
132ef13af6 | ||
|
|
4329e20359 | ||
|
|
6babbbdfe9 | ||
|
|
f7318c3033 | ||
|
|
80ff0a6f7b | ||
|
|
dfb48fcf0c | ||
|
|
3cd046fdd0 | ||
|
|
df65aa9aa6 | ||
|
|
5f9a0840cc | ||
|
|
805db97abd | ||
|
|
53afe35b12 | ||
|
|
01535f4add | ||
|
|
ecf6b96e0f | ||
|
|
77b005988b | ||
|
|
db2de36a4d | ||
|
|
c713c88749 | ||
|
|
7a32c6789b | ||
|
|
78522cca81 | ||
|
|
a50927e039 | ||
|
|
e821ddc1c8 | ||
|
|
7116de1a7e | ||
|
|
463dbccce4 | ||
|
|
0b8635565d | ||
|
|
5b9b68bc92 | ||
|
|
cbf1992d78 | ||
|
|
f799eaf0cd | ||
|
|
3c605a4480 | ||
|
|
6c66b28c1f | ||
|
|
876858458a | ||
|
|
d090071923 | ||
|
|
2c3b4588ef | ||
|
|
7fb52ccd4c | ||
|
|
b9c02025f5 | ||
|
|
e354190c31 | ||
|
|
6feb079005 |
No files matched your search
@@ -0,0 +1,120 @@
|
||||
# .clang-format for Qt Creator
|
||||
#
|
||||
# This is for clang-format >= 5.0.
|
||||
#
|
||||
# The configuration below follows the Qt Creator Coding Rules [1] as closely as
|
||||
# possible. For documentation of the options, see [2].
|
||||
#
|
||||
# Use ../../tests/manual/clang-format-for-qtc/test.cpp for documenting problems
|
||||
# or testing changes.
|
||||
#
|
||||
# In case you update this configuration please also update the qtcStyle() in src\plugins\clangformat\clangformatutils.cpp
|
||||
#
|
||||
# [1] https://doc-snapshots.qt.io/qtcreator-extending/coding-style.html
|
||||
# [2] https://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
||||
#
|
||||
# yaml-language-server: $schema=https://json.schemastore.org/clang-format.json
|
||||
#
|
||||
---
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: AlwaysBreak
|
||||
AlignConsecutiveAssignments: None
|
||||
AlignConsecutiveDeclarations: None
|
||||
AlignEscapedNewlines: DontAlign
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: true
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: false
|
||||
BreakBeforeBinaryOperators: All
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 100
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- forever # avoids { wrapped to next line
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IncludeCategories:
|
||||
- Regex: '^<Q.*'
|
||||
Priority: 200
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IndentCaseLabels: false
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
# InsertBraces: false
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
# Do not add QT_BEGIN_NAMESPACE/QT_END_NAMESPACE as this will indent lines in between.
|
||||
MacroBlockBegin: ""
|
||||
MacroBlockEnd: ""
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBlockIndentWidth: 4
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakAssignment: 88
|
||||
PenaltyBreakBeforeFirstCallParameter: 300
|
||||
PenaltyBreakComment: 500
|
||||
PenaltyBreakFirstLessLess: 400
|
||||
PenaltyBreakString: 600
|
||||
PenaltyExcessCharacter: 50
|
||||
PenaltyReturnTypeOnItsOwnLine: 300
|
||||
PointerAlignment: Right
|
||||
ReflowComments: false
|
||||
SortIncludes: CaseSensitive
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: true
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: Never
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: c++17
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
|
||||
---
|
||||
|
||||
## Environment
|
||||
|
||||
```sh
|
||||
# copypaste this script into your shell and replace it with the output
|
||||
date
|
||||
r2 -v
|
||||
iaito -v
|
||||
uname -ms
|
||||
```
|
||||
|
||||
## Description
|
||||
|
||||
<!-- Explain what's the issue and what would you expect to see -->
|
||||
|
||||
## Test
|
||||
|
||||
<!-- Steps to reproduce the issue and provide files/links/images/.. -->
|
||||
@@ -0,0 +1,6 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
@@ -1,7 +1,9 @@
|
||||
name: iaito CI
|
||||
|
||||
env:
|
||||
R2V: 5.7.8
|
||||
R2V: 6.0.4
|
||||
QT_MAC_INSTALL_VERSION: 6.9.*
|
||||
QT_WIN_INSTALL_VERSION: 6.8.*
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -13,21 +15,19 @@ on:
|
||||
|
||||
jobs:
|
||||
acr-linux-r2git:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: false # 'recursive' 'true' or 'false'
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-python@v4
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.8.x
|
||||
python-version: 3.12.x
|
||||
- name: apt dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt install -y libgraphviz-dev mesa-common-dev ninja-build meson
|
||||
sudo apt install -y libqt5svg5-dev qttools5-dev qttools5-dev-tools
|
||||
sudo apt install -y qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools
|
||||
sudo apt-get install -y libgraphviz-dev mesa-common-dev ninja-build meson libqt5svg5-dev qttools5-dev qttools5-dev-tools qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools
|
||||
- name: install r2
|
||||
run: git clone --depth=1 https://github.com/radareorg/radare2 r2git && CFLAGS=-O0 r2git/sys/install.sh
|
||||
- name: build iaito
|
||||
@@ -35,95 +35,118 @@ jobs:
|
||||
./configure --prefix=/usr
|
||||
make -j4
|
||||
- name: packaging
|
||||
run: |
|
||||
make -j -C dist/debian
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: iaito-amd64.deb
|
||||
path: dist/debian/*/*.deb
|
||||
acr-linux:
|
||||
runs-on: ubuntu-20.04
|
||||
run: make -j -C dist/debian
|
||||
indent-check:
|
||||
runs-on: ubuntu-24.04
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
submodules: false # 'recursive' 'true' or 'false'
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: 3.8.x
|
||||
- name: apt dependencies
|
||||
python-version: 3.12.x
|
||||
- name: Install clang-format 18
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt install -y libgraphviz-dev mesa-common-dev ninja-build
|
||||
sudo apt install -y libqt5svg5-dev qttools5-dev qttools5-dev-tools
|
||||
sudo apt install -y qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools
|
||||
sudo apt-get install clang-format-18
|
||||
sudo apt-get install -y libgraphviz-dev mesa-common-dev ninja-build libqt5svg5-dev qttools5-dev qttools5-dev-tools qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools
|
||||
- name: install r2
|
||||
run: |
|
||||
wget -q https://github.com/radareorg/radare2/releases/download/${{env.R2V}}/radare2_${{env.R2V}}_amd64.deb
|
||||
wget -q https://github.com/radareorg/radare2/releases/download/${{env.R2V}}/radare2-dev_${{env.R2V}}_amd64.deb
|
||||
sudo dpkg -i *.deb
|
||||
- name: configure iaito
|
||||
run: ./configure --prefix=/usr
|
||||
- name: make indent
|
||||
run: make indent && git diff --exit-code
|
||||
acr-linux:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: false # 'recursive' 'true' or 'false'
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.12.x
|
||||
- name: apt dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libgraphviz-dev mesa-common-dev ninja-build libqt5svg5-dev qttools5-dev qttools5-dev-tools qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools
|
||||
- name: install r2
|
||||
run: |
|
||||
wget -q https://github.com/radareorg/radare2/releases/download/${{env.R2V}}/radare2_${{env.R2V}}_amd64.deb
|
||||
wget -q https://github.com/radareorg/radare2/releases/download/${{env.R2V}}/radare2-dev_${{env.R2V}}_amd64.deb
|
||||
sudo dpkg -i *.deb
|
||||
- name: configure iaito
|
||||
run: ./configure --prefix=/usr
|
||||
- name: build iaito
|
||||
run: |
|
||||
./configure --prefix=/usr
|
||||
make -j4
|
||||
run: make -j4
|
||||
- name: packaging
|
||||
run: |
|
||||
make -C dist/debian
|
||||
- uses: actions/upload-artifact@v3
|
||||
run: make -C dist/debian
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: iaito-amd64.deb
|
||||
path: dist/debian/*/*.deb
|
||||
acr-macos:
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- arch: arm64
|
||||
macos: latest
|
||||
- arch: x64
|
||||
macos: 13
|
||||
runs-on: macos-${{ matrix.macos }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: false # 'recursive' 'true' or 'false'
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-python@v1
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.8.x
|
||||
- name: homebrew dependencies
|
||||
run: |
|
||||
brew update
|
||||
brew install pkg-config qt@5
|
||||
brew unlink qt@5 || true
|
||||
brew link --force qt@5
|
||||
pip3 install meson
|
||||
pip3 install ninja
|
||||
python-version: 3.12.x
|
||||
- name: uname
|
||||
run: uname -a
|
||||
- name: install dependencies
|
||||
run: pip3 install meson ninja
|
||||
- name: install Qt
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
version: ${{env.QT_MAC_INSTALL_VERSION}}
|
||||
- name: install r2
|
||||
working-directory: dist/macos
|
||||
run: |
|
||||
wget -q https://github.com/radareorg/radare2/releases/download/${{env.R2V}}/radare2-x64-${{env.R2V}}.pkg
|
||||
sudo installer -pkg *.pkg -target /
|
||||
curl -Lo radare2.pkg "https://github.com/radareorg/radare2/releases/download/${{env.R2V}}/radare2-${{ matrix.arch }}-${{env.R2V}}.pkg"
|
||||
sudo installer -pkg radare2.pkg -target /
|
||||
- name: download extra deps
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: make -C dist/macos extra
|
||||
- name: build iaito
|
||||
run: |
|
||||
export PATH="/usr/local/opt/qt@5/bin:$PATH"
|
||||
export PATH="/opt/homebrew/opt/qt@5/bin:$PATH" # doesnt seems to be necessary
|
||||
export LDFLAGS="-L/usr/local/opt/qt@5/lib"
|
||||
export CPPFLAGS="-I/usr/local/opt/qt@5/include"
|
||||
export PKG_CONFIG_PATH="/usr/local/opt/qt@5/lib/pkgconfig"
|
||||
./configure
|
||||
make -j4
|
||||
make -j4 -C dist/macos app
|
||||
- name: ad-hoc sign
|
||||
run: codesign --force --deep -s - dist/macos/disk/iaito.app
|
||||
- name: packaging
|
||||
run: |
|
||||
make -C dist/macos
|
||||
- uses: actions/upload-artifact@v3
|
||||
run: make -C dist/macos zip
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: iaito-mac-amd64.zip
|
||||
path: dist/macos/iaito*.zip
|
||||
name: iaito-macos-${{ matrix.arch }}
|
||||
path: dist/macos/iaito.zip
|
||||
meson:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-22.04, ubuntu-20.04, ubuntu-18.04, macos-latest]
|
||||
python-version: [3.8.x]
|
||||
os: [ubuntu-22.04]
|
||||
python-version: [3.12.x]
|
||||
system-deps: [true]
|
||||
cc-override: [default]
|
||||
cxx-override: [default]
|
||||
# Prevent one job from pausing the rest
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: false # 'recursive' 'true' or 'false'
|
||||
persist-credentials: false
|
||||
@@ -131,86 +154,264 @@ jobs:
|
||||
if: contains(matrix.os, 'ubuntu')
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install libgraphviz-dev mesa-common-dev
|
||||
sudo apt-get install ninja-build make git patch wget
|
||||
sudo apt install -y libqt5svg5-dev qttools5-dev qttools5-dev-tools
|
||||
sudo apt install -y qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools
|
||||
sudo apt-get install -y libgraphviz-dev mesa-common-dev ninja-build libqt5svg5-dev qttools5-dev qttools5-dev-tools qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools
|
||||
- name: install r2
|
||||
run: git clone --depth=1 https://github.com/radareorg/radare2 r2git && CFLAGS=-O0 r2git/sys/install.sh
|
||||
- uses: actions/setup-python@v1
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: homebrew dependencies
|
||||
- name: install dependencies
|
||||
if: contains(matrix.os, 'macos')
|
||||
run: pip3 install meson ninja
|
||||
- name: install Qt
|
||||
if: contains(matrix.os, 'macos')
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
version: ${{env.QT_MAC_INSTALL_VERSION}}
|
||||
- name: macos build
|
||||
if: contains(matrix.os, 'macos')
|
||||
run: |
|
||||
brew update --preinstall # temporary workaround for https://github.com/Homebrew/homebrew-bundle/issues/751
|
||||
brew install coreutils pkg-config
|
||||
- name: py dependencies
|
||||
run: |
|
||||
pip install meson
|
||||
meson setup -Dwith_qt6=true build src
|
||||
ninja -C build -j4
|
||||
- name: meson+ninja ubuntu
|
||||
if: contains(matrix.os, 'ubuntu')
|
||||
run: |
|
||||
set -euo pipefail #TODO: move to top once iaito-deps doesn't fail
|
||||
if [[ "${{ matrix.cc-override }}" != "default" ]]
|
||||
then
|
||||
export CC="${{matrix.cc-override}}"
|
||||
export CXX="${{matrix.cxx-override}}"
|
||||
fi
|
||||
cd src
|
||||
meson ../build
|
||||
cd ../build
|
||||
ninja -j4
|
||||
pip install meson
|
||||
meson setup build src
|
||||
ninja -C build -j4
|
||||
w64-meson:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: false # 'recursive' 'true' or 'false'
|
||||
submodules: false
|
||||
persist-credentials: false
|
||||
- name: Preparing msvc toolchain
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: x64
|
||||
# - uses: actions/setup-python@v1
|
||||
# with:
|
||||
# python-version: 3.8.x
|
||||
# - name: Prepare Qt
|
||||
# working-directory: build
|
||||
# shell: cmd
|
||||
# run: |
|
||||
# curl -vLo qt-unified-windows-x86-online.exe http://download.qt.io/official_releases/online_installers/qt-unified-windows-x86-online.exe
|
||||
# qt-unified-windows-x86-online.exe --verbose --script ..\ci\qt.qs
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
- name: dependencies
|
||||
shell: cmd
|
||||
run: |
|
||||
pip install ninja meson wget
|
||||
choco install zip
|
||||
# - name: install r2
|
||||
# shell: bash
|
||||
# run: |
|
||||
# python -m wget https://github.com/radareorg/radare2/releases/download/${{env.R2V}}/radare2-${{env.R2V}}-w64.zip -o r2.zip
|
||||
# unzip r2.zip
|
||||
# mv radare2-${{env.R2V}}-w64 radare2
|
||||
# pwd
|
||||
- name: w64-make
|
||||
shell: cmd
|
||||
run: |
|
||||
SET ARCH=x64
|
||||
set IAITO_DEPS=%CD%\iaito-deps
|
||||
set PATH=%CD%\iaito-deps\qt\bin;%CD%\r2_dist\bin;%PATH%
|
||||
pip install meson ninja wget
|
||||
call preconfigure.bat
|
||||
call configure.bat
|
||||
call make.bat
|
||||
dir /s
|
||||
- uses: actions/upload-artifact@v3
|
||||
- name: install Qt
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
name: iaito.exe
|
||||
version: ${{env.QT_WIN_INSTALL_VERSION}}
|
||||
- name: install dependencies
|
||||
shell: cmd
|
||||
run: pip install ninja meson
|
||||
- name: install r2 (preconfigure)
|
||||
shell: bash
|
||||
run: |
|
||||
curl -L -o r2.zip https://github.com/radareorg/radare2/releases/download/${{env.R2V}}/radare2-${{env.R2V}}-w64.zip
|
||||
7z x r2.zip
|
||||
mv radare2-${{env.R2V}}-w64 radare2
|
||||
echo "%CD%\radare2\bin" >> $GITHUB_PATH
|
||||
- name: configure
|
||||
shell: cmd
|
||||
run: configure.bat
|
||||
- name: make
|
||||
shell: cmd
|
||||
env:
|
||||
ARCH: x64
|
||||
run: make.bat -Dwith_qt6=true
|
||||
- name: dist
|
||||
shell: cmd
|
||||
run: 7z a iaito.zip iaito
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: iaito-w64.exe
|
||||
path: iaito\iaito.exe
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.PACKAGE_NAME }}
|
||||
path: build/${{ env.PACKAGE_NAME }}
|
||||
name: iaito-w64.zip
|
||||
path: iaito.zip
|
||||
|
||||
check_release:
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
outputs:
|
||||
is_release: ${{ steps.release.outputs.is }}
|
||||
tag_name: ${{ steps.release.outputs.tag }}
|
||||
needs:
|
||||
- acr-linux
|
||||
- acr-macos
|
||||
- w64-meson
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0 # Download all git history and tags
|
||||
- name: Check if is a release
|
||||
run: git describe --exact-match --tags ${{ github.sha }} | awk 'BEGIN{tag="-";r="no"}/^[0-9]+\.[0-9]+/{tag=$0;r="yes"};END{print "is="r;print "tag="tag}' >> ${GITHUB_OUTPUT}
|
||||
id: release
|
||||
|
||||
macos-sign:
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && needs.check_release.outputs.is_release == 'yes' }}
|
||||
needs:
|
||||
- check_release
|
||||
runs-on: macos-latest
|
||||
environment: release
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
pattern: iaito-macos-*
|
||||
path: dist/artifacts
|
||||
|
||||
- name: Install Apple Certificate
|
||||
env:
|
||||
CERTIFICATE_BASE64: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_P12_BASE64 }}
|
||||
CERTIFICATE_PASSWORD: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_PASSWORD }}
|
||||
KEYCHAIN_PASSWORD: "keychainpass-${{ github.run_id }}"
|
||||
run: |
|
||||
# Create keychain
|
||||
security create-keychain -p "${KEYCHAIN_PASSWORD}" release.keychain
|
||||
security default-keychain -s release.keychain
|
||||
security unlock-keychain -p "${KEYCHAIN_PASSWORD}" release.keychain
|
||||
security set-keychain-settings -t 3600 -u release.keychain
|
||||
|
||||
# Import certificate
|
||||
echo "$CERTIFICATE_BASE64" | base64 --decode > certificate.p12
|
||||
security import certificate.p12 -k release.keychain -P "${CERTIFICATE_PASSWORD}" -T /usr/bin/codesign
|
||||
security set-key-partition-list -S apple-tool:,apple: -s -k "${KEYCHAIN_PASSWORD}" release.keychain
|
||||
|
||||
# Check if the certificate was imported correctly and find its identity
|
||||
security find-identity -v -p codesigning release.keychain
|
||||
|
||||
# Clean up
|
||||
rm certificate.p12
|
||||
|
||||
- name: Sign and package the App Bundle
|
||||
run: |
|
||||
# Find the Developer ID Application certificate identity
|
||||
IDENTITY=$(security find-identity -v -p codesigning | awk '/Developer ID Application/{print $2;exit}')
|
||||
|
||||
if [ -z "$IDENTITY" ]; then
|
||||
echo "Error: No Developer ID Application certificate found in keychain"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Sign and package for all architectures
|
||||
for arch in arm64 x64; do
|
||||
echo "[${arch}] Extracting build..."
|
||||
mkdir -p dist/macos/disk
|
||||
ditto -x -k dist/artifacts/iaito-macos-${arch}/iaito.zip dist/macos/disk/
|
||||
|
||||
echo "[${arch}] Signing app bundle..."
|
||||
codesign --force --deep --options runtime --entitlements "dist/macos/iaito.entitlements" --sign "$IDENTITY" dist/macos/disk/iaito.app
|
||||
codesign --verify --verbose dist/macos/disk/iaito.app
|
||||
|
||||
echo "[${arch}] Packaging into DMG..."
|
||||
rm -v dist/macos/disk/READ*.txt # no workaround needed
|
||||
ln -fs /Applications dist/macos/disk/
|
||||
(cd dist/macos; hdiutil create -format UDZO -fs APFS -volname iaito -srcfolder disk iaito)
|
||||
mv -v dist/macos/iaito.dmg "iaito-${arch}.dmg"
|
||||
rm -fR dist/macos/disk
|
||||
|
||||
echo "[${arch}] Signing DMG..."
|
||||
codesign --force --sign "$IDENTITY" --timestamp "iaito-${arch}.dmg"
|
||||
done
|
||||
|
||||
- name: Notarize DMG
|
||||
env:
|
||||
APPLE_ID: ${{ secrets.APPLE_DEVELOPER_ID }}
|
||||
TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
APP_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
|
||||
run: |
|
||||
for arch in arm64 x64; do
|
||||
echo "[${arch}] Notary DMG..."
|
||||
xcrun notarytool submit "iaito-${arch}.dmg" --apple-id "$APPLE_ID" --team-id "$TEAM_ID" --password "$APP_PASSWORD" --wait
|
||||
xcrun stapler staple "iaito-${arch}.dmg"
|
||||
done
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: iaito-arm64.dmg
|
||||
path: iaito-arm64.dmg
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: iaito-x64.dmg
|
||||
path: iaito-x64.dmg
|
||||
|
||||
release:
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && needs.check_release.outputs.is_release == 'yes' }}
|
||||
needs:
|
||||
- macos-sign
|
||||
- check_release
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0 # Download all git history and tags
|
||||
- name: Extract version
|
||||
run: echo "string=`./configure -qV`" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
- name: Prepare release notes
|
||||
run: ./scripts/release-notes.sh | tee ./RELEASE_NOTES.md
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
path: dist/artifacts
|
||||
- name: Display structure of downloaded files
|
||||
run: find dist/artifacts
|
||||
- name: Create GitHub release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ needs.check_release.outputs.tag_name }}
|
||||
release_name: ${{ steps.version.outputs.string }}
|
||||
body_path: ./RELEASE_NOTES.md
|
||||
draft: false
|
||||
prerelease: false
|
||||
- name: Prepare release notes
|
||||
run: ./scripts/release-notes.sh | tee ./RELEASE_NOTES.md
|
||||
- name: Upload Linux asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: dist/artifacts/iaito-amd64.deb/iaito/iaito_${{ steps.version.outputs.string }}_amd64.deb
|
||||
asset_name: iaito_${{ steps.version.outputs.string }}_amd64.deb
|
||||
asset_content_type: application/vnd.debian.binary-package
|
||||
- name: Upload macOS x64 asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: dist/artifacts/iaito-x64.dmg/iaito-x64.dmg
|
||||
asset_name: iaito_${{ steps.version.outputs.string }}_x64.dmg
|
||||
asset_content_type: application/vnd.debian.binary-package
|
||||
- name: Upload macOS arm64 asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: dist/artifacts/iaito-arm64.dmg/iaito-arm64.dmg
|
||||
asset_name: iaito_${{ steps.version.outputs.string }}_arm64.dmg
|
||||
asset_content_type: application/vnd.debian.binary-package
|
||||
- name: Upload Windows QtDeploy asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: dist/artifacts/iaito-w64.zip/iaito.zip
|
||||
asset_name: iaito-${{ steps.version.outputs.string }}-w64.zip
|
||||
asset_content_type: application/zip
|
||||
- name: Upload Windows executable
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: dist/artifacts/iaito-w64.exe/iaito.exe
|
||||
asset_name: iaito-${{ steps.version.outputs.string }}.exe
|
||||
asset_content_type: application/zip
|
||||
@@ -0,0 +1,23 @@
|
||||
on:
|
||||
pull_request: {}
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
paths:
|
||||
- .github/workflows/semgrep.yml
|
||||
schedule:
|
||||
# random HH:MM to avoid a load spike on GitHub Actions at 00:00
|
||||
- cron: 45 3 * * *
|
||||
name: Semgrep
|
||||
jobs:
|
||||
semgrep:
|
||||
name: Scan
|
||||
runs-on: ubuntu-22.04
|
||||
env:
|
||||
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
|
||||
container:
|
||||
image: returntocorp/semgrep
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- run: semgrep ci
|
||||
@@ -91,4 +91,12 @@ src/out
|
||||
*.orig
|
||||
|
||||
# Translations
|
||||
src/translations
|
||||
src/translations
|
||||
|
||||
# macOS package
|
||||
/dist/macos/radare2.pkg
|
||||
/dist/macos/radare2-unpkg
|
||||
/dist/macos/disk
|
||||
/dist/macos/extra
|
||||
/dist/macos/*.dmg
|
||||
/dist/macos/*.zip
|
||||
@@ -6,22 +6,60 @@ else
|
||||
BIN=build/iaito
|
||||
endif
|
||||
|
||||
#QMAKE_FLAGS+=IAITO_ENABLE_PYTHON=false
|
||||
QMAKE_FLAGS+=-config release
|
||||
|
||||
#install_name_tool -change /path/to/Qt/lib/QtCore.framework/Versions/4.0/QtCore
|
||||
# @executable_path/../Frameworks/QtCore.framework/Versions/4.0/QtCore
|
||||
# plugandpaint.app/Contents/plugins/libpnp_basictools.dylib
|
||||
|
||||
ifeq ($(WANT_PYTHON),1)
|
||||
QMAKE_FLAGS+=IAITO_ENABLE_PYTHON=true
|
||||
endif
|
||||
ifeq ($(WANT_PYTHON_BINDINGS),1)
|
||||
QMAKE_FLAGS+=IAITO_ENABLE_PYTHON_BINDINGS=true
|
||||
endif
|
||||
QMAKE_FLAGS+=PREFIX=$(PREFIX)
|
||||
|
||||
all: iaito
|
||||
|
||||
CXX?=g++
|
||||
|
||||
reset:
|
||||
rm -rf ~/.config/radareorg/iaito.conf
|
||||
|
||||
QTLIBS=$(shell grep "^LIBS" build/Makefile | cut -d = -f 2-)
|
||||
R2LIBS=$(shell pkg-config --cflags --libs r_core)
|
||||
R2_LIBEXT=$(shell r2 -H R2_LIBEXT)
|
||||
R2_USER_PLUGINS=$(shell r2 -H R2_USER_PLUGINS)
|
||||
|
||||
plugin core_plugin: iaito
|
||||
SUBLIBS=true $(CXX) build/*.o src/CorePlugin.cpp -shared -fPIC $(QTLIBS) $(R2LIBS) -o build/CorePlugin.$(R2_LIBEXT)
|
||||
mkdir -p $(R2_USER_PLUGINS)
|
||||
rm -f $(R2_USER_PLUGINS)/IaitoPlugin.$(R2_LIBEXT)
|
||||
cp -f build/CorePlugin.$(R2_LIBEXT) $(R2_USER_PLUGINS)/IaitoPlugin.$(R2_LIBEXT)
|
||||
|
||||
asan:
|
||||
export CXXFLAGS=-fsanitize=address ; \
|
||||
export CFLAGS=-fsanitize=address ; \
|
||||
export LDFLAGS=-fsanitize=address ; \
|
||||
$(MAKE) build && $(MAKE) -C build -j4
|
||||
|
||||
clean:
|
||||
rm -f src/ui_*.h
|
||||
rm -rf build
|
||||
|
||||
dist:
|
||||
ifeq ($(shell uname),Darwin)
|
||||
$(MAKE) -C dist/macos
|
||||
else
|
||||
$(MAKE) -C dist/debian
|
||||
endif
|
||||
|
||||
mrproper: clean
|
||||
git clean -xdf
|
||||
|
||||
.PHONY: install run user-install clean mrproper install-translations
|
||||
.PHONY: install run user-install dist macos clean mrproper install-translations
|
||||
|
||||
# force qt5 build when QtCreator is installed in user's home
|
||||
ifeq ($(shell test -x ~/Qt/5.*/clang_64/bin/qmake || echo err),)
|
||||
@@ -29,7 +67,7 @@ QMAKE=~/Qt/5.*/clang_64/bin/qmake
|
||||
endif
|
||||
|
||||
iaito: build
|
||||
$(MAKE) -C build -j4
|
||||
$(MAKE) -C build
|
||||
|
||||
build:
|
||||
mkdir -p build
|
||||
@@ -77,6 +115,12 @@ user-uninstall:
|
||||
run:
|
||||
rarun2 libpath=$(shell r2 -H R2_LIBDIR) program=$(BIN)
|
||||
|
||||
gdb:
|
||||
gdb --args $(BIN)
|
||||
|
||||
lldb:
|
||||
lldb -- $(BIN)
|
||||
|
||||
src/translations/README.md:
|
||||
git clone https://github.com/radareorg/iaito-translations.git src/translations
|
||||
|
||||
@@ -85,3 +129,15 @@ install-translations: src/translations/README.md
|
||||
|
||||
user-install-translations: src/translations/README.md
|
||||
$(MAKE) -C src/translations user-install
|
||||
|
||||
dockindent:
|
||||
docker images | grep clang-format-image || make -C scripts/indent
|
||||
docker run --rm -v "$$PWD:/project" clang-format-image -i \
|
||||
$(shell find src -name '*.cpp' -o -name '*.h')
|
||||
|
||||
indent:
|
||||
ifeq ($(clang-format --version | grep 'version 18'),)
|
||||
$(MAKE) dockindent
|
||||
else
|
||||
clang-format -i $(shell find src -name '*.cpp' -o -name '*.h')
|
||||
endif
|
||||
@@ -1,31 +1,111 @@
|
||||
<img width="150" height="150" align="left" style="float: left; margin: 0 10px 0 0;" alt="Iaito logo" src="https://raw.githubusercontent.com/radareorg/iaito/master/src/img/iaito-circle.svg?sanitize=true">
|
||||
|
||||
# iaito
|
||||
# iaito: use radare2 with one hand!
|
||||
|
||||
iaito is the official graphical interface for radare2, a libre reverse engineering framework.
|
||||
|
||||
* Iaito was the original name of this GUI before being forked as Cutter.
|
||||
* It's written in Qt/C++ (qt5 for now). No Qt6 support yet (contribs are welcome)
|
||||
* Support latest versions, plugins and features of radare2
|
||||
* Use r2 plugins (f.ex: no need for r2ghidra-iaito plugin if r2ghidra is installed)
|
||||
* Focus on parity of commands, keybindings and r2-style workflows.
|
||||
* Translations are community [contributed](https://crowdin.com/project/iaito)!
|
||||
* Aims to support all the features from the core, not just disassembler-based ones
|
||||
* forensics, networking, bindiffing, solvers, ...
|
||||
<img width="150" height="150" align="left" style="float: left; margin: 0 30px 0 0;" alt="Iaito logo" src="https://raw.githubusercontent.com/radareorg/iaito/master/src/img/iaito.svg?sanitize=true">
|
||||
|
||||
* Based on radare2 and Qt-5/6
|
||||
* Iaito was the original name before being forked as Cutter.
|
||||
* Use all your favourite r2 plugins and scripts (nothing is specific to iaito)
|
||||
* Focus on simplicity, parity with commands, features, keybindings
|
||||
* Forensics, bindiffing, binary patching, .. not just a static disassembler
|
||||
|
||||
[](https://crowdin.com/project/iaito)
|
||||
[](https://github.com/radareorg/iaito/actions)
|
||||
[](https://repology.org/project/iaito/versions)
|
||||
|
||||

|
||||

|
||||
|
||||
## Help
|
||||
|
||||
Get help, updates, meet the community or discuss about development in these channels:
|
||||
|
||||
- **Discord:** [https://discord.gg/6RwDEJFr](https://discord.gg/6RwDEJFr)
|
||||
- **Telegram:** https://t.me/radare
|
||||
- **Mastodon:** [@radareorg](https://infosec.exchange/@radareorg)
|
||||
- **Translations:** [crowdin](https://crowdin.com/project/iaito)!
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
There are automated CI builds and [releases](https://github.com/radareorg/iaito/releases) of iaito for Linux, macOS and Windows.
|
||||
|
||||
On WSL or Linux you can use these steps to install it with Flatpak:
|
||||
|
||||
```sh
|
||||
sudo flatpak remote-add flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||
sudo flatpak install flathub org.radare.iaito
|
||||
flatpak run org.radare.iaito
|
||||
```
|
||||
|
||||
On macOS, you may want to fix the signature
|
||||
|
||||
```sh
|
||||
sudo xattr -c /Applications/iaito.app
|
||||
sudo codesign --force --deep --sign - /Applications/iaito.app
|
||||
```
|
||||
|
||||
<a href='https://flathub.org/apps/details/org.radare.iaito'><img width='120' alt='Download on Flathub' src='https://flathub.org/assets/badges/flathub-badge-en.png'/></a>
|
||||
|
||||
### Translations
|
||||
## Source Builds
|
||||
|
||||
### Dependencies
|
||||
|
||||
iaito requires [radare2](https://github.com/radareorg/radare2) and qt5 (or qt6):
|
||||
|
||||
```sh
|
||||
$ git clone https://github.com/radareorg/radare2 && radare2/sys/install.sh
|
||||
```
|
||||
|
||||
Install QT on macOS like this:
|
||||
|
||||
```sh
|
||||
brew install qt@5
|
||||
echo 'export PATH="/opt/homebrew/opt/qt@5/bin:$PATH"' >> ~/.profile
|
||||
```
|
||||
|
||||
On Ubuntu/Debian
|
||||
|
||||
```sh
|
||||
sudo apt install qttools5-dev qttools5-dev-tools qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libqt5svg5-dev make pkg-config build-essential
|
||||
```
|
||||
|
||||
For QT6:
|
||||
|
||||
```sh
|
||||
sudo apt install qt6-svg-dev
|
||||
```
|
||||
|
||||
### Compilation
|
||||
|
||||
```sh
|
||||
./configure
|
||||
make
|
||||
make run
|
||||
```
|
||||
|
||||
To install the app in your home:
|
||||
|
||||
```sh
|
||||
make install
|
||||
```
|
||||
|
||||
### Building iaito as an r2 plugin
|
||||
|
||||
It is also possible to launch iaito from the r2 shell reusing the Core instance:
|
||||
|
||||
```
|
||||
make plugin
|
||||
```
|
||||
|
||||
The previous command will build iaito, the iaito plugin and copy it it into your home plugin directory.
|
||||
|
||||
```
|
||||
$ r2 /bin/ls
|
||||
> iaito
|
||||
...
|
||||
```
|
||||
|
||||
### Translations (Optional)
|
||||
|
||||
Note: The flatpak/flathub version already ships the translations as an optional extension.
|
||||
|
||||
@@ -47,49 +127,14 @@ OR
|
||||
$ make install-translations # to install to system
|
||||
```
|
||||
|
||||
## Source Builds
|
||||
### Binaries
|
||||
|
||||
### Dependencies
|
||||
Most distros may Checkout the [Releases](https://github.com/radareorg/iaito/releases) page to download the build for Linux, macOS or Windows, and read the notes in case of problems!
|
||||
|
||||
iaito requires [radare2](https://github.com/radareorg/radare2) and qt5:
|
||||
As shown below, most distros are packaging iaito already, pick the build you like the most!
|
||||
|
||||
```sh
|
||||
$ git clone https://github.com/radareorg/radare2
|
||||
$ radare2/sys/install.sh
|
||||
```
|
||||
[](https://repology.org/project/iaito/versions)
|
||||
|
||||
Install QT on macOS like this:
|
||||
Snap:
|
||||
|
||||
```sh
|
||||
brew install qt@5
|
||||
echo 'export PATH="/opt/homebrew/opt/qt@5/bin:$PATH"' >> ~/.profile
|
||||
```
|
||||
|
||||
On Ubuntu/Debian
|
||||
|
||||
```sh
|
||||
sudo apt install qttools5-dev qttools5-dev-tools qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libqt5svg5-dev make pkg-config build-essential
|
||||
|
||||
```
|
||||
|
||||
## Building from sources
|
||||
|
||||
```sh
|
||||
./configure
|
||||
make
|
||||
make run
|
||||
```
|
||||
|
||||
To install the app in your home:
|
||||
|
||||
```sh
|
||||
make install
|
||||
```
|
||||
|
||||
## Help
|
||||
|
||||
Get help, updates, meet the community or discuss about development in these channels:
|
||||
|
||||
- **Telegram:** https://t.me/radare
|
||||
- **IRC:** #radare on irc.freenode.net
|
||||
- **Twitter:** [@radareorg](https://twitter.com/radareorg)
|
||||
[](https://snapcraft.io/iaito)
|
||||
@@ -24,7 +24,7 @@ else
|
||||
acr -p
|
||||
fi
|
||||
|
||||
. configure
|
||||
. ./configure
|
||||
|
||||
sed \
|
||||
-e "s,^IAITO_VERSION_MAJOR.*,IAITO_VERSION_MAJOR = ${VERSION_MAJOR}," \
|
||||
@@ -34,7 +34,10 @@ sed \
|
||||
|
||||
mv src/Iaito.pro.sed src/Iaito.pro
|
||||
${EDITOR} .github/workflows/ci.yml
|
||||
|
||||
echo
|
||||
echo "Press enter and add a new changelog entry for the new Flatpak version"
|
||||
read A
|
||||
${EDITOR} src/org.radare.iaito.appdata.xml
|
||||
#V=`./configure -qV | cut -d - -f -1`
|
||||
# meson rewrite kwargs set project / version "$V"
|
||||
# if [ -n "$1" ]; then
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
PREFIX=@PREFIX@
|
||||
QMAKE=@QMAKE@
|
||||
LRELEASE=@LRELEASE@
|
||||
QMAKE=@QMAKE_BIN@
|
||||
|
||||
WANT_PYTHON=@WANT_PYTHON@
|
||||
WANT_PYTHON_BINDINGS=@WANT_PYTHON_BINDINGS@
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# This script was automatically generated by ACR v2.0.0
|
||||
# This script was automatically generated by ACR v2.2.4
|
||||
# @author: pancake <nopcode.org>
|
||||
# @url: http://www.nopcode.org
|
||||
# @repo: git clone https://github.com/radare/acr
|
||||
@@ -18,6 +18,7 @@ control_c() {
|
||||
exit 1
|
||||
}
|
||||
trap control_c 2
|
||||
WANT_QMAKE6=0
|
||||
split_host() {
|
||||
S="$"
|
||||
while : ; do
|
||||
@@ -65,13 +66,27 @@ if [ -e "${VPATH}/config.guess" ]; then
|
||||
sh ${VPATH}/config.guess
|
||||
return
|
||||
fi
|
||||
CPU="`uname -m|sed -e 's, ,,g'|cut -d - -f 1`"
|
||||
CPU="`uname -m | tr 'A-Z' 'a-z' | sed -e 's, ,,g' | cut -d - -f 1`"
|
||||
OS="`uname -s|tr A-Z a-z`"
|
||||
uname -r | grep -qE "(Microsoft|WSL)" 2>/dev/null && OS="wsl"
|
||||
GNU="`uname --help 2>&1 | grep gnu`"
|
||||
[ "${GNU}" ] && OS="${OS}-gnu"
|
||||
[ "${CPU}" = ppc ] && CPU="powerpc"
|
||||
echo "${CPU}-unknown-${OS}"
|
||||
# normalize CPU
|
||||
case "${CPU}" in
|
||||
ppc*|powermac*|powermacintosh*|powerpc*)
|
||||
if echo "${CPU}" | grep -q '64'; then
|
||||
CPU=powerpc64
|
||||
else
|
||||
CPU=powerpc
|
||||
fi
|
||||
;;
|
||||
*) ;;
|
||||
esac
|
||||
VENDOR="unknown"
|
||||
if [ "${OS}" = "darwin" ]; then
|
||||
VENDOR=apple
|
||||
fi
|
||||
echo "${CPU}-${VENDOR}-${OS}"
|
||||
}
|
||||
|
||||
SEARCHPATH="/usr /usr/local /usr/pkg /sw"
|
||||
@@ -83,6 +98,7 @@ HOST="${BUILD}"
|
||||
TARGET="${HOST}"
|
||||
ETCDIR="/etc"
|
||||
SYSCONFDIR=""
|
||||
DESCRIPTION=""
|
||||
|
||||
create_environ() {
|
||||
: ${EPREFIX:="${PREFIX}"}
|
||||
@@ -91,6 +107,8 @@ create_environ() {
|
||||
: ${SBINDIR:="${PREFIX}/sbin"}
|
||||
: ${ETCDIR:="${SPREFIX}/etc"}
|
||||
: ${LIBDIR:="${SPREFIX}/lib"}
|
||||
: ${PKGCFG_LIBDIR:='${exec_prefix}/lib'}
|
||||
: ${PKGCFG_INCDIR:='${prefix}/include'}
|
||||
: ${LIBEXECDIR:="${SPREFIX}/libexec"}
|
||||
: ${INCLUDEDIR:="${SPREFIX}/include"}
|
||||
: ${DATADIR:="${SPREFIX}/share"}
|
||||
@@ -109,12 +127,12 @@ done
|
||||
: ${INSTALL_PROGRAM_STRIP:=${INSTALL} -m 755 -s}
|
||||
: ${INSTALL_MAN:=${INSTALL} -m 444}
|
||||
: ${INSTALL_LIB:=${INSTALL} -m 755 -c}
|
||||
PKGNAME='iaito' ; VERSION='5.7.6' ; VERSION_MAJOR=5; VERSION_MINOR=7; VERSION_PATCH=6; VERSION_NUMBER=50706; CONTACT_MAIL="[email protected]" ; CONTACT_NAME="pancake" ; CONTACT="pancake <[email protected]>" ;
|
||||
PKGNAME='iaito' ; VERSION='6.0.4' ; VERSION_MAJOR=6; VERSION_MINOR=0; VERSION_PATCH=4; VERSION_NUMBER=60004; CONTACT_MAIL="[email protected]" ; CONTACT_NAME="pancake" ; CONTACT="pancake <[email protected]>" ;
|
||||
}
|
||||
|
||||
show_usage() {
|
||||
cat <<EOF2
|
||||
'configure' configures iaito-5.7.6 to adapt to many kinds of systems.
|
||||
'configure' configures iaito-6.0.4 to adapt to many kinds of systems.
|
||||
|
||||
Usage: ./configure [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -156,6 +174,10 @@ System types:
|
||||
--target=TARGET configure for building compilers for TARGET [HOST]
|
||||
EOF2
|
||||
|
||||
printf "
|
||||
Optional Features:
|
||||
--with-qmake6 ignore qmake in path when qmake6 is found
|
||||
"
|
||||
printf "
|
||||
Some influential environment variables:
|
||||
CXX C++ compiler command
|
||||
@@ -186,10 +208,10 @@ ocho() {
|
||||
|
||||
show_version() {
|
||||
if [ "$QUIET" = 1 ]; then
|
||||
echo "5.7.6"
|
||||
echo "6.0.4"
|
||||
exit 0
|
||||
fi
|
||||
echo "iaito-5.7.6 configuration script done with acr v2.0.0.
|
||||
echo "iaito-6.0.4 configuration script done with acr v2.2.4.
|
||||
The 'Free Software Foundation' message is only for autodetection.
|
||||
Originally written by pancake <nopcode.org>."
|
||||
exit 0
|
||||
@@ -217,10 +239,13 @@ case $flag in
|
||||
-V|-version|--version)
|
||||
show_version ; ;;
|
||||
-r|--r|--report)
|
||||
echo "PKGNAME: iaito"
|
||||
echo "VERSION: 5.7.6"
|
||||
echo "LANGS: c++"
|
||||
echo "PKG-CONFIG: r_core"
|
||||
echo "PKGNAME: iaito"
|
||||
echo "VERSION: 6.0.4"
|
||||
echo "AUTHOR: pancake"
|
||||
echo "EMAIL: pancake@nopcode.org"
|
||||
echo "LANGS: c++"
|
||||
echo "PKGCONFIG: r_core"
|
||||
echo "FLAGS: --with-qmake6"
|
||||
exit 0
|
||||
;;
|
||||
--cache-file)
|
||||
@@ -260,16 +285,19 @@ echo "PKG-CONFIG: r_core"
|
||||
--localstatedir)
|
||||
LOCALSTATEDIR="$value"; ;;
|
||||
--libdir)
|
||||
LIBDIR="$value"; ;;
|
||||
LIBDIR="$value"
|
||||
PKGCFG_LIBDIR="$value"; ;;
|
||||
--libpath)
|
||||
LDFLAGS="${LDFLAGS} ${LIBPATH}$value"; ;;
|
||||
--includedir)
|
||||
PKGCFG_INCDIR="$value"
|
||||
INCLUDEDIR="$value"; CFLAGS="${CFLAGS} -I$value"; ;;
|
||||
--infodir)
|
||||
INFODIR="$value"; ;;
|
||||
--mandir)
|
||||
MANDIR="$value"; ;;
|
||||
|
||||
"--with-qmake6") WANT_QMAKE6="1"; ;;
|
||||
*) if [ "$value" ]; then eval "`echo $flag2=$value`" ;
|
||||
else echo ; echo "WARNING: Unknown flag '$flag'." >&2 ; echo ; fi ;;
|
||||
esac
|
||||
@@ -287,7 +315,7 @@ parse_options "$1"
|
||||
shift
|
||||
done
|
||||
|
||||
ENVWORDS="MANDIR INFODIR LIBDIR INCLUDEDIR LOCALSTATEDIR ETCDIR SYSCONFDIR DATADIR DOCDIR LIBEXECDIR SBINDIR BINDIR EPREFIX PREFIX SPREFIX TARGET HOST BUILD INSTALL INSTALL_LIB INSTALL_MAN INSTALL_PROGRAM INSTALL_PROGRAM_STRIP INSTALL_DIR INSTALL_SCRIPT INSTALL_DATA HOST_OS HOST_CPU BUILD_OS BUILD_CPU TARGET_OS TARGET_CPU VERSION VERSION_MAJOR VERSION_MINOR VERSION_PATCH VERSION_NUMBER PKGNAME VPATH CONTACT CONTACT_NAME CONTACT_MAIL CXX CXXFLAGS LDFLAGS HAVE_LANG_CXX CPP PKGCONFIG HAVE_R2 R2 R2_CFLAGS R2_LDFLAGS HAVE_PKGCFG_R_CORE HAVE_QMAKE QMAKE HAVE_LRELEASE LRELEASE WANT_PYTHON WANT_PYTHON_BINDINGS WANT_CRASH_REPORTS"
|
||||
ENVWORDS="MANDIR DESCRIPTION INFODIR LIBDIR INCLUDEDIR LOCALSTATEDIR ETCDIR SYSCONFDIR DATADIR DOCDIR LIBEXECDIR SBINDIR BINDIR EPREFIX PREFIX SPREFIX TARGET HOST BUILD INSTALL INSTALL_LIB INSTALL_MAN INSTALL_PROGRAM INSTALL_PROGRAM_STRIP INSTALL_DIR INSTALL_SCRIPT INSTALL_DATA HOST_OS HOST_CPU BUILD_OS BUILD_CPU TARGET_OS TARGET_CPU VERSION VERSION_MAJOR VERSION_MINOR VERSION_PATCH VERSION_NUMBER PKGCFG_LIBDIR PKGCFG_INCDIR PKGNAME VPATH CONTACT CONTACT_NAME CONTACT_MAIL CXX CXXFLAGS LDFLAGS HAVE_LANG_CXX CPP PKGCONFIG HAVE_R2 R2 R2_CFLAGS R2_LDFLAGS HAVE_PKGCFG_R_CORE HAVE_QMAKE QMAKE HAVE_QMAKE6 QMAKE6 WANT_QMAKE6 QMAKE_BIN WANT_PYTHON WANT_PYTHON_BINDINGS WANT_CRASH_REPORTS"
|
||||
|
||||
create_environ
|
||||
|
||||
@@ -302,8 +330,6 @@ ocho "checking for working directories... ${WODIS}"
|
||||
ocho "using prefix '${PREFIX}'"
|
||||
ACR_RMFILES=" test.c test.cxx a.out a.exe"
|
||||
|
||||
|
||||
|
||||
COMPILER=CXX
|
||||
HAVE_LANG_CXX=1
|
||||
ochof "checking for c++ compiler... "
|
||||
@@ -331,6 +357,7 @@ exit 1
|
||||
if [ 0 = 0 ]; then echo ${CPP}; else
|
||||
echo "ERROR: ${CPP} cannot parse sources"; fi
|
||||
ochof "checking for pkg-config... "
|
||||
ENVWORDS="${ENVWORDS} HAVE_PKGCONFIG"
|
||||
if [ -n "$PKGCONFIG" ]; then
|
||||
if [ -x "$PKGCONFIG" ]; then
|
||||
_HAVE_PKGCONFIG="${PKGCONFIG}"
|
||||
@@ -354,7 +381,9 @@ else
|
||||
fi
|
||||
if [ -n "${PKGCONFIG}" ]; then
|
||||
ocho ${PKGCONFIG}
|
||||
HAVE_PKGCONFIG=1
|
||||
else
|
||||
HAVE_PKGCONFIG=0
|
||||
echo "Cannot find pkg-config or pkgconf in PATH" >&2
|
||||
exit 1
|
||||
ocho no; fi
|
||||
@@ -426,18 +455,16 @@ if [ "" = 1 ]; then
|
||||
echo "Cannot find qmake" >&2
|
||||
else
|
||||
echo no
|
||||
fi
|
||||
echo "error: This program is required." >&2
|
||||
exit 1 ; fi
|
||||
ochof "checking for lrelease... "
|
||||
if [ -x "${LRELEASE}" ]; then
|
||||
FIND=${LRELEASE}
|
||||
fi ; fi
|
||||
ochof "checking for qmake6... "
|
||||
if [ -x "${QMAKE6}" ]; then
|
||||
FIND=${QMAKE6}
|
||||
else
|
||||
FIND=""
|
||||
IFS=:
|
||||
for A in ${PATH} ; do
|
||||
if [ -x "${A}/lrelease" ]; then
|
||||
FIND="${A}/lrelease"
|
||||
if [ -x "${A}/qmake6" ]; then
|
||||
FIND="${A}/qmake6"
|
||||
break;
|
||||
fi
|
||||
done
|
||||
@@ -445,18 +472,26 @@ else
|
||||
fi
|
||||
if [ -n "${FIND}" ]; then
|
||||
ocho ${FIND};
|
||||
HAVE_LRELEASE=1
|
||||
LRELEASE=${FIND}
|
||||
HAVE_QMAKE6=1
|
||||
QMAKE6=${FIND}
|
||||
else
|
||||
HAVE_LRELEASE=0
|
||||
LRELEASE=lrelease
|
||||
HAVE_QMAKE6=0
|
||||
QMAKE6=qmake6
|
||||
if [ "" = 1 ]; then
|
||||
echo "Cannot find lrelease" >&2
|
||||
echo "Cannot find qmake6" >&2
|
||||
else
|
||||
echo no
|
||||
fi
|
||||
echo "error: This program is required." >&2
|
||||
exit 1 ; fi
|
||||
fi ; fi
|
||||
if [ "$WANT_QMAKE6" = "1" ]; then
|
||||
if [ "$HAVE_QMAKE6" = "1" ]; then
|
||||
QMAKE_BIN="${QMAKE6}"
|
||||
else
|
||||
case "$undefined_variable" in 0|"") echo ; echo "ERROR: Missing qmake6" >&2 ; echo ; exit 1 ;; esac; fi
|
||||
else
|
||||
if [ "$HAVE_QMAKE" = "1" ]; then
|
||||
QMAKE_BIN="${QMAKE}"; fi; fi
|
||||
if [ "$QMAKE_BIN" = """" ]; then
|
||||
case "$undefined_variable" in 0|"") echo ; echo "ERROR: Missing qmake" >&2 ; echo ; exit 1 ;; esac; fi
|
||||
WANT_PYTHON="0"
|
||||
WANT_PYTHON_BINDINGS="0"
|
||||
WANT_CRASH_REPORTS="0"
|
||||
@@ -466,7 +501,14 @@ for A in ${ENVWORDS} ; do
|
||||
[ "${A}" = VPATH ] && continue
|
||||
[ "${A}" = srcdir ] && continue
|
||||
eval "VAR=\$${A}"
|
||||
VAR="`echo ${VAR} | sed -e 's/\,/\\\,/g'`"
|
||||
case "" in
|
||||
mingw*|cygwin*|msys*)
|
||||
VAR="`echo ${VAR} | sed -e 's/\\/\\\\/g' -e 's/\,/\\\,/g'`"
|
||||
;;
|
||||
*)
|
||||
VAR="`echo ${VAR} | sed -e 's/\,/\\\,/g'`"
|
||||
;;
|
||||
esac
|
||||
[ $COUNT = 10 ] && COUNT=0 && SEDFLAGS="${SEDFLAGS}' -e '"
|
||||
COUNT=$(($COUNT+1))
|
||||
SEDFLAGS="${SEDFLAGS}s,@${A}@,${VAR},g;"
|
||||
@@ -504,3 +546,12 @@ done
|
||||
done
|
||||
|
||||
do_remove
|
||||
if [ "$QUIET" = 0 ]; then
|
||||
echo
|
||||
echo "Final report:"
|
||||
for A in R2 QMAKE_BIN ; do
|
||||
eval VAL="\$${A}"
|
||||
[ -z "${VAL}" ] && VAL="\"\""
|
||||
echo " - ${A} = ${VAL}"
|
||||
done
|
||||
fi
|
||||
@@ -1,5 +1,5 @@
|
||||
PKGNAME iaito
|
||||
VERSION 5.7.6
|
||||
VERSION 6.0.4
|
||||
CONTACT pancake ; [email protected]
|
||||
|
||||
LANG_CXX!
|
||||
@@ -7,8 +7,28 @@ LANG_CXX!
|
||||
USE_PKGCONFIG!
|
||||
CHKPRG! R2 r2
|
||||
PKGCFG! R2_CFLAGS R2_LDFLAGS r_core
|
||||
CHKPRG! QMAKE qmake
|
||||
CHKPRG! LRELEASE lrelease
|
||||
CHKPRG QMAKE qmake
|
||||
CHKPRG QMAKE6 qmake6
|
||||
(( CHKPRG! LRELEASE lrelease ))
|
||||
|
||||
ARG_WITH WANT_QMAKE6 qmake6 ignore qmake in path when qmake6 is found ;
|
||||
|
||||
IFEQ WANT_QMAKE6 1 ; {
|
||||
IFEQ HAVE_QMAKE6 1 ; {
|
||||
QMAKE_BIN = ${QMAKE6} ;
|
||||
}{
|
||||
DIENOW Missing qmake6 ;
|
||||
}
|
||||
}{
|
||||
IFEQ HAVE_QMAKE 1 ; {
|
||||
QMAKE_BIN = ${QMAKE} ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
IFEQ QMAKE_BIN "" ; {
|
||||
DIENOW Missing qmake ;
|
||||
}
|
||||
|
||||
WANT_PYTHON = 0 ;
|
||||
WANT_PYTHON_BINDINGS = 0 ;
|
||||
@@ -20,3 +40,5 @@ ARG_WITH WANT_CRASH_REPORTS crash-reports handle crashes nicely ;
|
||||
))
|
||||
|
||||
SUBDIRS config.mk ;
|
||||
|
||||
REPORT R2 QMAKE_BIN ;
|
||||
@@ -10,7 +10,7 @@ IF !ERRORLEVEL! NEQ 0 (
|
||||
EXIT /B 1
|
||||
)
|
||||
|
||||
SET "R2DIST=r2_dist"
|
||||
SET "R2DIR=radare2"
|
||||
SET "BUILDDIR=build_%PLATFORM%"
|
||||
|
||||
|
||||
@@ -21,6 +21,10 @@ IF NOT EXIST "src\translations\NUL" (
|
||||
FOR %%i in (src\translations\*.ts) DO lrelease %%i
|
||||
|
||||
ECHO Preparing directory
|
||||
rem MOVE radare2 %R2DIR%
|
||||
IF NOT EXIST %BUILDDIR% (
|
||||
MKDIR %BUILDDIR%
|
||||
)
|
||||
CD %BUILDDIR%
|
||||
|
||||
IF NOT DEFINED IAITO_ENABLE_CRASH_REPORTS (
|
||||
@@ -29,4 +33,5 @@ SET "IAITO_ENABLE_CRASH_REPORTS=false"
|
||||
|
||||
ECHO Building iaito
|
||||
qmake BREAKPAD_SOURCE_DIR=%BREAKPAD_SOURCE_DIR% IAITO_ENABLE_CRASH_REPORTS=%IAITO_ENABLE_CRASH_REPORTS% %* ..\src\iaito.pro -config release
|
||||
COPY iaito_resource.rc ..\src
|
||||
IF !ERRORLEVEL! NEQ 0 EXIT /B 1
|
||||
@@ -1,7 +1,7 @@
|
||||
NAME=iaito
|
||||
SECTION=editors
|
||||
PRIORITY=optional
|
||||
DEPENDS=qt5-default libqt5svg5
|
||||
DEPENDS=$(shell ../getpkgversions.sh radare2 libqt5core5a libqt5gui5 libqt5widgets5 libqt5network5 libqt5svg5)
|
||||
MAINTAINER=pancake <[email protected]>
|
||||
ARCH?=amd64
|
||||
VERSION=$(shell ../../../configure -qV)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
for pkg in "$@"
|
||||
do
|
||||
VERSION=$(apt show $pkg 2> /dev/null | grep -F "Version: " | sed -e 's/Version:\s\([[[:digit:]\.]\+\).*/\1/')
|
||||
if [ $pkg != $1 ]; then
|
||||
echo -n ", "
|
||||
fi
|
||||
echo -n "$pkg (>= $VERSION)"
|
||||
done
|
||||
@@ -1,6 +1,5 @@
|
||||
PACKAGE_DIR=$(shell pwd)
|
||||
include ./CONFIG
|
||||
DEPENDS=
|
||||
|
||||
SUDO=fakeroot
|
||||
SUDO=sudo
|
||||
|
||||
@@ -1,8 +1,45 @@
|
||||
all:
|
||||
$(SHELL) make-macos-app.sh
|
||||
.PHONY: all app dmg zip extra clean mrproper
|
||||
|
||||
pkg:
|
||||
$(SHELL) make-macos-pkg.sh
|
||||
all: clean app dmg
|
||||
app: disk/iaito.app
|
||||
dmg: iaito.dmg
|
||||
zip: iaito.zip
|
||||
extra: extra/r2ai
|
||||
|
||||
disk/iaito.app: ../../build/iaito.app radare2-unpkg extra/r2ai
|
||||
mkdir disk
|
||||
cp -a ../../build/iaito.app disk/
|
||||
scripts/embed-radare2.sh radare2-unpkg disk/iaito.app
|
||||
cp -a extra/r2ai/decai/decai.r2.js disk/iaito.app/Contents/Resources/radare2/lib/radare2/last/
|
||||
macdeployqt disk/iaito.app -verbose=2
|
||||
|
||||
iaito.dmg: disk/iaito.app
|
||||
cp doc/README.txt disk/READ_THIS_FIRST.txt
|
||||
ln -fs /Applications disk/
|
||||
hdiutil create -format UDZO -fs APFS -volname iaito -srcfolder disk iaito
|
||||
|
||||
iaito.zip:
|
||||
cp doc/README.txt disk/READ_THIS_FIRST.txt
|
||||
ditto -c -k --rsrc --extattr --sequesterRsrc disk iaito.zip
|
||||
|
||||
radare2-unpkg: radare2.pkg
|
||||
pkgutil --expand-full $< $@
|
||||
|
||||
radare2.pkg:
|
||||
echo "Download first radare2.pkg from https://github.com/radareorg/radare2/releases"
|
||||
@false
|
||||
|
||||
extra/r2ai:
|
||||
mkdir -p extra
|
||||
curl -L "$(shell gh api /repos/radareorg/r2ai/releases/latest --jq .tarball_url)" | tar -xzC extra/
|
||||
cd extra && mv radareorg-r2ai-* r2ai
|
||||
|
||||
../../build/iaito.app:
|
||||
echo "Building iaito..."
|
||||
$(MAKE) -C ../.. QMAKE_FLAGS=IAITO_BUNDLE_R2_APPBUNDLE=true
|
||||
|
||||
clean:
|
||||
rm -rf macos-pkg tmp
|
||||
rm -rf radare2-unpkg disk iaito.dmg
|
||||
|
||||
mrproper: clean
|
||||
rm -rf radare2.pkg extra
|
||||
@@ -1,26 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<installer-gui-script minSpecVersion="2">
|
||||
<title>Iaito</title>
|
||||
<license file="COPYING.LESSER" mime-type="text/plain"/>
|
||||
<pkg-ref id="org.radare.iaito">
|
||||
<bundle-version/>
|
||||
</pkg-ref>
|
||||
<options customize="never" require-scripts="false" hostArchitectures="x86_64,arm64"/>
|
||||
<volume-check>
|
||||
<allowed-os-versions>
|
||||
<os-version min="10.7"/>
|
||||
</allowed-os-versions>
|
||||
</volume-check>
|
||||
<choices-outline>
|
||||
<line choice="default">
|
||||
<line choice="org.radare.iaito"/>
|
||||
</line>
|
||||
</choices-outline>
|
||||
<choice id="default" customLocation="usr"/>
|
||||
<choice id="org.radare.iaito" visible="false">
|
||||
<pkg-ref id="org.radare.iaito"/>
|
||||
</choice>
|
||||
<pkg-ref id="org.radare.iaito" version="0" onConclusion="none" installKBytes="51182">#iaito.pkg</pkg-ref>
|
||||
<welcome file="welcome.rtf" mime-type="text/enriched"/>
|
||||
<background file="iaitologo.png" mime-type="image/png" alignment="bottomleft"/>
|
||||
</installer-gui-script>
|
||||
@@ -1,674 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
@@ -1,165 +0,0 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
|
Before Width: | Height: | Size: 33 KiB |
@@ -1,13 +0,0 @@
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf210
|
||||
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\margl1440\margr1440\vieww10800\viewh6300\viewkind0
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural
|
||||
|
||||
\f0\fs28 \cf0 \
|
||||
\
|
||||
You will be guided through the steps necessary to\
|
||||
install this software. This pkg requires radare2 to\
|
||||
be installed in your system. \
|
||||
\
|
||||
This will install Iaito in /usr/local}
|
||||
@@ -0,0 +1,7 @@
|
||||
IMPORTANT!
|
||||
|
||||
To install iaito you can drag and drop the application to /Applications.
|
||||
But then you are required to run this commands from Terminal before you can execute for the first time.
|
||||
|
||||
sudo xattr -c /Applications/iaito.app
|
||||
sudo codesign --force --deep --sign - /Applications/iaito.app
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.debugger</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.disable-library-validation</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.allow-jit</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,50 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
SKIPBUILD=0
|
||||
|
||||
SRC=/tmp/iaito-macos
|
||||
PREFIX=/usr/local
|
||||
DST="$(pwd)/tmp/iaito.unpkg"
|
||||
if [ -n "$1" ]; then
|
||||
VERSION="$1"
|
||||
else
|
||||
VERSION="`../../configure -qV`"
|
||||
[ -z "${VERSION}" ] && VERSION=5.3.l
|
||||
fi
|
||||
|
||||
[ -z "${MAKE}" ] && MAKE=make
|
||||
|
||||
while : ; do
|
||||
[ -x "$PWD/configure" ] && break
|
||||
[ "$PWD" = / ] && break
|
||||
cd ..
|
||||
done
|
||||
|
||||
[ ! -x "$PWD/configure" ] && exit 1
|
||||
|
||||
pwd
|
||||
if [ ! -d build/iaito.app ]; then
|
||||
rm -rf "${SRC}"
|
||||
${MAKE} mrproper 2>/dev/null
|
||||
# ${MAKE} -j4 || exit 1
|
||||
fi
|
||||
export CFLAGS=-O2
|
||||
if [ "$SKIPBUILD" = 0 ]; then
|
||||
./configure --prefix="${PREFIX}" || exit 1
|
||||
fi
|
||||
${MAKE} install install-translations PREFIX="${PREFIX}" DESTDIR=${SRC} || exit 1
|
||||
mkdir -p "${DST}"
|
||||
echo "DST=$DST"
|
||||
if [ -d "${SRC}" ]; then
|
||||
(
|
||||
cd ${SRC} && find .
|
||||
mv usr/local/share/iaito/translations Applications/iaito.app/Contents/Resources || exit 1
|
||||
cd Applications || exit 1
|
||||
rm -f /tmp/iaito-${VERSION}.zip
|
||||
zip -r /tmp/iaito-${VERSION}.zip iaito.app
|
||||
)
|
||||
mv /tmp/iaito-${VERSION}.zip dist/macos
|
||||
else
|
||||
echo "Failed install. DESTDIR is empty"
|
||||
exit 1
|
||||
fi
|
||||
@@ -1,57 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# based on
|
||||
# http://blog.coolaj86.com/articles/how-to-unpackage-and-repackage-pkg-macos.html
|
||||
|
||||
# to uninstall:
|
||||
# sudo pkgutil --forget org.radare.iaito
|
||||
SKIPBUILD=0
|
||||
|
||||
SRC=/tmp/iaito-macos
|
||||
PREFIX=/usr/local
|
||||
DST="$(pwd)/tmp/iaito.unpkg"
|
||||
if [ -n "$1" ]; then
|
||||
VERSION="$1"
|
||||
else
|
||||
VERSION="`../../configure -qV`"
|
||||
[ -z "${VERSION}" ] && VERSION=5.3.l
|
||||
fi
|
||||
|
||||
[ -z "${MAKE}" ] && MAKE=make
|
||||
|
||||
while : ; do
|
||||
[ -x "$PWD/configure" ] && break
|
||||
[ "$PWD" = / ] && break
|
||||
cd ..
|
||||
done
|
||||
|
||||
[ ! -x "$PWD/configure" ] && exit 1
|
||||
|
||||
pwd
|
||||
if [ ! -d build/iaito.app ]; then
|
||||
rm -rf "${SRC}"
|
||||
${MAKE} mrproper 2>/dev/null
|
||||
# ${MAKE} -j4 || exit 1
|
||||
fi
|
||||
export CFLAGS=-O2
|
||||
if [ "$SKIPBUILD" = 0 ]; then
|
||||
./configure --prefix="${PREFIX}" || exit 1
|
||||
fi
|
||||
${MAKE} install install-translations PREFIX="${PREFIX}" DESTDIR=${SRC} || exit 1
|
||||
mkdir -p "${DST}"
|
||||
echo "DST=$DST"
|
||||
if [ -d "${SRC}" ]; then
|
||||
(
|
||||
cd ${SRC} && \
|
||||
find . | cpio -o --format odc | gzip -c > "${DST}/Payload"
|
||||
)
|
||||
echo mkbom "${SRC}" "${DST}/Bom"
|
||||
mkbom "${SRC}" "${DST}/Bom"
|
||||
cp -rf dist/macos/Metadata/* "${DST}"
|
||||
pwd
|
||||
# Repackage
|
||||
pkgutil --flatten "${DST}" "${DST}/../../iaito-${VERSION}.pkg"
|
||||
else
|
||||
echo "Failed install. DESTDIR is empty"
|
||||
exit 1
|
||||
fi
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
|
||||
CMD=$(basename "$0")
|
||||
APPDIR=$(cd "$(dirname "$0")/../../../.."; pwd)
|
||||
|
||||
R2_BINDIR="${APPDIR}/Contents/Helpers"
|
||||
R2_LIBDIR="${APPDIR}/Contents/Frameworks"
|
||||
R2_PREFIX="${APPDIR}/Contents/Resources/radare2"
|
||||
|
||||
XDG_CACHE_HOME="${HOME}/Library/Caches/radareorg/iaito"
|
||||
XDG_CONFIG_HOME="${HOME}/Library/Preferences/radareorg/iaito"
|
||||
XDG_DATA_HOME="${HOME}/Library/Application Support/radareorg/iaito"
|
||||
|
||||
export R2_BINDIR
|
||||
export R2_LIBDIR
|
||||
export R2_PREFIX
|
||||
export XDG_CACHE_HOME
|
||||
export XDG_CONFIG_HOME
|
||||
export XDG_DATA_HOME
|
||||
|
||||
exec "${R2_BINDIR}/${CMD}" "$@"
|
||||
@@ -0,0 +1,72 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
R2PKGDIR="$1"
|
||||
APPDIR="$2"
|
||||
|
||||
SCRIPTS="$(dirname "$0")"
|
||||
R2DIR="${R2PKGDIR}/Payload/usr/local"
|
||||
R2V=$(readlink "${R2DIR}/lib/radare2/last")
|
||||
|
||||
fix_binary() {
|
||||
FILE=$1
|
||||
PREFIX=$2
|
||||
shift 2
|
||||
echo "Change library paths for \"$FILE\"..."
|
||||
ARGS=$(otool -L "$FILE" | awk 'BEGIN{ORS=" "}/\/usr\/local\/lib\/libr_/{dst=$1; sub(/\/usr\/local\/lib/,"'"$PREFIX"'", dst); print "-change "$1" "dst}')
|
||||
if [ -n "$ARGS" -o -n "$1" ]; then
|
||||
echo " install_name_tool $@ $ARGS \"$FILE\""
|
||||
install_name_tool $@ $ARGS "$FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
mkdir -p \
|
||||
"${APPDIR}/Contents/Helpers" \
|
||||
"${APPDIR}/Contents/Frameworks" \
|
||||
"${APPDIR}/Contents/PlugIns/radare2" \
|
||||
"${APPDIR}/Contents/Resources/radare2/bin" \
|
||||
"${APPDIR}/Contents/Resources/radare2/lib/radare2/${R2V}/"
|
||||
|
||||
cp -a "${R2DIR}/bin/"* "${APPDIR}/Contents/Helpers/"
|
||||
cp -a "${R2DIR}/lib/radare2/${R2V}/"*.dylib "${APPDIR}/Contents/PlugIns/radare2/"
|
||||
cp -a "${R2DIR}/lib/"*.dylib "${APPDIR}/Contents/Frameworks/"
|
||||
cp -a "${R2DIR}/include" "${APPDIR}/Contents/Resources/radare2/"
|
||||
cp -a "${R2DIR}/share" "${APPDIR}/Contents/Resources/radare2/"
|
||||
#cp -a "${R2DIR}/lib/pkgconfig" "${APPDIR}/Contents/Resources/radare2/lib/"
|
||||
cp -p "${SCRIPTS}/command.sh" "${APPDIR}/Contents/Resources/radare2/bin/radare2"
|
||||
cp -a "${R2DIR}/lib/radare2/last" "${APPDIR}/Contents/Resources/radare2/lib/radare2/"
|
||||
#cp -a "${R2DIR}/lib/radare2/${R2V}/"*.js "${APPDIR}/Contents/Resources/radare2/lib/radare2/${R2V}/"
|
||||
|
||||
(
|
||||
cd "${APPDIR}/Contents/MacOS"
|
||||
fix_binary "iaito" "@rpath"
|
||||
)
|
||||
|
||||
(
|
||||
cd "${APPDIR}/Contents/Helpers"
|
||||
for c in *; do
|
||||
[ -L "$c" ] || fix_binary "$c" "@rpath" -add_rpath "@executable_path/../Frameworks"
|
||||
[ "$c" != "radare2" ] && ln -s radare2 "../Resources/radare2/bin/$c"
|
||||
done
|
||||
)
|
||||
|
||||
(
|
||||
LIBS=$(cd "${R2DIR}/lib"; ls *.dylib)
|
||||
cd "${APPDIR}/Contents/Frameworks"
|
||||
for c in $LIBS; do
|
||||
[ -L "$c" ] || fix_binary "$c" "@loader_path" -id "@rpath/$c"
|
||||
c2=$c # Resolve upto 2 link levels
|
||||
[ -L "$c2" ] && c2=$(readlink "$c2")
|
||||
[ -L "$c2" ] && c2=$(readlink "$c2")
|
||||
ln -s "../../../Frameworks/$c2" "../Resources/radare2/lib/$c"
|
||||
done
|
||||
)
|
||||
|
||||
(
|
||||
cd "${APPDIR}/Contents/PlugIns/radare2"
|
||||
for c in *.dylib; do
|
||||
[ -L "$c" ] || fix_binary "$c" "@rpath" -add_rpath "@loader_path/../../Frameworks" -id "$c"
|
||||
ln -s "../../../../../PlugIns/radare2/$c" "../../Resources/radare2/lib/radare2/${R2V}/$c"
|
||||
done
|
||||
# Required for plugins rpath when loaded from Resources
|
||||
ln -s "../../../Frameworks" "../../Resources/radare2/lib/Frameworks"
|
||||
)
|
||||
@@ -1,24 +1,30 @@
|
||||
SET "R2DIST=r2_dist"
|
||||
SET "R2DIR=radare2"
|
||||
SET "BUILDDIR=build_%PLATFORM%"
|
||||
|
||||
ECHO Preparing directory
|
||||
RMDIR /S /Q %BUILDDIR%
|
||||
MKDIR %BUILDDIR%
|
||||
CD src
|
||||
meson ..\release
|
||||
CD ..\release
|
||||
ninja -v -j1
|
||||
REM IF !ERRORLEVEL! NEQ 0 EXIT /B 1
|
||||
meson --buildtype=release %* ..\%BUILDDIR%
|
||||
CD ..\%BUILDDIR%
|
||||
ninja -j4
|
||||
if %ERRORLEVEL% NEQ 0 (
|
||||
EXIT /B 1
|
||||
)
|
||||
CD ..
|
||||
|
||||
ECHO Deploying iaito
|
||||
MKDIR iaito
|
||||
COPY release\iaito.exe iaito\iaito.exe
|
||||
XCOPY /S /I ..\%R2DIST%\share iaito\share
|
||||
XCOPY /S /I ..\%R2DIST%\lib iaito\lib
|
||||
DEL iaito\lib\*.lib
|
||||
COPY ..\%R2DIST%\bin\*.dll iaito\
|
||||
windeployqt iaito\iaito.exe
|
||||
FOR %%i in (..\src\translations\*.qm) DO MOVE "%%~fi" iaito\translations
|
||||
IF NOT EXIST release (
|
||||
MKDIR release
|
||||
)
|
||||
COPY %BUILDDIR%\iaito.exe release\iaito.exe
|
||||
XCOPY /S /I %R2DIR%\share release\share
|
||||
XCOPY /S /I %R2DIR%\lib release\lib
|
||||
DEL release\lib\*.lib
|
||||
COPY %R2DIR%\bin\*.dll release\
|
||||
windeployqt release\iaito.exe
|
||||
FOR %%i in (..\src\translations\*.qm) DO MOVE "%%~fi" release\translations
|
||||
|
||||
IF DEFINED CI (
|
||||
RENAME release iaito
|
||||
)
|
||||
|
||||
ENDLOCAL
|
||||
@@ -1,6 +1,6 @@
|
||||
@ECHO OFF
|
||||
|
||||
SET "R2V=5.7.0"
|
||||
IF NOT DEFINED R2V SET "R2V=5.8.8"
|
||||
SET ARCH=x64
|
||||
|
||||
SETLOCAL ENABLEDELAYEDEXPANSION
|
||||
@@ -14,24 +14,22 @@ IF !ERRORLEVEL! NEQ 0 (
|
||||
)
|
||||
|
||||
SET "PATH=%CD%;%PATH%"
|
||||
SET "R2DIST=r2_dist"
|
||||
SET "R2DIR=radare2"
|
||||
|
||||
IF NOT DEFINED CI (
|
||||
ECHO Downloading radare2 (%PLATFORM%)
|
||||
rem powershell -command "Invoke-WebRequest 'https://github.com/radareorg/radare2/releases/download/5.1.0/radare2-5.1.0_windows.zip' -OutFile 'radare2-5.1.0_windows.zip'"
|
||||
pip install wget
|
||||
python -m wget -o r2.zip https://github.com/radareorg/radare2/releases/download/%R2V%/radare2-%R2V%-w64.zip
|
||||
curl -L -o r2.zip https://github.com/radareorg/radare2/releases/download/%R2V%/radare2-%R2V%-w64.zip
|
||||
unzip r2.zip
|
||||
RENAME radare2-%R2V%-w64 radare2
|
||||
RMDIR /S /Q %R2DIST%
|
||||
MOVE radare2-%R2V%-w64 %R2DIST%
|
||||
SET "PATH=%CD%\%R2DIST%\bin;%PATH%"
|
||||
RENAME radare2-%R2V%-w64 %R2DIR%
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" %ARCH%
|
||||
)
|
||||
SET "PATH=%CD%\%R2DIR%\bin;%PATH%"
|
||||
|
||||
rem ECHO Building radare2 (%PLATFORM%)
|
||||
rem CD radare2
|
||||
rem git clean -xfd
|
||||
rem RMDIR /S /Q ..\%R2DIST%
|
||||
rem RMDIR /S /Q ..\%R2DIR%
|
||||
rem meson -C src r2_builddir
|
||||
rem meson.exe r2_builddir --buildtype=release --prefix=%CD%\..\%R2DIST% || EXIT /B 1
|
||||
rem meson.exe r2_builddir --buildtype=release --prefix=%CD%\..\%R2DIR% || EXIT /B 1
|
||||
rem ninja -C r2_builddir install || EXIT /B 1
|
||||
rem IF !ERRORLEVEL! NEQ 0 EXIT /B 1
|
||||
|
After Width: | Height: | Size: 138 KiB |
|
After Width: | Height: | Size: 175 KiB |
|
After Width: | Height: | Size: 138 KiB |
|
After Width: | Height: | Size: 143 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
@@ -1,59 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
if ! [[ $# -eq 3 ]]; then
|
||||
echo "Usage: $0 [Python.framework] [AppBundle.app] [AppBundle.app/Contents/MacOS/Executable]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
python_version=python3.6
|
||||
|
||||
py_framework=$1
|
||||
appbundle=$2
|
||||
executable=$3
|
||||
|
||||
echo "Embedding $py_framework into $appbundle | $executable"
|
||||
|
||||
mkdir -p "$appbundle/Contents/Frameworks"
|
||||
if [ ! -d "$appbundle/Contents/Frameworks/Python.framework" ]
|
||||
then
|
||||
cp -a -n "$py_framework" "$appbundle/Contents/Frameworks/"
|
||||
echo "Cleaning up embedded Python Framework"
|
||||
cd "$appbundle/Contents/Frameworks/Python.framework"
|
||||
find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf
|
||||
rm -r Versions/Current/Resources/* "Versions/Current/lib/$python_version/test" "Versions/Current/lib/$python_version/idlelib" "Versions/Current/lib/$python_version/curses" "Versions/Current/lib/$python_version/lib2to3" || echo "Couldn't remove something"
|
||||
else
|
||||
echo "Python.framework already exists, skipping copying"
|
||||
cd "$appbundle/Contents/Frameworks/Python.framework"
|
||||
fi
|
||||
|
||||
echo "Making executable $executable point to embedded Framework"
|
||||
install_name_tool -change `otool -L "$executable" | sed -n "s/^[[:blank:]]*\([^[:blank:]]*Python\) (.*$/\1/p"` @executable_path/../Frameworks/Python.framework/Versions/Current/Python "$executable"
|
||||
|
||||
<<<<<<< HEAD:scripts/appbundle_embed_python.sh
|
||||
echo "Cleaning up embedded Python Framework"
|
||||
cd "$appbundle/Contents/Frameworks/Python.framework" || exit 1
|
||||
find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf || exit 1
|
||||
rm -r Versions/Current/Resources/* Versions/Current/lib/python3.6/test Versions/Current/lib/python3.6/idlelib Versions/Current/lib/python3.6/curses Versions/Current/lib/python3.6/lib2to3 || exit 1
|
||||
|
||||
=======
|
||||
>>>>>>> 29cbd06a... Run macos packaging in GHA. (#2529):dist/appbundle_embed_python.sh
|
||||
echo "Checking if PySide2 is available"
|
||||
|
||||
pyside_prefix=$(pkg-config --variable=prefix pyside2)
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "PySide2 is not available, ignoring."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "PySide is at $pyside_prefix"
|
||||
|
||||
if [ ! -d "Versions/Current/lib/$python_version/site-packages/PySide2" ]
|
||||
then
|
||||
cp -va "$pyside_prefix/lib/$python_version/" "Versions/Current/lib/$python_version"
|
||||
cd .. # $appbundle/Contents/Frameworks
|
||||
cp -va "$pyside_prefix/lib/"*.dylib .
|
||||
else
|
||||
echo "site-packages/Pyside2 exists, skipping copying"
|
||||
fi
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
if ! [[ $# -eq 1 ]]; then
|
||||
echo "Usage: $0 [AppBundle.app]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
appbundle=$1
|
||||
qtwebegineprocess="$1/Contents/Frameworks/QtWebEngineCore.framework/Helpers/QtWebEngineProcess.app/Contents/MacOS/QtWebEngineProcess"
|
||||
|
||||
echo "Patching $appbundle to fix QtWebEngine"
|
||||
|
||||
if ! [[ -f "$qtwebegineprocess" ]]; then
|
||||
echo "$qtwebegineprocess does not exist. Did you forget to run macdeployqt?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
install_name_tool `otool -L "$qtwebegineprocess" | sed -n "s/^[[:blank:]]*\(\/usr\/local\/Cellar[^[:blank:]]*\(Qt[A-Za-z]*\.framework[^[:blank:]]*\)\) (.*$/-change \1 @executable_path\/..\/..\/..\/..\/..\/..\/..\/\2/p"` \
|
||||
$1/Contents/Frameworks/QtWebEngineCore.framework/Helpers/QtWebEngineProcess.app/Contents/MacOS/QtWebEngineProcess \
|
||||
|| exit 1
|
||||
|
||||
mkdir -p $1/Contents/Frameworks/QtWebEngineCore.framework/Helpers/QtWebEngineProcess.app/Contents/Frameworks
|
||||
ln -s ../../../../../../../QtCore.framework $1/Contents/Frameworks/QtWebEngineCore.framework/Helpers/QtWebEngineProcess.app/Contents/Frameworks/
|
||||
ln -s ../../../../../../../QtQuick.framework $1/Contents/Frameworks/QtWebEngineCore.framework/Helpers/QtWebEngineProcess.app/Contents/Frameworks/
|
||||
ln -s ../../../../../../../QtGui.framework $1/Contents/Frameworks/QtWebEngineCore.framework/Helpers/QtWebEngineProcess.app/Contents/Frameworks/
|
||||
ln -s ../../../../../../../QtQml.framework $1/Contents/Frameworks/QtWebEngineCore.framework/Helpers/QtWebEngineProcess.app/Contents/Frameworks/
|
||||
ln -s ../../../../../../../QtNetwork.framework $1/Contents/Frameworks/QtWebEngineCore.framework/Helpers/QtWebEngineProcess.app/Contents/Frameworks/
|
||||
ln -s ../../../../../../../QtWebChannel.framework $1/Contents/Frameworks/QtWebEngineCore.framework/Helpers/QtWebEngineProcess.app/Contents/Frameworks/
|
||||
ln -s ../../../../../../../QtPositioning.framework $1/Contents/Frameworks/QtWebEngineCore.framework/Helpers/QtWebEngineProcess.app/Contents/Frameworks/
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
if ! [[ $# -eq 1 ]]; then
|
||||
echo "Usage: $0 [appdir]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
python_version=python3.6
|
||||
|
||||
python_prefix=$(pkg-config --variable=prefix python3)
|
||||
appdir=$1
|
||||
|
||||
echo "Embedding Python from prefix $python_prefix in appdir $appdir"
|
||||
|
||||
mkdir -p "$appdir/usr"
|
||||
cd "$appdir/usr/" || exit 1
|
||||
|
||||
cp -RT "$python_prefix" "." || exit 1
|
||||
echo "Cleaning up embedded Python"
|
||||
find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf
|
||||
rm -r lib/$python_version/test lib/$python_version/idlelib lib/$python_version/curses lib/$python_version/lib2to3
|
||||
|
||||
echo "Checking if PySide2 is available"
|
||||
|
||||
pyside_prefix=$(pkg-config --variable=prefix pyside2)
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "PySide2 is not available, ignoring."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "PySide is at $pyside_prefix"
|
||||
|
||||
if [ "$pyside_prefix" == "$python_prefix" ]; then
|
||||
echo "Prefixes are equal, not copying anything from lib"
|
||||
else
|
||||
cp -RT "$pyside_prefix/lib/$python_version" "lib/$python_version" || exit 1
|
||||
fi
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
scripts/r2ghidra.sh \
|
||||
-DCMAKE_C_COMPILER=cl \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_PREFIX_PATH="$APPVEYOR_BUILD_FOLDER/r2_dist;$APPVEYOR_BUILD_FOLDER/r2_dist/include/libr;$APPVEYOR_BUILD_FOLDER/r2_dist/include/libr/sdb" \
|
||||
-DCMAKE_INSTALL_PREFIX="$APPVEYOR_BUILD_FOLDER/r2_dist" \
|
||||
-DRADARE2_INSTALL_PLUGDIR="$APPVEYOR_BUILD_FOLDER/r2_dist/lib/plugins" \
|
||||
-DBUILD_SLEIGH_PLUGIN=OFF
|
||||
@@ -1,8 +1,10 @@
|
||||
# This script is deprecated and it is not going to work
|
||||
# But it's kept for future work towards supporting it again
|
||||
$dist = $args[0]
|
||||
$python = Split-Path((Get-Command python.exe).Path)
|
||||
|
||||
if (-not (Test-Path -Path 'r2dec-js' -PathType Container)) {
|
||||
git clone https://github.com/radareorg/r2dec-js.git --branch master --depth 1
|
||||
git clone https://github.com/wargio/r2dec-js.git --branch master --depth 1
|
||||
}
|
||||
cd r2dec-js
|
||||
#git checkout b5a0d15c7bcc488f268ffb0931b7ced2919f6c9d
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
'includes': [
|
||||
'../../../build/common.gypi',
|
||||
],
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'dump_syms',
|
||||
'type': 'executable',
|
||||
'sources': [
|
||||
'dump_syms.cc',
|
||||
],
|
||||
'dependencies': [
|
||||
'../../../common/windows/common_windows.gyp:common_windows_lib',
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ ! $# -eq 2 ]; then
|
||||
echo "usage: $0 [Iaito.app] [dst]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
appbundle="$1"
|
||||
dst="$2"
|
||||
files="$appbundle/Contents/MacOS/Iaito.bin $appbundle/Contents/Frameworks/Python.framework/Python $(find "$appbundle" -type f -name '*.dylib')"
|
||||
|
||||
mkdir -p "$dst" || exit 1
|
||||
|
||||
for file in $files; do
|
||||
echo "Dumping syms from $file"
|
||||
dump_syms "$file" > "$dst/tmp.sym" || echo "Failed to dump syms from $file"
|
||||
infoline=($(head -n1 "$dst/tmp.sym"))
|
||||
id=${infoline[3]}
|
||||
name=${infoline[4]}
|
||||
dir="$dst/$name/$id"
|
||||
mkdir -p "$dir"
|
||||
mv "$dst/tmp.sym" "$dir/$name.sym"
|
||||
done
|
||||
|
||||
echo "Done"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
FROM ubuntu:24.04
|
||||
RUN apt-get update && apt-get install -y clang-format
|
||||
WORKDIR /project
|
||||
ENTRYPOINT ["clang-format"]
|
||||
@@ -0,0 +1,2 @@
|
||||
all:
|
||||
docker build -t clang-format-image .
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import re
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# This script parses the commit messages between the last 2 git tags
|
||||
# if the last commit contains the word "Release", otherwise it shows
|
||||
# all the changes between the last tag and HEAD.
|
||||
#
|
||||
# Commits are grouped in different sections specified in the commit
|
||||
# message with the middle-dot character '·'. The section names are
|
||||
# arbitrary and we may be careful to use them properly but having
|
||||
# in mind that this may change.
|
||||
#
|
||||
# Commits without any middle·dot in the message are discarted and
|
||||
# displayed in the "to review" section.
|
||||
#
|
||||
# The tool prints Markdown, no plans to support other formats.
|
||||
#
|
||||
# Usage: sys/release-notes.sh 4.5.1 # from HEAD to 4.5.1
|
||||
# $ sys/release-notes.sh 4.5.1 -v # same as above but include untagged commits
|
||||
# $ sys/release-notes.sh 4.5.0 4.5.1 # from 4.5.0 to 4.5.1
|
||||
#
|
||||
# --pancake
|
||||
|
||||
if [ -n "`git log -n 1 | grep Release`" ]; then
|
||||
VERS=`git tag --sort=committerdate | grep -v conti | tail -n 1`
|
||||
PREV=`git tag --sort=committerdate | grep -v conti | tail -n 2 | head -n1`
|
||||
else
|
||||
VERS=HEAD
|
||||
PREV=`git tag --sort=committerdate | grep -v conti | tail -n 1`
|
||||
fi
|
||||
|
||||
[ -n "$1" ] && PREV="$1"
|
||||
[ -n "$2" ] && VERS="$2"
|
||||
|
||||
git log ${PREV}..${VERS} > .l
|
||||
# When HEAD contains a tag do this magic
|
||||
if [ ! -s .l ]; then
|
||||
VERS=$PREV
|
||||
PREV=`git tag --sort=committerdate | grep -v conti | tail -n 2 | head -n1`
|
||||
git log ${PREV}..${VERS} > .l
|
||||
fi
|
||||
grep ^Author .l | cut -d : -f 2- | sed -e 's,radare,pancake,' | sort -u > .A
|
||||
|
||||
echo "## Release Notes"
|
||||
echo
|
||||
echo "Version: ${VERS} (previous: ${PREV})"
|
||||
N=`grep ^commit .l | wc -l`
|
||||
echo "Commits: $N from `wc -l .A | awk '{print $1}'` contributors"
|
||||
echo
|
||||
echo "Release builds (binary assets below) are considered work-in-progress, use flatpak or your distro packaging if anything is not working"
|
||||
echo
|
||||
echo "## Flatpak (WSL / Linux)"
|
||||
echo
|
||||
echo "\`\`\`sh"
|
||||
echo "sudo flatpak remote-add flathub https://dl.flathub.org/repo/flathub.flatpakrepo"
|
||||
echo "sudo flatpak install flathub org.radare.iaito"
|
||||
echo "flatpak run org.radare.iaito"
|
||||
echo "\`\`\`"
|
||||
echo
|
||||
echo "## Build from Source"
|
||||
echo
|
||||
echo "\`\`\`sh"
|
||||
echo "curl -sL https://github.com/radareorg/iaito/archive/refs/tags/${VERS}.tar.gz | tar xzv"
|
||||
echo "iaito-${VERS}/sys/install.sh"
|
||||
echo "\`\`\`"
|
||||
echo
|
||||
echo "## Highlights"
|
||||
|
||||
echo "<details><summary>More details</summary><p>"
|
||||
echo
|
||||
echo "## Authors"
|
||||
echo
|
||||
cat .A | perl -ne '/([^<]+)(.*)$/;$a=$1;$b=$2;$a=~s/^\s+|\s+$//g;$b=~s/[<>\s]//g;print "[$a](mailto:$b) "'
|
||||
echo
|
||||
echo
|
||||
|
||||
cat .x | grep -v '##' | sed -e 's,^ *,,g' | grep -v "^$" | \
|
||||
perl -ne 'if (/^\*/) { print "$_"; } else { print "* $_";}'
|
||||
|
||||
# echo "## Changes"
|
||||
# echo
|
||||
# cat .l | grep -v ^commit | grep -v ^Author | grep -v ^Date > .x
|
||||
# cat .x | grep '##' | perl -ne '/##([^ ]*)/; if ($1) {print "$1\n";}' | sort -u > .y
|
||||
# for a in `cat .y` ; do
|
||||
# echo "**$a**"
|
||||
# echo
|
||||
# cat .x | grep "##$a" | sed -e 's/##.*//g' | perl -ne '{ s/^\s+//; print "* $_"; }'
|
||||
# echo
|
||||
# done
|
||||
# rm -f .x .y .l .A
|
||||
|
||||
echo '</p></details>'
|
||||
@@ -1,64 +0,0 @@
|
||||
# Copyright 2019 Wason Technology, LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
if [ $# -eq 0 ]
|
||||
then
|
||||
echo "No bat file specified"
|
||||
return
|
||||
fi
|
||||
|
||||
#echo `dirname "$(readlink -f "$_")"`
|
||||
___update_env_func___() {
|
||||
tmpbat=$(mktemp --suffix .bat)
|
||||
rc=$?; if [[ $rc != 0 ]]; then
|
||||
echo "Could not create temporary bat file"
|
||||
return $rc
|
||||
fi
|
||||
|
||||
echo "@echo off " >> $tmpbat
|
||||
echo "call \"$@\" 1>&2 " >> $tmpbat
|
||||
echo "if %errorlevel% neq 0 exit /b %errorlevel%" >> $tmpbat
|
||||
echo "printenv " >> $tmpbat
|
||||
echo "if %errorlevel% neq 0 exit /b %errorlevel%" >> $tmpbat
|
||||
rc=$?; if [[ $rc != 0 ]]; then
|
||||
echo "Could not write temporary bat file"
|
||||
return $rc
|
||||
fi
|
||||
|
||||
tmpbat_win=$(basename $tmpbat)
|
||||
env_data=$(cmd "/c call %TEMP%\\$tmpbat_win ")
|
||||
rc=$?; if [[ $rc != 0 ]]; then
|
||||
echo "Could not run temporary bat file"
|
||||
return $rc
|
||||
fi
|
||||
|
||||
echo
|
||||
echo
|
||||
echo
|
||||
|
||||
#Space at the end is lost for some reason,
|
||||
#save and restore PS1
|
||||
ps1_old=$PS1
|
||||
|
||||
while read -r line; do
|
||||
echo "export $line"
|
||||
export "$line"
|
||||
done <<< "$env_data"
|
||||
|
||||
export PS1="$ps1_old"
|
||||
}
|
||||
|
||||
___update_env_func___ $@
|
||||
unset -f ___update_env_func___
|
||||
cd `pwd`
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
a="$1"
|
||||
b="$2"
|
||||
if [ -z "$a" ]; then
|
||||
echo "Usage: sys/subst.sh [old] [new]"
|
||||
exit 1
|
||||
fi
|
||||
#[ -z "$a" ] && a="r_str_chop "
|
||||
#[ -z "$b" ] && b="r_str_trim "
|
||||
WHERE="src"
|
||||
git grep "$a" ${WHERE} | less -R
|
||||
if [ -n "$b" ]; then
|
||||
FILES=`git grep "$a" ${WHERE} | cut -d : -f 1 | uniq `
|
||||
for f in $FILES ; do
|
||||
echo "Sedded $a"
|
||||
sed -e "s/$a/$b/g" < $f > $f.sub
|
||||
mv $f.sub $f
|
||||
done
|
||||
else
|
||||
echo "Oops"
|
||||
fi
|
||||
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env python
|
||||
import xml.etree.ElementTree as ET
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
def remove_lines_with_dashes(input_string):
|
||||
lines = input_string.splitlines()
|
||||
filtered_lines = [line for line in lines if "----------" not in line]
|
||||
return "\n".join(filtered_lines).strip()
|
||||
|
||||
# Define the translation function
|
||||
def translate_text(input_text, existing_translation, language):
|
||||
"""
|
||||
Calls an external program to translate the input text, using existing translation if provided.
|
||||
|
||||
Args:
|
||||
input_text (str): The text to translate.
|
||||
existing_translation (str): The existing translation to provide context.
|
||||
|
||||
Returns:
|
||||
str: The translated text.
|
||||
"""
|
||||
inspiration = ""
|
||||
if existing_translation and existing_translation != "":
|
||||
inspiration = ". Take this original text as inspiration: '"+existing_translation+"'"
|
||||
try:
|
||||
# Replace 'translation_program' with the actual program/command
|
||||
process = subprocess.Popen(
|
||||
['/usr/local/bin/ai', '--', '"translate this sentence to '+language+', the output must be just the text, the context for this translation is the Iaito program, which is the graphical interface for radare2, a reverse engineering tool for analyzing and debugging programs'+inspiration+'"'],
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True
|
||||
)
|
||||
print('"translate this sentence to '+language+', the output must be just the text, the context for this translation is the Iaito program, which is the graphical interface for radare2, a reverse engineering tool for analyzing and debugging programs'+inspiration+'"')
|
||||
input_data = f"{input_text}"
|
||||
stdout, stderr = process.communicate(input=input_data)
|
||||
|
||||
if process.returncode != 0:
|
||||
raise RuntimeError(f"Translation program error: {stderr.strip()}")
|
||||
|
||||
print(stdout)
|
||||
return remove_lines_with_dashes(stdout)
|
||||
except Exception as e:
|
||||
print(f"Error during translation: {e}", file=sys.stderr)
|
||||
return input_text # Fallback to the original text if an error occurs
|
||||
|
||||
# Define the function to find existing translation
|
||||
def find_existing_translation(existing_tree, source_text):
|
||||
"""
|
||||
Finds the translation for a given source text in an existing .ts file.
|
||||
|
||||
Args:
|
||||
existing_tree (ElementTree): Parsed XML tree of the existing .ts file.
|
||||
source_text (str): The source text to look for.
|
||||
|
||||
Returns:
|
||||
str: The existing translation if found, else an empty string.
|
||||
"""
|
||||
for context in existing_tree.findall('context'):
|
||||
for message in context.findall('message'):
|
||||
source = message.find('source')
|
||||
translation = message.find('translation')
|
||||
if source is not None and source.text == source_text and translation is not None:
|
||||
return translation.text
|
||||
return ""
|
||||
|
||||
# Define the main function to parse and modify the XML file
|
||||
def process_ts_file(input_file, output_file, existing_file, language):
|
||||
"""
|
||||
Parses the .ts file, adds a <translation> node with translated content, and writes the output.
|
||||
|
||||
Args:
|
||||
input_file (str): Path to the input .ts file.
|
||||
output_file (str): Path to save the modified .ts file.
|
||||
existing_file (str): Path to an existing .ts file to find previous translations.
|
||||
"""
|
||||
tree = ET.parse(input_file)
|
||||
root = tree.getroot()
|
||||
|
||||
existing_tree = ET.parse(existing_file)
|
||||
|
||||
for context in root.findall('context'):
|
||||
for message in context.findall('message'):
|
||||
source = message.find('source')
|
||||
if source is not None and source.text:
|
||||
original_text = source.text
|
||||
existing_translation = find_existing_translation(existing_tree, original_text)
|
||||
translated_text = translate_text(original_text, existing_translation, language)
|
||||
# Check if <translation> node exists, if not create it
|
||||
translation = message.find('translation')
|
||||
if translation is None:
|
||||
translation = ET.SubElement(message, 'translation')
|
||||
translation.text = translated_text
|
||||
if 'type' in translation.attrib:
|
||||
del translation.attrib['type']
|
||||
|
||||
# Save the updated XML to the output file
|
||||
tree.write(output_file, encoding='utf-8', xml_declaration=True)
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) <= 4:
|
||||
print("Usage: python script.py input.ts output.ts existing.ts (Language)", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
input_ts = sys.argv[1]
|
||||
output_ts = sys.argv[2]
|
||||
existing_ts = sys.argv[3]
|
||||
if len(sys.argv) <= 5:
|
||||
language = sys.argv[4]
|
||||
|
||||
process_ts_file(input_ts, output_ts, existing_ts, language)
|
||||
print(f"Translated file saved to {output_ts}")
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#include <r_core.h>
|
||||
|
||||
extern int main_iaito();
|
||||
static int r_cmd_anal_call(void *user, const char *input)
|
||||
{
|
||||
RCore *core = (RCore *) user;
|
||||
if (r_str_startswith(input, "iaito")) {
|
||||
char *n = r_str_newf("%p", user);
|
||||
r_sys_setenv("R2COREPTR", n);
|
||||
free(n);
|
||||
main_iaito();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
extern "C" {
|
||||
// PLUGIN Definition Info
|
||||
RCorePlugin r_core_plugin_iaito = {
|
||||
.meta =
|
||||
{
|
||||
.name = (char *)"iaito",
|
||||
.desc = (char *)"Start iaito GUI from the radare2 shell",
|
||||
.license = (char *)"LGPL3",
|
||||
},
|
||||
.call = r_cmd_anal_call,
|
||||
};
|
||||
|
||||
#ifndef R2_PLUGIN_INCORE
|
||||
#if R2_VERSION_NUMBER >= 50909
|
||||
R_API RLibStruct radare_plugin
|
||||
= {.type = R_LIB_TYPE_CORE,
|
||||
.data = &r_core_plugin_iaito,
|
||||
.version = R2_VERSION,
|
||||
.abiver = R2_ABIVERSION};
|
||||
#else
|
||||
R_API RLibStruct radare_plugin
|
||||
= {.type = R_LIB_TYPE_CORE, .data = &r_core_plugin_iaito, .version = R2_VERSION};
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
@@ -2,15 +2,33 @@ TEMPLATE = app
|
||||
|
||||
TARGET = iaito
|
||||
|
||||
IAITO_VERSION_MAJOR = 5
|
||||
IAITO_VERSION_MINOR = 7
|
||||
IAITO_VERSION_PATCH = 8
|
||||
IAITO_VERSION_MAJOR = 6
|
||||
IAITO_VERSION_MINOR = 0
|
||||
IAITO_VERSION_PATCH = 4
|
||||
|
||||
CONFIG += c++20
|
||||
QMAKE_CXXFLAGS += -std=c++20
|
||||
|
||||
CONFIG += app_bundle
|
||||
# LIBS+= -dead_strip
|
||||
|
||||
CONFIG += sdk_no_version_check
|
||||
|
||||
unix:QMAKE_RPATHDIR += /usr/local/lib
|
||||
unix:QMAKE_LFLAGS_RPATH=
|
||||
unix:QMAKE_LFLAGS += "-Wl,-rpath,/usr/local/lib"
|
||||
!defined(IAITO_BUNDLE_R2_APPBUNDLE, var) IAITO_BUNDLE_R2_APPBUNDLE=false
|
||||
equals(IAITO_BUNDLE_R2_APPBUNDLE, true) CONFIG += IAITO_BUNDLE_R2_APPBUNDLE
|
||||
|
||||
unix:!IAITO_BUNDLE_R2_APPBUNDLE {
|
||||
isEmpty(R2_LIBDIR) {
|
||||
R2_LIBDIR = $$system(r2 -H R2_LIBDIR)
|
||||
}
|
||||
QMAKE_RPATHDIR += $$(R2_LIBDIR)
|
||||
QMAKE_LFLAGS_RPATH=
|
||||
QMAKE_LFLAGS += "-Wl,-rpath,$$(R2_LIBDIR)"
|
||||
}
|
||||
|
||||
QMAKE_CXXFLAGS += $$(CXXFLAGS)
|
||||
QMAKE_CFLAGS += $$(CFLAGS)
|
||||
QMAKE_LFLAGS += $$(LDFLAGS)
|
||||
|
||||
# build with thread-sanitizer
|
||||
# unix:QMAKE_LFLAGS += "-fsanitize=thread"
|
||||
@@ -19,28 +37,28 @@ QMAKE_CXXFLAGS += -g -O0
|
||||
#QMAKE_CXXFLAGS += -O0 -fsanitize=address
|
||||
#QMAKE_LFLAGS += -fsanitize=address
|
||||
|
||||
|
||||
VERSION = $${IAITO_VERSION_MAJOR}.$${IAITO_VERSION_MINOR}.$${IAITO_VERSION_PATCH}
|
||||
|
||||
# Required QT version
|
||||
lessThan(QT_MAJOR_VERSION, 5): error("requires Qt 5")
|
||||
# Doesnt build for Qt6 yet... but will do soon
|
||||
lessThan(QT_MAJOR_VERSION, 5): error("requires at least Qt 5")
|
||||
|
||||
# Icon for OS X
|
||||
ICON = img/iaito-o.icns
|
||||
ICON = img/iaito.icns
|
||||
|
||||
# Icon/resources for Windows
|
||||
win32: RC_ICONS = img/iaito-o.ico
|
||||
win32: RC_ICONS = img/iaito.ico
|
||||
|
||||
QT += core gui widgets svg network
|
||||
QT += widgets svg network
|
||||
QT_CONFIG -= no-pkg-config
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 5): QT += svgwidgets
|
||||
|
||||
!defined(IAITO_ENABLE_CRASH_REPORTS, var) IAITO_ENABLE_CRASH_REPORTS=false
|
||||
equals(IAITO_ENABLE_CRASH_REPORTS, true) CONFIG += IAITO_ENABLE_CRASH_REPORTS
|
||||
|
||||
!defined(IAITO_ENABLE_PYTHON, var) IAITO_ENABLE_PYTHON=false
|
||||
equals(IAITO_ENABLE_PYTHON, true) CONFIG += IAITO_ENABLE_PYTHON
|
||||
IAITO_ENABLE_PYTHON=false
|
||||
|
||||
!defined(IAITO_ENABLE_PYTHON_BINDINGS, var) IAITO_ENABLE_PYTHON_BINDINGS=false
|
||||
equals(IAITO_ENABLE_PYTHON, true) {
|
||||
@@ -49,9 +67,6 @@ equals(IAITO_ENABLE_PYTHON, true) {
|
||||
}
|
||||
}
|
||||
|
||||
!defined(IAITO_BUNDLE_R2_APPBUNDLE, var) IAITO_BUNDLE_R2_APPBUNDLE=false
|
||||
equals(IAITO_BUNDLE_R2_APPBUNDLE, true) CONFIG += IAITO_BUNDLE_R2_APPBUNDLE
|
||||
|
||||
!defined(IAITO_APPVEYOR_R2DEC, var) IAITO_APPVEYOR_R2DEC=false
|
||||
equals(IAITO_APPVEYOR_R2DEC, true) CONFIG += IAITO_APPVEYOR_R2DEC
|
||||
|
||||
@@ -97,15 +112,15 @@ INCLUDEPATH *= . core widgets dialogs common plugins menus
|
||||
|
||||
win32 {
|
||||
# Generate debug symbols in release mode
|
||||
QMAKE_CXXFLAGS_RELEASE += -Zi # Compiler
|
||||
QMAKE_LFLAGS_RELEASE += /DEBUG # Linker
|
||||
# QMAKE_CXXFLAGS_RELEASE += -Zi # Compiler
|
||||
# QMAKE_LFLAGS_RELEASE += /DEBUG # Linker
|
||||
|
||||
# Multithreaded compilation
|
||||
QMAKE_CXXFLAGS += -MP
|
||||
}
|
||||
|
||||
macx {
|
||||
QMAKE_CXXFLAGS += -mmacosx-version-min=10.7 -std=c++17 -stdlib=libc++ -g
|
||||
QMAKE_CXXFLAGS += -mmacosx-version-min=10.7 -std=c++20 -stdlib=libc++ -g
|
||||
QMAKE_TARGET_BUNDLE_PREFIX = org.radare
|
||||
QMAKE_BUNDLE = iaito
|
||||
QMAKE_INFO_PLIST = macos/Info.plist
|
||||
@@ -319,20 +334,25 @@ SOURCES += \
|
||||
dialogs/XrefsDialog.cpp \
|
||||
core/MainWindow.cpp \
|
||||
common/Helpers.cpp \
|
||||
common/TextEditDialog.cpp \
|
||||
common/Highlighter.cpp \
|
||||
common/MdHighlighter.cpp \
|
||||
common/DirectionalComboBox.cpp \
|
||||
dialogs/preferences/AsmOptionsWidget.cpp \
|
||||
dialogs/NewFileDialog.cpp \
|
||||
common/TypeScriptHighlighter.cpp \
|
||||
common/AnalTask.cpp \
|
||||
dialogs/preferences/AsmOptionsWidget.cpp \
|
||||
dialogs/FortuneDialog.cpp \
|
||||
dialogs/NewFileDialog.cpp \
|
||||
widgets/CommentsWidget.cpp \
|
||||
widgets/ConsoleWidget.cpp \
|
||||
widgets/CustomCommandWidget.cpp \
|
||||
widgets/Dashboard.cpp \
|
||||
widgets/EntrypointWidget.cpp \
|
||||
widgets/ExportsWidget.cpp \
|
||||
widgets/FlagsWidget.cpp \
|
||||
widgets/FunctionsWidget.cpp \
|
||||
widgets/ImportsWidget.cpp \
|
||||
widgets/CodeEditor.cpp \
|
||||
widgets/Omnibar.cpp \
|
||||
widgets/RelocsWidget.cpp \
|
||||
widgets/SectionsWidget.cpp \
|
||||
@@ -369,6 +389,9 @@ SOURCES += \
|
||||
dialogs/R2PluginsDialog.cpp \
|
||||
widgets/IaitoDockWidget.cpp \
|
||||
widgets/IaitoTreeWidget.cpp \
|
||||
widgets/MapsWidget.cpp \
|
||||
widgets/BinariesWidget.cpp \
|
||||
widgets/FilesWidget.cpp \
|
||||
widgets/GraphWidget.cpp \
|
||||
widgets/OverviewWidget.cpp \
|
||||
common/JsonTreeItem.cpp \
|
||||
@@ -376,6 +399,7 @@ SOURCES += \
|
||||
dialogs/VersionInfoDialog.cpp \
|
||||
widgets/ZignaturesWidget.cpp \
|
||||
common/AsyncTask.cpp \
|
||||
common/DecompileTask.cpp \
|
||||
dialogs/AsyncTaskDialog.cpp \
|
||||
widgets/StackWidget.cpp \
|
||||
widgets/RegistersWidget.cpp \
|
||||
@@ -426,10 +450,15 @@ SOURCES += \
|
||||
common/HighDpiPixmap.cpp \
|
||||
widgets/GraphGridLayout.cpp \
|
||||
widgets/HexWidget.cpp \
|
||||
widgets/R2AIWidget.cpp \
|
||||
common/SelectionHighlight.cpp \
|
||||
common/Decompiler.cpp \
|
||||
common/R2GhidraCmdDecompiler.cpp \
|
||||
common/ShortcutKeys.cpp \
|
||||
dialogs/ShortcutKeysDialog.cpp \
|
||||
common/R2pdcCmdDecompiler.cpp \
|
||||
common/R2DecaiDecompiler.cpp \
|
||||
common/R2AnotesDecompiler.cpp \
|
||||
common/R2retdecDecompiler.cpp \
|
||||
menus/AddressableItemContextMenu.cpp \
|
||||
common/AddressableItemModel.cpp \
|
||||
@@ -448,21 +477,34 @@ SOURCES += \
|
||||
widgets/CallGraph.cpp \
|
||||
widgets/AddressableDockWidget.cpp \
|
||||
dialogs/preferences/AnalOptionsWidget.cpp \
|
||||
common/DecompilerHighlighter.cpp
|
||||
dialogs/preferences/KeyboardOptionsWidget.cpp \
|
||||
common/DecompilerHighlighter.cpp \
|
||||
dialogs/PackageManagerDialog.cpp
|
||||
|
||||
GRAPHVIZ_SOURCES = \
|
||||
widgets/GraphvizLayout.cpp
|
||||
|
||||
HEADERS += \
|
||||
common/R2Shims.h \
|
||||
core/Iaito.h \
|
||||
core/IaitoCommon.h \
|
||||
core/IaitoDescriptions.h \
|
||||
dialogs/EditStringDialog.h \
|
||||
dialogs/WriteCommandsDialogs.h \
|
||||
widgets/ClickableSvgWidget.h \
|
||||
widgets/DisassemblerGraphView.h \
|
||||
widgets/OverviewView.h \
|
||||
common/RichTextPainter.h \
|
||||
common/CachedFontMetrics.h \
|
||||
common/TypeScriptHighlighter.h \
|
||||
common/Helpers.h \
|
||||
common/ShortcutKeys.h \
|
||||
dialogs/ShortcutKeysDialog.h \
|
||||
common/TextEditDialog.h \
|
||||
common/Highlighter.h \
|
||||
common/MdHighlighter.h \
|
||||
common/DirectionalComboBox.h \
|
||||
common/AnalTask.h \
|
||||
dialogs/AboutDialog.h \
|
||||
dialogs/preferences/AsmOptionsWidget.h \
|
||||
dialogs/CommentsDialog.h \
|
||||
@@ -471,16 +513,12 @@ HEADERS += \
|
||||
dialogs/RemoteDebugDialog.h \
|
||||
dialogs/NativeDebugDialog.h \
|
||||
dialogs/XrefsDialog.h \
|
||||
common/Helpers.h \
|
||||
core/MainWindow.h \
|
||||
common/Highlighter.h \
|
||||
common/MdHighlighter.h \
|
||||
common/DirectionalComboBox.h \
|
||||
dialogs/InitialOptionsDialog.h \
|
||||
dialogs/NewFileDialog.h \
|
||||
common/AnalTask.h \
|
||||
widgets/CommentsWidget.h \
|
||||
widgets/ConsoleWidget.h \
|
||||
widgets/CustomCommandWidget.h \
|
||||
widgets/Dashboard.h \
|
||||
widgets/EntrypointWidget.h \
|
||||
widgets/ExportsWidget.h \
|
||||
@@ -489,6 +527,7 @@ HEADERS += \
|
||||
widgets/ImportsWidget.h \
|
||||
widgets/Omnibar.h \
|
||||
widgets/RelocsWidget.h \
|
||||
widgets/CodeEditor.h \
|
||||
widgets/SectionsWidget.h \
|
||||
widgets/SegmentsWidget.h \
|
||||
widgets/StringsWidget.h \
|
||||
@@ -523,6 +562,9 @@ HEADERS += \
|
||||
dialogs/R2PluginsDialog.h \
|
||||
widgets/IaitoDockWidget.h \
|
||||
widgets/IaitoTreeWidget.h \
|
||||
widgets/MapsWidget.h \
|
||||
widgets/BinariesWidget.h \
|
||||
widgets/FilesWidget.h \
|
||||
widgets/GraphWidget.h \
|
||||
widgets/OverviewWidget.h \
|
||||
common/JsonTreeItem.h \
|
||||
@@ -530,12 +572,14 @@ HEADERS += \
|
||||
dialogs/VersionInfoDialog.h \
|
||||
widgets/ZignaturesWidget.h \
|
||||
common/AsyncTask.h \
|
||||
common/DecompileTask.h \
|
||||
dialogs/AsyncTaskDialog.h \
|
||||
widgets/StackWidget.h \
|
||||
widgets/RegistersWidget.h \
|
||||
widgets/ThreadsWidget.h \
|
||||
widgets/ProcessesWidget.h \
|
||||
widgets/BacktraceWidget.h \
|
||||
dialogs/FortuneDialog.h \
|
||||
dialogs/MapFileDialog.h \
|
||||
common/StringsTask.h \
|
||||
common/FunctionsTask.h \
|
||||
@@ -580,15 +624,19 @@ HEADERS += \
|
||||
widgets/MemoryDockWidget.h \
|
||||
widgets/ColorThemeListView.h \
|
||||
dialogs/preferences/ColorThemeEditDialog.h \
|
||||
dialogs/preferences/KeyboardOptionsWidget.h \
|
||||
dialogs/LinkTypeDialog.h \
|
||||
common/BugReporting.h \
|
||||
common/HighDpiPixmap.h \
|
||||
widgets/GraphLayout.h \
|
||||
widgets/GraphGridLayout.h \
|
||||
widgets/HexWidget.h \
|
||||
widgets/R2AIWidget.h \
|
||||
common/SelectionHighlight.h \
|
||||
common/Decompiler.h \
|
||||
common/R2GhidraCmdDecompiler.h \
|
||||
common/R2DecaiDecompiler.h \
|
||||
common/R2AnotesDecompiler.h \
|
||||
common/R2pdcCmdDecompiler.h \
|
||||
common/R2retdecDecompiler.h \
|
||||
menus/AddressableItemContextMenu.h \
|
||||
@@ -611,7 +659,8 @@ HEADERS += \
|
||||
widgets/CallGraph.h \
|
||||
widgets/AddressableDockWidget.h \
|
||||
dialogs/preferences/AnalOptionsWidget.h \
|
||||
common/DecompilerHighlighter.h
|
||||
common/DecompilerHighlighter.h \
|
||||
dialogs/PackageManagerDialog.h
|
||||
|
||||
GRAPHVIZ_HEADERS = widgets/GraphvizLayout.h
|
||||
|
||||
@@ -628,7 +677,7 @@ FORMS += \
|
||||
dialogs/RemoteDebugDialog.ui \
|
||||
dialogs/NativeDebugDialog.ui \
|
||||
dialogs/XrefsDialog.ui \
|
||||
dialogs/NewfileDialog.ui \
|
||||
dialogs/NewFileDialog.ui \
|
||||
dialogs/InitialOptionsDialog.ui \
|
||||
dialogs/EditFunctionDialog.ui \
|
||||
core/MainWindow.ui \
|
||||
@@ -643,6 +692,7 @@ FORMS += \
|
||||
dialogs/preferences/AppearanceOptionsWidget.ui \
|
||||
dialogs/preferences/GraphOptionsWidget.ui \
|
||||
dialogs/preferences/InitializationFileEditor.ui \
|
||||
dialogs/preferences/KeyboardOptionsWidget.ui \
|
||||
widgets/QuickFilterView.ui \
|
||||
widgets/DecompilerWidget.ui \
|
||||
widgets/ClassesWidget.ui \
|
||||
@@ -680,6 +730,7 @@ FORMS += \
|
||||
widgets/ListDockWidget.ui \
|
||||
dialogs/LayoutManager.ui \
|
||||
widgets/R2GraphWidget.ui \
|
||||
widgets/CustomCommandWidget.ui \
|
||||
dialogs/preferences/AnalOptionsWidget.ui
|
||||
|
||||
RESOURCES += \
|
||||
|
||||
@@ -1,28 +1,33 @@
|
||||
#include "common/PythonManager.h"
|
||||
#include "common/CrashHandler.h"
|
||||
#include "IaitoApplication.h"
|
||||
#include "plugins/PluginManager.h"
|
||||
#include "IaitoConfig.h"
|
||||
#include "R2AnotesDecompiler.h"
|
||||
#include "R2DecaiDecompiler.h"
|
||||
#include "R2GhidraCmdDecompiler.h"
|
||||
#include "R2pdcCmdDecompiler.h"
|
||||
#include "R2retdecDecompiler.h"
|
||||
#include "IaitoConfig.h"
|
||||
#include "common/CrashHandler.h"
|
||||
#include "common/Decompiler.h"
|
||||
#include "common/PythonManager.h"
|
||||
#include "common/ResourcePaths.h"
|
||||
#include "plugins/PluginManager.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFileOpenEvent>
|
||||
#include <QCommandLineParser>
|
||||
#include <QEvent>
|
||||
#include <QFileOpenEvent>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QCommandLineParser>
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
#include <QTextCodec>
|
||||
#include <QStringList>
|
||||
#include <QProcess>
|
||||
#include <QPluginLoader>
|
||||
#endif
|
||||
#include <QDir>
|
||||
#include <QTranslator>
|
||||
#include <QLibraryInfo>
|
||||
#include <QFontDatabase>
|
||||
#include <QLibraryInfo>
|
||||
#include <QPluginLoader>
|
||||
#include <QProcess>
|
||||
#include <QStandardPaths>
|
||||
#include <QStringList>
|
||||
#include <QTranslator>
|
||||
#ifdef Q_OS_WIN
|
||||
#include <QtNetwork/QtNetwork>
|
||||
#endif // Q_OS_WIN
|
||||
@@ -33,37 +38,43 @@
|
||||
#include <R2GhidraDecompiler.h>
|
||||
#endif
|
||||
|
||||
static bool versionCheck() {
|
||||
static bool versionCheck()
|
||||
{
|
||||
// Check r2 version
|
||||
QString a = r_core_version (); // runtime library version
|
||||
QString b = "" R2_GITTAP; // compiled version
|
||||
QString a = r_core_version(); // runtime library version
|
||||
QString b = "" R2_GITTAP; // compiled version
|
||||
QStringList la = a.split(".");
|
||||
QStringList lb = b.split(".");
|
||||
if (la.size() < 2 && lb.size() < 2) {
|
||||
eprintf ("Invalid version string somwhere\n");
|
||||
return false;
|
||||
R_LOG_WARN("Invalid version string somwhere");
|
||||
return false;
|
||||
}
|
||||
if (la.at(0) != lb.at(0)) {
|
||||
eprintf ("Major version differs\n");
|
||||
return false;
|
||||
R_LOG_WARN("Major version differs");
|
||||
return false;
|
||||
}
|
||||
if (la.at(1) != lb.at(1)) {
|
||||
eprintf ("Minor version differs\n");
|
||||
return false;
|
||||
R_LOG_WARN("Minor version differs");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
IaitoApplication::IaitoApplication(int &argc, char **argv) : QApplication(argc, argv)
|
||||
IaitoApplication::IaitoApplication(int &argc, char **argv)
|
||||
: QApplication(argc, argv)
|
||||
{
|
||||
// Setup application information
|
||||
setApplicationVersion(IAITO_VERSION_FULL);
|
||||
setWindowIcon(QIcon(":/img/iaito-o.svg"));
|
||||
#ifndef Q_OS_MACOS
|
||||
setWindowIcon(QIcon(":/img/iaito.svg"));
|
||||
#endif
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#endif
|
||||
setLayoutDirection(Qt::LeftToRight);
|
||||
|
||||
// WARN!!! Put initialization code below this line. Code above this line is mandatory to be run First
|
||||
|
||||
// WARN!!! Put initialization code below this line. Code above this line is
|
||||
// mandatory to be run First
|
||||
#ifdef Q_OS_WIN
|
||||
// Hack to force Iaito load internet connection related DLL's
|
||||
QSslSocket s;
|
||||
@@ -89,30 +100,33 @@ IaitoApplication::IaitoApplication(int &argc, char **argv) : QApplication(argc,
|
||||
qWarning() << "Cannot load Incosolata-Regular font.";
|
||||
}
|
||||
|
||||
|
||||
// Set QString codec to UTF-8
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
|
||||
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
|
||||
#endif
|
||||
|
||||
#endif
|
||||
if (!parseCommandLineOptions()) {
|
||||
std::exit(1);
|
||||
QCoreApplication::exit();
|
||||
// std::exit(1);
|
||||
}
|
||||
|
||||
if (!versionCheck ()) {
|
||||
if (!versionCheck()) {
|
||||
QMessageBox msg;
|
||||
msg.setIcon(QMessageBox::Critical);
|
||||
msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
msg.setWindowTitle(QObject::tr("Version mismatch!"));
|
||||
QString localVersion = r_core_version ();
|
||||
QString localVersion = r_core_version();
|
||||
QString r2version = R2_GITTAP;
|
||||
msg.setText(QString(
|
||||
QObject::tr("The version used to compile Iaito (%1) does not match the binary version of radare2 (%2). This could result in unexpected behaviour. Are you sure you want to continue?")).arg(
|
||||
localVersion, r2version));
|
||||
msg.setText(QString(QObject::tr("The version used to compile Iaito (%1) does not match the "
|
||||
"binary version of radare2 (%2). This could result in "
|
||||
"unexpected behaviour. Are you sure you want to continue?"))
|
||||
.arg(localVersion, r2version));
|
||||
if (msg.exec() == QMessageBox::No) {
|
||||
std::exit(1);
|
||||
QCoreApplication::exit();
|
||||
// std::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,10 +143,42 @@ IaitoApplication::IaitoApplication(int &argc, char **argv) : QApplication(argc,
|
||||
qputenv("R_ALT_SRC_DIR", "1");
|
||||
#endif
|
||||
|
||||
#ifdef MACOS_R2_BUNDLED
|
||||
{
|
||||
auto appdir = QDir(QCoreApplication::applicationDirPath()); // Contents/MacOS
|
||||
appdir.cdUp(); // Contents
|
||||
|
||||
auto r2prefix = appdir; // Contents
|
||||
r2prefix.cd("Resources/radare2"); // Contents/Resources/radare2
|
||||
qputenv("R2_PREFIX", r2prefix.absolutePath().toLocal8Bit());
|
||||
|
||||
auto r2bin = appdir; // Contents
|
||||
r2bin.cd("Helpers"); // Contents/Helpers
|
||||
auto paths = QStringList(QString::fromLocal8Bit(qgetenv("PATH")));
|
||||
paths.prepend(r2bin.absolutePath());
|
||||
qputenv("PATH", paths.join(QLatin1Char(':')).toLocal8Bit());
|
||||
|
||||
// auto sleighHome = appdir; // Contents
|
||||
// sleighHome.cd("PlugIns/radare2/r2ghidra_sleigh"); // Contents/PlugIns/radare2/r2ghidra_sleigh
|
||||
// qputenv("SLEIGHHOME", sleighHome.absolutePath().toLocal8Bit());
|
||||
|
||||
// Allow bundled radare2 and its plugins to save its data inside iaito app folders
|
||||
qputenv(
|
||||
"XDG_CACHE_HOME",
|
||||
QStandardPaths::writableLocation(QStandardPaths::CacheLocation).toLocal8Bit());
|
||||
qputenv(
|
||||
"XDG_CONFIG_HOME",
|
||||
QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation).toLocal8Bit());
|
||||
qputenv(
|
||||
"XDG_DATA_HOME",
|
||||
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation).toLocal8Bit());
|
||||
}
|
||||
#endif
|
||||
|
||||
Core()->initialize(clOptions.enableR2Plugins);
|
||||
Core()->setSettings();
|
||||
Config()->loadInitial();
|
||||
Core()->loadIaitoRC();
|
||||
Core()->loadIaitoRC(0);
|
||||
|
||||
Config()->setOutputRedirectionEnabled(clOptions.outputRedirectionEnabled);
|
||||
|
||||
@@ -145,9 +191,15 @@ IaitoApplication::IaitoApplication(int &argc, char **argv) : QApplication(argc,
|
||||
if (R2DecDecompiler::isAvailable()) {
|
||||
Core()->registerDecompiler(new R2DecDecompiler(Core()));
|
||||
}
|
||||
if (R2DecaiDecompiler::isAvailable()) {
|
||||
Core()->registerDecompiler(new R2DecaiDecompiler(Core()));
|
||||
}
|
||||
if (R2GhidraCmdDecompiler::isAvailable()) {
|
||||
Core()->registerDecompiler(new R2GhidraCmdDecompiler(Core()));
|
||||
}
|
||||
if (R2AnotesDecompiler::isAvailable()) {
|
||||
Core()->registerDecompiler(new R2AnotesDecompiler(Core()));
|
||||
}
|
||||
|
||||
#if IAITO_R2GHIDRA_STATIC
|
||||
Core()->registerDecompiler(new R2GhidraDecompiler(Core()));
|
||||
@@ -167,10 +219,14 @@ IaitoApplication::IaitoApplication(int &argc, char **argv) : QApplication(argc,
|
||||
setStyle(new IaitoProxyStyle());
|
||||
#endif // QT_VERSION_CHECK(5, 10, 0) < QT_VERSION
|
||||
|
||||
if (clOptions.args.empty()) {
|
||||
RCore *kore = iaitoPluginCore();
|
||||
if (kore) {
|
||||
mainWindow->openCurrentCore(clOptions.fileOpenOptions, false);
|
||||
} else if (clOptions.args.empty()) {
|
||||
// check if this is the first execution of Iaito in this computer
|
||||
// Note: the execution after the preferences been reset, will be considered as first-execution
|
||||
if (Config()->isFirstExecution()) {
|
||||
// Note: the execution after the preferences been reset, will be
|
||||
// considered as first-execution
|
||||
if (clOptions.showWelcomeDialog || Config()->isFirstExecution()) {
|
||||
mainWindow->displayWelcomeDialog();
|
||||
}
|
||||
mainWindow->displayNewFileDialog();
|
||||
@@ -195,22 +251,6 @@ IaitoApplication::IaitoApplication(int &argc, char **argv) : QApplication(argc,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
{
|
||||
auto r2prefix = QDir(QCoreApplication::applicationDirPath()); // Contents/MacOS
|
||||
r2prefix.cdUp(); // Contents
|
||||
r2prefix.cd("Resources/r2"); // Contents/Resources/r2
|
||||
|
||||
auto sleighHome = r2prefix;
|
||||
sleighHome.cd("share/radare2/plugins/r2ghidra_sleigh"); // Contents/Resources/r2/share/radare2/plugins/r2ghidra_sleigh
|
||||
Core()->setConfig("r2ghidra.sleighhome", sleighHome.absolutePath());
|
||||
|
||||
auto r2decHome = r2prefix;
|
||||
r2decHome.cd("share/radare2/plugins/r2dec-js"); // Contents/Resources/r2/share/radare2/plugins/r2dec-js
|
||||
qputenv("R2DEC_HOME", r2decHome.absolutePath().toLocal8Bit());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef IAITO_APPVEYOR_R2DEC
|
||||
qputenv("R2DEC_HOME", "lib\\plugins\\r2dec-js");
|
||||
#endif
|
||||
@@ -251,15 +291,23 @@ void IaitoApplication::launchNewInstance(const QStringList &args)
|
||||
bool IaitoApplication::event(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::FileOpen) {
|
||||
RCore *kore = iaitoPluginCore();
|
||||
if (kore) {
|
||||
return false;
|
||||
}
|
||||
QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(e);
|
||||
if (openEvent) {
|
||||
if (m_FileAlreadyDropped) {
|
||||
// We already dropped a file in macOS, let's spawn another instance
|
||||
// (Like the File -> Open)
|
||||
// We already dropped a file in macOS, let's spawn another
|
||||
// instance (Like the File -> Open)
|
||||
QString fileName = openEvent->file();
|
||||
launchNewInstance({fileName});
|
||||
} else {
|
||||
QString fileName = openEvent->file();
|
||||
// eprintf ("FILE %s\n", fileName.toStdString().c_str());
|
||||
if (fileName == "") {
|
||||
return false;
|
||||
}
|
||||
m_FileAlreadyDropped = true;
|
||||
mainWindow->closeNewFileDialog();
|
||||
InitialOptions options;
|
||||
@@ -277,8 +325,8 @@ bool IaitoApplication::loadTranslations()
|
||||
if (language == QStringLiteral("en") || language.startsWith(QStringLiteral("en-"))) {
|
||||
return true;
|
||||
}
|
||||
const auto &allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript,
|
||||
QLocale::AnyCountry);
|
||||
const auto &allLocales
|
||||
= QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry);
|
||||
|
||||
bool iaitoTrLoaded = false;
|
||||
|
||||
@@ -293,10 +341,11 @@ bool IaitoApplication::loadTranslations()
|
||||
QTranslator *trQtBase = new QTranslator;
|
||||
QTranslator *trQt = new QTranslator;
|
||||
|
||||
const QStringList &cutterTrPaths = Iaito::getTranslationsDirectories();
|
||||
const QStringList &iaitoTrPaths = Iaito::getTranslationsDirectories();
|
||||
|
||||
for (const auto &trPath : cutterTrPaths) {
|
||||
if (trIaito && trIaito->load(it, QLatin1String("iaito"), QLatin1String("_"), trPath)) {
|
||||
for (const auto &trPath : iaitoTrPaths) {
|
||||
if (trIaito
|
||||
&& trIaito->load(it, QLatin1String("iaito"), QLatin1String("_"), trPath)) {
|
||||
installTranslator(trIaito);
|
||||
iaitoTrLoaded = true;
|
||||
trIaito = nullptr;
|
||||
@@ -341,59 +390,63 @@ bool IaitoApplication::parseCommandLineOptions()
|
||||
cmd_parser.addVersionOption();
|
||||
cmd_parser.addPositionalArgument("filename", QObject::tr("Filename to open."));
|
||||
|
||||
QCommandLineOption analOption({"A", "analysis"},
|
||||
QObject::tr("Automatically open file and optionally start analysis. "
|
||||
"Needs filename to be specified. May be a value between 0 and 3:"
|
||||
" 0 = no analysis, 1 = aa, 2 = aaa, 3 = aaaa (slow)"),
|
||||
QObject::tr("level"));
|
||||
QCommandLineOption analOption(
|
||||
{"A", "analysis"},
|
||||
QObject::tr("Automatically open file and optionally start analysis. "
|
||||
"Needs filename to be specified. May be a value between 0 and 3:"
|
||||
" 0 = no analysis, 1 = aa, 2 = aaa, 3 = aaaa (slow)"),
|
||||
QObject::tr("level"));
|
||||
cmd_parser.addOption(analOption);
|
||||
|
||||
QCommandLineOption formatOption({"F", "format"},
|
||||
QObject::tr("Force using a specific file format (bin plugin)"),
|
||||
QObject::tr("name"));
|
||||
QCommandLineOption formatOption(
|
||||
{"F", "format"},
|
||||
QObject::tr("Force using a specific file format (bin plugin)"),
|
||||
QObject::tr("name"));
|
||||
cmd_parser.addOption(formatOption);
|
||||
|
||||
QCommandLineOption baddrOption({"B", "base"},
|
||||
QObject::tr("Load binary at a specific base address"),
|
||||
QObject::tr("base address"));
|
||||
QCommandLineOption baddrOption(
|
||||
{"B", "base"},
|
||||
QObject::tr("Load binary at a specific base address"),
|
||||
QObject::tr("base address"));
|
||||
cmd_parser.addOption(baddrOption);
|
||||
|
||||
QCommandLineOption scriptOption("i",
|
||||
QObject::tr("Run script file"),
|
||||
QObject::tr("file"));
|
||||
QCommandLineOption scriptOption("i", QObject::tr("Run script file"), QObject::tr("file"));
|
||||
cmd_parser.addOption(scriptOption);
|
||||
|
||||
QCommandLineOption writeModeOption({"w", "writemode"}, QObject::tr("Open file in write mode"));
|
||||
cmd_parser.addOption(writeModeOption);
|
||||
|
||||
QCommandLineOption binCacheOption({"c", "bincache"}, QObject::tr("Enable bin.cache to make relocs work"));
|
||||
QCommandLineOption
|
||||
binCacheOption({"c", "bincache"}, QObject::tr("Patch relocs (enable bin.cache)"));
|
||||
cmd_parser.addOption(binCacheOption);
|
||||
|
||||
|
||||
QCommandLineOption pythonHomeOption("pythonhome",
|
||||
QObject::tr("PYTHONHOME to use for embedded python interpreter"),
|
||||
"PYTHONHOME");
|
||||
QCommandLineOption pythonHomeOption(
|
||||
"pythonhome",
|
||||
QObject::tr("PYTHONHOME to use for embedded python interpreter"),
|
||||
"PYTHONHOME");
|
||||
cmd_parser.addOption(pythonHomeOption);
|
||||
|
||||
QCommandLineOption disableRedirectOption("no-output-redirect",
|
||||
QObject::tr("Disable output redirection."
|
||||
" Some of the output in console widget will not be visible."
|
||||
" Use this option when debuging a crash or freeze and output "
|
||||
" redirection is causing some messages to be lost."));
|
||||
QCommandLineOption disableRedirectOption(
|
||||
"no-output-redirect",
|
||||
QObject::tr("Disable output redirection."
|
||||
" Some of the output in console widget will not be visible."
|
||||
" Use this option when debuging a crash or freeze and output "
|
||||
" redirection is causing some messages to be lost."));
|
||||
cmd_parser.addOption(disableRedirectOption);
|
||||
|
||||
QCommandLineOption disablePlugins("no-plugins",
|
||||
QObject::tr("Do not load plugins"));
|
||||
QCommandLineOption disablePlugins("no-plugins", QObject::tr("Do not load plugins"));
|
||||
cmd_parser.addOption(disablePlugins);
|
||||
|
||||
QCommandLineOption disableIaitoPlugins("no-iaito-plugins",
|
||||
QObject::tr("Do not load Iaito plugins"));
|
||||
QCommandLineOption
|
||||
disableIaitoPlugins("no-iaito-plugins", QObject::tr("Do not load Iaito plugins"));
|
||||
cmd_parser.addOption(disableIaitoPlugins);
|
||||
|
||||
QCommandLineOption disableR2Plugins("no-r2-plugins",
|
||||
QObject::tr("Do not load radare2 plugins"));
|
||||
QCommandLineOption disableR2Plugins("no-r2-plugins", QObject::tr("Do not load radare2 plugins"));
|
||||
cmd_parser.addOption(disableR2Plugins);
|
||||
|
||||
QCommandLineOption welcomeOption("welcome", QObject::tr("Show welcome dialog."));
|
||||
cmd_parser.addOption(welcomeOption);
|
||||
|
||||
cmd_parser.process(*this);
|
||||
|
||||
IaitoCommandLineOptions opts;
|
||||
@@ -403,9 +456,13 @@ bool IaitoApplication::parseCommandLineOptions()
|
||||
bool analLevelSpecified = false;
|
||||
int analLevel = cmd_parser.value(analOption).toInt(&analLevelSpecified);
|
||||
|
||||
if (!analLevelSpecified || analLevel < 0 || analLevel > 2) {
|
||||
fprintf(stderr, "%s\n",
|
||||
QObject::tr("Invalid Analysis Level. May be a value between 0 and 2.").toLocal8Bit().constData());
|
||||
if (!analLevelSpecified || analLevel < 0 || analLevel > 3) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s\n",
|
||||
QObject::tr("Invalid Analysis Level. May be a value between 0 and 3.")
|
||||
.toLocal8Bit()
|
||||
.constData());
|
||||
return false;
|
||||
}
|
||||
switch (analLevel) {
|
||||
@@ -418,12 +475,19 @@ bool IaitoApplication::parseCommandLineOptions()
|
||||
case 2:
|
||||
opts.analLevel = AutomaticAnalysisLevel::AAAA;
|
||||
break;
|
||||
case 3:
|
||||
opts.analLevel = AutomaticAnalysisLevel::AAAAA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.args.empty() && opts.analLevel != AutomaticAnalysisLevel::Ask) {
|
||||
fprintf(stderr, "%s\n",
|
||||
QObject::tr("Filename must be specified to start analysis automatically.").toLocal8Bit().constData());
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s\n",
|
||||
QObject::tr("Filename must be specified to start analysis automatically.")
|
||||
.toLocal8Bit()
|
||||
.constData());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -445,10 +509,13 @@ bool IaitoApplication::parseCommandLineOptions()
|
||||
opts.fileOpenOptions.analCmd = {};
|
||||
break;
|
||||
case AutomaticAnalysisLevel::AAA:
|
||||
opts.fileOpenOptions.analCmd = { {"aaa", "Auto analysis"} };
|
||||
opts.fileOpenOptions.analCmd = {{"aaa", "Auto analysis"}};
|
||||
break;
|
||||
case AutomaticAnalysisLevel::AAAA:
|
||||
opts.fileOpenOptions.analCmd = { {"aaaa", "Auto analysis (experimental)"} };
|
||||
opts.fileOpenOptions.analCmd = {{"aaaa", "Advanced analysis"}};
|
||||
break;
|
||||
case AutomaticAnalysisLevel::AAAAA:
|
||||
opts.fileOpenOptions.analCmd = {{"aaaaa", "Auto analysis (experimental)"}};
|
||||
break;
|
||||
}
|
||||
opts.fileOpenOptions.script = cmd_parser.value(scriptOption);
|
||||
@@ -474,11 +541,14 @@ bool IaitoApplication::parseCommandLineOptions()
|
||||
opts.enableR2Plugins = false;
|
||||
}
|
||||
|
||||
if (cmd_parser.isSet(welcomeOption)) {
|
||||
opts.showWelcomeDialog = true;
|
||||
}
|
||||
|
||||
this->clOptions = opts;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void IaitoProxyStyle::polish(QWidget *widget)
|
||||
{
|
||||
QProxyStyle::polish(widget);
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
#ifndef IAITOAPPLICATION_H
|
||||
#define IAITOAPPLICATION_H
|
||||
|
||||
#include <QEvent>
|
||||
#include <QApplication>
|
||||
#include <QEvent>
|
||||
#include <QList>
|
||||
#include <QProxyStyle>
|
||||
|
||||
#include "core/MainWindow.h"
|
||||
|
||||
enum class AutomaticAnalysisLevel {
|
||||
Ask, None, AAA, AAAA
|
||||
};
|
||||
enum class AutomaticAnalysisLevel { Ask, None, AAA, AAAA, AAAAA };
|
||||
|
||||
struct IaitoCommandLineOptions {
|
||||
struct IaitoCommandLineOptions
|
||||
{
|
||||
QStringList args;
|
||||
AutomaticAnalysisLevel analLevel = AutomaticAnalysisLevel::Ask;
|
||||
InitialOptions fileOpenOptions;
|
||||
@@ -20,6 +19,7 @@ struct IaitoCommandLineOptions {
|
||||
bool outputRedirectionEnabled = true;
|
||||
bool enableIaitoPlugins = true;
|
||||
bool enableR2Plugins = true;
|
||||
bool showWelcomeDialog = false;
|
||||
};
|
||||
|
||||
class IaitoApplication : public QApplication
|
||||
@@ -30,12 +30,10 @@ public:
|
||||
IaitoApplication(int &argc, char **argv);
|
||||
~IaitoApplication();
|
||||
|
||||
MainWindow *getMainWindow()
|
||||
{
|
||||
return mainWindow;
|
||||
}
|
||||
MainWindow *getMainWindow() { return mainWindow; }
|
||||
|
||||
void launchNewInstance(const QStringList &args = {});
|
||||
|
||||
protected:
|
||||
bool event(QEvent *e);
|
||||
|
||||
@@ -50,13 +48,13 @@ private:
|
||||
* @return false if options have error
|
||||
*/
|
||||
bool parseCommandLineOptions();
|
||||
|
||||
private:
|
||||
bool m_FileAlreadyDropped;
|
||||
MainWindow *mainWindow;
|
||||
IaitoCommandLineOptions clOptions;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief IaitoProxyStyle is used to force shortcuts displaying in context menu
|
||||
*/
|
||||
@@ -65,7 +63,8 @@ class IaitoProxyStyle : public QProxyStyle
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* @brief it is enough to get notification about QMenu polishing to force shortcut displaying
|
||||
* @brief it is enough to get notification about QMenu polishing to force
|
||||
* shortcut displaying
|
||||
*/
|
||||
void polish(QWidget *widget) override;
|
||||
};
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
|
||||
#include "IaitoApplication.h"
|
||||
#include "core/MainWindow.h"
|
||||
#include "common/UpdateWorker.h"
|
||||
#include "IaitoConfig.h"
|
||||
#include "common/CrashHandler.h"
|
||||
#include "common/SettingsUpgrade.h"
|
||||
#include "common/UpdateWorker.h"
|
||||
#include "core/MainWindow.h"
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <iostream>
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
|
||||
/**
|
||||
* @brief Attempt to connect to a parent console and configure outputs.
|
||||
@@ -23,8 +22,9 @@ static void connectToConsole()
|
||||
return;
|
||||
}
|
||||
|
||||
// Avoid reconfiguring stderr/stdout if one of them is already connected to a stream.
|
||||
// This can happen when running with stdout/stderr redirected to a file.
|
||||
// Avoid reconfiguring stderr/stdout if one of them is already connected to
|
||||
// a stream. This can happen when running with stdout/stderr redirected to a
|
||||
// file.
|
||||
if (0 > fileno(stdout)) {
|
||||
// Overwrite FD 1 and 2 for the benefit of any code that uses the FDs
|
||||
// directly. This is safe because the CRT allocates FDs 0, 1 and
|
||||
@@ -34,7 +34,8 @@ static void connectToConsole()
|
||||
_close(1);
|
||||
|
||||
if (freopen("CONOUT$", "a+", stdout)) {
|
||||
// Avoid buffering stdout/stderr since IOLBF is replaced by IOFBF in Win32.
|
||||
// Avoid buffering stdout/stderr since IOLBF is replaced by IOFBF in
|
||||
// Win32.
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
}
|
||||
}
|
||||
@@ -51,7 +52,6 @@ static void connectToConsole()
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc >= 3 && QString::fromLocal8Bit(argv[1]) == "--start-crash-handler") {
|
||||
@@ -71,16 +71,20 @@ int main(int argc, char *argv[])
|
||||
qRegisterMetaType<QList<FunctionDescription>>();
|
||||
|
||||
QCoreApplication::setOrganizationName("radareorg");
|
||||
QCoreApplication::setOrganizationDomain("radare.org");
|
||||
QCoreApplication::setApplicationName("iaito");
|
||||
QGuiApplication::setDesktopFileName("org.radare.iaito");
|
||||
|
||||
Iaito::initializeSettings();
|
||||
|
||||
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); // needed for QtWebEngine inside Plugins
|
||||
QCoreApplication::setAttribute(
|
||||
Qt::AA_ShareOpenGLContexts); // needed for QtWebEngine inside Plugins
|
||||
#ifdef Q_OS_WIN
|
||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
#endif
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
|
||||
Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
IaitoApplication a(argc, argv);
|
||||
@@ -90,18 +94,23 @@ int main(int argc, char *argv[])
|
||||
if (Config()->getAutoUpdateEnabled()) {
|
||||
#if IAITO_UPDATE_WORKER_AVAILABLE
|
||||
UpdateWorker *updateWorker = new UpdateWorker;
|
||||
QObject::connect(updateWorker, &UpdateWorker::checkComplete,
|
||||
[=](const QVersionNumber &version, const QString & error) {
|
||||
if (error.isEmpty() && version > UpdateWorker::currentVersionNumber()) {
|
||||
updateWorker->showUpdateDialog(true);
|
||||
}
|
||||
updateWorker->deleteLater();
|
||||
});
|
||||
QObject::connect(
|
||||
updateWorker,
|
||||
&UpdateWorker::checkComplete,
|
||||
[=](const QVersionNumber &version, const QString &error) {
|
||||
if (error.isEmpty() && version > UpdateWorker::currentVersionNumber()) {
|
||||
updateWorker->showUpdateDialog(true);
|
||||
}
|
||||
updateWorker->deleteLater();
|
||||
});
|
||||
updateWorker->checkCurrentVersion(7000);
|
||||
#endif
|
||||
}
|
||||
return a.exec();
|
||||
}
|
||||
|
||||
int ret = a.exec();
|
||||
|
||||
return ret;
|
||||
int main_iaito()
|
||||
{
|
||||
char *argv[] = {(char *) "iaito"};
|
||||
return main(1, argv);
|
||||
}
|
||||
@@ -4,11 +4,11 @@
|
||||
|
||||
// #define QT_ANNOTATE_ACCESS_SPECIFIER(a) __attribute__((annotate(#a)))
|
||||
|
||||
#include "../core/Iaito.h"
|
||||
#include "../common/Configuration.h"
|
||||
#include "../core/Iaito.h"
|
||||
#include "../core/MainWindow.h"
|
||||
#include "../widgets/IaitoDockWidget.h"
|
||||
#include "../plugins/IaitoPlugin.h"
|
||||
#include "../menus/AddressableItemContextMenu.h"
|
||||
#include "../plugins/IaitoPlugin.h"
|
||||
#include "../widgets/IaitoDockWidget.h"
|
||||
|
||||
#endif //IAITO_BINDINGS_H
|
||||
#endif // IAITO_BINDINGS_H
|
||||
@@ -1,11 +1,15 @@
|
||||
#include <stdexcept>
|
||||
#include "AddressableItemModel.h"
|
||||
#include <stdexcept>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
AddressableFilterProxyModel::AddressableFilterProxyModel(AddressableItemModelI *sourceModel,
|
||||
QObject *parent) :
|
||||
AddressableItemModel<QSortFilterProxyModel>(parent)
|
||||
AddressableItemModelI::~AddressableItemModelI()
|
||||
{ /* nothing to see */
|
||||
}
|
||||
|
||||
AddressableFilterProxyModel::AddressableFilterProxyModel(
|
||||
AddressableItemModelI *sourceModel, QObject *parent)
|
||||
: AddressableItemModel<QSortFilterProxyModel>(parent)
|
||||
{
|
||||
setSourceModel(sourceModel);
|
||||
addressableSourceModel = sourceModel;
|
||||
|
||||
@@ -4,30 +4,39 @@
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
#include "core/IaitoCommon.h"
|
||||
|
||||
class IAITO_EXPORT AddressableItemModelI
|
||||
{
|
||||
public:
|
||||
virtual ~AddressableItemModelI() = 0;
|
||||
virtual RVA address(const QModelIndex &index) const = 0;
|
||||
/**
|
||||
* @brief Get name for item, optional.
|
||||
* @param index item intex
|
||||
* @return Item name or empty QString if item doesn't have short descriptive name.
|
||||
* @return Item name or empty QString if item doesn't have short descriptive
|
||||
* name.
|
||||
*/
|
||||
virtual QString name(const QModelIndex &index) const { Q_UNUSED(index) return QString(); }
|
||||
virtual QString name(const QModelIndex &index) const
|
||||
{
|
||||
Q_UNUSED(index)
|
||||
return QString();
|
||||
}
|
||||
virtual QAbstractItemModel *asItemModel() = 0;
|
||||
};
|
||||
|
||||
template <class ParentModel = QAbstractItemModel>
|
||||
class IAITO_EXPORT AddressableItemModel : public ParentModel, public AddressableItemModelI
|
||||
template<class ParentModel = QAbstractItemModel>
|
||||
class IAITO_EXPORT AddressableItemModel : public ParentModel, public AddressableItemModelI
|
||||
{
|
||||
static_assert (std::is_base_of<QAbstractItemModel, ParentModel>::value,
|
||||
"ParentModel needs to inherit from QAbstractItemModel");
|
||||
static_assert(
|
||||
std::is_base_of<QAbstractItemModel, ParentModel>::value,
|
||||
"ParentModel needs to inherit from QAbstractItemModel");
|
||||
|
||||
public:
|
||||
explicit AddressableItemModel(QObject *parent = nullptr) : ParentModel(parent) {}
|
||||
explicit AddressableItemModel(QObject *parent = nullptr)
|
||||
: ParentModel(parent)
|
||||
{}
|
||||
virtual ~AddressableItemModel() {}
|
||||
QAbstractItemModel *asItemModel() { return this; }
|
||||
};
|
||||
@@ -35,12 +44,14 @@ public:
|
||||
class IAITO_EXPORT AddressableFilterProxyModel : public AddressableItemModel<QSortFilterProxyModel>
|
||||
{
|
||||
using ParentClass = AddressableItemModel<QSortFilterProxyModel>;
|
||||
|
||||
public:
|
||||
AddressableFilterProxyModel(AddressableItemModelI *sourceModel, QObject *parent);
|
||||
|
||||
RVA address(const QModelIndex &index) const override;
|
||||
QString name(const QModelIndex &) const override;
|
||||
void setSourceModel(AddressableItemModelI *sourceModel);
|
||||
|
||||
private:
|
||||
void setSourceModel(QAbstractItemModel *sourceModel) override; // Don't use this directly
|
||||
AddressableItemModelI *addressableSourceModel;
|
||||
|
||||
@@ -1,27 +1,30 @@
|
||||
#include "core/Iaito.h"
|
||||
#include "common/AnalTask.h"
|
||||
#include "core/Iaito.h"
|
||||
#include "core/MainWindow.h"
|
||||
#include "dialogs/InitialOptionsDialog.h"
|
||||
#include <QJsonArray>
|
||||
#include <QDebug>
|
||||
#include <QCheckBox>
|
||||
#include <QDebug>
|
||||
#include <QJsonArray>
|
||||
|
||||
AnalTask::AnalTask() :
|
||||
AsyncTask()
|
||||
{
|
||||
}
|
||||
AnalTask::AnalTask()
|
||||
: AsyncTask()
|
||||
{}
|
||||
|
||||
AnalTask::~AnalTask()
|
||||
{
|
||||
}
|
||||
AnalTask::~AnalTask() {}
|
||||
|
||||
void AnalTask::interrupt()
|
||||
{
|
||||
AsyncTask::interrupt();
|
||||
#if R2_VERSION_NUMBER >= 50909
|
||||
RCore *core = Core()->core_;
|
||||
core->cons->context->breaked = true;
|
||||
#else
|
||||
r_cons_singleton()->context->breaked = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
QString AnalTask::getTitle() {
|
||||
QString AnalTask::getTitle()
|
||||
{
|
||||
// If no file is loaded we consider it's Initial Analysis
|
||||
QJsonArray openedFiles = Core()->getOpenedFiles();
|
||||
if (!openedFiles.size()) {
|
||||
@@ -35,7 +38,7 @@ void AnalTask::runTask()
|
||||
int perms = R_PERM_RX;
|
||||
if (options.writeEnabled) {
|
||||
perms |= R_PERM_W;
|
||||
emit Core()->ioModeChanged();
|
||||
emit Core() -> ioModeChanged();
|
||||
}
|
||||
|
||||
// Demangle (must be before file Core()->loadFile)
|
||||
@@ -46,15 +49,17 @@ void AnalTask::runTask()
|
||||
if (!openedFiles.size() && options.filename.length()) {
|
||||
log(tr("Loading the file..."));
|
||||
openFailed = false;
|
||||
bool fileLoaded = Core()->loadFile(options.filename,
|
||||
options.binLoadAddr,
|
||||
options.mapAddr,
|
||||
perms,
|
||||
options.useVA,
|
||||
options.loadBinCache,
|
||||
options.loadBinInfo,
|
||||
options.forceBinPlugin);
|
||||
bool fileLoaded = Core()->loadFile(
|
||||
options.filename,
|
||||
options.binLoadAddr,
|
||||
options.mapAddr,
|
||||
perms,
|
||||
options.useVA,
|
||||
options.loadBinCache,
|
||||
options.loadBinInfo,
|
||||
options.forceBinPlugin);
|
||||
if (!fileLoaded) {
|
||||
log(tr("Cannot open file for some reason"));
|
||||
// Something wrong happened, fallback to open dialog
|
||||
openFailed = true;
|
||||
emit openFileFailed();
|
||||
@@ -63,13 +68,14 @@ void AnalTask::runTask()
|
||||
}
|
||||
}
|
||||
|
||||
// r_core_bin_load might change asm.bits, so let's set that after the bin is loaded
|
||||
// r_core_bin_load might change asm.bits, so let's set that after the bin is
|
||||
// loaded
|
||||
Core()->setCPU(options.arch, options.cpu, options.bits);
|
||||
|
||||
if (isInterrupted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Core()->setConfig("anal.vars", options.analVars);
|
||||
if (!options.os.isNull()) {
|
||||
Core()->setConfig("asm.os", options.os);
|
||||
}
|
||||
@@ -85,7 +91,8 @@ void AnalTask::runTask()
|
||||
|
||||
if (!options.shellcode.isNull() && options.shellcode.size() / 2 > 0) {
|
||||
log(tr("Loading shellcode..."));
|
||||
Core()->cmdRaw("wx " + options.shellcode);
|
||||
Core()->cmd("wx " + options.shellcode + " @e:io.va=0@0");
|
||||
// Core()->cmdRaw("wx " + options.shellcode);
|
||||
}
|
||||
|
||||
if (options.endian != InitialOptions::Endianness::Auto) {
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#define ANALTHREAD_H
|
||||
|
||||
#include "common/AsyncTask.h"
|
||||
#include "core/Iaito.h"
|
||||
#include "common/InitialOptions.h"
|
||||
#include "core/Iaito.h"
|
||||
|
||||
class IaitoCore;
|
||||
class MainWindow;
|
||||
@@ -19,11 +19,11 @@ public:
|
||||
|
||||
QString getTitle() override;
|
||||
|
||||
void setOptions(const InitialOptions &options) { this->options = options; }
|
||||
void setOptions(const InitialOptions &options) { this->options = options; }
|
||||
|
||||
void interrupt() override;
|
||||
|
||||
bool getOpenFileFailed() { return openFailed; }
|
||||
bool getOpenFileFailed() { return openFailed; }
|
||||
|
||||
protected:
|
||||
void runTask() override;
|
||||
|
||||
@@ -1,9 +1,53 @@
|
||||
|
||||
#include "AsyncTask.h"
|
||||
|
||||
#include <csignal>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <thread>
|
||||
|
||||
// On Windows, do not attempt to signal child processes (no POSIX APIs)
|
||||
#if defined(_WIN32)
|
||||
static void signalChildProcessesAsync(int sig)
|
||||
{
|
||||
(void) sig;
|
||||
}
|
||||
#else
|
||||
static void signalChildProcessesAsync(int sig)
|
||||
{
|
||||
// Run in detached thread to keep interrupt non-blocking.
|
||||
std::thread([sig]() {
|
||||
pid_t mypid = getpid();
|
||||
// Use ps to enumerate child processes (portable and simple).
|
||||
FILE *fp = popen("ps -axo pid,ppid", "r");
|
||||
if (!fp) {
|
||||
return;
|
||||
}
|
||||
char *line = nullptr;
|
||||
size_t len = 0;
|
||||
// Skip header line
|
||||
ssize_t read = getline(&line, &len, fp);
|
||||
(void) read;
|
||||
while ((read = getline(&line, &len, fp)) != -1) {
|
||||
// parse two integers
|
||||
long pid = 0, ppid = 0;
|
||||
if (sscanf(line, "%ld %ld", &pid, &ppid) != 2) {
|
||||
continue;
|
||||
}
|
||||
if ((pid_t) ppid == mypid && (pid_t) pid != mypid) {
|
||||
// Send the requested signal to the direct child.
|
||||
kill((pid_t) pid, sig);
|
||||
}
|
||||
}
|
||||
free(line);
|
||||
pclose(fp);
|
||||
}).detach();
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
AsyncTask::AsyncTask()
|
||||
: QObject(nullptr),
|
||||
QRunnable()
|
||||
: QObject(nullptr)
|
||||
, QRunnable()
|
||||
{
|
||||
setAutoDelete(false);
|
||||
running = false;
|
||||
@@ -32,6 +76,10 @@ bool AsyncTask::wait(int timeout)
|
||||
void AsyncTask::interrupt()
|
||||
{
|
||||
interrupted = true;
|
||||
// Non-blocking best-effort: signal child processes (e.g., curl spawned by r2js)
|
||||
// with SIGINT so they stop promptly. This is done asynchronously so
|
||||
// interrupt() returns immediately.
|
||||
signalChildProcessesAsync(SIGINT);
|
||||
}
|
||||
|
||||
void AsyncTask::prepareRun()
|
||||
@@ -70,9 +118,7 @@ AsyncTaskManager::AsyncTaskManager(QObject *parent)
|
||||
threadPool = new QThreadPool(this);
|
||||
}
|
||||
|
||||
AsyncTaskManager::~AsyncTaskManager()
|
||||
{
|
||||
}
|
||||
AsyncTaskManager::~AsyncTaskManager() {}
|
||||
|
||||
void AsyncTaskManager::start(AsyncTask::Ptr task)
|
||||
{
|
||||
|
||||
@@ -4,19 +4,19 @@
|
||||
|
||||
#include "core/IaitoCommon.h"
|
||||
|
||||
#include <QRunnable>
|
||||
#include <QThreadPool>
|
||||
#include <QMutex>
|
||||
#include <QElapsedTimer>
|
||||
#include <QSharedPointer>
|
||||
#include <QList>
|
||||
#include <QMutex>
|
||||
#include <QRunnable>
|
||||
#include <QSharedPointer>
|
||||
#include <QThreadPool>
|
||||
|
||||
class AsyncTaskManager;
|
||||
|
||||
// 8 MB should be enough for deep analysis.. default is 512KB
|
||||
#define R2THREAD_STACK_SIZE 1024*1024*8
|
||||
#define R2THREAD_STACK_SIZE 1024 * 1024 * 8
|
||||
|
||||
class IAITO_EXPORT AsyncTask : public QObject, public QRunnable
|
||||
class IAITO_EXPORT AsyncTask : public QObject, public QRunnable
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -33,17 +33,17 @@ public:
|
||||
void wait();
|
||||
bool wait(int timeout);
|
||||
virtual void interrupt();
|
||||
bool isInterrupted() { return interrupted; }
|
||||
bool isRunning() { return running; }
|
||||
bool isInterrupted() { return interrupted; }
|
||||
bool isRunning() { return running; }
|
||||
|
||||
const QString &getLog() { return logBuffer; }
|
||||
const QElapsedTimer &getTimer() { return timer; }
|
||||
qint64 getElapsedTime() { return timer.isValid() ? timer.elapsed() : 0; }
|
||||
const QString &getLog() { return logBuffer; }
|
||||
const QElapsedTimer &getTimer() { return timer; }
|
||||
qint64 getElapsedTime() { return timer.isValid() ? timer.elapsed() : 0; }
|
||||
|
||||
virtual QString getTitle() { return QString(); }
|
||||
virtual QString getTitle() { return QString(); }
|
||||
|
||||
protected:
|
||||
virtual void runTask() =0;
|
||||
virtual void runTask() = 0;
|
||||
|
||||
void log(QString s);
|
||||
|
||||
@@ -81,5 +81,4 @@ signals:
|
||||
void tasksChanged();
|
||||
};
|
||||
|
||||
|
||||
#endif //ASYNCTASK_H
|
||||
#endif // ASYNCTASK_H
|
||||
@@ -1,8 +1,6 @@
|
||||
#include "BasicBlockHighlighter.h"
|
||||
|
||||
BasicBlockHighlighter::BasicBlockHighlighter()
|
||||
{
|
||||
}
|
||||
BasicBlockHighlighter::BasicBlockHighlighter() {}
|
||||
|
||||
BasicBlockHighlighter::~BasicBlockHighlighter()
|
||||
{
|
||||
@@ -41,7 +39,7 @@ BasicBlock *BasicBlockHighlighter::getBasicBlock(RVA address)
|
||||
|
||||
it = bbMap.find(address);
|
||||
if (it != bbMap.end()) {
|
||||
return it->second;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
@@ -6,12 +6,13 @@ class BasicBlockHighlighter;
|
||||
#include "Iaito.h"
|
||||
#include <map>
|
||||
|
||||
struct BasicBlock {
|
||||
struct BasicBlock
|
||||
{
|
||||
RVA address;
|
||||
QColor color;
|
||||
};
|
||||
|
||||
typedef std::map<RVA, BasicBlock*>::iterator BasicBlockIt;
|
||||
typedef std::map<RVA, BasicBlock *>::iterator BasicBlockIt;
|
||||
|
||||
class BasicBlockHighlighter
|
||||
{
|
||||
@@ -24,7 +25,7 @@ public:
|
||||
BasicBlock *getBasicBlock(RVA address);
|
||||
|
||||
private:
|
||||
std::map<RVA, BasicBlock*> bbMap;
|
||||
std::map<RVA, BasicBlock *> bbMap;
|
||||
};
|
||||
|
||||
#endif // BASICBLOCKHIGHLIGHTER_H
|
||||
#endif // BASICBLOCKHIGHLIGHTER_H
|
||||
@@ -41,7 +41,7 @@ void BasicInstructionHighlighter::clear(RVA address, RVA size)
|
||||
}
|
||||
}
|
||||
|
||||
for ( BasicInstruction newInstr : newInstructions) {
|
||||
for (BasicInstruction newInstr : newInstructions) {
|
||||
biMap[newInstr.address] = newInstr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
#include <map>
|
||||
#include <QColor>
|
||||
|
||||
struct BasicInstruction {
|
||||
struct BasicInstruction
|
||||
{
|
||||
RVA address;
|
||||
RVA size;
|
||||
QColor color;
|
||||
|
||||
@@ -5,22 +5,24 @@
|
||||
* \brief Utilities to simplify creation of specialized augmented binary trees.
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
#include <climits>
|
||||
#include <cstdint>
|
||||
#include <algorithm>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* Not really a segment tree for storing segments as referred in academic literature. Can be considered a
|
||||
* full, almost perfect, augmented binary tree. In the context of competitive programming often called segment tree.
|
||||
* Not really a segment tree for storing segments as referred in academic
|
||||
* literature. Can be considered a full, almost perfect, augmented binary tree.
|
||||
* In the context of competitive programming often called segment tree.
|
||||
*
|
||||
* Child classes are expected to implement updateFromChildren(NodeType&parent, NodeType& left, NodeType& right)
|
||||
* method which calculates inner node values from children nodes.
|
||||
* Child classes are expected to implement updateFromChildren(NodeType&parent,
|
||||
* NodeType& left, NodeType& right) method which calculates inner node values
|
||||
* from children nodes.
|
||||
*
|
||||
* \tparam NodeTypeT type of each tree element
|
||||
* \tparam FinalType final child class used for curiously recurring template pattern
|
||||
* \tparam FinalType final child class used for curiously recurring template
|
||||
* pattern
|
||||
*/
|
||||
template<class NodeTypeT, class FinalType>
|
||||
class SegmentTreeBase
|
||||
@@ -51,33 +53,19 @@ public:
|
||||
{
|
||||
init(initialValue);
|
||||
}
|
||||
|
||||
protected:
|
||||
// Curiously recurring template pattern
|
||||
FinalType &This()
|
||||
{
|
||||
return static_cast<FinalType &>(*this);
|
||||
}
|
||||
FinalType &This() { return static_cast<FinalType &>(*this); }
|
||||
|
||||
// Curiously recurring template pattern
|
||||
const FinalType &This() const
|
||||
{
|
||||
return static_cast<const FinalType &>(*this);
|
||||
}
|
||||
const FinalType &This() const { return static_cast<const FinalType &>(*this); }
|
||||
|
||||
size_t leavePositionToIndex(NodePosition pos) const
|
||||
{
|
||||
return pos - size;
|
||||
}
|
||||
size_t leavePositionToIndex(NodePosition pos) const { return pos - size; }
|
||||
|
||||
NodePosition leaveIndexToPosition(size_t index) const
|
||||
{
|
||||
return index + size;
|
||||
}
|
||||
NodePosition leaveIndexToPosition(size_t index) const { return index + size; }
|
||||
|
||||
bool isLeave(NodePosition position) const
|
||||
{
|
||||
return position >= size;
|
||||
}
|
||||
bool isLeave(NodePosition position) const { return position >= size; }
|
||||
|
||||
/**
|
||||
* @brief Calculate inner node values from leaves.
|
||||
@@ -111,6 +99,7 @@ template<class NodeType, class FinalType>
|
||||
class PointSetSegmentTree : public SegmentTreeBase<NodeType, FinalType>
|
||||
{
|
||||
using BaseType = SegmentTreeBase<NodeType, FinalType>;
|
||||
|
||||
public:
|
||||
using BaseType::BaseType;
|
||||
|
||||
@@ -125,7 +114,8 @@ public:
|
||||
this->nodes[pos] = value;
|
||||
while (pos > 1) {
|
||||
auto parrent = pos >> 1;
|
||||
this->This().updateFromChildren(this->nodes[parrent], this->nodes[pos], this->nodes[pos ^ 1]);
|
||||
this->This()
|
||||
.updateFromChildren(this->nodes[parrent], this->nodes[pos], this->nodes[pos ^ 1]);
|
||||
pos = parrent;
|
||||
}
|
||||
}
|
||||
@@ -141,6 +131,7 @@ public:
|
||||
class PointSetMinTree : public PointSetSegmentTree<int, PointSetMinTree>
|
||||
{
|
||||
using BaseType = PointSetSegmentTree<int, PointSetMinTree>;
|
||||
|
||||
public:
|
||||
using NodeType = int;
|
||||
|
||||
@@ -152,23 +143,24 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find right most position with value than less than given in range [0; position].
|
||||
* @brief Find right most position with value than less than given in range
|
||||
* [0; position].
|
||||
* @param position inclusive right side of query range
|
||||
* @param value search for position less than this
|
||||
* @return returns the position with searched property or -1 if there is no such position.
|
||||
* @return returns the position with searched property or -1 if there is no
|
||||
* such position.
|
||||
*/
|
||||
int rightMostLessThan(size_t position, int value)
|
||||
{
|
||||
auto isGood = [&](size_t pos) {
|
||||
return nodes[pos] < value;
|
||||
};
|
||||
auto isGood = [&](size_t pos) { return nodes[pos] < value; };
|
||||
// right side exclusive range [l;r)
|
||||
size_t goodSubtree = 0;
|
||||
for (size_t l = leaveIndexToPosition(0), r = leaveIndexToPosition(position + 1); l < r;
|
||||
l >>= 1, r >>= 1) {
|
||||
l >>= 1, r >>= 1) {
|
||||
if (l & 1) {
|
||||
if (isGood(l)) {
|
||||
// mark subtree as good but don't stop yet, there might be something good further to the right
|
||||
// mark subtree as good but don't stop yet, there might be
|
||||
// something good further to the right
|
||||
goodSubtree = l;
|
||||
}
|
||||
++l;
|
||||
@@ -195,20 +187,20 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find left most position with value less than \a value in range [position; size).
|
||||
* @brief Find left most position with value less than \a value in range
|
||||
* [position; size).
|
||||
* @param position inclusive left side of query range
|
||||
* @param value search for position less than this
|
||||
* @return returns the position with searched property or -1 if there is no such position.
|
||||
* @return returns the position with searched property or -1 if there is no
|
||||
* such position.
|
||||
*/
|
||||
int leftMostLessThan(size_t position, int value)
|
||||
{
|
||||
auto isGood = [&](size_t pos) {
|
||||
return nodes[pos] < value;
|
||||
};
|
||||
auto isGood = [&](size_t pos) { return nodes[pos] < value; };
|
||||
// right side exclusive range [l;r)
|
||||
size_t goodSubtree = 0;
|
||||
for (size_t l = leaveIndexToPosition(position), r = leaveIndexToPosition(size); l < r;
|
||||
l >>= 1, r >>= 1) {
|
||||
l >>= 1, r >>= 1) {
|
||||
if (l & 1) {
|
||||
if (isGood(l)) {
|
||||
goodSubtree = l;
|
||||
@@ -220,7 +212,8 @@ public:
|
||||
--r;
|
||||
if (isGood(r)) {
|
||||
goodSubtree = r;
|
||||
// mark subtree as good but don't stop yet, there might be something good further to the left
|
||||
// mark subtree as good but don't stop yet, there might be
|
||||
// something good further to the left
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -241,19 +234,22 @@ public:
|
||||
/**
|
||||
* \brief Tree that supports lazily applying an operation to range.
|
||||
*
|
||||
* Each inner node has a promise value describing an operation that needs to be applied to corresponding subtree.
|
||||
* Each inner node has a promise value describing an operation that needs to be
|
||||
* applied to corresponding subtree.
|
||||
*
|
||||
* Child classes are expected to implement to pushDown(size_t nodePosition) method. Which applies the applies the
|
||||
* operation stored in \a promise for nodePosition to the direct children nodes.
|
||||
* Child classes are expected to implement to pushDown(size_t nodePosition)
|
||||
* method. Which applies the applies the operation stored in \a promise for
|
||||
* nodePosition to the direct children nodes.
|
||||
*
|
||||
* \tparam NodeType type of tree nodes
|
||||
* \tparam PromiseType type describing operation that needs to be applied to subtree
|
||||
* \tparam FinalType child class type for CRTP. See SegmentTreeBase
|
||||
* \tparam PromiseType type describing operation that needs to be applied to
|
||||
* subtree \tparam FinalType child class type for CRTP. See SegmentTreeBase
|
||||
*/
|
||||
template <class NodeType, class PromiseType, class FinalType>
|
||||
template<class NodeType, class PromiseType, class FinalType>
|
||||
class LazySegmentTreeBase : public SegmentTreeBase<NodeType, FinalType>
|
||||
{
|
||||
using BaseType = SegmentTreeBase<NodeType, FinalType>;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @param size Number of tree leaves.
|
||||
@@ -305,7 +301,8 @@ public:
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Ensure that all the parents of node \a p have the operation applied.
|
||||
* @brief Ensure that all the parents of node \a p have the operation
|
||||
* applied.
|
||||
* @param p Node position
|
||||
*/
|
||||
void pushDownFromRoot(typename BaseType::NodePosition p)
|
||||
@@ -324,7 +321,8 @@ protected:
|
||||
while (p > 1) {
|
||||
auto parent = p >> 1;
|
||||
if (promise[parent] == neutralPromiseElement) {
|
||||
This().updateFromChildren(this->nodes[parent], this->nodes[p & ~size_t(1)], this->nodes[p | 1]);
|
||||
This().updateFromChildren(
|
||||
this->nodes[parent], this->nodes[p & ~size_t(1)], this->nodes[p | 1]);
|
||||
}
|
||||
p = parent;
|
||||
}
|
||||
@@ -337,19 +335,18 @@ protected:
|
||||
std::vector<PromiseType> promise;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Structure supporting range assignment and range maximum operations.
|
||||
*/
|
||||
class RangeAssignMaxTree : public LazySegmentTreeBase<int, uint8_t, RangeAssignMaxTree>
|
||||
{
|
||||
using BaseType = LazySegmentTreeBase<int, uint8_t, RangeAssignMaxTree>;
|
||||
|
||||
public:
|
||||
using ValueType = int;
|
||||
RangeAssignMaxTree(size_t size, ValueType initialValue)
|
||||
: BaseType(size, initialValue, 0)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
void updateFromChildren(NodeType &parent, const NodeType &left, const NodeType &right)
|
||||
{
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
#include "BugReporting.h"
|
||||
|
||||
#include "Iaito.h"
|
||||
#include <QUrl>
|
||||
#include <QJsonObject>
|
||||
#include "IaitoConfig.h"
|
||||
#include <QDesktopServices>
|
||||
#include <QJsonObject>
|
||||
#include <QUrl>
|
||||
|
||||
void openIssue()
|
||||
{
|
||||
QString url, osInfo, format, arch, type;
|
||||
//Pull in info needed for git issue
|
||||
osInfo = QSysInfo::productType() + " " +
|
||||
(QSysInfo::productVersion() == "unknown"
|
||||
? ""
|
||||
: QSysInfo::productVersion());
|
||||
// Pull in info needed for git issue
|
||||
osInfo = QSysInfo::productType() + " "
|
||||
+ (QSysInfo::productVersion() == "unknown" ? "" : QSysInfo::productVersion());
|
||||
QJsonDocument docu = Core()->getFileInfo();
|
||||
QJsonObject coreObj = docu.object()["core"].toObject();
|
||||
QJsonObject binObj = docu.object()["bin"].toObject();
|
||||
@@ -30,16 +28,19 @@ void openIssue()
|
||||
arch = "N/A";
|
||||
type = "N/A";
|
||||
}
|
||||
url =
|
||||
"https://github.com/radareorg/iaito/issues/new?&body=**Environment information**\n* Operating System: "
|
||||
+ osInfo + "\n* Iaito version: " + IAITO_VERSION_FULL +
|
||||
"\n* File format: " + format + "\n * Arch: " + arch + "\n * Type: " + type +
|
||||
"\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\n"
|
||||
"Steps to reproduce the behavior:\n1. Go to '...'\n2. Click on '....'\n3. Scroll down to '....'\n"
|
||||
"4. See error\n\n**Expected behavior**\n"
|
||||
"A clear and concise description of what you expected to happen.\n\n"
|
||||
"**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n"
|
||||
"**Additional context**\nAdd any other context about the problem here.";
|
||||
url = "https://github.com/radareorg/iaito/issues/new?&body=**Environment "
|
||||
"information**\n* Operating System: "
|
||||
+ osInfo + "\n* Iaito version: " + IAITO_VERSION_FULL + "\n* File format: " + format
|
||||
+ "\n * Arch: " + arch + "\n * Type: " + type
|
||||
+ "\n\n**Describe the bug**\nA clear and concise description of what the "
|
||||
"bug is.\n\n**To Reproduce**\n"
|
||||
"Steps to reproduce the behavior:\n1. Go to '...'\n2. Click on "
|
||||
"'....'\n3. Scroll down to '....'\n"
|
||||
"4. See error\n\n**Expected behavior**\n"
|
||||
"A clear and concise description of what you expected to happen.\n\n"
|
||||
"**Screenshots**\nIf applicable, add screenshots to help explain your "
|
||||
"problem.\n\n"
|
||||
"**Additional context**\nAdd any other context about the problem here.";
|
||||
|
||||
QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode));
|
||||
QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode));
|
||||
}
|
||||
@@ -3,9 +3,9 @@
|
||||
|
||||
#include "common/Metrics.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QFont>
|
||||
#include <QFontMetrics>
|
||||
#include <QObject>
|
||||
|
||||
template<typename T>
|
||||
class CachedFontMetrics
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
|
||||
T width(const QChar &ch)
|
||||
{
|
||||
//return mFontMetrics.width(ch);
|
||||
// return mFontMetrics.width(ch);
|
||||
auto unicode = ch.unicode();
|
||||
if (unicode >= 0xD800) {
|
||||
if (unicode >= 0xE000)
|
||||
@@ -49,10 +49,7 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
T height()
|
||||
{
|
||||
return mHeight;
|
||||
}
|
||||
T height() { return mHeight; }
|
||||
|
||||
T position(const QString &text, T offset)
|
||||
{
|
||||
@@ -84,7 +81,7 @@ private:
|
||||
|
||||
T fetchWidth(QChar c)
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5,11,0)
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
|
||||
return mFontMetrics.width(c);
|
||||
#else
|
||||
return mFontMetrics.horizontalAdvance(c);
|
||||
@@ -93,7 +90,7 @@ private:
|
||||
|
||||
T fetchWidth(const QString &s)
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5,11,0)
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
|
||||
return mFontMetrics.width(s);
|
||||
#else
|
||||
return mFontMetrics.horizontalAdvance(s);
|
||||
|
||||
@@ -1,98 +1,75 @@
|
||||
#include "ColorThemeWorker.h"
|
||||
|
||||
#include <QColor>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QColor>
|
||||
#include <QJsonArray>
|
||||
#include <QStandardPaths>
|
||||
#include <QRegularExpression>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#include "common/Configuration.h"
|
||||
|
||||
const QStringList ColorThemeWorker::cutterSpecificOptions = {
|
||||
"wordHighlight",
|
||||
"lineHighlight",
|
||||
"gui.main",
|
||||
"gui.imports",
|
||||
"highlightPC",
|
||||
"gui.navbar.err",
|
||||
"gui.navbar.seek",
|
||||
"gui.navbar.pc",
|
||||
"gui.navbar.sym",
|
||||
"gui.dataoffset",
|
||||
"gui.navbar.code",
|
||||
"gui.navbar.empty",
|
||||
"angui.navbar.str",
|
||||
"gui.disass_selected",
|
||||
"gui.breakpoint_background",
|
||||
"gui.overview.node",
|
||||
"gui.overview.fill",
|
||||
"gui.overview.border",
|
||||
"gui.border",
|
||||
"gui.background",
|
||||
"gui.alt_background",
|
||||
"gui.disass_selected"
|
||||
};
|
||||
const QStringList ColorThemeWorker::iaitoSpecificOptions
|
||||
= {"wordHighlight", "lineHighlight", "gui.main",
|
||||
"gui.imports", "highlightPC", "gui.navbar.err",
|
||||
"gui.navbar.seek", "gui.navbar.pc", "gui.navbar.sym",
|
||||
"gui.dataoffset", "gui.navbar.code", "gui.navbar.empty",
|
||||
"angui.navbar.str", "gui.disass_selected", "gui.breakpoint_background",
|
||||
"gui.overview.node", "gui.overview.fill", "gui.overview.border",
|
||||
"gui.border", "gui.background", "gui.alt_background",
|
||||
"gui.disass_selected"};
|
||||
|
||||
const QStringList ColorThemeWorker::radare2UnusedOptions = {
|
||||
"linehl",
|
||||
"wordhl",
|
||||
"graph.box",
|
||||
"graph.box2",
|
||||
"graph.box3",
|
||||
"graph.box4",
|
||||
"graph.current",
|
||||
"graph.box2",
|
||||
"widget_sel",
|
||||
"widget_bg",
|
||||
"label",
|
||||
"ai.write",
|
||||
"invalid",
|
||||
"ai.seq",
|
||||
"args",
|
||||
"ai.read",
|
||||
"ai.exec",
|
||||
"ai.ascii",
|
||||
"prompt",
|
||||
"graph.traced"
|
||||
};
|
||||
const QStringList ColorThemeWorker::radare2UnusedOptions
|
||||
= {"linehl", "wordhl", "graph.box", "graph.box2", "graph.box3",
|
||||
"graph.box4", "graph.current", "graph.box2", "widget_sel", "widget_bg",
|
||||
"label", "ai.write", "invalid", "ai.seq", "args",
|
||||
"ai.read", "ai.exec", "ai.ascii", "prompt", "graph.traced"};
|
||||
|
||||
ColorThemeWorker::ColorThemeWorker(QObject *parent) : QObject (parent)
|
||||
ColorThemeWorker::ColorThemeWorker(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
#if R2_VERSION_NUMBER < 50709
|
||||
char* szThemes = r_str_home (R2_HOME_THEMES);
|
||||
char *szThemes = r_str_home(R2_HOME_THEMES);
|
||||
#else
|
||||
char* szThemes = r_xdg_datadir ("cons");
|
||||
char *szThemes = r_xdg_datadir("cons");
|
||||
#endif
|
||||
customR2ThemesLocationPath = szThemes;
|
||||
r_mem_free (szThemes);
|
||||
if (!QDir (customR2ThemesLocationPath).exists ()) {
|
||||
QDir().mkpath (customR2ThemesLocationPath);
|
||||
r_mem_free(szThemes);
|
||||
if (!QDir(customR2ThemesLocationPath).exists()) {
|
||||
// let the user place their color themes here
|
||||
QDir().mkpath(customR2ThemesLocationPath);
|
||||
}
|
||||
|
||||
QDir currDir {
|
||||
QStringLiteral("%1%2%3")
|
||||
.arg(r_sys_prefix(nullptr))
|
||||
.arg(R_SYS_DIR)
|
||||
.arg(R2_THEMES)
|
||||
};
|
||||
if (currDir.exists ()) {
|
||||
standardR2ThemesLocationPath = currDir.absolutePath ();
|
||||
// resolve system path (version specific)
|
||||
QDir currDir{QStringLiteral("%1%2%3").arg(r_sys_prefix(nullptr)).arg(R_SYS_DIR).arg(R2_THEMES)};
|
||||
if (currDir.exists()) {
|
||||
standardR2ThemesLocationPath = currDir.absolutePath();
|
||||
} else {
|
||||
QMessageBox::critical (nullptr,
|
||||
tr("Standard themes not found"),
|
||||
tr("The radare2 standard themes could not be found in '%1'. "
|
||||
"Most likely, radare2 is not properly installed.")
|
||||
.arg(currDir.path())
|
||||
);
|
||||
// if not found just use /last/ instead of the version
|
||||
QDir currDir{
|
||||
QStringLiteral("%1/%3").arg(r_sys_prefix(nullptr)).arg("share/radare2/last/cons")};
|
||||
if (currDir.exists()) {
|
||||
standardR2ThemesLocationPath = currDir.absolutePath();
|
||||
} else {
|
||||
QMessageBox::critical(
|
||||
nullptr,
|
||||
tr("Standard themes not found"),
|
||||
tr("Cannot find radare2 console themes in '%1'. ").arg(currDir.path()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QColor ColorThemeWorker::mergeColors(const QColor& upper, const QColor& lower) const
|
||||
QColor ColorThemeWorker::mergeColors(const QColor &upper, const QColor &lower) const
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
// not implemented Qt::SHIFT doesnt exist
|
||||
float r1, g1, b1, a1;
|
||||
float r2, g2, b2, a2;
|
||||
float r, g, b, a;
|
||||
#else
|
||||
qreal r1, g1, b1, a1;
|
||||
qreal r2, g2, b2, a2;
|
||||
qreal r, g, b, a;
|
||||
#endif
|
||||
|
||||
upper.getRgbF(&r1, &g1, &b1, &a1);
|
||||
lower.getRgbF(&r2, &g2, &b2, &a2);
|
||||
@@ -107,12 +84,10 @@ QColor ColorThemeWorker::mergeColors(const QColor& upper, const QColor& lower) c
|
||||
return res;
|
||||
}
|
||||
|
||||
QString ColorThemeWorker::copy(const QString &srcThemeName,
|
||||
const QString ©ThemeName) const
|
||||
QString ColorThemeWorker::copy(const QString &srcThemeName, const QString ©ThemeName) const
|
||||
{
|
||||
if (!isThemeExist(srcThemeName)) {
|
||||
return tr("Theme <b>%1</b> does not exist.")
|
||||
.arg(srcThemeName);
|
||||
return tr("Theme <b>%1</b> does not exist.").arg(srcThemeName);
|
||||
}
|
||||
|
||||
return save(getTheme(srcThemeName), copyThemeName);
|
||||
@@ -122,13 +97,11 @@ QString ColorThemeWorker::save(const QJsonDocument &theme, const QString &themeN
|
||||
{
|
||||
QFile fOut(QDir(customR2ThemesLocationPath).filePath(themeName));
|
||||
if (!fOut.open(QFile::WriteOnly | QFile::Truncate)) {
|
||||
return tr("The file <b>%1</b> cannot be opened.")
|
||||
.arg(QFileInfo(fOut).filePath());
|
||||
return tr("The file <b>%1</b> cannot be opened.").arg(QFileInfo(fOut).filePath());
|
||||
}
|
||||
|
||||
QJsonObject obj = theme.object();
|
||||
for (auto it = obj.constBegin(); it != obj.constEnd(); it++) {
|
||||
|
||||
QJsonArray arr = it.value().toArray();
|
||||
QColor color;
|
||||
if (arr.isEmpty()) {
|
||||
@@ -140,14 +113,14 @@ QString ColorThemeWorker::save(const QJsonDocument &theme, const QString &themeN
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
if (cutterSpecificOptions.contains(it.key())) {
|
||||
fOut.write(QString("#~%1 rgb:%2\n")
|
||||
.arg(it.key(), color.name(QColor::HexArgb).remove('#'))
|
||||
.toUtf8());
|
||||
if (iaitoSpecificOptions.contains(it.key())) {
|
||||
fOut.write(QStringLiteral("#~%1 rgb:%2\n")
|
||||
.arg(it.key(), color.name(QColor::HexArgb).remove('#'))
|
||||
.toUtf8());
|
||||
} else {
|
||||
fOut.write(QString("ec %1 rgb:%2\n")
|
||||
.arg(it.key(), color.name(QColor::HexRgb).remove('#'))
|
||||
.toUtf8());
|
||||
fOut.write(QStringLiteral("ec %1 rgb:%2\n")
|
||||
.arg(it.key(), color.name(QColor::HexRgb).remove('#'))
|
||||
.toUtf8());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,16 +139,16 @@ bool ColorThemeWorker::isThemeExist(const QString &name) const
|
||||
return themes.contains(name);
|
||||
}
|
||||
|
||||
QJsonDocument ColorThemeWorker::getTheme(const QString& themeName) const
|
||||
QJsonDocument ColorThemeWorker::getTheme(const QString &themeName) const
|
||||
{
|
||||
int r, g, b, a;
|
||||
QVariantMap theme;
|
||||
QString curr = Config()->getColorTheme();
|
||||
|
||||
if (themeName != curr) {
|
||||
Core()->cmdRaw(QString("eco %1").arg(themeName));
|
||||
Core()->cmdRaw(QStringLiteral("eco %1").arg(themeName));
|
||||
theme = Core()->cmdj("ecj").object().toVariantMap();
|
||||
Core()->cmdRaw(QString("eco %1").arg(curr));
|
||||
Core()->cmdRaw(QStringLiteral("eco %1").arg(curr));
|
||||
} else {
|
||||
theme = Core()->cmdj("ecj").object().toVariantMap();
|
||||
}
|
||||
@@ -191,8 +164,8 @@ QJsonDocument ColorThemeWorker::getTheme(const QString& themeName) const
|
||||
colorFlags = Configuration::relevantThemes[themeName];
|
||||
}
|
||||
|
||||
for (auto& it : cutterSpecificOptions) {
|
||||
Configuration::cutterOptionColors[it][colorFlags].getRgb(&r, &g, &b, &a);
|
||||
for (auto &it : iaitoSpecificOptions) {
|
||||
Configuration::iaitoOptionColors[it][colorFlags].getRgb(&r, &g, &b, &a);
|
||||
theme.insert(it, QJsonArray{r, g, b, a});
|
||||
}
|
||||
|
||||
@@ -217,8 +190,9 @@ QJsonDocument ColorThemeWorker::getTheme(const QString& themeName) const
|
||||
}
|
||||
|
||||
// manualy converting instead of using QJsonObject::fromVariantMap because
|
||||
// Qt < 5.6 QJsonValue.fromVariant doesn't expect QVariant to already contain
|
||||
// QJson values like QJsonArray. https://github.com/qt/qtbase/commit/26237f0a2d8db80024b601f676bbce54d483e672
|
||||
// Qt < 5.6 QJsonValue.fromVariant doesn't expect QVariant to already
|
||||
// contain QJson values like QJsonArray.
|
||||
// https://github.com/qt/qtbase/commit/26237f0a2d8db80024b601f676bbce54d483e672
|
||||
QJsonObject obj;
|
||||
for (auto it = theme.begin(); it != theme.end(); it++) {
|
||||
auto &value = it.value();
|
||||
@@ -227,7 +201,6 @@ QJsonDocument ColorThemeWorker::getTheme(const QString& themeName) const
|
||||
} else {
|
||||
obj[it.key()] = QJsonValue::fromVariant(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return QJsonDocument(obj);
|
||||
@@ -244,33 +217,30 @@ QString ColorThemeWorker::deleteTheme(const QString &themeName) const
|
||||
|
||||
QFile file(QDir(customR2ThemesLocationPath).filePath(themeName));
|
||||
if (file.isWritable()) {
|
||||
return tr("You have no permission to write to <b>%1</b>")
|
||||
.arg(QFileInfo(file).filePath());
|
||||
return tr("You have no permission to write to <b>%1</b>").arg(QFileInfo(file).filePath());
|
||||
}
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
return tr("File <b>%1</b> can not be opened.")
|
||||
.arg(QFileInfo(file).filePath());
|
||||
return tr("File <b>%1</b> can not be opened.").arg(QFileInfo(file).filePath());
|
||||
}
|
||||
if (!file.remove()) {
|
||||
return tr("File <b>%1</b> can not be removed.")
|
||||
.arg(QFileInfo(file).filePath());
|
||||
return tr("File <b>%1</b> can not be removed.").arg(QFileInfo(file).filePath());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
QString ColorThemeWorker::importTheme(const QString& file) const
|
||||
QString ColorThemeWorker::importTheme(const QString &file) const
|
||||
{
|
||||
QFileInfo src(file);
|
||||
if (!src.exists()) {
|
||||
return tr("File <b>%1</b> does not exist.").arg(file);
|
||||
}
|
||||
if (!src.exists()) {
|
||||
return tr("File <b>%1</b> does not exist.").arg(file);
|
||||
}
|
||||
|
||||
bool ok;
|
||||
bool isTheme = isFileTheme(file, &ok);
|
||||
if (!ok) {
|
||||
return tr("File <b>%1</b> could not be opened. "
|
||||
"Please make sure you have access to it and try again.")
|
||||
.arg(file);
|
||||
.arg(file);
|
||||
} else if (!isTheme) {
|
||||
return tr("File <b>%1</b> is not a Iaito color theme").arg(file);
|
||||
}
|
||||
@@ -281,35 +251,37 @@ QString ColorThemeWorker::importTheme(const QString& file) const
|
||||
}
|
||||
|
||||
if (QFile::copy(file, QDir(customR2ThemesLocationPath).filePath(name))) {
|
||||
return "";
|
||||
} else {
|
||||
return tr("Error occurred during importing. "
|
||||
"Please make sure you have an access to "
|
||||
"the directory <b>%1</b> and try again.")
|
||||
.arg(src.dir().path());
|
||||
return "";
|
||||
} else {
|
||||
return tr("Error occurred during importing. "
|
||||
"Please make sure you have an access to "
|
||||
"the directory <b>%1</b> and try again.")
|
||||
.arg(src.dir().path());
|
||||
}
|
||||
}
|
||||
|
||||
QString ColorThemeWorker::renameTheme(const QString& themeName, const QString& newName) const
|
||||
QString ColorThemeWorker::renameTheme(const QString &themeName, const QString &newName) const
|
||||
{
|
||||
if (isThemeExist(newName)) {
|
||||
return tr("A color theme named <b>\"%1\"</b> already exists.").arg(newName);
|
||||
}
|
||||
return tr("A color theme named <b>\"%1\"</b> already exists.").arg(newName);
|
||||
}
|
||||
|
||||
if (!isCustomTheme(themeName)) {
|
||||
return tr("You can not rename standard radare2 themes.");
|
||||
}
|
||||
if (!isCustomTheme(themeName)) {
|
||||
return tr("You can not rename standard radare2 themes.");
|
||||
}
|
||||
|
||||
QDir dir = customR2ThemesLocationPath;
|
||||
bool ok = QFile::rename(dir.filePath(themeName), dir.filePath(newName));
|
||||
if (!ok) {
|
||||
return tr("Something went wrong during renaming. "
|
||||
"Please make sure you have access to the directory <b>\"%1\"</b>.").arg(dir.path());
|
||||
}
|
||||
return "";
|
||||
QDir dir = customR2ThemesLocationPath;
|
||||
bool ok = QFile::rename(dir.filePath(themeName), dir.filePath(newName));
|
||||
if (!ok) {
|
||||
return tr("Something went wrong during renaming. "
|
||||
"Please make sure you have access to the directory "
|
||||
"<b>\"%1\"</b>.")
|
||||
.arg(dir.path());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool ColorThemeWorker::isFileTheme(const QString& filePath, bool* ok) const
|
||||
bool ColorThemeWorker::isFileTheme(const QString &filePath, bool *ok) const
|
||||
{
|
||||
QFile f(filePath);
|
||||
if (!f.open(QFile::ReadOnly)) {
|
||||
@@ -318,12 +290,15 @@ bool ColorThemeWorker::isFileTheme(const QString& filePath, bool* ok) const
|
||||
}
|
||||
|
||||
const QString colors = "black|red|white|green|magenta|yellow|cyan|blue|gray|none";
|
||||
QString options = (Core()->cmdj("ecj").object().keys() << cutterSpecificOptions)
|
||||
.join('|')
|
||||
.replace(".", "\\.");
|
||||
QString options = (Core()->cmdj("ecj").object().keys() << iaitoSpecificOptions)
|
||||
.join('|')
|
||||
.replace(".", "\\.");
|
||||
|
||||
QString pattern = QString("((ec\\s+(%1)\\s+(((rgb:|#)[0-9a-fA-F]{3,8})|(%2))))\\s*").arg(options).arg(colors);
|
||||
// The below construct mimics the behaviour of QRegexP::exactMatch(), which was here before
|
||||
QString pattern = QStringLiteral("((ec\\s+(%1)\\s+(((rgb:|#)[0-9a-fA-F]{3,8})|(%2))))\\s*")
|
||||
.arg(options)
|
||||
.arg(colors);
|
||||
// The below construct mimics the behaviour of QRegexP::exactMatch(), which
|
||||
// was here before
|
||||
QRegularExpression regexp("\\A(?:" + pattern + ")\\z");
|
||||
|
||||
for (auto &line : QString(f.readAll()).split('\n', IAITO_QT_SKIP_EMPTY_PARTS)) {
|
||||
|
||||
@@ -1,34 +1,37 @@
|
||||
#ifndef COLORTHEMEWORKER_H
|
||||
#define COLORTHEMEWORKER_H
|
||||
|
||||
#include <QFile>
|
||||
#include <QColor>
|
||||
#include <QObject>
|
||||
#include "Iaito.h"
|
||||
#include <QColor>
|
||||
#include <QFile>
|
||||
#include <QJsonObject>
|
||||
#include <QObject>
|
||||
|
||||
#define ThemeWorker() (ColorThemeWorker::instance())
|
||||
|
||||
/**
|
||||
* @brief The ColorThemeWorker class is a singletone that provides API for working with
|
||||
* color themes.
|
||||
* @brief The ColorThemeWorker class is a singletone that provides API for
|
||||
* working with color themes.
|
||||
*/
|
||||
class ColorThemeWorker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* @brief radare2SpecificOptions is list of all available radare2-only color options.
|
||||
* @brief radare2SpecificOptions is list of all available radare2-only color
|
||||
* options.
|
||||
*/
|
||||
const QStringList radare2SpecificOptions = Core()->cmdj("ecj").object().keys();
|
||||
|
||||
/**
|
||||
* @brief cutterSpecificOptions is list of all available Iaito-only color options.
|
||||
* @brief iaitoSpecificOptions is list of all available Iaito-only color
|
||||
* options.
|
||||
*/
|
||||
static const QStringList cutterSpecificOptions;
|
||||
static const QStringList iaitoSpecificOptions;
|
||||
|
||||
/**
|
||||
* @brief radare2UnusedOptions is a list of all radare2 options that Iaito does not use.
|
||||
* @brief radare2UnusedOptions is a list of all radare2 options that Iaito
|
||||
* does not use.
|
||||
*/
|
||||
static const QStringList radare2UnusedOptions;
|
||||
|
||||
@@ -40,7 +43,6 @@ public:
|
||||
|
||||
virtual ~ColorThemeWorker() {}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Copies @a srcThemeName with name @a copyThemeName.
|
||||
* @param srcThemeName
|
||||
@@ -59,10 +61,11 @@ public:
|
||||
* Name of theme to save.
|
||||
* @return "" on success or error message.
|
||||
*/
|
||||
QString save(const QJsonDocument& theme, const QString &themeName) const;
|
||||
QString save(const QJsonDocument &theme, const QString &themeName) const;
|
||||
|
||||
/**
|
||||
* @brief Returns whether or not @a themeName theme is custom (created by user or imported) or not.
|
||||
* @brief Returns whether or not @a themeName theme is custom (created by
|
||||
* user or imported) or not.
|
||||
* @param themeName
|
||||
* Name of theme to check.
|
||||
*/
|
||||
@@ -75,7 +78,8 @@ public:
|
||||
bool isThemeExist(const QString &name) const;
|
||||
|
||||
/**
|
||||
* @brief Returns theme as Json where key is option name and value is array of 3 Ints (Red, Green, Blue).
|
||||
* @brief Returns theme as Json where key is option name and value is array
|
||||
* of 3 Ints (Red, Green, Blue).
|
||||
* @param themeName
|
||||
* Theme to get.
|
||||
*/
|
||||
@@ -93,13 +97,13 @@ public:
|
||||
* @brief Imports theme from @a file.
|
||||
* @return "" on success or error message.
|
||||
*/
|
||||
QString importTheme(const QString& file) const;
|
||||
QString importTheme(const QString &file) const;
|
||||
|
||||
/**
|
||||
* @brief Renames theme from @a themeName to @a newName.
|
||||
* @return "" on success or error message.
|
||||
*/
|
||||
QString renameTheme(const QString& themeName, const QString& newName) const;
|
||||
QString renameTheme(const QString &themeName, const QString &newName) const;
|
||||
|
||||
/**
|
||||
* @brief Returns whether or not file at @a filePath is a color theme.
|
||||
@@ -107,7 +111,8 @@ public:
|
||||
* Path to file to check.
|
||||
* @param ok
|
||||
* Output parameter. Indicates wheter or not check was successful.
|
||||
* @return true if given file is color theme and ok == true, otherwise returns false.
|
||||
* @return true if given file is color theme and ok == true, otherwise
|
||||
* returns false.
|
||||
*/
|
||||
bool isFileTheme(const QString &filePath, bool *ok) const;
|
||||
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
#include "Colors.h"
|
||||
#include "common/Configuration.h"
|
||||
|
||||
Colors::Colors()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Colors::Colors() {}
|
||||
|
||||
void Colors::colorizeAssembly(RichTextPainter::List &list, QString opcode, ut64 type_num)
|
||||
{
|
||||
@@ -13,7 +9,8 @@ void Colors::colorizeAssembly(RichTextPainter::List &list, QString opcode, ut64
|
||||
assembly.highlight = false;
|
||||
assembly.flags = RichTextPainter::FlagColor;
|
||||
|
||||
// TODO cut opcode and use op["ptr"] to colorate registers and immediate values
|
||||
// TODO cut opcode and use op["ptr"] to colorate registers and immediate
|
||||
// values
|
||||
assembly.text = opcode;
|
||||
|
||||
QString colorName = Colors::getColor(type_num);
|
||||
@@ -22,7 +19,8 @@ void Colors::colorizeAssembly(RichTextPainter::List &list, QString opcode, ut64
|
||||
}
|
||||
|
||||
// Temporary solution
|
||||
// Copied from R_API const char* r_print_color_op_type(RPrint *p, ut64 anal_type) {
|
||||
// Copied from R_API const char* r_print_color_op_type(RPrint *p, ut64
|
||||
// anal_type) {
|
||||
QString Colors::getColor(ut64 type)
|
||||
{
|
||||
switch (type & R_ANAL_OP_TYPE_MASK) {
|
||||
@@ -101,4 +99,3 @@ QString Colors::getColor(ut64 type)
|
||||
return "invalid";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#ifndef COLORS_H
|
||||
#define COLORS_H
|
||||
|
||||
#include "core/Iaito.h"
|
||||
#include "common/RichTextPainter.h"
|
||||
#include "core/Iaito.h"
|
||||
#include <r_anal.h>
|
||||
|
||||
class Colors
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
#include "TempConfig.h"
|
||||
|
||||
CommandTask::CommandTask(const QString &cmd, ColorMode colorMode, bool outFormatHtml)
|
||||
: cmd(cmd), colorMode(colorMode), outFormatHtml(outFormatHtml)
|
||||
{
|
||||
}
|
||||
: cmd(cmd)
|
||||
, colorMode(colorMode)
|
||||
, outFormatHtml(outFormatHtml)
|
||||
{}
|
||||
|
||||
void CommandTask::runTask() {
|
||||
void CommandTask::runTask()
|
||||
{
|
||||
TempConfig tempConfig;
|
||||
tempConfig.set("scr.color", colorMode);
|
||||
auto res = Core()->cmdTask(cmd);
|
||||
|
||||
@@ -5,16 +5,22 @@
|
||||
#include "common/AsyncTask.h"
|
||||
#include "core/Iaito.h"
|
||||
|
||||
class IAITO_EXPORT CommandTask : public AsyncTask
|
||||
class IAITO_EXPORT CommandTask : public AsyncTask
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum ColorMode {DISABLED=COLOR_MODE_DISABLED, MODE_16=COLOR_MODE_16, MODE_256=COLOR_MODE_256, MODE_16M=COLOR_MODE_16M};
|
||||
enum ColorMode {
|
||||
DISABLED = COLOR_MODE_DISABLED,
|
||||
MODE_16 = COLOR_MODE_16,
|
||||
MODE_256 = COLOR_MODE_256,
|
||||
MODE_16M = COLOR_MODE_16M
|
||||
};
|
||||
|
||||
CommandTask(const QString &cmd, ColorMode colorMode=ColorMode::DISABLED, bool outFormatHtml=false);
|
||||
CommandTask(
|
||||
const QString &cmd, ColorMode colorMode = ColorMode::DISABLED, bool outFormatHtml = false);
|
||||
|
||||
QString getTitle() override { return tr("Running Command"); }
|
||||
QString getTitle() override { return tr("Running Command"); }
|
||||
|
||||
signals:
|
||||
void finished(const QString &result);
|
||||
@@ -28,4 +34,4 @@ private:
|
||||
bool outFormatHtml;
|
||||
};
|
||||
|
||||
#endif //COMMANDTASK_H
|
||||
#endif // COMMANDTASK_H
|
||||
@@ -1,168 +1,187 @@
|
||||
#include "Configuration.h"
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QDir>
|
||||
#include <QFontDatabase>
|
||||
#include <QFile>
|
||||
#include <QApplication>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFontDatabase>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
|
||||
#ifdef IAITO_ENABLE_KSYNTAXHIGHLIGHTING
|
||||
#include <KSyntaxHighlighting/Definition>
|
||||
#include <KSyntaxHighlighting/Repository>
|
||||
#include <KSyntaxHighlighting/Theme>
|
||||
#include <KSyntaxHighlighting/Definition>
|
||||
#endif
|
||||
|
||||
#include "common/ColorThemeWorker.h"
|
||||
#include "common/SyntaxHighlighter.h"
|
||||
#include "common/ResourcePaths.h"
|
||||
#include "common/SyntaxHighlighter.h"
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QVariant>
|
||||
|
||||
namespace {
|
||||
static inline int variantTypeId(const QVariant &v)
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
return v.metaType().id();
|
||||
#else
|
||||
return v.userType();
|
||||
#endif
|
||||
}
|
||||
} // namespace
|
||||
|
||||
/* Map with names of themes associated with its color palette
|
||||
* (Dark or Light), so for dark interface themes will be shown only Dark color themes
|
||||
* and for light - only light ones.
|
||||
* (Dark or Light), so for dark interface themes will be shown only Dark color
|
||||
* themes and for light - only light ones.
|
||||
*/
|
||||
const QHash<QString, ColorFlags> Configuration::relevantThemes = {
|
||||
{ "ayu", DarkFlag },
|
||||
{ "basic", DarkFlag },
|
||||
{ "bluy", DarkFlag },
|
||||
{ "bold", DarkFlag },
|
||||
{ "bright", DarkFlag },
|
||||
{ "cga", DarkFlag },
|
||||
{ "consonance", DarkFlag },
|
||||
{ "darkda", DarkFlag },
|
||||
{ "focus", DarkFlag },
|
||||
{ "gb", DarkFlag },
|
||||
{ "lima", DarkFlag },
|
||||
{ "monokai", DarkFlag },
|
||||
{ "ogray", DarkFlag },
|
||||
{ "onedark", DarkFlag },
|
||||
{ "pink", DarkFlag },
|
||||
{ "rasta", DarkFlag },
|
||||
{ "sepia", DarkFlag },
|
||||
{ "smyck", DarkFlag },
|
||||
{ "solarized", DarkFlag },
|
||||
{ "twilight", DarkFlag },
|
||||
{ "zenburn", DarkFlag },
|
||||
// light themes
|
||||
{ "iaito", LightFlag },
|
||||
{ "dark", LightFlag },
|
||||
{ "matrix", LightFlag },
|
||||
{ "rasta", LightFlag },
|
||||
{ "tango", LightFlag },
|
||||
{ "white", LightFlag },
|
||||
{ "white2", LightFlag }
|
||||
};
|
||||
const QHash<QString, ColorFlags> Configuration::relevantThemes
|
||||
= {{"ayu", DarkFlag},
|
||||
{"basic", DarkFlag},
|
||||
{"bluy", DarkFlag},
|
||||
{"bold", DarkFlag},
|
||||
{"bright", DarkFlag},
|
||||
{"cga", DarkFlag},
|
||||
{"consonance", DarkFlag},
|
||||
{"darkda", DarkFlag},
|
||||
{"focus", DarkFlag},
|
||||
{"gb", DarkFlag},
|
||||
{"lima", DarkFlag},
|
||||
{"monokai", DarkFlag},
|
||||
{"ogray", DarkFlag},
|
||||
{"onedark", DarkFlag},
|
||||
{"pink", DarkFlag},
|
||||
{"rasta", DarkFlag},
|
||||
{"sepia", DarkFlag},
|
||||
{"smyck", DarkFlag},
|
||||
{"solarized", DarkFlag},
|
||||
{"twilight", DarkFlag},
|
||||
{"zenburn", DarkFlag},
|
||||
// light themes
|
||||
{"iaito", LightFlag},
|
||||
{"dark", LightFlag},
|
||||
{"matrix", LightFlag},
|
||||
{"rasta", LightFlag},
|
||||
{"tango", LightFlag},
|
||||
{"white", LightFlag},
|
||||
{"white2", LightFlag}};
|
||||
static const QString DEFAULT_LIGHT_COLOR_THEME = "iaito";
|
||||
static const QString DEFAULT_DARK_COLOR_THEME = "ayu";
|
||||
|
||||
|
||||
const QHash<QString, QHash<ColorFlags, QColor>> Configuration::cutterOptionColors = {
|
||||
{ "gui.cflow", { { DarkFlag, QColor(0xff, 0xff, 0xff) },
|
||||
{ LightFlag, QColor(0x00, 0x00, 0x00) }} },
|
||||
{ "gui.dataoffset", { { DarkFlag, QColor(0xff, 0xff, 0xff) },
|
||||
{ LightFlag, QColor(0x00, 0x00, 0x00) }} },
|
||||
{ "gui.imports", { { DarkFlag, QColor(0x32, 0x8c, 0xff) },
|
||||
{ LightFlag, QColor(0x32, 0x8c, 0xff) }} },
|
||||
{ "gui.item_invalid", { { DarkFlag, QColor(0x9b, 0x9b, 0x9b) },
|
||||
{ LightFlag, QColor(0x9b, 0x9b, 0x9b) }} },
|
||||
{ "gui.main", { { DarkFlag, QColor(0x00, 0x80, 0x00) },
|
||||
{ LightFlag, QColor(0x00, 0x80, 0x00) }} },
|
||||
{ "gui.item_unsafe", { { DarkFlag, QColor(0xff, 0x81, 0x7b) },
|
||||
{ LightFlag, QColor(0xff, 0x81, 0x7b) }} },
|
||||
{ "gui.navbar.seek", { { DarkFlag, QColor(0xe9, 0x56, 0x56) },
|
||||
{ LightFlag, QColor(0xff, 0x00, 0x00) }} },
|
||||
{ "gui.navbar.pc", { { DarkFlag, QColor(0x42, 0xee, 0xf4) },
|
||||
{ LightFlag, QColor(0x42, 0xee, 0xf4) }} },
|
||||
{ "gui.navbar.code", { { DarkFlag, QColor(0x82, 0xa8, 0x6f) },
|
||||
{ LightFlag, QColor(0x68, 0xc5, 0x45) }} },
|
||||
{ "gui.navbar.str", { { DarkFlag, QColor(0x6f, 0x86, 0xd8) },
|
||||
{ LightFlag, QColor(0x45, 0x68, 0xe5) }} },
|
||||
{ "gui.navbar.sym", { { DarkFlag, QColor(0xdd, 0xa3, 0x68) },
|
||||
{ LightFlag, QColor(0xe5, 0x96, 0x45) }} },
|
||||
{ "gui.navbar.empty", { { DarkFlag, QColor(0x64, 0x64, 0x64) },
|
||||
{ LightFlag, QColor(0xdc, 0xec, 0xf5) }} },
|
||||
{ "gui.breakpoint_background", { { DarkFlag, QColor(0x8c, 0x4c, 0x4c) },
|
||||
{ LightFlag, QColor(0xe9, 0x8f, 0x8f) }} },
|
||||
{ "gui.overview.node", { { DarkFlag, QColor(0x64, 0x64, 0x64) },
|
||||
{ LightFlag, QColor(0xf5, 0xfa, 0xff) }} },
|
||||
{ "gui.tooltip.background", { { DarkFlag, QColor(0x2a, 0x2c, 0x2e) },
|
||||
{ LightFlag, QColor(0xfa, 0xfc, 0xfe) }} },
|
||||
{ "gui.tooltip.foreground", { { DarkFlag, QColor(0xfa, 0xfc, 0xfe) },
|
||||
{ LightFlag, QColor(0x2a, 0x2c, 0x2e) }} },
|
||||
{ "gui.border", { { DarkFlag, QColor(0x64, 0x64, 0x64) },
|
||||
{ LightFlag, QColor(0x91, 0xc8, 0xfa) }} },
|
||||
{ "gui.background", { { DarkFlag, QColor(0x25, 0x28, 0x2b) },
|
||||
{ LightFlag, QColor(0xff, 0xff, 0xff) }} },
|
||||
{ "gui.alt_background", { { DarkFlag, QColor(0x1c, 0x1f, 0x24) },
|
||||
{ LightFlag, QColor(0xf5, 0xfa, 0xff) }} },
|
||||
{ "gui.disass_selected", { { DarkFlag, QColor(0x1f, 0x22, 0x28) },
|
||||
{ LightFlag, QColor(0xff, 0xff, 0xff) }} },
|
||||
{ "lineHighlight", { { DarkFlag, QColor(0x15, 0x1d, 0x1d, 0x96) },
|
||||
{ LightFlag, QColor(0xd2, 0xd2, 0xff, 0x96) }} },
|
||||
{ "wordHighlight", { { DarkFlag, QColor(0x34, 0x3a, 0x47, 0xff) },
|
||||
{ LightFlag, QColor(0xb3, 0x77, 0xd6, 0x3c) }} },
|
||||
{ "highlightPC", { { DarkFlag, QColor(0x57, 0x1a, 0x07) },
|
||||
{ LightFlag, QColor(0xd6, 0xff, 0xd2) }} },
|
||||
{ "gui.overview.fill", { { DarkFlag, QColor(0xff, 0xff, 0xff, 0x28) },
|
||||
{ LightFlag, QColor(0xaf, 0xd9, 0xea, 0x41) }} },
|
||||
{ "gui.overview.border", { { DarkFlag, QColor(0x63, 0xda, 0xe8, 0x32) },
|
||||
{ LightFlag, QColor(0x63, 0xda, 0xe8, 0x32) }} },
|
||||
{ "gui.navbar.err", { { DarkFlag, QColor(0x03, 0xaa, 0xf5) },
|
||||
{ LightFlag, QColor(0x03, 0xaa, 0xf5) }} }
|
||||
};
|
||||
const QHash<QString, QHash<ColorFlags, QColor>> Configuration::iaitoOptionColors
|
||||
= {{"gui.cflow", {{DarkFlag, QColor(0xff, 0xff, 0xff)}, {LightFlag, QColor(0x00, 0x00, 0x00)}}},
|
||||
{"gui.dataoffset",
|
||||
{{DarkFlag, QColor(0xff, 0xff, 0xff)}, {LightFlag, QColor(0x00, 0x00, 0x00)}}},
|
||||
{"gui.imports",
|
||||
{{DarkFlag, QColor(0x32, 0x8c, 0xff)}, {LightFlag, QColor(0x32, 0x8c, 0xff)}}},
|
||||
{"gui.item_invalid",
|
||||
{{DarkFlag, QColor(0x9b, 0x9b, 0x9b)}, {LightFlag, QColor(0x9b, 0x9b, 0x9b)}}},
|
||||
{"gui.main", {{DarkFlag, QColor(0x00, 0x80, 0x00)}, {LightFlag, QColor(0x00, 0x80, 0x00)}}},
|
||||
{"gui.item_unsafe",
|
||||
{{DarkFlag, QColor(0xff, 0x81, 0x7b)}, {LightFlag, QColor(0xff, 0x81, 0x7b)}}},
|
||||
{"gui.item_thread_unsafe",
|
||||
{{DarkFlag, QColor(0x7b, 0x81, 0xff)}, {LightFlag, QColor(0x7b, 0x81, 0xff)}}},
|
||||
{"gui.navbar.seek",
|
||||
{{DarkFlag, QColor(0xe9, 0x56, 0x56)}, {LightFlag, QColor(0xff, 0x00, 0x00)}}},
|
||||
{"gui.navbar.pc",
|
||||
{{DarkFlag, QColor(0x42, 0xee, 0xf4)}, {LightFlag, QColor(0x42, 0xee, 0xf4)}}},
|
||||
{"gui.navbar.code",
|
||||
{{DarkFlag, QColor(0x82, 0xa8, 0x6f)}, {LightFlag, QColor(0x68, 0xc5, 0x45)}}},
|
||||
{"gui.navbar.str",
|
||||
{{DarkFlag, QColor(0x6f, 0x86, 0xd8)}, {LightFlag, QColor(0x45, 0x68, 0xe5)}}},
|
||||
{"gui.navbar.sym",
|
||||
{{DarkFlag, QColor(0xdd, 0xa3, 0x68)}, {LightFlag, QColor(0xe5, 0x96, 0x45)}}},
|
||||
{"gui.navbar.empty",
|
||||
{{DarkFlag, QColor(0x64, 0x64, 0x64)}, {LightFlag, QColor(0xdc, 0xec, 0xf5)}}},
|
||||
{"gui.breakpoint_background",
|
||||
{{DarkFlag, QColor(0x8c, 0x4c, 0x4c)}, {LightFlag, QColor(0xe9, 0x8f, 0x8f)}}},
|
||||
{"gui.overview.node",
|
||||
{{DarkFlag, QColor(0x64, 0x64, 0x64)}, {LightFlag, QColor(0xf5, 0xfa, 0xff)}}},
|
||||
{"gui.tooltip.background",
|
||||
{{DarkFlag, QColor(0x2a, 0x2c, 0x2e)}, {LightFlag, QColor(0xfa, 0xfc, 0xfe)}}},
|
||||
{"gui.tooltip.foreground",
|
||||
{{DarkFlag, QColor(0xfa, 0xfc, 0xfe)}, {LightFlag, QColor(0x2a, 0x2c, 0x2e)}}},
|
||||
{"gui.border", {{DarkFlag, QColor(0x64, 0x64, 0x64)}, {LightFlag, QColor(0x91, 0xc8, 0xfa)}}},
|
||||
{"gui.background",
|
||||
{{DarkFlag, QColor(0x25, 0x28, 0x2b)}, {LightFlag, QColor(0xff, 0xff, 0xff)}}},
|
||||
{"gui.alt_background",
|
||||
{{DarkFlag, QColor(0x1c, 0x1f, 0x24)}, {LightFlag, QColor(0xf5, 0xfa, 0xff)}}},
|
||||
{"gui.disass_selected",
|
||||
{{DarkFlag, QColor(0x1f, 0x22, 0x28)}, {LightFlag, QColor(0xff, 0xff, 0xff)}}},
|
||||
{"lineHighlight",
|
||||
{{DarkFlag, QColor(0x15, 0x1d, 0x1d, 0x96)}, {LightFlag, QColor(0xd2, 0xd2, 0xff, 0x96)}}},
|
||||
{"wordHighlight",
|
||||
{{DarkFlag, QColor(0x34, 0x3a, 0x47, 0xff)}, {LightFlag, QColor(0xb3, 0x77, 0xd6, 0x3c)}}},
|
||||
{"highlightPC",
|
||||
{{DarkFlag, QColor(0x57, 0x1a, 0x07)}, {LightFlag, QColor(0xd6, 0xff, 0xd2)}}},
|
||||
{"gui.overview.fill",
|
||||
{{DarkFlag, QColor(0xff, 0xff, 0xff, 0x28)}, {LightFlag, QColor(0xaf, 0xd9, 0xea, 0x41)}}},
|
||||
{"gui.overview.border",
|
||||
{{DarkFlag, QColor(0x63, 0xda, 0xe8, 0x32)}, {LightFlag, QColor(0x63, 0xda, 0xe8, 0x32)}}},
|
||||
{"gui.navbar.err",
|
||||
{{DarkFlag, QColor(0x03, 0xaa, 0xf5)}, {LightFlag, QColor(0x03, 0xaa, 0xf5)}}}};
|
||||
|
||||
Configuration *Configuration::mPtr = nullptr;
|
||||
|
||||
/**
|
||||
* @brief All asm.* options saved as settings. Values are the default values.
|
||||
*/
|
||||
static const QHash<QString, QVariant> asmOptions = {
|
||||
{ "asm.esil", false },
|
||||
{ "asm.pseudo", false },
|
||||
{ "asm.offset", true },
|
||||
{ "asm.xrefs", false },
|
||||
{ "asm.indent", false },
|
||||
{ "asm.describe", false },
|
||||
{ "asm.slow", true },
|
||||
{ "asm.lines", true },
|
||||
{ "asm.lines.fcn", true },
|
||||
{ "asm.flags.offset", false },
|
||||
{ "asm.emu", false },
|
||||
{ "emu.str", true},
|
||||
{ "asm.cmt.right", true },
|
||||
{ "asm.cmt.col", 60 },
|
||||
{ "asm.var.summary", 0 },
|
||||
{ "asm.bytes", false },
|
||||
{ "asm.size", false },
|
||||
{ "asm.bytes.space", false },
|
||||
{ "asm.lbytes", true },
|
||||
{ "asm.nbytes", 10 },
|
||||
{ "asm.syntax", "intel" },
|
||||
{ "asm.ucase", false },
|
||||
{ "asm.lines.bb", false },
|
||||
{ "asm.capitalize", false },
|
||||
{ "asm.sub.var", true },
|
||||
{ "asm.sub.varonly", true },
|
||||
{ "asm.tabs", 8 },
|
||||
{ "asm.tabs.off", 5 },
|
||||
{ "asm.marks", false },
|
||||
{ "asm.refptr", false },
|
||||
{ "asm.flags.real", true },
|
||||
{ "asm.offset.relative",false },
|
||||
{ "asm.offset.flags", false },
|
||||
{ "esil.breakoninvalid",true },
|
||||
{ "graph.offset", false}
|
||||
static const QHash<QString, QVariant> asmOptions
|
||||
= {{"asm.esil", false},
|
||||
{"asm.pseudo", false},
|
||||
{"asm.xrefs", false},
|
||||
{"asm.indent", false},
|
||||
{"asm.describe", false},
|
||||
{"asm.slow", true},
|
||||
{"asm.lines", true},
|
||||
{"asm.lines.fcn", true},
|
||||
{"asm.flags.offset", false},
|
||||
{"asm.emu", false},
|
||||
{"emu.str", true},
|
||||
{"asm.cmt.right", true},
|
||||
{"asm.cmt.col", 60},
|
||||
{"asm.var.summary", 4},
|
||||
{"asm.bytes", false},
|
||||
{"asm.size", false},
|
||||
{"asm.bytes.space", false},
|
||||
{"asm.lbytes", true},
|
||||
{"asm.nbytes", 10},
|
||||
{"asm.syntax", "intel"},
|
||||
{"asm.ucase", false},
|
||||
{"asm.lines.bb", false},
|
||||
{"asm.capitalize", false},
|
||||
{"asm.sub.var", true},
|
||||
{"asm.sub.varonly", true},
|
||||
{"asm.tabs", 8},
|
||||
{"asm.tabs.off", 5},
|
||||
{"asm.marks", false},
|
||||
{"asm.refptr", false},
|
||||
{"asm.flags.real", true},
|
||||
{"esil.breakoninvalid", false},
|
||||
#if R2_VERSION_NUMBER >= 50909
|
||||
{"graph.addr", true},
|
||||
{"asm.addr", true},
|
||||
{"asm.addr.relto", ""},
|
||||
{"asm.flags.addr", false}
|
||||
#else
|
||||
{"graph.offset", true},
|
||||
{"asm.offset", true},
|
||||
{"asm.offset.relative", false},
|
||||
{"asm.offset.flags", false}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
Configuration::Configuration() : QObject(), nativePalette(qApp->palette())
|
||||
Configuration::Configuration()
|
||||
: QObject()
|
||||
, nativePalette(qApp->palette())
|
||||
{
|
||||
mPtr = this;
|
||||
if (!s.isWritable()) {
|
||||
QMessageBox::critical(nullptr,
|
||||
tr("Critical!"),
|
||||
tr("!!! Settings are not writable! Make sure you have a write access to \"%1\"")
|
||||
.arg(s.fileName())
|
||||
);
|
||||
QMessageBox::critical(
|
||||
nullptr,
|
||||
tr("Critical!"),
|
||||
tr("!!! Settings are not writable! Make sure you "
|
||||
"have a write access to \"%1\"")
|
||||
.arg(s.fileName()));
|
||||
}
|
||||
#ifdef IAITO_ENABLE_KSYNTAXHIGHLIGHTING
|
||||
kSyntaxHighlightingRepository = nullptr;
|
||||
@@ -233,8 +252,9 @@ int Configuration::getNewFileLastClicked()
|
||||
void Configuration::resetAll()
|
||||
{
|
||||
// Don't reset all r2 vars, that currently breaks a bunch of stuff.
|
||||
// settingsFile.remove()+loadInitials() should reset all settings configurable using Iaito GUI.
|
||||
//Core()->cmdRaw("e-");
|
||||
// settingsFile.remove()+loadInitials() should reset all settings
|
||||
// configurable using Iaito GUI.
|
||||
// Core()->cmdRaw("e-");
|
||||
|
||||
Core()->setSettings();
|
||||
// Delete the file so no extra configuration is in it.
|
||||
@@ -281,8 +301,8 @@ void Configuration::setLocale(const QLocale &l)
|
||||
*/
|
||||
bool Configuration::setLocaleByName(const QString &language)
|
||||
{
|
||||
const auto &allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript,
|
||||
QLocale::AnyCountry);
|
||||
const auto &allLocales
|
||||
= QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry);
|
||||
|
||||
for (auto &it : allLocales) {
|
||||
if (QString::compare(it.nativeLanguageName(), language, Qt::CaseInsensitive) == 0) {
|
||||
@@ -327,7 +347,8 @@ void Configuration::loadNativeStylesheet()
|
||||
qApp->setPalette(nativePalette);
|
||||
/* Some widgets does not change its palette when QApplication changes one
|
||||
* so this loop force all widgets do this, but all widgets take palette from
|
||||
* QApplication::palette() when they are created so line above is necessary too.
|
||||
* QApplication::palette() when they are created so line above is necessary
|
||||
* too.
|
||||
*/
|
||||
for (auto widget : qApp->allWidgets()) {
|
||||
widget->setPalette(nativePalette);
|
||||
@@ -366,8 +387,9 @@ void Configuration::loadDarkStylesheet()
|
||||
f.open(QFile::ReadOnly | QFile::Text);
|
||||
QTextStream ts(&f);
|
||||
QString stylesheet = ts.readAll();
|
||||
#ifdef Q_OS_MACX
|
||||
// see https://github.com/ColinDuquesnoy/QDarkStyleSheet/issues/22#issuecomment-96179529
|
||||
#ifdef Q_OS_MACOS
|
||||
// see
|
||||
// https://github.com/ColinDuquesnoy/QDarkStyleSheet/issues/22#issuecomment-96179529
|
||||
stylesheet += "QDockWidget::title"
|
||||
"{"
|
||||
" background-color: #31363b;"
|
||||
@@ -409,9 +431,9 @@ const QFont Configuration::getBaseFont() const
|
||||
|
||||
const QFont Configuration::getFont() const
|
||||
{
|
||||
QFont font = getBaseFont();
|
||||
font.setPointSizeF(font.pointSizeF() * getZoomFactor());
|
||||
return font;
|
||||
QFont font = getBaseFont();
|
||||
font.setPointSizeF(font.pointSizeF() * getZoomFactor());
|
||||
return font;
|
||||
}
|
||||
|
||||
void Configuration::setFont(const QFont &font)
|
||||
@@ -425,31 +447,31 @@ void Configuration::refreshFont()
|
||||
emit fontsUpdated();
|
||||
}
|
||||
|
||||
qreal Configuration::getZoomFactor() const {
|
||||
qreal fontZoom = s.value("zoomFactor", 1.0).value<qreal>();
|
||||
return qMax(fontZoom, 0.1);
|
||||
qreal Configuration::getZoomFactor() const
|
||||
{
|
||||
qreal fontZoom = s.value("zoomFactor", 1.0).value<qreal>();
|
||||
return qMax(fontZoom, 0.1);
|
||||
}
|
||||
|
||||
void Configuration::setZoomFactor(qreal zoom) {
|
||||
s.setValue("zoomFactor", qMax(zoom, 0.1));
|
||||
emit fontsUpdated();
|
||||
void Configuration::setZoomFactor(qreal zoom)
|
||||
{
|
||||
s.setValue("zoomFactor", qMax(zoom, 0.1));
|
||||
emit fontsUpdated();
|
||||
}
|
||||
|
||||
QString Configuration::getLastThemeOf(const IaitoInterfaceTheme &currInterfaceTheme) const
|
||||
{
|
||||
return s.value("lastThemeOf." + currInterfaceTheme.name,
|
||||
Config()->getColorTheme()).toString();
|
||||
return s.value("lastThemeOf." + currInterfaceTheme.name, Config()->getColorTheme()).toString();
|
||||
}
|
||||
|
||||
void Configuration::setInterfaceTheme(int theme)
|
||||
{
|
||||
if (theme >= cutterInterfaceThemesList().size() ||
|
||||
theme < 0) {
|
||||
if (theme >= iaitoInterfaceThemesList().size() || theme < 0) {
|
||||
theme = 0;
|
||||
}
|
||||
s.setValue("ColorPalette", theme);
|
||||
|
||||
IaitoInterfaceTheme interfaceTheme = cutterInterfaceThemesList()[theme];
|
||||
IaitoInterfaceTheme interfaceTheme = iaitoInterfaceThemesList()[theme];
|
||||
|
||||
if (interfaceTheme.name == "Native") {
|
||||
loadNativeStylesheet();
|
||||
@@ -463,7 +485,7 @@ void Configuration::setInterfaceTheme(int theme)
|
||||
loadNativeStylesheet();
|
||||
}
|
||||
|
||||
for (auto it = cutterOptionColors.cbegin(); it != cutterOptionColors.cend(); it++) {
|
||||
for (auto it = iaitoOptionColors.cbegin(); it != iaitoOptionColors.cend(); it++) {
|
||||
setColor(it.key(), it.value()[interfaceTheme.flag]);
|
||||
}
|
||||
|
||||
@@ -479,11 +501,11 @@ void Configuration::setInterfaceTheme(int theme)
|
||||
const IaitoInterfaceTheme *Configuration::getCurrentTheme()
|
||||
{
|
||||
int i = getInterfaceTheme();
|
||||
if (i < 0 || i >= cutterInterfaceThemesList().size()) {
|
||||
if (i < 0 || i >= iaitoInterfaceThemesList().size()) {
|
||||
i = 0;
|
||||
setInterfaceTheme(i);
|
||||
}
|
||||
return &cutterInterfaceThemesList()[i];
|
||||
return &iaitoInterfaceThemesList()[i];
|
||||
}
|
||||
|
||||
#ifdef IAITO_ENABLE_KSYNTAXHIGHLIGHTING
|
||||
@@ -500,8 +522,8 @@ KSyntaxHighlighting::Theme Configuration::getKSyntaxHighlightingTheme()
|
||||
}
|
||||
return repo->defaultTheme(
|
||||
getCurrentTheme()->flag & DarkFlag
|
||||
? KSyntaxHighlighting::Repository::DefaultTheme::DarkTheme
|
||||
: KSyntaxHighlighting::Repository::DefaultTheme::LightTheme);
|
||||
? KSyntaxHighlighting::Repository::DefaultTheme::DarkTheme
|
||||
: KSyntaxHighlighting::Repository::DefaultTheme::LightTheme);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -521,9 +543,8 @@ QSyntaxHighlighter *Configuration::createSyntaxHighlighter(QTextDocument *docume
|
||||
|
||||
QString Configuration::getLogoFile()
|
||||
{
|
||||
return windowColorIsDark()
|
||||
? QString(":/img/iaito-o-light.svg")
|
||||
: QString(":/img/iaito-o.svg");
|
||||
return windowColorIsDark() ? QStringLiteral(":/img/iaito-o-light.svg")
|
||||
: QStringLiteral(":/img/iaito-o.svg");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -536,7 +557,8 @@ void Configuration::setColor(const QString &name, const QColor &color)
|
||||
s.setValue("colors." + name, color);
|
||||
}
|
||||
|
||||
void Configuration::setLastThemeOf(const IaitoInterfaceTheme &currInterfaceTheme, const QString &theme)
|
||||
void Configuration::setLastThemeOf(
|
||||
const IaitoInterfaceTheme &currInterfaceTheme, const QString &theme)
|
||||
{
|
||||
s.setValue("lastThemeOf." + currInterfaceTheme.name, theme);
|
||||
}
|
||||
@@ -606,14 +628,13 @@ void Configuration::applySavedAsmOptions()
|
||||
}
|
||||
}
|
||||
|
||||
const QList<IaitoInterfaceTheme>& Configuration::cutterInterfaceThemesList()
|
||||
const QList<IaitoInterfaceTheme> &Configuration::iaitoInterfaceThemesList()
|
||||
{
|
||||
static const QList<IaitoInterfaceTheme> list = {
|
||||
{ "Native", Configuration::nativeWindowIsDark() ? DarkFlag : LightFlag },
|
||||
{ "Dark", DarkFlag },
|
||||
{ "Midnight", DarkFlag },
|
||||
{ "Light", LightFlag }
|
||||
};
|
||||
static const QList<IaitoInterfaceTheme> list
|
||||
= {{"Native", Configuration::nativeWindowIsDark() ? DarkFlag : LightFlag},
|
||||
{"Dark", DarkFlag},
|
||||
{"Midnight", DarkFlag},
|
||||
{"Light", LightFlag}};
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -621,10 +642,10 @@ QVariant Configuration::getConfigVar(const QString &key)
|
||||
{
|
||||
QHash<QString, QVariant>::const_iterator it = asmOptions.find(key);
|
||||
if (it != asmOptions.end()) {
|
||||
switch (it.value().type()) {
|
||||
case QVariant::Type::Bool:
|
||||
switch (variantTypeId(it.value())) {
|
||||
case QMetaType::Bool:
|
||||
return Core()->getConfigb(key);
|
||||
case QVariant::Type::Int:
|
||||
case QMetaType::Int:
|
||||
return Core()->getConfigi(key);
|
||||
default:
|
||||
return Core()->getConfig(key);
|
||||
@@ -633,7 +654,6 @@ QVariant Configuration::getConfigVar(const QString &key)
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
||||
bool Configuration::getConfigBool(const QString &key)
|
||||
{
|
||||
return getConfigVar(key).toBool();
|
||||
@@ -677,8 +697,8 @@ QStringList Configuration::getAvailableTranslations()
|
||||
if (!dir.exists()) {
|
||||
continue;
|
||||
}
|
||||
const QStringList &currTrFileNames = dir.entryList(QStringList("iaito_*.qm"), QDir::Files,
|
||||
QDir::Name);
|
||||
const QStringList &currTrFileNames
|
||||
= dir.entryList(QStringList("iaito_*.qm"), QDir::Files, QDir::Name);
|
||||
for (const auto &trFile : currTrFileNames) {
|
||||
fileNamesSet << trFile;
|
||||
}
|
||||
@@ -688,16 +708,19 @@ QStringList Configuration::getAvailableTranslations()
|
||||
std::sort(fileNames.begin(), fileNames.end());
|
||||
QStringList languages;
|
||||
QString currLanguageName;
|
||||
auto allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript,
|
||||
QLocale::AnyCountry);
|
||||
auto allLocales
|
||||
= QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry);
|
||||
|
||||
for (auto i : fileNames) {
|
||||
QString localeName = i.mid(sizeof("iaito_") - 1, 2);
|
||||
for (auto j : allLocales) {
|
||||
if (j.name().startsWith(localeName)) {
|
||||
currLanguageName = j.nativeLanguageName();
|
||||
currLanguageName = currLanguageName.at(0).toUpper() +
|
||||
currLanguageName.right(currLanguageName.length() - 1);
|
||||
if (currLanguageName == nullptr) {
|
||||
break;
|
||||
}
|
||||
currLanguageName = currLanguageName.at(0).toUpper()
|
||||
+ currLanguageName.right(currLanguageName.length() - 1);
|
||||
languages << currLanguageName;
|
||||
break;
|
||||
}
|
||||
@@ -741,6 +764,17 @@ void Configuration::setDecompilerAutoRefreshEnabled(bool enabled)
|
||||
s.setValue("decompilerAutoRefresh", enabled);
|
||||
}
|
||||
|
||||
bool Configuration::getDecompilerRunInBackground()
|
||||
{
|
||||
// Disabled by default: run synchronously (safer)
|
||||
return s.value("decompilerRunInBackground", false).toBool();
|
||||
}
|
||||
|
||||
void Configuration::setDecompilerRunInBackground(bool enabled)
|
||||
{
|
||||
s.setValue("decompilerRunInBackground", enabled);
|
||||
}
|
||||
|
||||
void Configuration::enableDecompilerAnnotationHighlighter(bool useDecompilerHighlighter)
|
||||
{
|
||||
s.setValue("decompilerAnnotationHighlighter", !useDecompilerHighlighter);
|
||||
|
||||
@@ -1,35 +1,34 @@
|
||||
#ifndef CONFIGURATION_H
|
||||
#define CONFIGURATION_H
|
||||
|
||||
#include <QSettings>
|
||||
#include <QFont>
|
||||
#include <core/Iaito.h>
|
||||
#include <QFont>
|
||||
#include <QSettings>
|
||||
|
||||
#define Config() (Configuration::instance())
|
||||
#define ConfigColor(x) Config()->getColor(x)
|
||||
|
||||
#ifdef IAITO_ENABLE_KSYNTAXHIGHLIGHTING
|
||||
namespace KSyntaxHighlighting {
|
||||
class Repository;
|
||||
class Theme;
|
||||
}
|
||||
class Repository;
|
||||
class Theme;
|
||||
} // namespace KSyntaxHighlighting
|
||||
#endif
|
||||
|
||||
class QSyntaxHighlighter;
|
||||
class QTextDocument;
|
||||
|
||||
|
||||
enum ColorFlags {
|
||||
LightFlag = 1,
|
||||
DarkFlag = 2,
|
||||
};
|
||||
|
||||
struct IaitoInterfaceTheme {
|
||||
struct IaitoInterfaceTheme
|
||||
{
|
||||
QString name;
|
||||
ColorFlags flag;
|
||||
};
|
||||
|
||||
|
||||
class IAITO_EXPORT Configuration : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -56,9 +55,9 @@ private:
|
||||
void applySavedAsmOptions();
|
||||
|
||||
public:
|
||||
static const QList<IaitoInterfaceTheme>& cutterInterfaceThemesList();
|
||||
static const QList<IaitoInterfaceTheme> &iaitoInterfaceThemesList();
|
||||
static const QHash<QString, ColorFlags> relevantThemes;
|
||||
static const QHash<QString, QHash<ColorFlags, QColor>> cutterOptionColors;
|
||||
static const QHash<QString, QHash<ColorFlags, QColor>> iaitoOptionColors;
|
||||
|
||||
// Functions
|
||||
static Configuration *instance();
|
||||
@@ -83,11 +82,11 @@ public:
|
||||
* @brief Gets the configured font set by the font selection box
|
||||
* @return the configured font
|
||||
*/
|
||||
const QFont getBaseFont() const;
|
||||
const QFont getBaseFont() const;
|
||||
|
||||
/**
|
||||
* @brief Gets the configured font with the point size adjusted by the configured zoom
|
||||
* level (minimum of 10%)
|
||||
* @brief Gets the configured font with the point size adjusted by the
|
||||
* configured zoom level (minimum of 10%)
|
||||
* @return the configured font size adjusted by zoom level
|
||||
*/
|
||||
const QFont getFont() const;
|
||||
@@ -101,10 +100,7 @@ public:
|
||||
void setLastThemeOf(const IaitoInterfaceTheme &currInterfaceTheme, const QString &theme);
|
||||
QString getLastThemeOf(const IaitoInterfaceTheme &currInterfaceTheme) const;
|
||||
void setInterfaceTheme(int theme);
|
||||
int getInterfaceTheme()
|
||||
{
|
||||
return s.value("ColorPalette", 0).toInt();
|
||||
}
|
||||
int getInterfaceTheme() { return s.value("ColorPalette", 0).toInt(); }
|
||||
|
||||
const IaitoInterfaceTheme *getCurrentTheme();
|
||||
|
||||
@@ -129,10 +125,11 @@ public:
|
||||
// Asm Options
|
||||
void resetToDefaultAsmOptions();
|
||||
|
||||
QString getColorTheme() const { return s.value("theme", "cutter").toString(); }
|
||||
QString getColorTheme() const { return s.value("theme", "iaito").toString(); }
|
||||
void setColorTheme(const QString &theme);
|
||||
/**
|
||||
* @brief Change current color theme if it doesn't much native theme's darkness.
|
||||
* @brief Change current color theme if it doesn't much native theme's
|
||||
* darkness.
|
||||
*/
|
||||
void adjustColorThemeDarkness();
|
||||
int colorThemeDarkness(const QString &colorTheme) const;
|
||||
@@ -141,7 +138,8 @@ public:
|
||||
const QColor getColor(const QString &name) const;
|
||||
|
||||
/**
|
||||
* @brief Get the value of a config var either from r2 or settings, depending on the key.
|
||||
* @brief Get the value of a config var either from r2 or settings,
|
||||
* depending on the key.
|
||||
*/
|
||||
QVariant getConfigVar(const QString &key);
|
||||
bool getConfigBool(const QString &key);
|
||||
@@ -149,13 +147,15 @@ public:
|
||||
QString getConfigString(const QString &key);
|
||||
|
||||
/**
|
||||
* @brief Set the value of a config var either to r2 or settings, depending on the key.
|
||||
* @brief Set the value of a config var either to r2 or settings, depending
|
||||
* on the key.
|
||||
*/
|
||||
void setConfig(const QString &key, const QVariant &value);
|
||||
bool isFirstExecution();
|
||||
|
||||
/**
|
||||
* @return id of the last selected decompiler (see IaitoCore::getDecompilerById)
|
||||
* @return id of the last selected decompiler (see
|
||||
* IaitoCore::getDecompilerById)
|
||||
*/
|
||||
QString getSelectedDecompiler();
|
||||
void setSelectedDecompiler(const QString &id);
|
||||
@@ -163,21 +163,20 @@ public:
|
||||
bool getDecompilerAutoRefreshEnabled();
|
||||
void setDecompilerAutoRefreshEnabled(bool enabled);
|
||||
|
||||
// Decompiler execution mode
|
||||
bool getDecompilerRunInBackground();
|
||||
void setDecompilerRunInBackground(bool enabled);
|
||||
|
||||
void enableDecompilerAnnotationHighlighter(bool useDecompilerHighlighter);
|
||||
bool isDecompilerAnnotationHighlighterEnabled();
|
||||
|
||||
// Graph
|
||||
int getGraphBlockMaxChars() const
|
||||
{
|
||||
return s.value("graph.maxcols", 100).toInt();
|
||||
}
|
||||
void setGraphBlockMaxChars(int ch)
|
||||
{
|
||||
s.setValue("graph.maxcols", ch);
|
||||
}
|
||||
int getGraphBlockMaxChars() const { return s.value("graph.maxcols", 100).toInt(); }
|
||||
void setGraphBlockMaxChars(int ch) { s.setValue("graph.maxcols", ch); }
|
||||
|
||||
/**
|
||||
* @brief Getters and setters for the transaparent option state and scale factor for bitmap graph exports.
|
||||
* @brief Getters and setters for the transaparent option state and scale
|
||||
* factor for bitmap graph exports.
|
||||
*/
|
||||
bool getBitmapTransparentState();
|
||||
double getBitmapExportScaleFactor();
|
||||
@@ -188,21 +187,24 @@ public:
|
||||
QPoint getGraphEdgeSpacing();
|
||||
|
||||
/**
|
||||
* @brief Gets whether the entry offset of each block has to be displayed or not
|
||||
* @brief Gets whether the entry offset of each block has to be displayed or
|
||||
* not
|
||||
* @return true if the entry offset has to be displayed, false otherwise
|
||||
*/
|
||||
bool getGraphBlockEntryOffset();
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the displaying of the entry offset in each graph block
|
||||
* @param enabled set this to true for displaying the entry offset in each graph block, false otherwise
|
||||
* @brief Enable or disable the displaying of the entry offset in each graph
|
||||
* block
|
||||
* @param enabled set this to true for displaying the entry offset in each
|
||||
* graph block, false otherwise
|
||||
*/
|
||||
void setGraphBlockEntryOffset(bool enabled);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable Iaito output redirection.
|
||||
* Output redirection state can only be changed early during Iaito initialization.
|
||||
* Changing it later will have no effect
|
||||
* Output redirection state can only be changed early during Iaito
|
||||
* initialization. Changing it later will have no effect
|
||||
* @param enabled set this to false for disabling output redirection
|
||||
*/
|
||||
void setOutputRedirectionEnabled(bool enabled);
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
#include "CrashHandler.h"
|
||||
#include "BugReporting.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QFileDialog>
|
||||
#include <QStandardPaths>
|
||||
#include <QTime>
|
||||
|
||||
#ifdef IAITO_ENABLE_CRASH_REPORTS
|
||||
|
||||
#include <QApplication>
|
||||
#include <QString>
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QMap>
|
||||
#include <QProcess>
|
||||
#include <QString>
|
||||
|
||||
#if defined (Q_OS_LINUX)
|
||||
#if defined(Q_OS_LINUX)
|
||||
#include "client/linux/handler/exception_handler.h"
|
||||
#elif defined (Q_OS_WIN32)
|
||||
#elif defined(Q_OS_WIN32)
|
||||
#include "client/windows/handler/exception_handler.h"
|
||||
#elif defined (Q_OS_MACOS)
|
||||
#elif defined(Q_OS_MACOS)
|
||||
#include "client/mac/handler/exception_handler.h"
|
||||
#endif // Q_OS
|
||||
|
||||
@@ -34,38 +34,42 @@ static void finishCrashHandler()
|
||||
#ifdef Q_OS_WIN32
|
||||
// Called if crash dump was successfully created
|
||||
// Saves path to file
|
||||
bool callback(const wchar_t *_dump_dir,
|
||||
const wchar_t *_minidump_id,
|
||||
void *context, EXCEPTION_POINTERS *exinfo,
|
||||
MDRawAssertionInfo *assertion,
|
||||
bool success)
|
||||
bool callback(
|
||||
const wchar_t *_dump_dir,
|
||||
const wchar_t *_minidump_id,
|
||||
void *context,
|
||||
EXCEPTION_POINTERS *exinfo,
|
||||
MDRawAssertionInfo *assertion,
|
||||
bool success)
|
||||
{
|
||||
const QDir dir = QString::fromWCharArray(_dump_dir);
|
||||
const QString id = QString::fromWCharArray(_minidump_id);
|
||||
QProcess::startDetached(QCoreApplication::applicationFilePath(),
|
||||
{ "--start-crash-handler", dir.filePath(id + ".dmp") });
|
||||
QProcess::startDetached(
|
||||
QCoreApplication::applicationFilePath(),
|
||||
{"--start-crash-handler", dir.filePath(id + ".dmp")});
|
||||
_exit(1);
|
||||
return true;
|
||||
}
|
||||
#elif defined (Q_OS_LINUX)
|
||||
#elif defined(Q_OS_LINUX)
|
||||
// Called if crash dump was successfully created
|
||||
// Saves path to file
|
||||
bool callback(const google_breakpad::MinidumpDescriptor &md, void *context, bool b)
|
||||
{
|
||||
QProcess::startDetached(QCoreApplication::applicationFilePath(),
|
||||
{ "--start-crash-handler", md.path() });
|
||||
QProcess::startDetached(
|
||||
QCoreApplication::applicationFilePath(), {"--start-crash-handler", md.path()});
|
||||
_exit(1);
|
||||
return true;
|
||||
}
|
||||
#elif defined (Q_OS_MACOS)
|
||||
#elif defined(Q_OS_MACOS)
|
||||
// Called if crash dump was successfully created
|
||||
// Saves path to file
|
||||
bool callback(const char *dump_dir, const char *minidump_id, void *context, bool succeeded)
|
||||
{
|
||||
const QDir dir = QString::fromUtf8(dump_dir);
|
||||
const QString id = QString::fromUtf8(minidump_id);
|
||||
QProcess::startDetached(QCoreApplication::applicationFilePath(),
|
||||
{ "--start-crash-handler", dir.filePath(id + ".dmp") });
|
||||
QProcess::startDetached(
|
||||
QCoreApplication::applicationFilePath(),
|
||||
{"--start-crash-handler", dir.filePath(id + ".dmp")});
|
||||
_exit(1);
|
||||
return true;
|
||||
}
|
||||
@@ -79,43 +83,31 @@ void initCrashHandler()
|
||||
// Here will be placed crash dump at the first place
|
||||
// and then moved if needed
|
||||
|
||||
#if defined (Q_OS_LINUX)
|
||||
static std::string tmpLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString();
|
||||
exceptionHandler = new google_breakpad::ExceptionHandler(google_breakpad::MinidumpDescriptor(tmpLocation),
|
||||
nullptr,
|
||||
callback,
|
||||
nullptr,
|
||||
true,
|
||||
-1);
|
||||
#elif defined (Q_OS_MACOS)
|
||||
static std::string tmpLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString();
|
||||
exceptionHandler = new google_breakpad::ExceptionHandler(tmpLocation,
|
||||
nullptr,
|
||||
callback,
|
||||
nullptr,
|
||||
true,
|
||||
nullptr);
|
||||
#if defined(Q_OS_LINUX)
|
||||
static std::string tmpLocation
|
||||
= QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString();
|
||||
exceptionHandler = new google_breakpad::ExceptionHandler(
|
||||
google_breakpad::MinidumpDescriptor(tmpLocation), nullptr, callback, nullptr, true, -1);
|
||||
#elif defined(Q_OS_MACOS)
|
||||
static std::string tmpLocation
|
||||
= QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString();
|
||||
exceptionHandler = new google_breakpad::ExceptionHandler(
|
||||
tmpLocation, nullptr, callback, nullptr, true, nullptr);
|
||||
#else
|
||||
static std::wstring tmpLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdWString();
|
||||
exceptionHandler = new google_breakpad::ExceptionHandler(tmpLocation,
|
||||
nullptr,
|
||||
callback,
|
||||
nullptr,
|
||||
google_breakpad::ExceptionHandler::HANDLER_ALL);
|
||||
static std::wstring tmpLocation
|
||||
= QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdWString();
|
||||
exceptionHandler = new google_breakpad::ExceptionHandler(
|
||||
tmpLocation, nullptr, callback, nullptr, google_breakpad::ExceptionHandler::HANDLER_ALL);
|
||||
#endif
|
||||
atexit(finishCrashHandler);
|
||||
}
|
||||
|
||||
#else // IAITO_ENABLE_CRASH_REPORTS
|
||||
|
||||
void initCrashHandler()
|
||||
{
|
||||
|
||||
}
|
||||
void initCrashHandler() {}
|
||||
|
||||
#endif // IAITO_ENABLE_CRASH_REPORTS
|
||||
|
||||
|
||||
void showCrashDialog(const QString &dumpFile)
|
||||
{
|
||||
QMessageBox mb;
|
||||
@@ -137,14 +129,13 @@ void showCrashDialog(const QString &dumpFile)
|
||||
if (placementFailCounter == 4) {
|
||||
break;
|
||||
}
|
||||
dumpSaveFileName = QFileDialog::getSaveFileName(nullptr,
|
||||
QObject::tr("Choose a directory to save the crash dump in"),
|
||||
QStandardPaths::writableLocation(QStandardPaths::HomeLocation) +
|
||||
QDir::separator() +
|
||||
"Iaito_crash_dump_"
|
||||
+ QDate::currentDate().toString("dd.MM.yy") + "_"
|
||||
+ QTime::currentTime().toString("HH.mm.ss") + ".dmp",
|
||||
QObject::tr("Minidump (*.dmp)"));
|
||||
dumpSaveFileName = QFileDialog::getSaveFileName(
|
||||
nullptr,
|
||||
QObject::tr("Choose a directory to save the crash dump in"),
|
||||
QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + QDir::separator()
|
||||
+ "Iaito_crash_dump_" + QDate::currentDate().toString("dd.MM.yy") + "_"
|
||||
+ QTime::currentTime().toString("HH.mm.ss") + ".dmp",
|
||||
QObject::tr("Minidump (*.dmp)"));
|
||||
|
||||
if (dumpSaveFileName.isEmpty()) {
|
||||
return;
|
||||
@@ -153,18 +144,20 @@ void showCrashDialog(const QString &dumpFile)
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
QMessageBox::critical(nullptr,
|
||||
QObject::tr("Save Crash Dump"),
|
||||
QObject::tr("Failed to write to %1.<br/>"
|
||||
"Please make sure you have access to that directory "
|
||||
"and try again.").arg(QFileInfo(dumpSaveFileName).dir().path()));
|
||||
QMessageBox::critical(
|
||||
nullptr,
|
||||
QObject::tr("Save Crash Dump"),
|
||||
QObject::tr("Failed to write to %1.<br/>"
|
||||
"Please make sure you have access to that directory "
|
||||
"and try again.")
|
||||
.arg(QFileInfo(dumpSaveFileName).dir().path()));
|
||||
} while (true);
|
||||
|
||||
if (ok) {
|
||||
QMessageBox info;
|
||||
info.setWindowTitle(QObject::tr("Success"));
|
||||
info.setText(QObject::tr("<a href=\"%1\">Crash dump</a> was successfully created.")
|
||||
.arg(QFileInfo(dumpSaveFileName).dir().path()));
|
||||
.arg(QFileInfo(dumpSaveFileName).dir().path()));
|
||||
info.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
info.button(QMessageBox::Yes)->setText(QObject::tr("Open an Issue"));
|
||||
@@ -176,9 +169,10 @@ void showCrashDialog(const QString &dumpFile)
|
||||
openIssue();
|
||||
}
|
||||
} else {
|
||||
QMessageBox::critical(nullptr,
|
||||
QObject::tr("Error"),
|
||||
QObject::tr("Error occurred during crash dump creation."));
|
||||
QMessageBox::critical(
|
||||
nullptr,
|
||||
QObject::tr("Error"),
|
||||
QObject::tr("Error occurred during crash dump creation."));
|
||||
}
|
||||
} else {
|
||||
QFile f(dumpFile);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* If IAITO_ENABLE_CRASH_REPORTS is true, initializes
|
||||
* crash handling and reporting, otherwise does nothing.
|
||||
*/
|
||||
*/
|
||||
void initCrashHandler();
|
||||
|
||||
void showCrashDialog(const QString &dumpFile);
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
#include "DecompileTask.h"
|
||||
#include "common/Configuration.h"
|
||||
#include "core/Iaito.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QMetaObject>
|
||||
|
||||
static bool loopInterrupted = false;
|
||||
DecompileTask::DecompileTask(Decompiler *decompiler, RVA addr, QObject *parent)
|
||||
: AsyncTask()
|
||||
, decompiler(decompiler)
|
||||
, addr(addr)
|
||||
, code(nullptr)
|
||||
{}
|
||||
|
||||
DecompileTask::~DecompileTask() {}
|
||||
|
||||
void DecompileTask::interrupt()
|
||||
{
|
||||
loopInterrupted = true;
|
||||
AsyncTask::interrupt();
|
||||
#if R2_VERSION_NUMBER >= 50909
|
||||
RCore *core = Core()->core_;
|
||||
if (core && core->cons && core->cons->context) {
|
||||
core->cons->context->breaked = true;
|
||||
}
|
||||
#else
|
||||
if (r_cons_singleton() && r_cons_singleton()->context) {
|
||||
r_cons_singleton()->context->breaked = true;
|
||||
}
|
||||
#endif
|
||||
// Previously we raised SIGINT in-process here which can interrupt
|
||||
// Qt/libc allocations and lead to crashes. Instead rely on radare2's
|
||||
// break flag plus signaling child processes from AsyncTask::interrupt.
|
||||
}
|
||||
|
||||
#include <QEventLoop>
|
||||
#include <QObject>
|
||||
|
||||
void DecompileTask::runTask()
|
||||
{
|
||||
// async
|
||||
if (!decompiler) {
|
||||
code = Decompiler::makeWarning(QObject::tr("No decompiler available"));
|
||||
return;
|
||||
}
|
||||
// Respect user setting: when background mode is disabled (default), run synchronously.
|
||||
const bool runSync = !Config()->getDecompilerRunInBackground();
|
||||
if (runSync) {
|
||||
// Some decompilers and core commands expect to run on the main (GUI) thread
|
||||
// to properly collect output. Execute the synchronous decompilation on the
|
||||
// decompiler's thread (main thread) using a blocking queued invocation so
|
||||
// r2 internals behave correctly.
|
||||
RCodeMeta *result = nullptr;
|
||||
bool invoked = QMetaObject::invokeMethod(
|
||||
decompiler,
|
||||
[&result, this]() { result = decompiler->decompileSync(addr); },
|
||||
Qt::BlockingQueuedConnection);
|
||||
if (!invoked) {
|
||||
code = Decompiler::makeWarning(
|
||||
QObject::tr("Failed to invoke decompiler synchronously"));
|
||||
} else {
|
||||
code = result;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Prefer using the decompiler's asynchronous API so radare2 runs the
|
||||
// decompilation as a core task and does not hold the global core mutex in
|
||||
// this thread. We create a local event loop and a notifier QObject that
|
||||
// lives in this worker thread to receive the finished() signal with a
|
||||
// queued connection.
|
||||
|
||||
QEventLoop loop;
|
||||
QObject notifier;
|
||||
// Ensure notifier lives in this thread (it is created here so it's fine).
|
||||
|
||||
RCodeMeta *resultCode = nullptr;
|
||||
|
||||
// Connect using a queued connection so the slot runs in this thread's
|
||||
// event loop when the decompiler emits finished() from the r2 task thread.
|
||||
connect(
|
||||
decompiler,
|
||||
&Decompiler::finished,
|
||||
¬ifier,
|
||||
[&](RCodeMeta *c) {
|
||||
resultCode = c;
|
||||
loop.quit();
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
|
||||
// Start asynchronous decompilation which will enqueue an r2 core task.
|
||||
// Ensure the call runs on the decompiler's thread (main thread) so radare2
|
||||
// internals behave correctly. Invoke the decompilation using a queued
|
||||
// invocation on the decompiler object.
|
||||
bool invoked = QMetaObject::invokeMethod(
|
||||
decompiler, [this]() { decompiler->decompileAt(addr); }, Qt::QueuedConnection);
|
||||
if (!invoked) {
|
||||
code = Decompiler::makeWarning(QObject::tr("Failed to invoke decompiler asynchronously"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Run the local event loop and wait for the finished signal to be queued
|
||||
// and processed here. This avoids holding the IaitoCore mutex in this
|
||||
// thread while radare2 executes the heavy work.
|
||||
loop.exec();
|
||||
|
||||
if (loopInterrupted) {
|
||||
eprintf("DecompilerTask was interrupted\n");
|
||||
loopInterrupted = false;
|
||||
return;
|
||||
}
|
||||
// Store resulting code (or a warning if null). To avoid potential
|
||||
// use-after-free or allocator/lifetime issues caused by R2 internals
|
||||
// allocating objects in different threads, deep-copy the RCodeMeta we
|
||||
// received and free the original.
|
||||
if (resultCode) {
|
||||
RCodeMeta *copy = r_codemeta_new("");
|
||||
if (resultCode->code) {
|
||||
copy->code = strdup(resultCode->code);
|
||||
} else {
|
||||
copy->code = strdup("");
|
||||
}
|
||||
// Copy annotations safely (only essential fields)
|
||||
void *iter;
|
||||
r_vector_foreach(&resultCode->annotations, iter)
|
||||
{
|
||||
RCodeMetaItem *oldItem = (RCodeMetaItem *) iter;
|
||||
RCodeMetaItem *newItem = r_codemeta_item_new();
|
||||
newItem->start = oldItem->start;
|
||||
newItem->end = oldItem->end;
|
||||
newItem->type = oldItem->type;
|
||||
if (newItem->type == R_CODEMETA_TYPE_OFFSET) {
|
||||
newItem->offset.offset = oldItem->offset.offset;
|
||||
}
|
||||
r_codemeta_add_item(copy, newItem);
|
||||
}
|
||||
// Free original and keep our copy
|
||||
// XXX may fail is result fails
|
||||
r_codemeta_free(resultCode);
|
||||
code = copy;
|
||||
} else {
|
||||
code = Decompiler::makeWarning(QObject::tr("Failed to decompile (no result)"));
|
||||
}
|
||||
|
||||
// Disconnect to be safe (not strictly necessary for local notifier)
|
||||
disconnect(decompiler, &Decompiler::finished, ¬ifier, nullptr);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef DECOMPILETASK_H
|
||||
#define DECOMPILETASK_H
|
||||
|
||||
#include "common/AsyncTask.h"
|
||||
#include "common/Decompiler.h"
|
||||
#include "core/IaitoCommon.h"
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
class DecompileTask : public AsyncTask
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DecompileTask(Decompiler *decompiler, RVA addr, QObject *parent = nullptr);
|
||||
~DecompileTask() override;
|
||||
|
||||
void interrupt() override;
|
||||
|
||||
RCodeMeta *getCode() { return code; }
|
||||
|
||||
protected:
|
||||
void runTask() override;
|
||||
|
||||
private:
|
||||
Decompiler *decompiler;
|
||||
RVA addr;
|
||||
RCodeMeta *code;
|
||||
};
|
||||
|
||||
#endif // DECOMPILETASK_H
|
||||
@@ -2,17 +2,17 @@
|
||||
#include "Decompiler.h"
|
||||
#include "Iaito.h"
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
|
||||
Decompiler::Decompiler(const QString &id, const QString &name, QObject *parent)
|
||||
: QObject(parent),
|
||||
id(id),
|
||||
name(name)
|
||||
{
|
||||
}
|
||||
: QObject(parent)
|
||||
, id(id)
|
||||
, name(name)
|
||||
{}
|
||||
|
||||
RCodeMeta *Decompiler::makeWarning(QString warningMessage){
|
||||
RCodeMeta *Decompiler::makeWarning(QString warningMessage)
|
||||
{
|
||||
std::string temporary = warningMessage.toStdString();
|
||||
return r_codemeta_new(temporary.c_str());
|
||||
}
|
||||
@@ -34,11 +34,13 @@ RCodeMeta *R2DecDecompiler::decompileSync(RVA addr)
|
||||
auto document = Core()->cmdjAt("pddj", addr);
|
||||
QJsonObject json = document.object();
|
||||
if (json.isEmpty()) {
|
||||
// emit finished(Decompiler::makeWarning(tr("Failed to parse JSON from pdc")));
|
||||
// emit finished(Decompiler::makeWarning(tr("Failed to parse JSON
|
||||
// from pdc")));
|
||||
return NULL;
|
||||
}
|
||||
// note that r2dec doesnt have the "text" object like pdc does. so we cant reuse code
|
||||
RCodeMeta *code = r_codemeta_new (nullptr);
|
||||
// note that r2dec doesnt have the "text" object like pdc does. so we cant
|
||||
// reuse code
|
||||
RCodeMeta *code = r_codemeta_new("");
|
||||
QString codeString = "";
|
||||
for (const auto line : json["log"].toArray()) {
|
||||
if (!line.isString()) {
|
||||
@@ -53,7 +55,7 @@ RCodeMeta *R2DecDecompiler::decompileSync(RVA addr)
|
||||
if (lineObject.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
RCodeMetaItem *mi = r_codemeta_item_new ();
|
||||
RCodeMetaItem *mi = r_codemeta_item_new();
|
||||
mi->start = codeString.length();
|
||||
codeString.append(lineObject["str"].toString() + "\n");
|
||||
mi->end = codeString.length();
|
||||
@@ -79,6 +81,7 @@ void R2DecDecompiler::decompileAt(RVA addr)
|
||||
if (task) {
|
||||
return;
|
||||
}
|
||||
|
||||
task = new R2Task("pddj @ " + QString::number(addr));
|
||||
connect(task, &R2Task::finished, this, [this]() {
|
||||
QJsonObject json = task->getResultJson().object();
|
||||
@@ -88,7 +91,7 @@ void R2DecDecompiler::decompileAt(RVA addr)
|
||||
emit finished(Decompiler::makeWarning(tr("Failed to parse JSON from r2dec")));
|
||||
return;
|
||||
}
|
||||
RCodeMeta *code = r_codemeta_new (nullptr);
|
||||
RCodeMeta *code = r_codemeta_new("");
|
||||
QString codeString = "";
|
||||
for (const auto line : json["log"].toArray()) {
|
||||
if (!line.isString()) {
|
||||
@@ -103,7 +106,7 @@ void R2DecDecompiler::decompileAt(RVA addr)
|
||||
if (lineObject.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
RCodeMetaItem *mi = r_codemeta_item_new ();
|
||||
RCodeMetaItem *mi = r_codemeta_item_new();
|
||||
mi->start = codeString.length();
|
||||
codeString.append(lineObject["str"].toString() + "\n");
|
||||
mi->end = codeString.length();
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
#include "IaitoCommon.h"
|
||||
#include "R2Task.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
/**
|
||||
* Implements a decompiler that can be registered using IaitoCore::registerDecompiler()
|
||||
* Implements a decompiler that can be registered using
|
||||
* IaitoCore::registerDecompiler()
|
||||
*/
|
||||
class IAITO_EXPORT Decompiler: public QObject
|
||||
class IAITO_EXPORT Decompiler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -24,20 +25,20 @@ public:
|
||||
|
||||
static RCodeMeta *makeWarning(QString warningMessage);
|
||||
|
||||
QString getId() const { return id; }
|
||||
QString getName() const { return name; }
|
||||
virtual bool isRunning() { return false; }
|
||||
QString getId() const { return id; }
|
||||
QString getName() const { return name; }
|
||||
virtual bool isRunning() { return false; }
|
||||
virtual bool isCancelable() { return false; }
|
||||
|
||||
virtual void decompileAt(RVA addr) =0;
|
||||
virtual RCodeMeta *decompileSync(RVA addr) =0;
|
||||
virtual void decompileAt(RVA addr) = 0;
|
||||
virtual RCodeMeta *decompileSync(RVA addr) = 0;
|
||||
virtual void cancel() {}
|
||||
|
||||
signals:
|
||||
void finished(RCodeMeta *codeDecompiled);
|
||||
};
|
||||
|
||||
class R2DecDecompiler: public Decompiler
|
||||
class R2DecDecompiler : public Decompiler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -49,10 +50,9 @@ public:
|
||||
RCodeMeta *decompileSync(RVA addr) override;
|
||||
void decompileAt(RVA addr) override;
|
||||
|
||||
bool isRunning() override { return task != nullptr; }
|
||||
bool isRunning() override { return task != nullptr; }
|
||||
|
||||
static bool isAvailable();
|
||||
};
|
||||
|
||||
|
||||
#endif //DECOMPILER_H
|
||||
#endif // DECOMPILER_H
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "common/Configuration.h"
|
||||
|
||||
DecompilerHighlighter::DecompilerHighlighter(QTextDocument *parent)
|
||||
: QSyntaxHighlighter(parent)
|
||||
: QSyntaxHighlighter(parent)
|
||||
{
|
||||
setupTheme();
|
||||
connect(Config(), &Configuration::colorsUpdated, this, [this]() {
|
||||
@@ -19,7 +19,8 @@ void DecompilerHighlighter::setAnnotations(RCodeMeta *code)
|
||||
|
||||
void DecompilerHighlighter::setupTheme()
|
||||
{
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
RSyntaxHighlightType type;
|
||||
QString name;
|
||||
} mapping[] = {
|
||||
@@ -49,12 +50,13 @@ void DecompilerHighlighter::highlightBlock(const QString &)
|
||||
|
||||
auto cm = r_codemeta_in(code, start, end);
|
||||
if (cm == nullptr) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
std::unique_ptr<RPVector, decltype(&r_pvector_free)> annotations(cm, &r_pvector_free);
|
||||
void **iter;
|
||||
r_pvector_foreach(annotations.get(), iter) {
|
||||
RCodeMetaItem *annotation = static_cast<RCodeMetaItem*>(*iter);
|
||||
r_pvector_foreach(annotations.get(), iter)
|
||||
{
|
||||
RCodeMetaItem *annotation = static_cast<RCodeMetaItem *>(*iter);
|
||||
if (annotation->type != R_CODEMETA_TYPE_SYNTAX_HIGHLIGHT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
#define DECOMPILER_HIGHLIGHTER_H
|
||||
|
||||
#include "IaitoCommon.h"
|
||||
#include <QSyntaxHighlighter>
|
||||
#include <QTextDocument>
|
||||
#include <QTextCharFormat>
|
||||
#include <array>
|
||||
#include <QSyntaxHighlighter>
|
||||
#include <QTextCharFormat>
|
||||
#include <QTextDocument>
|
||||
|
||||
/**
|
||||
* \brief SyntaxHighlighter based on annotations from decompiled code.
|
||||
@@ -21,17 +21,17 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Set the code with annotations to be used for highlighting.
|
||||
*
|
||||
* It is callers responsibility to ensure that it is synchronized with currentTextDocument and
|
||||
* has sufficiently long lifetime.
|
||||
*
|
||||
* @param code
|
||||
*
|
||||
* It is callers responsibility to ensure that it is synchronized with
|
||||
* currentTextDocument and has sufficiently long lifetime.
|
||||
*
|
||||
* @param code
|
||||
*/
|
||||
void setAnnotations(RCodeMeta *code);
|
||||
|
||||
protected:
|
||||
void highlightBlock(const QString &text) override;
|
||||
|
||||
|
||||
private:
|
||||
void setupTheme();
|
||||
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
#include "DirectionalComboBox.h"
|
||||
|
||||
DirectionalComboBox::DirectionalComboBox(QWidget *parent, bool upwards)
|
||||
: QComboBox(parent), popupUpwards(upwards)
|
||||
{
|
||||
}
|
||||
: QComboBox(parent)
|
||||
, popupUpwards(upwards)
|
||||
{}
|
||||
|
||||
void DirectionalComboBox::showPopup()
|
||||
{
|
||||
QComboBox::showPopup();
|
||||
QWidget *popup = this->findChild<QFrame *>();
|
||||
if (popupUpwards) {
|
||||
popup->move(popup->x(),
|
||||
mapToGlobal(this->rect().bottomLeft()).y() - popup->height());
|
||||
popup->move(popup->x(), mapToGlobal(this->rect().bottomLeft()).y() - popup->height());
|
||||
} else {
|
||||
popup->move(popup->x(),
|
||||
mapToGlobal(this->rect().topLeft()).y());
|
||||
popup->move(popup->x(), mapToGlobal(this->rect().topLeft()).y());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
#include <QComboBox>
|
||||
/**
|
||||
* @brief Custom QComboBox created to prevent the menu popup from opening up at different
|
||||
* offsets for different items, which may result in list items being rendered outside
|
||||
* of the screen/containing widget.
|
||||
* @brief Custom QComboBox created to prevent the menu popup from opening up at
|
||||
* different offsets for different items, which may result in list items being
|
||||
* rendered outside of the screen/containing widget.
|
||||
*/
|
||||
class DirectionalComboBox : public QComboBox
|
||||
{
|
||||
@@ -20,4 +20,3 @@ private:
|
||||
|
||||
void showPopup();
|
||||
};
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
|
||||
class FunctionsTask : public AsyncTask
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QString getTitle() override { return tr("Fetching Functions"); }
|
||||
QString getTitle() override { return tr("Fetching Functions"); }
|
||||
|
||||
signals:
|
||||
void fetchFinished(const QList<FunctionDescription> &strings);
|
||||
@@ -27,4 +27,4 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
#endif //FUNCTIONSTASK_H
|
||||
#endif // FUNCTIONSTASK_H
|
||||
@@ -2,25 +2,36 @@
|
||||
#include "Configuration.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QTextEdit>
|
||||
#include <QFileInfo>
|
||||
#include <QtCore>
|
||||
#include <QCryptographicHash>
|
||||
#include <QTreeWidget>
|
||||
#include <QString>
|
||||
#include <QAbstractItemView>
|
||||
#include <QAbstractButton>
|
||||
#include <QDockWidget>
|
||||
#include <QMenu>
|
||||
#include <QAbstractItemView>
|
||||
#include <QComboBox>
|
||||
#include <QCryptographicHash>
|
||||
#include <QDockWidget>
|
||||
#include <QFileInfo>
|
||||
#include <QMenu>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QString>
|
||||
#include <QTextEdit>
|
||||
#include <QTreeWidget>
|
||||
#include <QtCore>
|
||||
|
||||
static QAbstractItemView::ScrollMode scrollMode()
|
||||
{
|
||||
const bool use_scrollperpixel = true;
|
||||
return use_scrollperpixel ? QAbstractItemView::ScrollPerPixel : QAbstractItemView::ScrollPerItem;
|
||||
return use_scrollperpixel ? QAbstractItemView::ScrollPerPixel
|
||||
: QAbstractItemView::ScrollPerItem;
|
||||
}
|
||||
|
||||
RCore *iaitoPluginCore(void)
|
||||
{
|
||||
char *p = r_sys_getenv("R2COREPTR");
|
||||
if (R_STR_ISNOTEMPTY(p)) {
|
||||
RCore *k = (RCore *) (void *) (size_t) r_num_get(NULL, p);
|
||||
free(p);
|
||||
return k;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
namespace qhelpers {
|
||||
|
||||
@@ -35,20 +46,26 @@ QString formatBytecount(const uint64_t bytecount)
|
||||
|
||||
QString str;
|
||||
QTextStream stream(&str);
|
||||
stream << qSetRealNumberPrecision(3) << bytecount / pow(1024, exp)
|
||||
<< ' ' << suffixes[exp] << 'B';
|
||||
stream << qSetRealNumberPrecision(3) << bytecount / pow(1024, exp) << ' ' << suffixes[exp]
|
||||
<< 'B';
|
||||
return stream.readAll();
|
||||
}
|
||||
|
||||
void adjustColumns(QTreeView *tv, int columnCount, int padding)
|
||||
{
|
||||
for (int i = 0; i != columnCount; ++i) {
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
for (int i = 0; i < columnCount; i++) {
|
||||
tv->resizeColumnToContents(i);
|
||||
if (padding > 0) {
|
||||
int width = tv->columnWidth(i);
|
||||
tv->setColumnWidth(i, width + padding);
|
||||
}
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(tv)
|
||||
Q_UNUSED(columnCount)
|
||||
Q_UNUSED(padding)
|
||||
#endif
|
||||
}
|
||||
|
||||
void adjustColumns(QTreeWidget *tw, int padding)
|
||||
@@ -56,8 +73,13 @@ void adjustColumns(QTreeWidget *tw, int padding)
|
||||
adjustColumns(tw, tw->columnCount(), padding);
|
||||
}
|
||||
|
||||
QTreeWidgetItem *appendRow(QTreeWidget *tw, const QString &str, const QString &str2,
|
||||
const QString &str3, const QString &str4, const QString &str5)
|
||||
QTreeWidgetItem *appendRow(
|
||||
QTreeWidget *tw,
|
||||
const QString &str,
|
||||
const QString &str2,
|
||||
const QString &str3,
|
||||
const QString &str4,
|
||||
const QString &str5)
|
||||
{
|
||||
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
|
||||
// Fill dummy hidden column
|
||||
@@ -161,9 +183,8 @@ int getMaxFullyDisplayedLines(QTextEdit *textEdit)
|
||||
{
|
||||
QFontMetrics fontMetrics(textEdit->document()->defaultFont());
|
||||
return (textEdit->height()
|
||||
- (textEdit->contentsMargins().top()
|
||||
+ textEdit->contentsMargins().bottom()
|
||||
+ (int)(textEdit->document()->documentMargin() * 2)))
|
||||
- (textEdit->contentsMargins().top() + textEdit->contentsMargins().bottom()
|
||||
+ (int) (textEdit->document()->documentMargin() * 2)))
|
||||
/ fontMetrics.lineSpacing();
|
||||
}
|
||||
|
||||
@@ -171,17 +192,17 @@ int getMaxFullyDisplayedLines(QPlainTextEdit *plainTextEdit)
|
||||
{
|
||||
QFontMetrics fontMetrics(plainTextEdit->document()->defaultFont());
|
||||
return (plainTextEdit->height()
|
||||
- (plainTextEdit->contentsMargins().top()
|
||||
+ plainTextEdit->contentsMargins().bottom()
|
||||
+ (int)(plainTextEdit->document()->documentMargin() * 2)))
|
||||
- (plainTextEdit->contentsMargins().top() + plainTextEdit->contentsMargins().bottom()
|
||||
+ (int) (plainTextEdit->document()->documentMargin() * 2)))
|
||||
/ fontMetrics.lineSpacing();
|
||||
}
|
||||
|
||||
QByteArray applyColorToSvg(const QByteArray &data, QColor color)
|
||||
{
|
||||
static const QRegularExpression styleRegExp("(?:style=\".*fill:(.*?);.*?\")|(?:fill=\"(.*?)\")");
|
||||
static const QRegularExpression styleRegExp(
|
||||
"(?:style=\".*fill:(.*?);.*?\")|(?:fill=\"(.*?)\")");
|
||||
|
||||
QString replaceStr = QString("#%1").arg(color.rgb() & 0xffffff, 6, 16, QLatin1Char('0'));
|
||||
QString replaceStr = QStringLiteral("#%1").arg(color.rgb() & 0xffffff, 6, 16, QLatin1Char('0'));
|
||||
int replaceStrLen = replaceStr.length();
|
||||
|
||||
QString xml = QString::fromUtf8(data);
|
||||
@@ -210,14 +231,16 @@ QByteArray applyColorToSvg(const QString &filename, QColor color)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief finds the theme-specific icon path and calls `setter` functor providing a pointer of an object which has to be used
|
||||
* and loaded icon
|
||||
* @brief finds the theme-specific icon path and calls `setter` functor
|
||||
* providing a pointer of an object which has to be used and loaded icon
|
||||
* @param supportedIconsNames list of <object ptr, icon name>
|
||||
* @param setter functor which has to be called
|
||||
* for example we need to set an action icon, the functor can be just [](void* o, const QIcon &icon) { static_cast<QAction*>(o)->setIcon(icon); }
|
||||
* for example we need to set an action icon, the functor can be just [](void*
|
||||
* o, const QIcon &icon) { static_cast<QAction*>(o)->setIcon(icon); }
|
||||
*/
|
||||
void setThemeIcons(QList<QPair<void *, QString>> supportedIconsNames,
|
||||
std::function<void(void *, const QIcon &)> setter)
|
||||
void setThemeIcons(
|
||||
QList<QPair<void *, QString>> supportedIconsNames,
|
||||
std::function<void(void *, const QIcon &)> setter)
|
||||
{
|
||||
if (supportedIconsNames.isEmpty() || !setter) {
|
||||
return;
|
||||
@@ -232,10 +255,25 @@ void setThemeIcons(QList<QPair<void *, QString>> supportedIconsNames,
|
||||
iconPath = iconsDirPath;
|
||||
// Verify that indeed there is an alternative icon in this theme
|
||||
// Otherwise, fallback to the regular icon folder
|
||||
if (QFile::exists(iconPath + relativeThemeDir + p.second)) {
|
||||
if (QFile::exists(iconPath + relativeThemeDir + p.second)) {
|
||||
iconPath += relativeThemeDir;
|
||||
}
|
||||
setter(p.first, QIcon(iconPath + p.second));
|
||||
// Ensure icon creation and setter invocation happen on the GUI thread
|
||||
QString fullPath = iconPath + p.second;
|
||||
if (QCoreApplication::instance()
|
||||
&& QThread::currentThread() == QCoreApplication::instance()->thread()) {
|
||||
setter(p.first, QIcon(fullPath));
|
||||
} else if (QCoreApplication::instance()) {
|
||||
// Post the setter invocation to the GUI thread to avoid creating
|
||||
// QIcon/QPixmap on worker threads which is not safe.
|
||||
QMetaObject::invokeMethod(
|
||||
QCoreApplication::instance(),
|
||||
[p, fullPath, setter]() { setter(p.first, QIcon(fullPath)); },
|
||||
Qt::QueuedConnection);
|
||||
} else {
|
||||
// Fallback: call directly
|
||||
setter(p.first, QIcon(fullPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,11 +311,8 @@ void emitColumnChanged(QAbstractItemModel *model, int column)
|
||||
{
|
||||
if (model && model->rowCount()) {
|
||||
emit model->dataChanged(
|
||||
model->index(0, column),
|
||||
model->index(model->rowCount() - 1, column),
|
||||
{ Qt::DisplayRole }
|
||||
);
|
||||
model->index(0, column), model->index(model->rowCount() - 1, column), {Qt::DisplayRole});
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
} // namespace qhelpers
|
||||
@@ -3,10 +3,10 @@
|
||||
|
||||
#include "core/IaitoCommon.h"
|
||||
|
||||
#include <QString>
|
||||
#include <functional>
|
||||
#include <QColor>
|
||||
#include <QSizePolicy>
|
||||
#include <functional>
|
||||
#include <QString>
|
||||
|
||||
class QIcon;
|
||||
class QPlainTextEdit;
|
||||
@@ -30,20 +30,43 @@ class QComboBox;
|
||||
#define IAITO_QT_SKIP_EMPTY_PARTS Qt::SkipEmptyParts
|
||||
#endif
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
#define FILTER_REGEX this->filterRegularExpression()
|
||||
#else
|
||||
#define FILTER_REGEX filterRegExp()
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
#include <utility>
|
||||
using std::as_const;
|
||||
#else
|
||||
template<typename T>
|
||||
constexpr const T &as_const(T &t) noexcept
|
||||
{
|
||||
return t;
|
||||
}
|
||||
#endif
|
||||
|
||||
RCore *iaitoPluginCore(void);
|
||||
namespace qhelpers {
|
||||
IAITO_EXPORT QString formatBytecount(const uint64_t bytecount);
|
||||
IAITO_EXPORT void adjustColumns(QTreeView *tv, int columnCount, int padding);
|
||||
IAITO_EXPORT void adjustColumns(QTreeWidget *tw, int padding);
|
||||
IAITO_EXPORT bool selectFirstItem(QAbstractItemView *itemView);
|
||||
IAITO_EXPORT QTreeWidgetItem *appendRow(QTreeWidget *tw, const QString &str, const QString &str2 = QString(),
|
||||
const QString &str3 = QString(), const QString &str4 = QString(), const QString &str5 = QString());
|
||||
IAITO_EXPORT QTreeWidgetItem *appendRow(
|
||||
QTreeWidget *tw,
|
||||
const QString &str,
|
||||
const QString &str2 = QString(),
|
||||
const QString &str3 = QString(),
|
||||
const QString &str4 = QString(),
|
||||
const QString &str5 = QString());
|
||||
|
||||
IAITO_EXPORT void setVerticalScrollMode(QAbstractItemView *tw);
|
||||
|
||||
IAITO_EXPORT void setCheckedWithoutSignals(QAbstractButton *button, bool checked);
|
||||
|
||||
|
||||
struct IAITO_EXPORT SizePolicyMinMax {
|
||||
struct IAITO_EXPORT SizePolicyMinMax
|
||||
{
|
||||
QSizePolicy sizePolicy;
|
||||
int min;
|
||||
int max;
|
||||
@@ -61,7 +84,9 @@ IAITO_EXPORT int getMaxFullyDisplayedLines(QPlainTextEdit *plainTextEdit);
|
||||
IAITO_EXPORT QByteArray applyColorToSvg(const QByteArray &data, QColor color);
|
||||
IAITO_EXPORT QByteArray applyColorToSvg(const QString &filename, QColor color);
|
||||
|
||||
IAITO_EXPORT void setThemeIcons(QList<QPair<void*, QString>> supportedIconsNames, std::function<void(void *, const QIcon &)> setter);
|
||||
IAITO_EXPORT void setThemeIcons(
|
||||
QList<QPair<void *, QString>> supportedIconsNames,
|
||||
std::function<void(void *, const QIcon &)> setter);
|
||||
|
||||
IAITO_EXPORT void prependQAction(QAction *action, QMenu *menu);
|
||||
IAITO_EXPORT qreal devicePixelRatio(const QPaintDevice *p);
|
||||
@@ -73,12 +98,12 @@ IAITO_EXPORT qreal devicePixelRatio(const QPaintDevice *p);
|
||||
*/
|
||||
IAITO_EXPORT void selectIndexByData(QComboBox *comboBox, QVariant data, int defaultIndex = -1);
|
||||
/**
|
||||
* @brief Emit data change signal in a model's column (DisplayRole)
|
||||
* @brief Emit data change signal in a model's column (DisplayRole)
|
||||
* @param model - model containing data with changes
|
||||
* @param column - column in the model
|
||||
*/
|
||||
IAITO_EXPORT void emitColumnChanged(QAbstractItemModel *model, int column);
|
||||
|
||||
} // qhelpers
|
||||
} // namespace qhelpers
|
||||
|
||||
#endif // HELPERS_H
|
||||
@@ -16,8 +16,9 @@ static qreal GetDevicePixelRatio(qreal devicePixelRatio)
|
||||
}
|
||||
|
||||
HighDpiPixmap::HighDpiPixmap(int width, int height, qreal devicePixelRatio)
|
||||
: QPixmap(int(width * GetDevicePixelRatio(devicePixelRatio)),
|
||||
int(height * GetDevicePixelRatio(devicePixelRatio)))
|
||||
: QPixmap(
|
||||
int(width * GetDevicePixelRatio(devicePixelRatio)),
|
||||
int(height * GetDevicePixelRatio(devicePixelRatio)))
|
||||
{
|
||||
setDevicePixelRatio(GetDevicePixelRatio(devicePixelRatio));
|
||||
}
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
#include <QtGui>
|
||||
|
||||
Highlighter::Highlighter(QTextDocument *parent) :
|
||||
QSyntaxHighlighter(parent)
|
||||
Highlighter::Highlighter(QTextDocument *parent)
|
||||
: QSyntaxHighlighter(parent)
|
||||
{
|
||||
HighlightingRule rule;
|
||||
|
||||
@@ -28,7 +28,6 @@ Highlighter::Highlighter(QTextDocument *parent) :
|
||||
highlightingRules.append(rule);
|
||||
}
|
||||
|
||||
|
||||
singleLineCommentFormat.setFontWeight(QFont::Bold);
|
||||
singleLineCommentFormat.setForeground(QColor(63, 195, 128));
|
||||
rule.pattern.setPattern(";[^\n]*");
|
||||
@@ -57,17 +56,19 @@ void Highlighter::highlightBlock(const QString &text)
|
||||
startIndex = QRegularExpression(commentStartRegularExpression).match(text).capturedStart();
|
||||
|
||||
while (startIndex >= 0) {
|
||||
QRegularExpressionMatch commentEndMatch = QRegularExpression(commentEndRegularExpression).match(text.mid(startIndex));
|
||||
QRegularExpressionMatch commentEndMatch
|
||||
= QRegularExpression(commentEndRegularExpression).match(text.mid(startIndex));
|
||||
int endIndex = commentEndMatch.capturedStart();
|
||||
int commentLength;
|
||||
if (endIndex == -1) {
|
||||
setCurrentBlockState(1);
|
||||
commentLength = text.length() - startIndex;
|
||||
} else {
|
||||
commentLength = endIndex - startIndex
|
||||
+ commentEndMatch.capturedLength();
|
||||
commentLength = endIndex - startIndex + commentEndMatch.capturedLength();
|
||||
}
|
||||
setFormat(startIndex, commentLength, multiLineCommentFormat);
|
||||
startIndex = QRegularExpression(commentStartRegularExpression).match(text.mid(startIndex + commentLength)).capturedStart();
|
||||
startIndex = QRegularExpression(commentStartRegularExpression)
|
||||
.match(text.mid(startIndex + commentLength))
|
||||
.capturedStart();
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,10 @@
|
||||
|
||||
#include "core/Iaito.h"
|
||||
|
||||
#include <QSyntaxHighlighter>
|
||||
#include <QHash>
|
||||
#include <QTextCharFormat>
|
||||
#include <QRegularExpression>
|
||||
#include <QSyntaxHighlighter>
|
||||
#include <QTextCharFormat>
|
||||
|
||||
class QTextDocument;
|
||||
class MainWindow;
|
||||
@@ -24,7 +24,8 @@ protected:
|
||||
private:
|
||||
IaitoCore *core;
|
||||
|
||||
struct HighlightingRule {
|
||||
struct HighlightingRule
|
||||
{
|
||||
QRegularExpression pattern;
|
||||
QTextCharFormat format;
|
||||
};
|
||||
@@ -42,4 +43,4 @@ private:
|
||||
QTextCharFormat functionFormat;
|
||||
};
|
||||
|
||||
#endif // HIGHLIGHTER_H
|
||||
#endif // HIGHLIGHTER_H
|
||||
@@ -2,10 +2,10 @@
|
||||
#include "Iaito.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QPushButton>
|
||||
#include <QObject>
|
||||
#include <QMessageBox>
|
||||
#include <QJsonObject>
|
||||
#include <QMessageBox>
|
||||
#include <QObject>
|
||||
#include <QPushButton>
|
||||
|
||||
bool IOModesController::canWrite()
|
||||
{
|
||||
@@ -51,17 +51,19 @@ bool IOModesController::prepareForWriting()
|
||||
QMessageBox msgBox;
|
||||
msgBox.setIcon(QMessageBox::Icon::Critical);
|
||||
msgBox.setWindowTitle(QObject::tr("Write error"));
|
||||
msgBox.setText(
|
||||
QObject::tr("Your file is opened in read-only mode. "
|
||||
"Editing is only available when the file is opened in either Write or Cache modes.\n\n"
|
||||
"WARNING: In Write mode, any changes will be committed to the file on disk. "
|
||||
"For safety, please consider using Cache mode and then commit the changes manually "
|
||||
"via File -> Commit modifications to disk."));
|
||||
msgBox.setText(QObject::tr("Your file is opened in read-only mode. "
|
||||
"Editing is only available when the file is "
|
||||
"opened in either Write or Cache modes.\n\n"
|
||||
"WARNING: In Write mode, any changes will be "
|
||||
"committed to the file on disk. "
|
||||
"For safety, please consider using Cache mode "
|
||||
"and then commit the changes manually "
|
||||
"via File -> Commit modifications to disk."));
|
||||
msgBox.addButton(QObject::tr("Cancel"), QMessageBox::RejectRole);
|
||||
QAbstractButton *reopenButton = msgBox.addButton(QObject::tr("Reopen in Write mode"),
|
||||
QMessageBox::YesRole);
|
||||
QAbstractButton *iocacheButton = msgBox.addButton(QObject::tr("Enable Cache mode"),
|
||||
QMessageBox::YesRole);
|
||||
QAbstractButton *reopenButton
|
||||
= msgBox.addButton(QObject::tr("Reopen in Write mode"), QMessageBox::YesRole);
|
||||
QAbstractButton *iocacheButton
|
||||
= msgBox.addButton(QObject::tr("Enable Cache mode"), QMessageBox::YesRole);
|
||||
|
||||
msgBox.exec();
|
||||
|
||||
@@ -95,15 +97,19 @@ bool IOModesController::askCommitUnsavedChanges()
|
||||
{
|
||||
// Check if there are uncommitted changes
|
||||
if (!allChangesComitted()) {
|
||||
QMessageBox::StandardButton ret = QMessageBox::question(NULL, QObject::tr("Uncomitted changes"),
|
||||
QObject::tr("It seems that you have changes or patches that are not committed to the file.\n"
|
||||
"Do you want to commit them now?"),
|
||||
(QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel));
|
||||
QMessageBox::StandardButton ret = QMessageBox::question(
|
||||
NULL,
|
||||
QObject::tr("Uncomitted changes"),
|
||||
QObject::tr("It seems that you have changes or patches that are "
|
||||
"not committed to the file.\n"
|
||||
"Do you want to commit them now?"),
|
||||
(QMessageBox::StandardButtons)(
|
||||
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel));
|
||||
if (ret == QMessageBox::Save) {
|
||||
Core()->commitWriteCache();
|
||||
} else if (ret == QMessageBox::Discard) {
|
||||
Core()->cmdRaw("wcr");
|
||||
emit Core()->refreshCodeViews();
|
||||
emit Core() -> refreshCodeViews();
|
||||
} else if (ret == QMessageBox::Cancel) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
#include <QString>
|
||||
#include <QVariantMap>
|
||||
|
||||
namespace Iaito
|
||||
{
|
||||
namespace Iaito {
|
||||
|
||||
struct IaitoLayout
|
||||
{
|
||||
@@ -21,5 +20,5 @@ const QString LAYOUT_DEBUG = "Debug";
|
||||
|
||||
bool isBuiltinLayoutName(const QString &name);
|
||||
|
||||
}
|
||||
} // namespace Iaito
|
||||
#endif
|
||||
@@ -1,12 +1,10 @@
|
||||
#include "core/MainWindow.h"
|
||||
#include "IaitoSeekable.h"
|
||||
#include "core/MainWindow.h"
|
||||
|
||||
#include <QPlainTextEdit>
|
||||
|
||||
|
||||
IaitoSeekable::IaitoSeekable(QObject *parent)
|
||||
:
|
||||
QObject(parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
connect(Core(), &IaitoCore::seekChanged, this, &IaitoSeekable::onCoreSeekChanged);
|
||||
}
|
||||
@@ -38,7 +36,6 @@ void IaitoSeekable::updateSeek(RVA addr, bool localOnly)
|
||||
emit seekableSeekChanged(addr);
|
||||
}
|
||||
|
||||
|
||||
void IaitoSeekable::seekPrev()
|
||||
{
|
||||
if (synchronized) {
|
||||
@@ -65,20 +62,20 @@ bool IaitoSeekable::isSynchronized()
|
||||
|
||||
void IaitoSeekable::seekToReference(RVA offset)
|
||||
{
|
||||
if (offset == RVA_INVALID)
|
||||
{
|
||||
if (offset == RVA_INVALID) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
RVA target;
|
||||
QList<XrefDescription> refs = Core()->getXRefs(offset, false, false);
|
||||
|
||||
|
||||
if (refs.length()) {
|
||||
if (refs.length() > 1) {
|
||||
qWarning() << tr("More than one (%1) references here. Weird behaviour expected.")
|
||||
.arg(refs.length());
|
||||
qWarning() << tr("More than one (%1) references here. Weird "
|
||||
"behaviour expected.")
|
||||
.arg(refs.length());
|
||||
}
|
||||
|
||||
|
||||
target = refs.at(0).to;
|
||||
if (target != RVA_INVALID) {
|
||||
seek(target);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
class MainWindow;
|
||||
|
||||
class IAITO_EXPORT IaitoSeekable : public QObject
|
||||
class IAITO_EXPORT IaitoSeekable : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -45,7 +45,8 @@ public:
|
||||
bool isSynchronized();
|
||||
|
||||
/**
|
||||
* @brief seekToReference will seek to the function or the object which is referenced in a given offset
|
||||
* @brief seekToReference will seek to the function or the object which is
|
||||
* referenced in a given offset
|
||||
* @param offset - an address that contains a reference to jump to
|
||||
*/
|
||||
void seekToReference(RVA offset);
|
||||
@@ -88,7 +89,8 @@ private:
|
||||
|
||||
/**
|
||||
* @brief internal method for changing the seek
|
||||
* @param localOnly whether the seek should be updated globally if synchronized
|
||||
* @param localOnly whether the seek should be updated globally if
|
||||
* synchronized
|
||||
*/
|
||||
void updateSeek(RVA addr, bool localOnly);
|
||||
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
#include "core/Iaito.h"
|
||||
|
||||
/**
|
||||
* @brief The CommandDescription struct is a pair of a radare2 command and its description
|
||||
* @brief The CommandDescription struct is a pair of a radare2 command and its
|
||||
* description
|
||||
*/
|
||||
struct CommandDescription {
|
||||
struct CommandDescription
|
||||
{
|
||||
QString command;
|
||||
QString description;
|
||||
};
|
||||
@@ -26,6 +28,7 @@ struct InitialOptions
|
||||
QString cpu;
|
||||
int bits = 0;
|
||||
QString os;
|
||||
bool analVars = true;
|
||||
|
||||
Endianness endian;
|
||||
|
||||
@@ -38,10 +41,10 @@ struct InitialOptions
|
||||
|
||||
QString pdbFile;
|
||||
QString script;
|
||||
|
||||
QList<CommandDescription> analCmd = { {"aaa", "Auto analysis"} };
|
||||
|
||||
QList<CommandDescription> analCmd = {{"aaa", "Auto analysis"}};
|
||||
|
||||
QString shellcode;
|
||||
};
|
||||
|
||||
#endif //IAITO_INITIALOPTIONS_H
|
||||
#endif // IAITO_INITIALOPTIONS_H
|
||||