├── ida-cmake
├── .gitignore
├── cmake
│ ├── template.vcxproj.user
│ └── IDA.cmake
├── LICENSE
├── README.md
└── build.py
├── resources
├── edit.png
├── delete.png
├── rsrc.qrc
└── default_rules.ini
├── .gitignore
├── template.vcxproj.user
├── LICENSE
├── src
├── Utils.cpp
├── RETypedef.hpp
├── Config.hpp
├── Settings.cpp
├── Settings.hpp
├── ImportExport.hpp
├── REtypedef.cpp
├── SubstitutionManager.hpp
├── Core.hpp
├── Utils.hpp
├── SubstitutionManager.cpp
├── ImportExport.cpp
├── Ui.hpp
├── Core.cpp
└── Ui.cpp
├── CMakeLists.txt
├── README.md
└── ui
├── AboutDialog.ui
└── SubstitutionEditor.ui
/ida-cmake/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
--------------------------------------------------------------------------------
/resources/edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NyaMisty/REtypedef/HEAD/resources/edit.png
--------------------------------------------------------------------------------
/resources/delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NyaMisty/REtypedef/HEAD/resources/delete.png
--------------------------------------------------------------------------------
/resources/rsrc.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | delete.png
4 | edit.png
5 |
6 |
7 | default_rules.ini
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files
2 | *.slo
3 | *.lo
4 | *.o
5 | *.obj
6 |
7 | # Precompiled Headers
8 | *.gch
9 | *.pch
10 |
11 | # Compiled Dynamic libraries
12 | *.so
13 | *.dylib
14 | *.dll
15 |
16 | # Fortran module files
17 | *.mod
18 |
19 | # Compiled Static libraries
20 | *.lai
21 | *.la
22 | *.a
23 | *.lib
24 |
25 | # Executables
26 | *.exe
27 | *.out
28 | *.app
29 |
30 | # CMake
31 | build/*
32 |
33 | .DS_Store
34 |
--------------------------------------------------------------------------------
/template.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | @IDA_NATIVE_DIR@\idaq.exe
5 | WindowsLocalDebugger
6 |
7 |
8 | @IDA_NATIVE_DIR@\idaq.exe
9 | WindowsLocalDebugger
10 |
11 |
12 | @IDA_NATIVE_DIR@\idaq.exe
13 | WindowsLocalDebugger
14 |
15 |
16 | @IDA_NATIVE_DIR@\idaq.exe
17 | WindowsLocalDebugger
18 |
19 |
--------------------------------------------------------------------------------
/ida-cmake/cmake/template.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | @IDA_NATIVE_DIR@\idaq.exe
5 | WindowsLocalDebugger
6 |
7 |
8 | @IDA_NATIVE_DIR@\idaq.exe
9 | WindowsLocalDebugger
10 |
11 |
12 | @IDA_NATIVE_DIR@\idaq.exe
13 | WindowsLocalDebugger
14 |
15 |
16 | @IDA_NATIVE_DIR@\idaq.exe
17 | WindowsLocalDebugger
18 |
19 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 Joel Hoener
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/ida-cmake/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 Joel Höner
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/Utils.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 athre0z
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | #include "Utils.hpp"
26 |
27 | namespace Utils
28 | {
29 |
30 | }
--------------------------------------------------------------------------------
/src/RETypedef.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 athre0z
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | #ifndef RETYPEDEF_HPP
26 | #define RETYPEDEF_HPP
27 |
28 | #include
29 |
30 | extern __declspec(dllexport) plugin_t PLUGIN;
31 |
32 | #endif // RETYPEDEF_HPP
--------------------------------------------------------------------------------
/src/Config.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 athre0z
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | #ifndef CONFIG_HPP
26 | #define CONFIG_HPP
27 |
28 | #define MAKE_PLUGIN_VERSION(maj, min, rev) ((maj << 16) | (min << 8) | rev)
29 | #define PLUGIN_TEXTUAL_VERSION "v1.0.3"
30 | #define PLUGIN_VERSION MAKE_PLUGIN_VERSION(1, 0, 3)
31 |
32 | #define PLUGIN_NAME "REtypedef"
33 |
34 | #endif
--------------------------------------------------------------------------------
/resources/default_rules.ini:
--------------------------------------------------------------------------------
1 | [substitutions]
2 | size=8
3 | 1\pattern="(.*)std::basic_(streambuf|iostream|ostream|ios|istream|filebuf)\\s*>(.*)"
4 | 1\repl=$1std::$2$3
5 | 2\pattern="(.*)std::basic_(string|istringstream|ostringstream|stringstream|stringbuf),\\s*(?:class\\s+)?std::allocator\\s*>(.*)"
6 | 2\repl=$1std::$2$3
7 | 3\pattern="(.*)std::basic_(streambuf|iostream|ostream|ios|istream|filebuf)\\s*>(.*)"
8 | 3\repl=$1std::w$2$3
9 | 4\pattern="(.*)std::basic_(string|istringstream|ostringstream|stringstream|stringbuf),\\s*(?:class\\s+)?std::allocator\\s*>(.*)"
10 | 4\repl=$1std::w$2$3
11 | 5\pattern="(.*)std::__cxx11::basic_(streambuf|iostream|ostream|ios|istream|filebuf)\\s*>(.*)"
12 | 5\repl=$1std::$2$3
13 | 6\pattern="(.*)std::__cxx11::basic_(string|istringstream|ostringstream|stringstream|stringbuf),\\s*(?:class\\s+)?std::allocator\\s*>(.*)"
14 | 6\repl=$1std::$2$3
15 | 7\pattern="(.*)std::__cxx11::basic_(streambuf|iostream|ostream|ios|istream|filebuf)\\s*>(.*)"
16 | 7\repl=$1std::w$2$3
17 | 8\pattern="(.*)std::__cxx11::basic_(string|istringstream|ostringstream|stringstream|stringbuf),\\s*(?:class\\s+)?std::allocator\\s*>(.*)"
18 | 8\repl=$1std::w$2$3
--------------------------------------------------------------------------------
/ida-cmake/README.md:
--------------------------------------------------------------------------------
1 | IDA plugin CMake build-script
2 | =============================
3 |
4 | This repository holds CMake build scripts and a Python helper allowing
5 | compilation of C++ IDA plugins for Windows, macOS and Linux without
6 | much user effort.
7 |
8 | ## Simple plugin example usage:
9 |
10 | ##### Create plugin repo
11 | ```bash
12 | git init myplugin
13 | cd myplugin
14 | git submodule add https://github.com/zyantific/ida-cmake.git ida-cmake
15 | mkdir src
16 | touch src/myplugin.cpp CMakeLists.txt
17 | ```
18 |
19 | ##### CMakeLists.txt
20 | ```CMake
21 | cmake_minimum_required(VERSION 3.1)
22 | project(myplugin)
23 |
24 | include("ida-cmake/cmake/IDA.cmake")
25 |
26 | set(sources "src/myplugin.cpp")
27 | add_ida_plugin(${CMAKE_PROJECT_NAME} ${sources})
28 | ```
29 |
30 | ##### src/myplugin.cpp
31 | ```cpp
32 | #include
33 | #include
34 | #include
35 |
36 | /**
37 | * @brief Initialization callback for IDA.
38 | * @return A @c PLUGIN_ constant from loader.hpp.
39 | */
40 | int idaapi init()
41 | {
42 | msg("%s", "Hello, IDA plugin world!\n");
43 | return PLUGIN_KEEP;
44 | }
45 |
46 | /**
47 | * @brief Run callback for IDA.
48 | */
49 | void idaapi run(int /*arg*/) {}
50 |
51 | /**
52 | * @brief Shutdown callback for IDA.
53 | */
54 | void idaapi term() {}
55 |
56 | plugin_t PLUGIN =
57 | {
58 | IDP_INTERFACE_VERSION,
59 | 0,
60 | &init,
61 | &term,
62 | &run,
63 | "My plugin name",
64 | "My plugin description",
65 | "My plugin menu entry text",
66 | nullptr, // plugin hotkey, e.g. "Ctrl-Shift-A"
67 | };
68 | ```
69 |
70 | ##### Building the plugin for IDA 6.95 on macOS
71 | ```bash
72 | ida-cmake/build.py \
73 | -i \
74 | -p unix \
75 | -t 6.95 \
76 | --idaq-path '/Applications/IDA Pro 6.95.app/Contents/MacOS/'
77 | ```
78 | Substitute `` with a directory you store your target IDA SDKs,
79 | named like `idasdk68`, `idasdk695`, etc..
80 |
--------------------------------------------------------------------------------
/src/Settings.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 athre0z
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | #include "Settings.hpp"
26 |
27 | #include "Config.hpp"
28 |
29 | // ============================================================================================== //
30 | // [Settings] //
31 | // ============================================================================================== //
32 |
33 | const QString Settings::kSubstitutionGroup = "substitutions";
34 | const QString Settings::kSubstitutionPattern = "pattern";
35 | const QString Settings::kSubstitutionReplacement = "repl";
36 | const QString Settings::kFirstStart = "firstStart";
37 |
38 | Settings::Settings()
39 | : QSettings("athre0z", PLUGIN_NAME)
40 | {
41 |
42 | }
43 |
44 | Settings::~Settings()
45 | {
46 |
47 | }
48 |
49 | // ============================================================================================== //
50 | //
--------------------------------------------------------------------------------
/src/Settings.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 athre0z
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | #ifndef SETTINGS_HPP
26 | #define SETTINGS_HPP
27 |
28 | #include
29 |
30 | // ============================================================================================== //
31 | // [Settings] //
32 | // ============================================================================================== //
33 |
34 | class Settings : public QSettings
35 | {
36 | public:
37 | /**
38 | * @brief Default constructor.
39 | */
40 | Settings();
41 | virtual ~Settings();
42 | public:
43 | // Constants.
44 | static const QString kSubstitutionGroup;
45 | static const QString kSubstitutionPattern;
46 | static const QString kSubstitutionReplacement;
47 | static const QString kFirstStart;
48 | };
49 |
50 | // ============================================================================================== //
51 |
52 | #endif
--------------------------------------------------------------------------------
/src/ImportExport.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 athre0z
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | #ifndef IMPORTEXPORT_HPP
26 | #define IMPORTEXPORT_HPP
27 |
28 | #include "Utils.hpp"
29 |
30 | #include
31 | #include
32 |
33 | class SubstitutionManager;
34 |
35 | // ============================================================================================== //
36 | // [SettingsImporterExporter] //
37 | // ============================================================================================== //
38 |
39 | class SettingsImporterExporter : public Utils::NonCopyable
40 | {
41 | QSettings* m_settings;
42 | SubstitutionManager* m_manager;
43 | public:
44 | class Error : public std::runtime_error
45 | { public: explicit Error(const char *error) : runtime_error(error) {} };
46 | public:
47 | explicit SettingsImporterExporter(SubstitutionManager* manager, QSettings* settings);
48 | virtual ~SettingsImporterExporter() {}
49 | void importRules() const;
50 | void exportRules() const;
51 | };
52 |
53 | // ============================================================================================== //
54 |
55 | #endif // IMPORTEXPORT_HPP
56 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License (MIT)
3 | #
4 | # Copyright (c) 2017 Joel Höner
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 | #
24 |
25 | cmake_minimum_required(VERSION 3.1)
26 | cmake_policy(SET CMP0054 NEW)
27 | project(REtypedef)
28 |
29 | set(IDA_ENABLE_QT_SUPPORT ON CACHE BOOL "")
30 | include("ida-cmake/cmake/IDA.cmake")
31 |
32 | set(headers
33 | "src/Config.hpp"
34 | "src/Core.hpp"
35 | "src/ImportExport.hpp"
36 | "src/RETypedef.hpp"
37 | "src/Settings.hpp"
38 | "src/SubstitutionManager.hpp"
39 | "src/Ui.hpp"
40 | "src/Utils.hpp")
41 | set(sources
42 | "src/Core.cpp"
43 | "src/ImportExport.cpp"
44 | "src/REtypedef.cpp"
45 | "src/Settings.cpp"
46 | "src/SubstitutionManager.cpp"
47 | "src/Ui.cpp"
48 | "src/Utils.cpp")
49 | set(forms
50 | "ui/AboutDialog.ui"
51 | "ui/SubstitutionEditor.ui")
52 | set(resources
53 | "resources/rsrc.qrc")
54 |
55 | # Add IDA plugin target
56 | include_directories("src")
57 | add_ida_qt_plugin(
58 | ${CMAKE_PROJECT_NAME}
59 | ${headers} ${sources}
60 | ${forms} ${resources})
61 |
62 | find_package(Qt5 COMPONENTS Widgets REQUIRED)
63 | find_package(Qt5 COMPONENTS Core REQUIRED)
64 | target_link_libraries(${CMAKE_PROJECT_NAME} Qt5::Widgets)
65 | target_link_libraries(${CMAKE_PROJECT_NAME} Qt5::Core)
--------------------------------------------------------------------------------
/src/REtypedef.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 athre0z
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | #include "Config.hpp"
26 | #include "Core.hpp"
27 | #include "RETypedef.hpp"
28 |
29 | #include
30 | #include
31 |
32 |
33 | // ============================================================================================== //
34 |
35 | /**
36 | * @brief Initialization callback for IDA.
37 | * @return A @c PLUGIN_ constant from loader.hpp.
38 | */
39 | int idaapi init()
40 | {
41 | if (!is_idaq()) return PLUGIN_SKIP;
42 | msg("[" PLUGIN_NAME "] " PLUGIN_TEXTUAL_VERSION " by athre0z loaded!\n");
43 |
44 | try
45 | {
46 | Core::instance();
47 | }
48 | catch (const std::runtime_error &e)
49 | {
50 | msg("[" PLUGIN_NAME "][ERROR] Cannot load plugin: %s\n", e.what());
51 | return PLUGIN_UNL;
52 | }
53 |
54 | return PLUGIN_KEEP;
55 | }
56 |
57 | /**
58 | * @brief Run callback for IDA.
59 | */
60 | bool idaapi run(size_t /*arg*/)
61 | {
62 | Core::instance().runPlugin();
63 | return true;
64 | }
65 |
66 | /**
67 | * @brief Shutdown callback for IDA.
68 | */
69 | void idaapi term()
70 | {
71 | if (Core::isInstantiated())
72 | Core::freeInstance();
73 | }
74 |
75 | plugin_t PLUGIN =
76 | {
77 | IDP_INTERFACE_VERSION,
78 | 0,
79 | &init,
80 | &term,
81 | &run,
82 | "Reverse typedef resolution",
83 | "Reverse typedef resolution plugin.",
84 | PLUGIN_NAME ": About"
85 | };
86 |
87 | // ============================================================================================== //
88 |
--------------------------------------------------------------------------------
/src/SubstitutionManager.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 athre0z
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | #ifndef SUBSTITUTIONMANAGER_HPP
26 | #define SUBSTITUTIONMANAGER_HPP
27 |
28 | #include "Utils.hpp"
29 |
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 |
37 | // ============================================================================================== //
38 | // [Substitution] //
39 | // ============================================================================================== //
40 |
41 | struct Substitution
42 | {
43 | std::string regexpPattern;
44 | std::regex regexp;
45 | std::string replacement;
46 | };
47 |
48 | // ============================================================================================== //
49 | // [SubstitutionManager] //
50 | // ============================================================================================== //
51 |
52 | class SubstitutionManager : public QObject, public Utils::NonCopyable
53 | {
54 | Q_OBJECT
55 |
56 | public:
57 | typedef std::vector> SubstitutionList;
58 | protected:
59 | static const std::regex m_kMarkerFinder;
60 | SubstitutionList m_rules;
61 | public:
62 | SubstitutionManager();
63 | ~SubstitutionManager();
64 | public:
65 | void addRule(const std::shared_ptr subst);
66 | void removeRule(const Substitution* subst);
67 | void clearRules();
68 | const SubstitutionList& rules() const { return m_rules; }
69 | public:
70 | void applyToString(qstring* str) const;
71 | signals:
72 | void entryAdded();
73 | void entryDeleted();
74 | };
75 |
76 | // ============================================================================================== //
77 |
78 | #endif // SUBSTITUTIONMANAGER_HPP
79 |
--------------------------------------------------------------------------------
/src/Core.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 athre0z
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | #ifndef CORE_HPP
26 | #define CORE_HPP
27 |
28 | #include "Utils.hpp"
29 | #include "SubstitutionManager.hpp"
30 |
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 |
38 | // ============================================================================================== //
39 | // [Core] //
40 | // ============================================================================================== //
41 |
42 | /**
43 | * @brief Plugin core singleton.
44 | */
45 | class Core : public QObject, public Utils::Singleton
46 | {
47 | Q_OBJECT
48 |
49 | SubstitutionManager m_substitutionManager;
50 | demangler_t *m_originalMangler;
51 | public:
52 | /**
53 | * @brief Default constructor.
54 | */
55 | Core();
56 | /**
57 | * @brief Destructor.
58 | */
59 | ~Core();
60 | /**
61 | * @brief Runs the plugin.
62 | */
63 | void runPlugin();
64 | /**
65 | * @brief Replacement function for IDA's @c demangle routine.
66 | * @param answer The output buffer for the demangled name.
67 | * @param answerLength Length of @c answer bufer.
68 | * @param str The mangled name.
69 | * @param disableMask See @c demangle.hpp in IDA SDK.
70 | * @return See @c demangle.hpp in IDA SDK.
71 | */
72 | static ssize_t idaapi IDP_Hook(void* user_data, int notification_code, va_list va);
73 | private:
74 | #if IDA_SDK_VERSION >= 670
75 | struct OptionsMenuItemClickedAction : public action_handler_t
76 | {
77 | int idaapi activate(action_activation_ctx_t *ctx);
78 | action_state_t idaapi update(action_update_ctx_t *ctx);
79 | } m_optionsMenuItemClickedAction;
80 | #endif
81 | /**
82 | * @brief Handles clicks on the "Edit name substitutions" menu entry in IDA.
83 | * @param userData @c this.
84 | * @return Always 0.
85 | */
86 | static bool idaapi onOptionsMenuItemClicked(void* userData);
87 | private slots:
88 | /**
89 | * @brief Saves the rules from the substitution manager to the settings.
90 | */
91 | void saveToSettings();
92 | };
93 |
94 | // ============================================================================================== //
95 |
96 | #endif
--------------------------------------------------------------------------------
/src/Utils.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 athre0z
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | #ifndef UTILS_HPP
26 | #define UTILS_HPP
27 |
28 | #include
29 | #include
30 |
31 | namespace Utils
32 | {
33 |
34 | // ============================================================================================== //
35 | // [NonCopyable] //
36 | // ============================================================================================== //
37 |
38 | /**
39 | * @brief Makes derived classes non-copyable.
40 | */
41 | class NonCopyable
42 | {
43 | NonCopyable(const NonCopyable&); // not implemented
44 | NonCopyable& operator = (const NonCopyable&); // not implemented
45 | public:
46 | NonCopyable() {}
47 | virtual ~NonCopyable() {}
48 | };
49 |
50 | // ============================================================================================== //
51 | // [Singleton] //
52 | // ============================================================================================== //
53 |
54 | template
55 | class Singleton : public NonCopyable
56 | {
57 | static T *m_instance;
58 | protected:
59 | Singleton() {}
60 | virtual ~Singleton() {}
61 | public:
62 | static T& instance();
63 | static void freeInstance();
64 | static bool isInstantiated();
65 | };
66 |
67 | // ============================================================================================== //
68 | // Implementation of inline methods [Singleton] //
69 | // ============================================================================================== //
70 |
71 | template T *Singleton::m_instance = nullptr;
72 |
73 | template inline
74 | T& Singleton::instance()
75 | {
76 | if (!m_instance)
77 | m_instance = new T;
78 | return *m_instance;
79 | }
80 |
81 | template inline
82 | void Singleton::freeInstance()
83 | {
84 | if (m_instance)
85 | {
86 | delete m_instance;
87 | m_instance = nullptr;
88 | }
89 | }
90 |
91 | template inline
92 | bool Singleton::isInstantiated()
93 | {
94 | return m_instance != nullptr;
95 | }
96 |
97 | // ============================================================================================== //
98 |
99 | }
100 |
101 | #endif
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | REtypedef
2 | =========
3 |
4 | ## What is this?
5 | REtypedef is an IDA PRO plugin that allows defining custom substitutions for function names. It comes with a default ruleset providing substitutions for many common STL types.
6 |
7 | ## Example output
8 | ### Without REtypedef
9 | ```asm
10 | .text:0040142E ; =============== S U B R O U T I N E =======================================
11 | .text:0040142E
12 | .text:0040142E ; Attributes: thunk
13 | .text:0040142E
14 | .text:0040142E public: void __thiscall std::basic_string, class std::allocator>::swap(class std::basic_string, class std::allocator> &) proc near
15 | .text:0040142E
16 | .text:0040142E _Right = dword ptr 4
17 | .text:0040142E
18 | .text:0040142E jmp std::basic_string,std::allocator>::swap(std::basic_string,std::allocator> &)
19 | .text:0040142E public: void __thiscall std::basic_string, class std::allocator>::swap(class std::basic_string, class std::allocator> &) endp
20 | .text:0040142E
21 | .text:00401433
22 | .text:00401433 ; =============== S U B R O U T I N E =======================================
23 | .text:00401433
24 | .text:00401433 ; Attributes: thunk
25 | .text:00401433
26 | .text:00401433 public: class std::basic_string, class std::allocator> & __thiscall std::basic_string, class std::allocator>::insert(unsigned int, class std::basic_string, class std::allocator> const &) proc near
27 | .text:00401433
28 | .text:00401433 _Off = dword ptr 4
29 | .text:00401433 _Right = dword ptr 8
30 | .text:00401433
31 | .text:00401433 jmp std::basic_string,std::allocator>::insert(uint,std::basic_string,std::allocator> const &)
32 | .text:00401433 public: class std::basic_string, class std::allocator> & __thiscall std::basic_string, class std::allocator>::insert(unsigned int, class std::basic_string, class std::allocator> const &) endp
33 | ```
34 |
35 | ### With REtypedef
36 | ```asm
37 | .text:0040142E ; =============== S U B R O U T I N E =======================================
38 | .text:0040142E
39 | .text:0040142E ; Attributes: thunk
40 | .text:0040142E
41 | .text:0040142E public: void __thiscall std::string::swap(class std::string &) proc near
42 | .text:0040142E
43 | .text:0040142E _Right = dword ptr 4
44 | .text:0040142E
45 | .text:0040142E jmp std::string::swap(std::string &)
46 | .text:0040142E public: void __thiscall std::string::swap(class std::string &) endp
47 | .text:0040142E
48 | .text:00401433
49 | .text:00401433 ; =============== S U B R O U T I N E =======================================
50 | .text:00401433
51 | .text:00401433 ; Attributes: thunk
52 | .text:00401433
53 | .text:00401433 public: class std::string & __thiscall std::string::insert(unsigned int, class std::string const &) proc near
54 | .text:00401433
55 | .text:00401433 _Off = dword ptr 4
56 | .text:00401433 _Right = dword ptr 8
57 | .text:00401433
58 | .text:00401433 jmp std::string::insert(uint,std::string const &)
59 | .text:00401433 public: class std::string & __thiscall std::string::insert(unsigned int, class std::string const &) endp
60 | ```
61 |
62 | ## Binary distribution
63 | [Download latest binary version from github.](https://github.com/athre0z/REtypedef/releases/latest) Currently only the Windows version of IDA is supported.
64 |
65 | ## Installation
66 | Place `REtypedef.plX` into the `plugins` directory of your IDA installation.
--------------------------------------------------------------------------------
/src/SubstitutionManager.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 athre0z
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | #include "SubstitutionManager.hpp"
26 |
27 | #include "Settings.hpp"
28 |
29 | #include
30 | #include
31 | #include
32 |
33 | // ============================================================================================== //
34 | // [SubstitutionManager] //
35 | // ============================================================================================== //
36 |
37 | const std::regex SubstitutionManager::m_kMarkerFinder
38 | = std::regex("\\$(\\d+)", std::regex_constants::optimize);
39 |
40 | SubstitutionManager::SubstitutionManager()
41 | {
42 |
43 | }
44 |
45 | SubstitutionManager::~SubstitutionManager()
46 | {
47 |
48 | }
49 |
50 | void SubstitutionManager::addRule(const std::shared_ptr subst)
51 | {
52 | m_rules.push_back(std::move(subst));
53 | emit entryAdded();
54 | }
55 |
56 | void SubstitutionManager::removeRule(const Substitution* subst)
57 | {
58 | for (auto it = m_rules.begin(), end = m_rules.end(); it != end; ++it)
59 | {
60 | if (it->get() == subst)
61 | {
62 | it = m_rules.erase(it);
63 | emit entryDeleted();
64 | if (it == m_rules.end())
65 | break;
66 | }
67 | }
68 | }
69 |
70 | void SubstitutionManager::clearRules()
71 | {
72 | if (m_rules.size())
73 | {
74 | m_rules.clear();
75 | emit entryDeleted();
76 | }
77 | }
78 |
79 | void SubstitutionManager::applyToString(qstring* str) const
80 | {
81 | for (auto it = m_rules.cbegin(), end = m_rules.cend(); it != end; ++it)
82 | {
83 | std::cmatch groups;
84 | while (std::regex_match(str->c_str(), groups, (*it)->regexp))
85 | {
86 | auto processed = (*it)->replacement;
87 | std::smatch markerGroups;
88 | while (std::regex_search(processed, markerGroups, m_kMarkerFinder))
89 | {
90 | assert(markerGroups.size() == 2);
91 | auto idx = static_cast(std::stoi(markerGroups[1]));
92 | if (idx >= groups.size())
93 | break;
94 |
95 | size_t pos = 0;
96 | std::string search = markerGroups[0];
97 | std::string replace = groups[idx];
98 | while((pos = processed.find(search, pos)) != std::string::npos)
99 | {
100 | processed.replace(pos, search.length(), replace);
101 | pos += replace.length();
102 | }
103 | }
104 | //::qstrncpy(str, processed.c_str(), outLen);
105 | *str = processed.c_str();
106 | }
107 | }
108 | }
109 |
110 | // ============================================================================================== //
111 |
--------------------------------------------------------------------------------
/src/ImportExport.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 athre0z
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | #include "ImportExport.hpp"
26 |
27 | #include "Settings.hpp"
28 | #include "SubstitutionManager.hpp"
29 | #include "Config.hpp"
30 |
31 | #include
32 | #include
33 | #include
34 |
35 | // ============================================================================================== //
36 | // [SettingsImporterExporter] //
37 | // ============================================================================================== //
38 |
39 | SettingsImporterExporter::SettingsImporterExporter(
40 | SubstitutionManager* manager, QSettings* settings)
41 | : m_manager(manager)
42 | , m_settings(settings)
43 | {
44 | assert(manager);
45 | assert(settings);
46 | }
47 |
48 | void SettingsImporterExporter::importRules() const
49 | {
50 | assert(m_manager);
51 |
52 | int size = m_settings->beginReadArray(Settings::kSubstitutionGroup);
53 | for (int i = 0; i < size; ++i)
54 | {
55 | m_settings->setArrayIndex(i);
56 | auto sbst = std::make_shared();
57 | sbst->replacement
58 | = m_settings->value(Settings::kSubstitutionReplacement).toString().toStdString();
59 | sbst->regexpPattern
60 | = m_settings->value(Settings::kSubstitutionPattern).toString().toStdString();
61 |
62 | try
63 | {
64 | sbst->regexp = std::regex(sbst->regexpPattern, std::regex_constants::optimize);
65 | }
66 | catch (const std::regex_error &e)
67 | {
68 | msg("[" PLUGIN_NAME "] Cannot import entry, invalid regexp: %s\n", e.what());
69 | continue;
70 | }
71 |
72 | const auto& substs = m_manager->rules();
73 | auto it = std::find_if(substs.cbegin(), substs.cend(),
74 | [&sbst](const std::shared_ptr& cur) -> bool
75 | {
76 | assert(cur);
77 | return cur->regexpPattern == sbst->regexpPattern;
78 | });
79 |
80 | if (it != substs.cend())
81 | continue;
82 |
83 | m_manager->addRule(std::move(sbst));
84 | }
85 | m_settings->endArray();
86 | }
87 |
88 | void SettingsImporterExporter::exportRules() const
89 | {
90 | assert(m_manager);
91 |
92 | const auto& rules = m_manager->rules();
93 | m_settings->beginWriteArray(Settings::kSubstitutionGroup, rules.size());
94 | int i = 0;
95 | for (auto it = rules.cbegin(), end = rules.cend(); it != end; ++it, ++i)
96 | {
97 | m_settings->setArrayIndex(i);
98 | m_settings->setValue(Settings::kSubstitutionPattern,
99 | QString::fromStdString((*it)->regexpPattern));
100 | m_settings->setValue(Settings::kSubstitutionReplacement,
101 | QString::fromStdString((*it)->replacement));
102 | }
103 | m_settings->endArray();
104 | }
105 |
106 | // ============================================================================================== //
107 | //
--------------------------------------------------------------------------------
/ui/AboutDialog.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | AboutDialog
4 |
5 |
6 |
7 | 0
8 | 0
9 | 303
10 | 127
11 |
12 |
13 |
14 | About
15 |
16 |
17 |
18 |
19 |
20 | -
21 |
22 |
23 |
24 | 16
25 | 75
26 | true
27 |
28 |
29 |
30 | REtypedef
31 |
32 |
33 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
34 |
35 |
36 |
37 | -
38 |
39 |
40 | by athre0z
41 |
42 |
43 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
44 |
45 |
46 |
47 | -
48 |
49 |
50 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
51 | <html><head><meta name="qrichtext" content="1" /><style type="text/css">
52 | p, li { white-space: pre-wrap; }
53 | </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
54 | <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Github: </span><a href="https://github.com/athre0z/REtypedef"><span style=" text-decoration: underline; color:#0000ff;">https://github.com/athre0z/REtypedef</span></a></p></body></html>
55 |
56 |
57 | Qt::RichText
58 |
59 |
60 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
61 |
62 |
63 | true
64 |
65 |
66 |
67 | -
68 |
69 |
70 |
71 | 75
72 | true
73 |
74 |
75 |
76 | Copyright notes of third party code:
77 |
78 |
79 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
80 |
81 |
82 |
83 | -
84 |
85 |
86 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
87 | <html><head><meta name="qrichtext" content="1" /><style type="text/css">
88 | p, li { white-space: pre-wrap; }
89 | </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
90 | <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="#"><span style=" font-size:8pt; text-decoration: underline; color:#0000ff;">udis86 - Disassembler libraray</span></a></p></body></html>
91 |
92 |
93 | Qt::RichText
94 |
95 |
96 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/src/Ui.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 athre0z
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | #ifndef UI_HPP
26 | #define UI_HPP
27 |
28 | #include "ui_SubstitutionEditor.h"
29 | #include "ui_AboutDialog.h"
30 | #include "SubstitutionManager.hpp"
31 |
32 | #include
33 | #include
34 |
35 | // ============================================================================================== //
36 | // [SubstitutionModel] //
37 | // ============================================================================================== //
38 |
39 | class SubstitutionModel : public QAbstractItemModel
40 | {
41 | SubstitutionManager *m_substMgr;
42 | public:
43 | explicit SubstitutionModel(SubstitutionManager* data=nullptr, QObject* parent=nullptr);
44 | public: // Implementation of QAbstractItemModel interface.
45 | int rowCount(const QModelIndex& parent=QModelIndex()) const override;
46 | int columnCount(const QModelIndex& parent=QModelIndex()) const override;
47 | QModelIndex index(int row, int column,
48 | const QModelIndex& parent=QModelIndex()) const override;
49 | QVariant data(const QModelIndex& index, int role=Qt::DisplayRole) const override;
50 | QVariant headerData(int section, Qt::Orientation orientation,
51 | int role=Qt::DisplayRole) const override;
52 | QModelIndex parent(const QModelIndex& index) const override;
53 | Qt::ItemFlags flags(const QModelIndex& index) const override;
54 | public: // Public interface.
55 | const Substitution* substitutionByIndex(const QModelIndex& index);
56 | void update();
57 | public: // Accessors.
58 | SubstitutionManager* substitutionManager() { return m_substMgr; }
59 | };
60 |
61 | // ============================================================================================== //
62 | // [SubstitutionEditor] //
63 | // ============================================================================================== //
64 |
65 | class SubstitutionEditor : public QDialog
66 | {
67 | Q_OBJECT
68 |
69 | Ui::SubstitutionEditor m_widgets;
70 | const Substitution* m_contextMenuSelectedItem;
71 | public:
72 | explicit SubstitutionEditor(QWidget* parent=nullptr);
73 | virtual ~SubstitutionEditor() {}
74 | public:
75 | void setModel(SubstitutionModel* model);
76 | SubstitutionModel* model();
77 | protected slots:
78 | void addSubstitution(bool); // any idea how ofen I wrote "substitution" today? goddamit.
79 | void displayContextMenu(const QPoint& point);
80 | void deleteSubstitution(bool);
81 | void editSubstitution(bool);
82 | void importRules(bool);
83 | void exportRules(bool);
84 | };
85 |
86 | // ============================================================================================== //
87 | // [AboutDialog] //
88 | // ============================================================================================== //
89 |
90 | class AboutDialog : public QDialog
91 | {
92 | Q_OBJECT
93 |
94 | Ui::AboutDialog m_widgets;
95 | public:
96 | AboutDialog();
97 | virtual ~AboutDialog() {}
98 | };
99 |
100 | // ============================================================================================== //
101 |
102 | #endif // UI_HPP
103 |
--------------------------------------------------------------------------------
/ui/SubstitutionEditor.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | SubstitutionEditor
4 |
5 |
6 |
7 | 0
8 | 0
9 | 755
10 | 445
11 |
12 |
13 |
14 | Edit name substitutions...
15 |
16 |
17 |
18 |
19 |
20 | -
21 |
22 |
23 | QAbstractItemView::SingleSelection
24 |
25 |
26 | QAbstractItemView::SelectRows
27 |
28 |
29 | 300
30 |
31 |
32 | 100
33 |
34 |
35 | 20
36 |
37 |
38 | 20
39 |
40 |
41 |
42 | -
43 |
44 |
45 | QLayout::SetMaximumSize
46 |
47 |
-
48 |
49 |
-
50 |
51 |
52 |
53 | 1
54 | 0
55 |
56 |
57 |
58 | Add substitution
59 |
60 |
61 |
-
62 |
63 |
64 | Search text (regexp):
65 |
66 |
67 |
68 | -
69 |
70 |
71 | -
72 |
73 |
74 | Replacement:
75 |
76 |
77 |
78 | -
79 |
80 |
81 | -
82 |
83 |
84 | Add!
85 |
86 |
87 |
88 |
89 |
90 |
91 | -
92 |
93 |
-
94 |
95 |
96 | Import
97 |
98 |
99 |
100 | -
101 |
102 |
103 | Export
104 |
105 |
106 |
107 | -
108 |
109 |
110 |
111 | 0
112 | 0
113 |
114 |
115 |
116 | Qt::Horizontal
117 |
118 |
119 | QDialogButtonBox::Ok
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 | buttonBox
137 | accepted()
138 | SubstitutionEditor
139 | accept()
140 |
141 |
142 | 259
143 | 433
144 |
145 |
146 | 157
147 | 274
148 |
149 |
150 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/src/Core.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 athre0z
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | #include "Core.hpp"
26 |
27 | #include "Config.hpp"
28 | #include "Settings.hpp"
29 | #include "Ui.hpp"
30 | #include "ImportExport.hpp"
31 | #include "RETypedef.hpp"
32 |
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 |
41 | // =============================================================================================== //
42 | // [Core] //
43 | // =============================================================================================== //
44 |
45 | Core::Core()
46 | : m_originalMangler(nullptr)
47 | {
48 | #if IDA_SDK_VERSION >= 670
49 | static const action_desc_t action =
50 | {
51 | sizeof(action),
52 | "retypedef_open_name_subst_editor",
53 | "Edit name substitutions...",
54 | &m_optionsMenuItemClickedAction,
55 | &PLUGIN
56 | };
57 |
58 | register_action(action);
59 | attach_action_to_menu("Options/", "retypedef_open_name_subst_editor", 0);
60 | #else
61 | add_menu_item("Options/", "Edit name substitutions...", nullptr, 0,
62 | &Core::onOptionsMenuItemClicked, this);
63 | #endif
64 |
65 | // First start? Initialize with default rules.
66 | Settings settings;
67 | if (settings.value(Settings::kFirstStart, true).toBool())
68 | {
69 | QSettings defaultRules(":/Misc/default_rules.ini", QSettings::IniFormat);
70 | SettingsImporterExporter importer(&m_substitutionManager, &defaultRules);
71 | importer.importRules();
72 | saveToSettings();
73 | settings.setValue(Settings::kFirstStart, false);
74 | }
75 |
76 | // Load rules from settings and subscribe to changes in the manager
77 | try
78 | {
79 | SettingsImporterExporter importer(&m_substitutionManager, &settings);
80 | importer.importRules();
81 | }
82 | catch (const SettingsImporterExporter::Error& e)
83 | {
84 | msg("[" PLUGIN_NAME "] Cannot load settings: %s\n", e.what());
85 | }
86 | connect(&m_substitutionManager, SIGNAL(entryAdded()), SLOT(saveToSettings()));
87 | connect(&m_substitutionManager, SIGNAL(entryDeleted()), SLOT(saveToSettings()));
88 |
89 | hook_to_notification_point(HT_IDP, &Core::IDP_Hook);
90 | }
91 |
92 | Core::~Core()
93 | {
94 | // Remove demangler detour
95 | unhook_from_notification_point(HT_IDP, &Core::IDP_Hook);
96 |
97 | #if IDA_SDK_VERSION >= 670
98 | detach_action_from_menu("Options/", "retypedef_open_name_subst_editor");
99 | unregister_action("retypedef_open_name_subst_editor");
100 | #else
101 | del_menu_item("Options/Edit name substitutions...");
102 | #endif
103 | }
104 |
105 | #if IDA_SDK_VERSION >= 670
106 | int Core::OptionsMenuItemClickedAction::activate(action_activation_ctx_t * /*ctx*/)
107 | {
108 | onOptionsMenuItemClicked(&Core::instance());
109 | return 1;
110 | }
111 |
112 | action_state_t Core::OptionsMenuItemClickedAction::update(action_update_ctx_t * /*ctx*/)
113 | {
114 | return AST_ENABLE_ALWAYS;
115 | }
116 | #endif
117 |
118 | void Core::runPlugin()
119 | {
120 | AboutDialog().exec();
121 | }
122 |
123 | ssize_t idaapi Core::IDP_Hook(void* user_data, int notification_code, va_list va) {
124 | switch (notification_code) {
125 | case ::processor_t::ev_demangle_name:
126 | int32_t *res = va_arg(va, int32_t *);
127 | qstring *out = va_arg(va, qstring *);
128 | const char* name = va_arg(va, const char *);
129 | uint32 disable_mask = va_arg(va, uint32);
130 | int32 demreq = va_arg(va, int32);
131 | unhook_from_notification_point(HT_IDP, &Core::IDP_Hook);
132 |
133 | auto _res = demangle_name(out, name, disable_mask, (demreq_type_t)demreq);
134 | int ret = 0;
135 | if (_res < ME_NOERROR_LIMIT || _res >= 0) {
136 | auto& thiz = instance();
137 | thiz.m_substitutionManager.applyToString(out);
138 | ret = 1;
139 | *res = _res;
140 | }
141 |
142 | hook_to_notification_point(HT_IDP, &Core::IDP_Hook);
143 | return ret;
144 | }
145 | return 0;
146 | }
147 |
148 | bool Core::onOptionsMenuItemClicked(void* userData)
149 | {
150 | auto thiz = reinterpret_cast(userData);
151 | SubstitutionModel model(&thiz->m_substitutionManager);
152 | SubstitutionEditor editor(qApp->activeWindow());
153 | editor.setModel(&model);
154 |
155 | editor.exec();
156 | return 0;
157 | }
158 |
159 | void Core::saveToSettings()
160 | {
161 | try
162 | {
163 | Settings settings;
164 | SettingsImporterExporter exporter(&m_substitutionManager, &settings);
165 | exporter.exportRules();
166 |
167 | request_refresh(IWID_NAMES | IWID_DISASMS);
168 | }
169 | catch (const SettingsImporterExporter::Error &e)
170 | {
171 | msg("[" PLUGIN_NAME "] Cannot save to settings: %s\n", e.what());
172 | }
173 | }
174 |
175 | // ============================================================================================== //
176 |
--------------------------------------------------------------------------------
/ida-cmake/build.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | """
4 | This script builds the binary distribution for multiple IDA versions in
5 | one batch.
6 |
7 | The MIT License (MIT)
8 |
9 | Copyright (c) 2017 Joel Hoener
10 |
11 | Permission is hereby granted, free of charge, to any person obtaining a copy
12 | of this software and associated documentation files (the "Software"), to deal
13 | in the Software without restriction, including without limitation the rights
14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 | copies of the Software, and to permit persons to whom the Software is
16 | furnished to do so, subject to the following conditions:
17 | The above copyright notice and this permission notice shall be included in all
18 | copies or substantial portions of the Software.
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | SOFTWARE.
26 | """
27 |
28 | from __future__ import absolute_import, division, print_function, unicode_literals
29 |
30 | import os
31 | import errno
32 | import argparse
33 | import glob
34 |
35 | from subprocess import Popen, PIPE
36 | from distutils.spawn import find_executable
37 |
38 |
39 | def get_build_cmd(platform):
40 | return {'unix': 'make', 'win': 'MSBuild'}[platform]
41 |
42 |
43 | def get_cmake_gen(platform, cur_target):
44 | if platform == 'unix':
45 | return 'Unix Makefiles'
46 | elif platform == 'win':
47 | return 'Visual Studio ' + ('10' if cur_target[0] <= 6 and cur_target[1] <= 8 else '14')
48 | else:
49 | raise Exception('Unknown platform "%s"' % platform)
50 |
51 |
52 | def get_build_solution_arguments(platform, build_dir):
53 | build_bin = get_build_cmd(platform)
54 | if platform == 'win':
55 | sln, = glob.glob(os.path.join(build_dir, '*.sln'))
56 | sln = os.path.basename(sln)
57 | return [build_bin, sln, '/p:Configuration=Release']
58 | elif platform == 'unix':
59 | # Speed things up a little.
60 | from multiprocessing import cpu_count
61 | return [build_bin, '-j%d' % cpu_count()]
62 | else:
63 | raise Exception('Unknown platform "%s"' % platform)
64 |
65 |
66 | def get_install_solution_arguments(platform):
67 | build_bin = get_build_cmd(platform)
68 | if platform == 'win':
69 | return [build_bin, 'INSTALL.vcxproj', '/p:Configuration=Release']
70 | elif platform == 'unix':
71 | return [build_bin, 'install', 'VERBOSE=1']
72 | else:
73 | raise Exception('Unrecognized platform "%s"' % platform)
74 |
75 |
76 | if __name__ == '__main__':
77 | #
78 | # Parse arguments
79 | #
80 | parser = argparse.ArgumentParser(
81 | description='Batch build script creating the plugin for multiple IDA versions.')
82 |
83 | target_args = parser.add_argument_group('target configuration')
84 | target_args.add_argument('--ida-sdks-path', '-i', type=str, required=True,
85 | help='Path containing the IDA SDKs for the desired IDA target versions')
86 | target_args.add_argument('--platform', '-p', type=str, choices=['win', 'unix'],
87 | help='Platform to build for (e.g. win, unix)', required=True)
88 | target_args.add_argument('--target-version', '-t', action='append', required=True,
89 | help='IDA versions to build for (e.g. 6.9). May be passed multiple times.')
90 | target_args.add_argument('--idaq-path', type=str, required=False,
91 | help='Path with idaq binary, required on unixoid platforms for linkage.')
92 |
93 | parser.add_argument('--skip-install', action='store_true', default=False,
94 | help='Do not execute install target')
95 | parser.add_argument('cmake_args', default='', type=str,
96 | help='Additional arguments passed to CMake', nargs=argparse.REMAINDER)
97 | args = parser.parse_args()
98 |
99 | def print_usage(error=None):
100 | parser.print_usage()
101 | if error:
102 | print(error)
103 | exit()
104 |
105 | target_versions = []
106 | for cur_version in args.target_version:
107 | cur_version = cur_version.strip().split('.')
108 | try:
109 | target_versions.append((int(cur_version[0]), int(cur_version[1])))
110 | except (ValueError, IndexError):
111 | print_usage('[-] Invalid version format, expected something like "6.5"')
112 |
113 | # Unix specific sanity checks
114 | if args.platform == 'unix':
115 | if len(target_versions) > 1:
116 | print_usage(
117 | '[-] On unix-like platforms, due to linkage against IDA directly, only '
118 | 'a single target is allowed per invocation.'
119 | )
120 | if not args.idaq_path:
121 | print_usage('[-] On unix-like platforms, --idaq-path is required.')
122 |
123 | #
124 | # Find tools
125 | #
126 | cmake_bin = find_executable('cmake')
127 | build_bin = find_executable(get_build_cmd(args.platform))
128 | if not cmake_bin:
129 | print_usage('[-] Unable to find cmake binary')
130 | if not build_bin:
131 | print_usage('[-] Unable to find build (please use Visual Studio MSBuild CMD or make)')
132 |
133 | #
134 | # Build targets
135 | #
136 | for arch in (32, 64):
137 | for cur_target in target_versions:
138 | build_dir = 'build-{}.{}-{}'.format(*(cur_target + (arch,)))
139 | try:
140 | os.mkdir(build_dir)
141 | except OSError as e:
142 | if e.errno != errno.EEXIST:
143 | raise
144 |
145 | # Run cmake
146 | cmake_cmd = [
147 | cmake_bin,
148 | '-DIDA_SDK=' + os.path.join(args.ida_sdks_path, 'idasdk{}{}'.format(*cur_target)),
149 | #'-G', get_cmake_gen(args.platform, cur_target),
150 | '-G', "Ninja",
151 | '-DCMAKE_INSTALL_PREFIX:PATH=../dist/IDA-{}.{}'.format(*cur_target),
152 | '-DIDA_VERSION={}{:02}'.format(*cur_target),
153 | ]
154 |
155 | if args.idaq_path:
156 | cmake_cmd.append('-DIDA_INSTALL_DIR=' + args.idaq_path)
157 | if arch == 64:
158 | cmake_cmd.append('-DIDA_ARCH_64=TRUE')
159 |
160 | cmake_cmd.append('..')
161 |
162 | print('Cmake command:')
163 | print(' '.join("'%s'" % x if ' ' in x else x for x in cmake_cmd))
164 |
165 | proc = Popen(cmake_cmd, cwd=build_dir)
166 | if proc.wait() != 0:
167 | print('[-] CMake failed, giving up.')
168 | exit()
169 |
170 | # Build plugin
171 | cmake_cmd = [
172 | cmake_bin,
173 | '--build', '.',
174 | ]
175 | proc = Popen(cmake_cmd, cwd=build_dir)
176 | if proc.wait() != 0:
177 | print('[-] Build failed, giving up.')
178 | exit()
179 |
180 | if not args.skip_install:
181 | cmake_cmd = [
182 | cmake_bin,
183 | '--build', '.', '--target', 'install',
184 | ]
185 |
186 | # Install plugin
187 | proc = Popen(cmake_cmd, cwd=build_dir)
188 | if proc.wait() != 0:
189 | print('[-] Install failed, giving up.')
190 | exit()
191 |
192 | print('[+] Done!')
193 |
--------------------------------------------------------------------------------
/src/Ui.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 athre0z
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | #include "Ui.hpp"
26 |
27 | #include "Config.hpp"
28 | #include "ImportExport.hpp"
29 |
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 |
37 | // ============================================================================================== //
38 | // [SubstitutionModel] //
39 | // ============================================================================================== //
40 |
41 | SubstitutionModel::SubstitutionModel(SubstitutionManager *data, QObject *parent)
42 | : QAbstractItemModel(parent)
43 | , m_substMgr(data)
44 | {
45 |
46 | }
47 |
48 | int SubstitutionModel::rowCount(const QModelIndex &parent) const
49 | {
50 | return m_substMgr->rules().size();
51 | }
52 |
53 | int SubstitutionModel::columnCount(const QModelIndex &/*parent*/) const
54 | {
55 | return 2;
56 | }
57 |
58 | QModelIndex SubstitutionModel::index(int row, int column, const QModelIndex &parent) const
59 | {
60 | return createIndex(row, column, nullptr);
61 | }
62 |
63 | QVariant SubstitutionModel::data(const QModelIndex &index, int role) const
64 | {
65 | if (!index.isValid() || role != Qt::DisplayRole)
66 | return QVariant();
67 |
68 | assert(static_cast(index.row()) < m_substMgr->rules().size());
69 | auto sbst = m_substMgr->rules().at(index.row());
70 | return index.column() == 0 ? QString::fromStdString(sbst->regexpPattern)
71 | : QString::fromStdString(sbst->replacement);
72 | }
73 |
74 | QVariant SubstitutionModel::headerData(int section,
75 | Qt::Orientation orientation, int role) const
76 | {
77 | if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
78 | return QVariant();
79 |
80 | switch (section)
81 | {
82 | case 0:
83 | return "Search text";
84 | case 1:
85 | return "Replacement";
86 | default:
87 | return QVariant();
88 | }
89 | }
90 |
91 | QModelIndex SubstitutionModel::parent(const QModelIndex &index) const
92 | {
93 | return QModelIndex();
94 | }
95 |
96 | Qt::ItemFlags SubstitutionModel::flags(const QModelIndex &index) const
97 | {
98 | return Qt::NoItemFlags;
99 | }
100 |
101 | const Substitution* SubstitutionModel::substitutionByIndex(const QModelIndex& index)
102 | {
103 | assert(m_substMgr);
104 | assert(m_substMgr->rules().size() > static_cast(index.row()));
105 | return m_substMgr->rules().at(index.row()).get();
106 | }
107 |
108 | void SubstitutionModel::update()
109 | {
110 | emit layoutAboutToBeChanged();
111 | emit layoutChanged();
112 | }
113 |
114 | // ============================================================================================== //
115 | // [SubstitutionEditor] //
116 | // ============================================================================================== //
117 |
118 | SubstitutionEditor::SubstitutionEditor(QWidget* parent)
119 | : QDialog(parent)
120 | {
121 | m_widgets.setupUi(this);
122 |
123 | connect(m_widgets.tvSubstitutions,
124 | SIGNAL(customContextMenuRequested(const QPoint&)),
125 | SLOT(displayContextMenu(const QPoint&)));
126 | connect(m_widgets.btnAdd, SIGNAL(clicked(bool)), SLOT(addSubstitution(bool)));
127 | connect(m_widgets.btnImport, SIGNAL(clicked(bool)), SLOT(importRules(bool)));
128 | connect(m_widgets.btnExport, SIGNAL(clicked(bool)), SLOT(exportRules(bool)));
129 |
130 | m_widgets.tvSubstitutions->setContextMenuPolicy(Qt::CustomContextMenu);
131 | }
132 |
133 | void SubstitutionEditor::setModel(SubstitutionModel* model)
134 | {
135 | assert(model);
136 | m_widgets.tvSubstitutions->setModel(model);
137 | }
138 |
139 | SubstitutionModel* SubstitutionEditor::model()
140 | {
141 | return static_cast(m_widgets.tvSubstitutions->model());
142 | }
143 |
144 | void SubstitutionEditor::addSubstitution(bool)
145 | {
146 | assert(model());
147 | assert(model()->substitutionManager());
148 |
149 | auto regexp = m_widgets.leSearchText->text().toStdString();
150 |
151 | // Empty?
152 | if (regexp.empty())
153 | {
154 | QMessageBox::warning(qApp->activeWindow(), PLUGIN_NAME, "Search text may not be empty!");
155 | return;
156 | }
157 |
158 | // Unique?
159 | const auto& substs = model()->substitutionManager()->rules();
160 | auto it = std::find_if(substs.cbegin(), substs.cend(),
161 | [®exp](const std::shared_ptr& cur) -> bool
162 | {
163 | assert(cur);
164 | return cur->regexpPattern == regexp;
165 | });
166 |
167 | if (it != substs.cend())
168 | {
169 | QMessageBox::warning(qApp->activeWindow(), PLUGIN_NAME, "Search texts must be unique!");
170 | return;
171 | }
172 |
173 | // Valid?
174 | auto newSubst = std::make_shared();
175 | try
176 | {
177 | newSubst->regexp = std::regex(regexp, std::regex_constants::optimize);
178 | }
179 | catch (const std::regex_error& e)
180 | {
181 | QMessageBox::warning(qApp->activeWindow(), PLUGIN_NAME,
182 | QString("The given regexp does not seem to be valid:\n") + e.what());
183 | return;
184 | }
185 |
186 | newSubst->replacement = m_widgets.leReplacement->text().toStdString();
187 | newSubst->regexpPattern = regexp;
188 |
189 | // Sane, add to list.
190 | m_widgets.leSearchText->clear();
191 | m_widgets.leReplacement->clear();
192 | model()->substitutionManager()->addRule(std::move(newSubst));
193 | model()->update();
194 | }
195 |
196 | void SubstitutionEditor::displayContextMenu(const QPoint& point)
197 | {
198 | QModelIndex index = m_widgets.tvSubstitutions->indexAt(point);
199 |
200 | if (!index.isValid())
201 | return;
202 |
203 | assert(model());
204 | m_contextMenuSelectedItem = model()->substitutionByIndex(index);
205 | assert(m_contextMenuSelectedItem);
206 |
207 | QMenu menu(this);
208 | QAction *deleteAction = menu.addAction(QIcon(":/SubstitutionEditor/delete.png"), "&Delete");
209 | connect(deleteAction, SIGNAL(triggered(bool)), SLOT(deleteSubstitution(bool)));
210 | QAction *editAction = menu.addAction(QIcon(":/SubstitutionEditor/edit.png"), "&Edit");
211 | connect(editAction, SIGNAL(triggered(bool)), SLOT(editSubstitution(bool)));
212 |
213 | menu.exec(m_widgets.tvSubstitutions->viewport()->mapToGlobal(point));
214 | }
215 |
216 | void SubstitutionEditor::deleteSubstitution(bool)
217 | {
218 | if (QMessageBox::question(qApp->activeWindow(), PLUGIN_NAME,
219 | "Are you sure your want to delete this entry?", QMessageBox::Yes | QMessageBox::No)
220 | != QMessageBox::Yes)
221 | {
222 | return;
223 | }
224 |
225 | assert(model());
226 | assert(model()->substitutionManager());
227 | assert(m_contextMenuSelectedItem);
228 | model()->substitutionManager()->removeRule(m_contextMenuSelectedItem);
229 | m_contextMenuSelectedItem = nullptr;
230 | model()->update();
231 | }
232 |
233 | void SubstitutionEditor::importRules(bool)
234 | {
235 | auto fileName = QFileDialog::getOpenFileName(qApp->activeWindow(), "Import rules...",
236 | QString(), "Rule file (*.ini)");
237 |
238 | if (fileName.isEmpty())
239 | return;
240 |
241 | QSettings settings(fileName, QSettings::IniFormat);
242 | SettingsImporterExporter importer(model()->substitutionManager(), &settings);
243 | importer.importRules();
244 |
245 | model()->update();
246 | }
247 |
248 | void SubstitutionEditor::exportRules(bool)
249 | {
250 | auto fileName = QFileDialog::getSaveFileName(qApp->activeWindow(), "Export rules...",
251 | QString(), "Rule file (*.ini)");
252 |
253 | if (fileName.isEmpty())
254 | return;
255 |
256 | QSettings settings(fileName, QSettings::IniFormat);
257 | SettingsImporterExporter exporter(model()->substitutionManager(), &settings);
258 | exporter.exportRules();
259 | }
260 |
261 | void SubstitutionEditor::editSubstitution(bool)
262 | {
263 | assert(model());
264 | assert(model()->substitutionManager());
265 | assert(m_contextMenuSelectedItem);
266 | m_widgets.leSearchText->setText(QString::fromStdString(
267 | m_contextMenuSelectedItem->regexpPattern));
268 | m_widgets.leReplacement->setText(QString::fromStdString(
269 | m_contextMenuSelectedItem->replacement));
270 | model()->substitutionManager()->removeRule(m_contextMenuSelectedItem);
271 | m_contextMenuSelectedItem = nullptr;
272 | model()->update();
273 | }
274 |
275 | // ============================================================================================== //
276 | // [AboutDialog] //
277 | // ============================================================================================== //
278 |
279 | AboutDialog::AboutDialog()
280 | {
281 | m_widgets.setupUi(this);
282 | }
283 |
284 | // ============================================================================================== //
--------------------------------------------------------------------------------
/ida-cmake/cmake/IDA.cmake:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License (MIT)
3 | #
4 | # Copyright (c) 2017 Joel Höner
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 | #
24 |
25 | cmake_minimum_required(VERSION 3.1)
26 | cmake_policy(SET CMP0054 NEW)
27 |
28 | # =============================================================================================== #
29 | # Overridable options #
30 | # =============================================================================================== #
31 |
32 | set(IDA_ARCH_64 OFF CACHE BOOL "Build for 64 bit IDA" )
33 | set(IDA_SDK_PATH "" CACHE PATH "Path to IDA SDK" )
34 | set(IDA_INSTALL_DIR "" CACHE PATH "Install path of IDA" )
35 | set(IDA_VERSION 690 CACHE INT "IDA Version to build for (e.g. 6.9 is 690).")
36 | set(IDA_ENABLE_QT_SUPPORT OFF CACHE BOOL "Enable support for building plugins with Qt")
37 |
38 | # =============================================================================================== #
39 | # General preparation #
40 | # =============================================================================================== #
41 |
42 | # Compiler specific switches
43 | if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR
44 | "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR
45 | "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
46 | set(compiler_specific "-m32 -std=c++0x ")
47 | elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
48 | set(compiler_specific "/MP /D__VC__")
49 |
50 | # Hack for MSVC to always use /MD, even when generating debug code
51 | set(manipulated_vars
52 | CMAKE_CXX_FLAGS_DEBUG
53 | CMAKE_CXX_FLAGS_MINSIZEREL
54 | CMAKE_CXX_FLAGS_RELEASE
55 | CMAKE_CXX_FLAGS_RELWITHDEBINFO
56 | CMAKE_C_FLAGS_DEBUG
57 | CMAKE_C_FLAGS_MINSIZEREL
58 | CMAKE_C_FLAGS_RELEASE
59 | CMAKE_C_FLAGS_RELWITHDEBINFO)
60 | foreach(cur_var ${manipulated_vars})
61 | string(REGEX REPLACE "/(LD|(M(T|D)))d?( +|$)" "/MD " new_var ${${cur_var}})
62 | string(REGEX REPLACE "(/|-)D *_DEBUG" "" new_var ${new_var})
63 | set(${cur_var} ${new_var} CACHE STRING "" FORCE)
64 | endforeach()
65 | endif ()
66 |
67 | # OS specific switches
68 | if (WIN32)
69 | set(os_specific "-D_WIN32_WINNT=0x0501 -D__NT__")
70 |
71 | if (IDA_ARCH_64)
72 | set(plugin_extension "64.dll")
73 | else()
74 | set(plugin_extension ".dll")
75 | endif()
76 | elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
77 | set(os_specific "-D__MAC__ -D_FORTIFY_SOURCE=0")
78 |
79 | if (IDA_ARCH_64)
80 | set(plugin_extension ".pmc64")
81 | else()
82 | set(plugin_extension ".pmc")
83 | endif()
84 | elseif (UNIX)
85 | set(os_specific "-D__LINUX__")
86 |
87 | if (IDA_ARCH_64)
88 | set(plugin_extension ".plx64")
89 | else()
90 | set(plugin_extension ".plx")
91 | endif()
92 | endif ()
93 |
94 | if (IDA_ARCH_64)
95 | set(ida_lib_path_arch "64")
96 | set(arch_specific "-D__EA64__ -D__X64__")
97 | else ()
98 | set(ida_lib_path_arch "32")
99 | set(arch_specific "-D__X64__")
100 | endif ()
101 |
102 | set(plugin_extension "${plugin_extension}" CACHE INTERNAL "Plugin file extension" FORCE)
103 | set(other_defs "-DQT_NAMESPACE=QT -DNO_OBSOLETE_FUNCS -D__IDP__ -DQPROJECT_LIBRARY")
104 |
105 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${compiler_specific} ${os_specific} ${arch_specific} ${other_defs}"
106 | CACHE STRING "Flags used by the compiler during all build types." FORCE)
107 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${compiler_specific} ${os_specific} ${arch_specific} ${other_defs}"
108 | CACHE STRING "Flags used by the compiler during all build types." FORCE)
109 |
110 | # Library dependencies and include pathes
111 | if (WIN32)
112 | # On Windows, we use HR's lib files shipped with the SDK.
113 | set(IDA_LIB_DIR "${IDA_SDK}/lib/x64_win_vc_${ida_lib_path_arch}"
114 | CACHE PATH "IDA SDK library path" FORCE)
115 |
116 | message("IDA library path: ${IDA_LIB_DIR}")
117 |
118 | if (NOT EXISTS ${IDA_LIB_DIR})
119 | set(IDA_LIB_DIR NOTFOUND)
120 | endif ()
121 |
122 | message("Path exist")
123 | find_library(IDA_IDA_LIBRARY NAMES "ida.lib" PATHS ${IDA_LIB_DIR} REQUIRED)
124 | message("Got library path: ${IDA_IDA_LIBRARY}")
125 | list(APPEND ida_libraries ${IDA_IDA_LIBRARY})
126 | find_library(IDA_PRO_LIBRARY NAMES "pro" PATHS ${IDA_LIB_DIR})
127 | if (IDA_PRO_LIBRARY)
128 | list(APPEND ida_libraries ${IDA_PRO_LIBRARY})
129 | endif ()
130 | elseif (UNIX)
131 | # On unixoid platforms, we link against IDA directly.
132 | if (IDA_ARCH_64)
133 | find_library(IDA_IDA_LIBRARY NAMES "ida64" PATHS ${IDA_INSTALL_DIR} REQUIRED)
134 | else ()
135 | find_library(IDA_IDA_LIBRARY NAMES "ida" PATHS ${IDA_INSTALL_DIR} REQUIRED)
136 | endif ()
137 | list(APPEND ida_libraries ${IDA_IDA_LIBRARY})
138 | endif ()
139 |
140 | set(ida_libraries ${ida_libraries} CACHE INTERNAL "IDA libraries" FORCE)
141 | include_directories("${IDA_SDK}/include")
142 |
143 | if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND NOT IDA_INSTALL_DIR STREQUAL "")
144 | # Normalize path.
145 | file(TO_CMAKE_PATH ${IDA_INSTALL_DIR} ida_dir)
146 | file(TO_NATIVE_PATH ${ida_dir} IDA_NATIVE_DIR)
147 | endif ()
148 |
149 | # =============================================================================================== #
150 | # Qt support #
151 | # =============================================================================================== #
152 |
153 | if (IDA_ENABLE_QT_SUPPORT)
154 | set(CMAKE_AUTOMOC ON)
155 | set(CMAKE_INCLUDE_CURRENT_DIR ON)
156 |
157 | # IDA 6.9 and above use Qt5, older versions Qt4.
158 | if (IDA_VERSION LESS 690)
159 | set(ida_qt_major 4)
160 | else ()
161 | set(ida_qt_major 5)
162 | endif ()
163 |
164 | # On macOS, we can look up the path of each Qt library inside the IDA installation.
165 | # It might be possible to get this to work also on linux by parameterizing the file suffix.
166 | if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
167 | foreach(qtlib Gui;Core;Widgets)
168 | file(GLOB_RECURSE qtlibpaths "${IDA_INSTALL_DIR}/../Frameworks/Qt${qtlib}")
169 | # Typically we will find exactly 2 paths to the libfile on macOS because of
170 | # how the framework versioning works. Either one is fine, so pick the first.
171 | foreach(p ${qtlibpaths})
172 | set(IDA_Qt${qtlib}_LIBRARY ${p} CACHE FILEPATH "Path to IDA's Qt${qtlib}")
173 | break()
174 | endforeach()
175 | endforeach()
176 | elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
177 | if (ida_qt_major EQUAL 5)
178 | foreach(qtlib Gui;Core;Widgets)
179 | set(IDA_Qt${qtlib}_LIBRARY
180 | "${IDA_INSTALL_DIR}/libQt5${qtlib}.so.5"
181 | CACHE FILEPATH "Path to IDA's Qt ${qtlib}")
182 | endforeach()
183 | else ()
184 | foreach(qtlib Gui;Core)
185 | set(IDA_Qt${qtlib}_LIBRARY
186 | "${IDA_INSTALL_DIR}/libQt{qtlib}.so.4"
187 | CACHE FILEPATH "Path to IDA's Qt ${qtlib}")
188 | endforeach()
189 | endif()
190 | elseif (WIN32)
191 | message(Win32)
192 | foreach(qtlib Gui;Core;Widgets;PrintSupport)
193 | set(IDA_Qt${qtlib}_LIBRARY
194 | "${IDA_SDK}/lib/x64_win_qt/Qt5${qtlib}.lib"
195 | CACHE FILEPATH "Path to IDA's Qt ${qtlib}")
196 | find_package(Qt5 COMPONENTS ${qtlib} REQUIRED)
197 | endforeach()
198 | find_package(Qt5 COMPONENTS Widgets REQUIRED)
199 | find_package(Qt5 COMPONENTS Core REQUIRED)
200 | endif()
201 |
202 | # Locate Qt.
203 | if (ida_qt_major EQUAL 4)
204 | find_package(Qt4 REQUIRED QtCore QtGui)
205 | else ()
206 | find_package(Qt5Widgets REQUIRED)
207 | endif ()
208 |
209 | # Hack Qt to use release libraries even when generating debug binaries
210 | # for compatibility with IDA.
211 | get_cmake_property(all_vars VARIABLES)
212 | foreach(cur_var ${all_vars})
213 | string(REGEX MATCH "^(QT_.*LIBRARY)$" lib_match ${cur_var})
214 | if (lib_match)
215 | set(${lib_match} "${lib_match}_RELEASE")
216 | endif()
217 | endforeach()
218 | endif ()
219 |
220 | # =============================================================================================== #
221 | # Functions for adding IDA plugin targets #
222 | # =============================================================================================== #
223 |
224 | function (add_ida_plugin plugin_name)
225 | set(sources ${ARGV})
226 | if (sources)
227 | list(REMOVE_AT sources 0)
228 | endif ()
229 |
230 | # Define target
231 | string(STRIP "${sources}" sources)
232 | add_library(${plugin_name} SHARED ${sources})
233 | set_target_properties(${plugin_name} PROPERTIES
234 | PREFIX ""
235 | SUFFIX ${plugin_extension}
236 | OUTPUT_NAME ${plugin_name})
237 |
238 | target_link_libraries(${plugin_name} ${ida_libraries})
239 |
240 | # Define install rule
241 | install(TARGETS ${plugin_name} DESTINATION plugins)
242 |
243 | if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
244 | # When generating for Visual Studio,
245 | # generate user file for convenient debugging support.
246 | configure_file(
247 | "template.vcxproj.user"
248 | "${plugin_name}.vcxproj.user"
249 | @ONLY)
250 | endif ()
251 | endfunction (add_ida_plugin)
252 |
253 |
254 | # =============================================================================================== #
255 | # Functions for adding IDA plugin targets with Qt support #
256 | # =============================================================================================== #
257 |
258 |
259 | function (add_ida_qt_plugin plugin_name)
260 | set(sources ${ARGV})
261 | if (sources)
262 | list(REMOVE_AT sources 0)
263 | endif ()
264 |
265 | # Divide between UI and resource files and regular C/C++ sources.
266 | foreach (cur_file ${sources})
267 | if (${cur_file} MATCHES ".*\\.ui")
268 | list(APPEND ui_sources ${cur_file})
269 | elseif (${cur_file} MATCHES ".*\\.qrc")
270 | list(APPEND rsrc_sources ${cur_file})
271 | else ()
272 | list(APPEND non_ui_sources ${cur_file})
273 | endif ()
274 | endforeach ()
275 |
276 | # Compile UI files.
277 | if (ida_qt_major EQUAL 4)
278 | QT4_WRAP_UI(form_headers ${ui_sources})
279 | else ()
280 | QT5_WRAP_UI(form_headers ${ui_sources})
281 | endif ()
282 |
283 | # Compile resources.
284 | if (ida_qt_major EQUAL 4)
285 | QT4_ADD_RESOURCES(rsrc_headers ${rsrc_sources})
286 | else ()
287 | QT5_ADD_RESOURCES(rsrc_headers ${rsrc_sources})
288 | endif ()
289 |
290 | # Add plugin.
291 | add_ida_plugin(${plugin_name} ${non_ui_sources} ${form_headers} ${rsrc_headers})
292 |
293 | # Link against Qt.
294 | if (ida_qt_major EQUAL 4)
295 | foreach (qtlib Core;Gui)
296 | target_link_libraries(${CMAKE_PROJECT_NAME} "Qt4::Qt${qtlib}")
297 | # On macs, we need to link to the frameworks in the IDA application folder
298 | if ((${CMAKE_SYSTEM_NAME} MATCHES "Darwin") OR
299 | (${CMAKE_SYSTEM_NAME} MATCHES "Linux"))
300 | set_target_properties(
301 | "Qt4::Qt${qtlib}"
302 | PROPERTIES
303 | IMPORTED_LOCATION_RELEASE "${IDA_Qt${qtlib}_LIBRARY}")
304 | endif ()
305 | endforeach()
306 | else ()
307 | foreach (qtlib Widgets Core PrintSupport Gui)
308 | target_link_libraries(${CMAKE_PROJECT_NAME} "Qt5::${qtlib}")
309 | message(${IDA_Qt${qtlib}_LIBRARY})
310 | target_link_libraries(${CMAKE_PROJECT_NAME} "${IDA_Qt${qtlib}_LIBRARY}")
311 | set_target_properties(
312 | "Qt5::${qtlib}"
313 | PROPERTIES
314 | IMPORTED_LOCATION_RELEASE "${IDA_Qt${qtlib}_LIBRARY}")
315 | endforeach()
316 | endif ()
317 | endfunction ()
318 |
--------------------------------------------------------------------------------