idapro 0.0.0__tar.gz → 0.0.3.dev1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Hex-Rays SA
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.
@@ -0,0 +1,213 @@
1
+ Metadata-Version: 2.4
2
+ Name: idapro
3
+ Version: 0.0.3.dev1
4
+ Summary: IDA Library Python module
5
+ Author: Hex-Rays SA
6
+ Author-email: support@hex-rays.com
7
+ License: MIT
8
+ Classifier: Development Status :: 2 - Pre-Alpha
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Topic :: Software Development :: Disassemblers
13
+ Requires-Python: >=3.8
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Dynamic: author
17
+ Dynamic: author-email
18
+ Dynamic: classifier
19
+ Dynamic: description
20
+ Dynamic: description-content-type
21
+ Dynamic: license
22
+ Dynamic: license-file
23
+ Dynamic: requires-python
24
+ Dynamic: summary
25
+
26
+
27
+ # IDA Library Python Module
28
+
29
+ **⚠️ This is a dev pre-release version. APIs may change without notice and pre-release versions may be deleted at any time.**
30
+
31
+
32
+ The IDA Library Python module enables running IDA Pro as an independent Python package outside the IDA UI environment, allowing for programmatic binary analysis and reverse engineering tasks.
33
+
34
+
35
+ ## Prerequisites
36
+
37
+ ### Environment Setup
38
+
39
+ Set the `IDADIR` environment variable to point to your IDA installation directory:
40
+
41
+ **Linux/macOS:**
42
+ ```bash
43
+ export IDADIR="/path/to/your/ida/installation"
44
+ ```
45
+
46
+ **Windows:**
47
+ ```cmd
48
+ set IDADIR="C:\Program Files\IDA Pro 9.1"
49
+ ```
50
+
51
+ **Example paths:**
52
+ - **macOS:** `/Applications/IDA Professional 9.1.app/Contents/MacOS/`
53
+ - **Windows:** `C:\Program Files\IDA Pro 9.1\`
54
+ - **Linux:** `/opt/ida-9.1/`
55
+
56
+ > **Note:** If you have already installed and configured the `idapro` Python package in the past using script provided with IDA installation package, setting `IDADIR` is not required.
57
+
58
+ ## Usage example:
59
+
60
+ ```python
61
+ #!/usr/bin/env python3
62
+ """
63
+ IDA Pro Python Library Usage Example
64
+ This example demonstrates how to analyze a binary file using IDA Pro Python library.
65
+ """
66
+
67
+ import argparse
68
+ import importlib.metadata
69
+
70
+ # You need to import first idapro module
71
+ import idapro
72
+
73
+ # After idapro module was loaded, you can simply import IDA Python modules
74
+ import ida_entry
75
+ import ida_nalt
76
+ import idaapi
77
+ import idc
78
+ import idautils
79
+ import ida_ida
80
+ import ida_funcs
81
+ import ida_name
82
+ import ida_bytes
83
+ import ida_typeinf
84
+
85
+ # Read versions, configured IDA pro kernel and python package
86
+ kern_major, kern_minor, kern_build = idapro.get_library_version()
87
+ idapro_version = importlib.metadata.version('idapro')
88
+ kernel_path = idapro.get_ida_install_dir()
89
+
90
+ # Parse input arguments
91
+ parser = argparse.ArgumentParser(description=f"IDA Library usage example, idapro version: {idapro_version}, "
92
+ f"kernel version: {kern_major}.{kern_minor}.{kern_build}, kernel libraries path: {kernel_path}")
93
+ parser.add_argument(
94
+ "-f",
95
+ "--input-file",
96
+ help="Binary input file to be loaded",
97
+ type=str,
98
+ required=True,
99
+ default=None
100
+ )
101
+ args = parser.parse_args()
102
+
103
+ # Print banner with components versions
104
+ print(f"{parser.description}\n")
105
+
106
+ # Open database
107
+ if idapro.open_database(args.input_file, True) == 0:
108
+ # Extract minimum/maxim addresses
109
+ min_ea = ida_ida.inf_get_min_ea()
110
+ max_ea = ida_ida.inf_get_max_ea()
111
+ print(f"Addresses range: {hex(min_ea)} - {hex(max_ea)}")
112
+
113
+ # Print entry point
114
+ entry_point = ida_entry.get_entry_ordinal(0)
115
+ if entry_point != idaapi.BADADDR:
116
+ entry_addr = ida_entry.get_entry(entry_point)
117
+ print(f"Entry point: {hex(entry_addr)}")
118
+
119
+ # Print some metadata
120
+ print(f"Metadata:")
121
+ print(f" path: {idaapi.get_input_file_path()}")
122
+ print(f" module: {idaapi.get_root_filename()}")
123
+ print(f" base: {hex(idaapi.get_imagebase())}")
124
+ print(f" filesize: {hex(ida_nalt.retrieve_input_file_size())}")
125
+ print(f" md5: {ida_nalt.retrieve_input_file_md5()}")
126
+ print(f" sha256: {ida_nalt.retrieve_input_file_sha256()}")
127
+ print(f" crc32: {hex(ida_nalt.retrieve_input_file_crc32())}")
128
+
129
+ # Iterate functions
130
+ for func_ea in idautils.Functions():
131
+ f = ida_funcs.get_func(func_ea)
132
+ print(f"Function - name {f.name}, start ea {hex(f.start_ea)}, end ea {hex(f.end_ea)}")
133
+
134
+ for seg_ea in idautils.Segments():
135
+ name = idc.get_segm_name(seg_ea)
136
+ print(f"Segment - name {name}")
137
+
138
+ # Iterate types
139
+ til = ida_typeinf.get_idati()
140
+ if til:
141
+ max_ord = ida_typeinf.get_ordinal_limit(til)
142
+ current_index = -1
143
+ current_named_type = None
144
+
145
+ while current_index < max_ord - 1:
146
+ current_index += 1
147
+ tinfo = ida_typeinf.tinfo_t()
148
+ if tinfo.get_numbered_type(til, current_index):
149
+ print(f"Type - id {tinfo.get_tid()}")
150
+
151
+ while True:
152
+ if current_named_type is None:
153
+ current_named_type = ida_typeinf.first_named_type(til, ida_typeinf.NTF_TYPE)
154
+ else:
155
+ current_named_type = ida_typeinf.next_named_type(til, current_named_type, ida_typeinf.NTF_TYPE)
156
+
157
+ if not current_named_type:
158
+ break
159
+
160
+ tinfo = ida_typeinf.tinfo_t()
161
+ if tinfo.get_named_type(til, current_named_type):
162
+ print(f"Type - name {tinfo.get_type_name()}, id {tinfo.get_tid()}")
163
+
164
+ # Iterate comments
165
+ for ea in idautils.Heads(min_ea, max_ea):
166
+ cmt = idc.get_cmt(ea, 0)
167
+ if cmt:
168
+ print(f"Comment - value {cmt}")
169
+
170
+ # Iterate strings
171
+ for s in idautils.Strings():
172
+ print(f"String - value {s}")
173
+
174
+ for ea, name in idautils.Names():
175
+ print(f"Name - value {name}")
176
+
177
+ # Iterate basic blocks
178
+ for func_ea in idautils.Functions():
179
+ func = ida_funcs.get_func(func_ea)
180
+ if func:
181
+ fc = idaapi.FlowChart(func)
182
+ for b in fc:
183
+ print(f"Basic block - start ea {hex(b.start_ea)}, end ea {hex(b.end_ea)}")
184
+
185
+ # Iterate binary instructions
186
+ for ea in idautils.Heads(min_ea, max_ea):
187
+ if ida_bytes.is_code(ida_bytes.get_flags(ea)):
188
+ disasm = idc.generate_disasm_line(ea, 0)
189
+ print(f"Instruction - ea {hex(ea)}, asm {disasm}")
190
+
191
+ # Close database discarding the changes
192
+ idapro.close_database(False)
193
+ ```
194
+
195
+ ## Troubleshooting
196
+
197
+ ### Common Issues
198
+
199
+ **ModuleNotFoundError: No module named 'idapro'**
200
+ - Ensure `IDADIR` is set correctly
201
+ - Verify IDA Pro is properly installed
202
+
203
+ **License Issues**
204
+ - Ensure you have a valid IDA Pro license
205
+ - Check that IDA can run normally in GUI mode first
206
+
207
+ ## API Reference
208
+
209
+ For detailed API documentation, refer to:
210
+ - IDA Python documentation at https://python.docs.hex-rays.com/
211
+ - Built-in help: `help(idapro)` after importing
212
+ - IDA Pro SDK documentation https://docs.hex-rays.com/developer-guide/c++-sdk
213
+
@@ -0,0 +1,69 @@
1
+ # IDA Library Python Module
2
+
3
+ The IDA Library Python module enables running IDA Pro as an independent Python package outside the IDA UI environment, allowing for programmatic binary analysis and reverse engineering tasks.
4
+
5
+ ## Prerequisites
6
+
7
+ ### Environment Setup
8
+
9
+ Set the `IDADIR` environment variable to point to your IDA installation directory:
10
+
11
+ **Linux/macOS:**
12
+ ```bash
13
+ export IDADIR="/path/to/your/ida/installation"
14
+ ```
15
+
16
+ **Windows:**
17
+ ```cmd
18
+ set IDADIR="C:\Program Files\IDA Pro 9.1"
19
+ ```
20
+
21
+ **Example paths:**
22
+ - **macOS:** `/Applications/IDA Professional 9.1.app/Contents/MacOS/`
23
+ - **Windows:** `C:\Program Files\IDA Pro 9.1\`
24
+ - **Linux:** `/opt/ida-9.1/`
25
+
26
+ > **Note:** If you have already installed and configured the `idapro` Python package in the past using script provided with IDA installation package, setting `IDADIR` is not required.
27
+
28
+ ## Usage Example
29
+
30
+ ```python
31
+ # You need to import first idapro module
32
+ import idapro
33
+ # After idapro module is loaded, you can import IDA Python modules
34
+ import idautils
35
+ import ida_funcs
36
+ import ida_name
37
+
38
+ # Open the database using idapro module
39
+ if idapro.open_database("program.exe", True) == 0:
40
+ # Iterate functions and print basic information for each of them
41
+ for func_ea in idautils.Functions():
42
+ f = ida_funcs.get_func(func_ea)
43
+ func_name = ida_name.get_name(func_ea)
44
+ print(f"Function - name {func_name}, start ea {hex(f.start_ea)}, end ea {hex(f.end_ea)}")
45
+
46
+ # Close database discarding the changes
47
+ idapro.close_database(False)
48
+ ```
49
+
50
+ **For a complete traversing database example, see:** [traverse.py](./examples/traverse.py)
51
+
52
+ ## Troubleshooting
53
+
54
+ ### Common Issues
55
+
56
+ **ModuleNotFoundError: No module named 'idapro'**
57
+ - Ensure `IDADIR` is set correctly
58
+ - Verify IDA Pro is properly installed
59
+
60
+ **License Issues**
61
+ - Ensure you have a valid IDA Pro license
62
+ - Check that IDA can run normally in GUI mode first
63
+
64
+ ## API Reference
65
+
66
+ For detailed API documentation, refer to:
67
+ - IDA Python documentation at [https://python.docs.hex-rays.com/](https://python.docs.hex-rays.com/)
68
+ - Built-in help: `help(idapro)` after importing
69
+ - IDA Pro SDK documentation at [https://docs.hex-rays.com/developer-guide/c++-sdk](https://docs.hex-rays.com/developer-guide/c++-sdk)
@@ -0,0 +1,118 @@
1
+ from __future__ import annotations
2
+ import sys
3
+ import platform
4
+ from pathlib import Path
5
+ import ctypes
6
+ import os
7
+ from .config import get_ida_install_dir
8
+
9
+ def find_file(name, path):
10
+ """Internal method used for recursively find a file in a folder"""
11
+ for root, dirs, files in os.walk(path):
12
+ if name in files:
13
+ return os.path.join(root, name)
14
+ return None
15
+
16
+ # get the right filename based on platform
17
+ platform_str = platform.system()
18
+
19
+ if platform_str == "Windows":
20
+ name = "idalib.dll"
21
+ elif platform_str == "Linux":
22
+ name = "libidalib.so"
23
+ elif platform_str == "Darwin":
24
+ name = "libidalib.dylib"
25
+ else:
26
+ raise ImportError(f"Unknown platform {platform_str}")
27
+
28
+ # Get the ida-install-dir setting
29
+ root_dir = get_ida_install_dir()
30
+
31
+ if platform_str == "Windows":
32
+ # IDA kernel and modules may need dependencies in its root dir (e.g. clp64.dll)
33
+ # tell Windows loader where they can be found
34
+ # NB: for AddDllDirectory() be effective for indirectly loaded DLLs,
35
+ # SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_USER_DIRS) has to be called first
36
+ kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
37
+ SetDefaultDllDirectories = getattr(kernel32, "SetDefaultDllDirectories")
38
+ if SetDefaultDllDirectories:
39
+ from ctypes.wintypes import DWORD, BOOL
40
+ SetDefaultDllDirectories.argtypes = [DWORD]
41
+ SetDefaultDllDirectories.restype = BOOL
42
+ LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x00001000
43
+ LOAD_LIBRARY_SEARCH_USER_DIRS = 0x00000400
44
+ flags = LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_USER_DIRS
45
+ if SetDefaultDllDirectories(flags):
46
+ # finally, add IDA's directory for dependencies
47
+ os.add_dll_directory(root_dir)
48
+ else:
49
+ os.environ['PATH'] = root_dir + os.pathsep + os.environ.get('PATH', '')
50
+
51
+ idalib_path = find_file(name=name, path=root_dir)
52
+ if idalib_path is None:
53
+ raise ImportError(f"Could not find {name} in {root_dir}. Please make sure you have an IDA version 9.0 or newer and run py-activate-idalib.py utility shipped with it in order to activate this module.")
54
+
55
+ if "IDA_IS_INTERACTIVE" in os.environ:
56
+ if os.environ["IDA_IS_INTERACTIVE"] == "1":
57
+ raise ImportError("The IDA library can only be run in a separate process and cannot be loaded within IDA itself.")
58
+
59
+ # load the library and initialize the kernel
60
+ try:
61
+ libida = ctypes.cdll.LoadLibrary(idalib_path)
62
+ except Exception as e:
63
+ raise ImportError(f"Failed loading IDA library file {idalib_path}, exception {e}\n")
64
+
65
+ try:
66
+ error_description = None
67
+ init_code = libida.init_library(0, None)
68
+ if init_code != 0:
69
+ error_description = f"init_library error code {init_code}"
70
+ except Exception as e:
71
+ error_description = f"exception {e}"
72
+
73
+ if error_description != None:
74
+ raise ImportError(f"Failed to initialize IDA library, {error_description}, check logging for additional information\n")
75
+
76
+ sys.path.append(str(Path(idalib_path).parent / "python/lib-dynload"))
77
+ sys.path.append(str(Path(idalib_path).parent / "python"))
78
+
79
+ def open_database(file_name:str, run_auto_analysis: bool, args: str = None)->int:
80
+ """Opens the database specified by the file_name argument.
81
+ If run_auto_analysis is set to True, the auto-analysis will start and wait for its completion.
82
+ Optionally, additional arguments can be provided via args parameter, which follow the same format as IDA's command-line arguments.
83
+ NOTE: All library functions must be called from the same thread that initialized the library.
84
+ The library is single-threaded, and performing database operations from a different thread may result in undefined behavior."""
85
+ return libida.open_database(file_name.encode(), run_auto_analysis, args.encode() if args is not None else None)
86
+
87
+ def close_database(save = True)->None:
88
+ """Close the current database"""
89
+ libida.close_database(save)
90
+
91
+ def make_signatures(only_pat = False)->bool:
92
+ """Generate .sig and .pat files for the current database"""
93
+ return libida.make_signatures(only_pat)
94
+
95
+ def enable_console_messages(enable:bool)->None:
96
+ """Enable console messages, they are disabled by default"""
97
+ libida.enable_console_messages(enable)
98
+
99
+ def set_screen_ea(screen_ea: "ea_t")->None:
100
+ """Set screen ea, let the user specify the current screen ea
101
+ subsequent calls to get_screen_ea will return this value"""
102
+ libida.set_screen_ea.argtypes = [ctypes.c_uint64]
103
+ libida.set_screen_ea(screen_ea)
104
+
105
+ def get_library_version()->tuple[int, int, int] | None:
106
+ """Get IDA library version, return minor, major build in case of success, None if fails"""
107
+ major = ctypes.c_int()
108
+ minor = ctypes.c_int()
109
+ build = ctypes.c_int()
110
+
111
+ libida.get_library_version.argtypes = [ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int)]
112
+ libida.get_library_version.restype = ctypes.c_bool
113
+ success = libida.get_library_version(ctypes.byref(major), ctypes.byref(minor), ctypes.byref(build))
114
+
115
+ if success:
116
+ return major.value, minor.value, build.value
117
+ else:
118
+ return None
@@ -0,0 +1,82 @@
1
+ import os
2
+ import json
3
+ from pathlib import Path
4
+ import platform
5
+
6
+ def get_user_config_path():
7
+ """Get the path to the user's config file based on platform following IDA's user directories."""
8
+ system = platform.system()
9
+
10
+ if system == "Windows":
11
+ # On Windows, use the %APPDATA%\Hex-Rays\IDA Pro directory
12
+ config_dir = Path(os.getenv('APPDATA')) / "Hex-Rays" / "IDA Pro"
13
+ else:
14
+ # On macOS and Linux, use ~/.idapro
15
+ config_dir = Path.home() / ".idapro"
16
+
17
+ # Return the full path to the config file (now in JSON format)
18
+ user_config_path = config_dir / "ida-config.json"
19
+ return user_config_path
20
+
21
+ def create_default_config(user_config_path):
22
+ """Create a default config file in JSON format."""
23
+ # Create a default JSON config structure
24
+ default_config = {
25
+ "Paths": {
26
+ "ida-install-dir": ""
27
+ }
28
+ }
29
+
30
+ # Create the directory if it doesn't exist
31
+ user_config_path.parent.mkdir(parents=True, exist_ok=True)
32
+
33
+ # Write the default config to the user-specific config file
34
+ with user_config_path.open('w') as configfile:
35
+ json.dump(default_config, configfile, indent=4)
36
+
37
+ print(f"Default config file created at {user_config_path}")
38
+ return default_config
39
+
40
+ def load_config():
41
+ """Load the user-specific config from JSON file."""
42
+ user_config_path = get_user_config_path()
43
+
44
+ if not user_config_path.exists():
45
+ # If the config file doesn't exist, create it with default values
46
+ config = create_default_config(user_config_path)
47
+ else:
48
+ # If the config file exists, load it
49
+ with user_config_path.open('r') as configfile:
50
+ config = json.load(configfile)
51
+
52
+ return config
53
+
54
+ def set_ida_install_dir(new_path):
55
+ """Set the IDA installation directory in the user-specific JSON config file."""
56
+ # Get the user-specific config path
57
+ user_config_path = get_user_config_path()
58
+
59
+ # Load the existing config or create default if missing
60
+ config = load_config()
61
+
62
+ # Set the new IDA installation directory path
63
+ config['Paths']['ida-install-dir'] = new_path
64
+
65
+ # Write the changes back to the user-specific config file
66
+ with user_config_path.open('w') as configfile:
67
+ json.dump(config, configfile, indent=4)
68
+
69
+ print(f"IDA installation directory set to: {new_path}")
70
+
71
+ def get_ida_install_dir():
72
+ """Retrieve the IDA installation directory."""
73
+
74
+ # Read the configuration JSON file
75
+ config = load_config()
76
+ install_dir = config['Paths'].get('ida-install-dir', None)
77
+
78
+ # Fallback to IDADIR env var if the JSON value is not set
79
+ if install_dir is None or len(install_dir) == 0:
80
+ install_dir = os.environ.get('IDADIR', '')
81
+
82
+ return install_dir
@@ -0,0 +1,213 @@
1
+ Metadata-Version: 2.4
2
+ Name: idapro
3
+ Version: 0.0.3.dev1
4
+ Summary: IDA Library Python module
5
+ Author: Hex-Rays SA
6
+ Author-email: support@hex-rays.com
7
+ License: MIT
8
+ Classifier: Development Status :: 2 - Pre-Alpha
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Topic :: Software Development :: Disassemblers
13
+ Requires-Python: >=3.8
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Dynamic: author
17
+ Dynamic: author-email
18
+ Dynamic: classifier
19
+ Dynamic: description
20
+ Dynamic: description-content-type
21
+ Dynamic: license
22
+ Dynamic: license-file
23
+ Dynamic: requires-python
24
+ Dynamic: summary
25
+
26
+
27
+ # IDA Library Python Module
28
+
29
+ **⚠️ This is a dev pre-release version. APIs may change without notice and pre-release versions may be deleted at any time.**
30
+
31
+
32
+ The IDA Library Python module enables running IDA Pro as an independent Python package outside the IDA UI environment, allowing for programmatic binary analysis and reverse engineering tasks.
33
+
34
+
35
+ ## Prerequisites
36
+
37
+ ### Environment Setup
38
+
39
+ Set the `IDADIR` environment variable to point to your IDA installation directory:
40
+
41
+ **Linux/macOS:**
42
+ ```bash
43
+ export IDADIR="/path/to/your/ida/installation"
44
+ ```
45
+
46
+ **Windows:**
47
+ ```cmd
48
+ set IDADIR="C:\Program Files\IDA Pro 9.1"
49
+ ```
50
+
51
+ **Example paths:**
52
+ - **macOS:** `/Applications/IDA Professional 9.1.app/Contents/MacOS/`
53
+ - **Windows:** `C:\Program Files\IDA Pro 9.1\`
54
+ - **Linux:** `/opt/ida-9.1/`
55
+
56
+ > **Note:** If you have already installed and configured the `idapro` Python package in the past using script provided with IDA installation package, setting `IDADIR` is not required.
57
+
58
+ ## Usage example:
59
+
60
+ ```python
61
+ #!/usr/bin/env python3
62
+ """
63
+ IDA Pro Python Library Usage Example
64
+ This example demonstrates how to analyze a binary file using IDA Pro Python library.
65
+ """
66
+
67
+ import argparse
68
+ import importlib.metadata
69
+
70
+ # You need to import first idapro module
71
+ import idapro
72
+
73
+ # After idapro module was loaded, you can simply import IDA Python modules
74
+ import ida_entry
75
+ import ida_nalt
76
+ import idaapi
77
+ import idc
78
+ import idautils
79
+ import ida_ida
80
+ import ida_funcs
81
+ import ida_name
82
+ import ida_bytes
83
+ import ida_typeinf
84
+
85
+ # Read versions, configured IDA pro kernel and python package
86
+ kern_major, kern_minor, kern_build = idapro.get_library_version()
87
+ idapro_version = importlib.metadata.version('idapro')
88
+ kernel_path = idapro.get_ida_install_dir()
89
+
90
+ # Parse input arguments
91
+ parser = argparse.ArgumentParser(description=f"IDA Library usage example, idapro version: {idapro_version}, "
92
+ f"kernel version: {kern_major}.{kern_minor}.{kern_build}, kernel libraries path: {kernel_path}")
93
+ parser.add_argument(
94
+ "-f",
95
+ "--input-file",
96
+ help="Binary input file to be loaded",
97
+ type=str,
98
+ required=True,
99
+ default=None
100
+ )
101
+ args = parser.parse_args()
102
+
103
+ # Print banner with components versions
104
+ print(f"{parser.description}\n")
105
+
106
+ # Open database
107
+ if idapro.open_database(args.input_file, True) == 0:
108
+ # Extract minimum/maxim addresses
109
+ min_ea = ida_ida.inf_get_min_ea()
110
+ max_ea = ida_ida.inf_get_max_ea()
111
+ print(f"Addresses range: {hex(min_ea)} - {hex(max_ea)}")
112
+
113
+ # Print entry point
114
+ entry_point = ida_entry.get_entry_ordinal(0)
115
+ if entry_point != idaapi.BADADDR:
116
+ entry_addr = ida_entry.get_entry(entry_point)
117
+ print(f"Entry point: {hex(entry_addr)}")
118
+
119
+ # Print some metadata
120
+ print(f"Metadata:")
121
+ print(f" path: {idaapi.get_input_file_path()}")
122
+ print(f" module: {idaapi.get_root_filename()}")
123
+ print(f" base: {hex(idaapi.get_imagebase())}")
124
+ print(f" filesize: {hex(ida_nalt.retrieve_input_file_size())}")
125
+ print(f" md5: {ida_nalt.retrieve_input_file_md5()}")
126
+ print(f" sha256: {ida_nalt.retrieve_input_file_sha256()}")
127
+ print(f" crc32: {hex(ida_nalt.retrieve_input_file_crc32())}")
128
+
129
+ # Iterate functions
130
+ for func_ea in idautils.Functions():
131
+ f = ida_funcs.get_func(func_ea)
132
+ print(f"Function - name {f.name}, start ea {hex(f.start_ea)}, end ea {hex(f.end_ea)}")
133
+
134
+ for seg_ea in idautils.Segments():
135
+ name = idc.get_segm_name(seg_ea)
136
+ print(f"Segment - name {name}")
137
+
138
+ # Iterate types
139
+ til = ida_typeinf.get_idati()
140
+ if til:
141
+ max_ord = ida_typeinf.get_ordinal_limit(til)
142
+ current_index = -1
143
+ current_named_type = None
144
+
145
+ while current_index < max_ord - 1:
146
+ current_index += 1
147
+ tinfo = ida_typeinf.tinfo_t()
148
+ if tinfo.get_numbered_type(til, current_index):
149
+ print(f"Type - id {tinfo.get_tid()}")
150
+
151
+ while True:
152
+ if current_named_type is None:
153
+ current_named_type = ida_typeinf.first_named_type(til, ida_typeinf.NTF_TYPE)
154
+ else:
155
+ current_named_type = ida_typeinf.next_named_type(til, current_named_type, ida_typeinf.NTF_TYPE)
156
+
157
+ if not current_named_type:
158
+ break
159
+
160
+ tinfo = ida_typeinf.tinfo_t()
161
+ if tinfo.get_named_type(til, current_named_type):
162
+ print(f"Type - name {tinfo.get_type_name()}, id {tinfo.get_tid()}")
163
+
164
+ # Iterate comments
165
+ for ea in idautils.Heads(min_ea, max_ea):
166
+ cmt = idc.get_cmt(ea, 0)
167
+ if cmt:
168
+ print(f"Comment - value {cmt}")
169
+
170
+ # Iterate strings
171
+ for s in idautils.Strings():
172
+ print(f"String - value {s}")
173
+
174
+ for ea, name in idautils.Names():
175
+ print(f"Name - value {name}")
176
+
177
+ # Iterate basic blocks
178
+ for func_ea in idautils.Functions():
179
+ func = ida_funcs.get_func(func_ea)
180
+ if func:
181
+ fc = idaapi.FlowChart(func)
182
+ for b in fc:
183
+ print(f"Basic block - start ea {hex(b.start_ea)}, end ea {hex(b.end_ea)}")
184
+
185
+ # Iterate binary instructions
186
+ for ea in idautils.Heads(min_ea, max_ea):
187
+ if ida_bytes.is_code(ida_bytes.get_flags(ea)):
188
+ disasm = idc.generate_disasm_line(ea, 0)
189
+ print(f"Instruction - ea {hex(ea)}, asm {disasm}")
190
+
191
+ # Close database discarding the changes
192
+ idapro.close_database(False)
193
+ ```
194
+
195
+ ## Troubleshooting
196
+
197
+ ### Common Issues
198
+
199
+ **ModuleNotFoundError: No module named 'idapro'**
200
+ - Ensure `IDADIR` is set correctly
201
+ - Verify IDA Pro is properly installed
202
+
203
+ **License Issues**
204
+ - Ensure you have a valid IDA Pro license
205
+ - Check that IDA can run normally in GUI mode first
206
+
207
+ ## API Reference
208
+
209
+ For detailed API documentation, refer to:
210
+ - IDA Python documentation at https://python.docs.hex-rays.com/
211
+ - Built-in help: `help(idapro)` after importing
212
+ - IDA Pro SDK documentation https://docs.hex-rays.com/developer-guide/c++-sdk
213
+
@@ -1,6 +1,10 @@
1
- pyproject.toml
1
+ LICENSE
2
+ README.md
3
+ setup.py
2
4
  idapro/__init__.py
5
+ idapro/config.py
3
6
  idapro.egg-info/PKG-INFO
4
7
  idapro.egg-info/SOURCES.txt
5
8
  idapro.egg-info/dependency_links.txt
9
+ idapro.egg-info/not-zip-safe
6
10
  idapro.egg-info/top_level.txt
@@ -0,0 +1,79 @@
1
+ from setuptools import setup, find_packages
2
+ example_code = "#!/usr/bin/env python3\n\"\"\"\nIDA Pro Python Library Usage Example\nThis example demonstrates how to analyze a binary file using IDA Pro Python library.\n\"\"\"\n\nimport argparse\nimport importlib.metadata\n\n# You need to import first idapro module\nimport idapro\n\n# After idapro module was loaded, you can simply import IDA Python modules\nimport ida_entry\nimport ida_nalt\nimport idaapi\nimport idc\nimport idautils\nimport ida_ida\nimport ida_funcs\nimport ida_name\nimport ida_bytes\nimport ida_typeinf\n\n# Read versions, configured IDA pro kernel and python package\nkern_major, kern_minor, kern_build = idapro.get_library_version()\nidapro_version = importlib.metadata.version('idapro')\nkernel_path = idapro.get_ida_install_dir()\n\n# Parse input arguments\nparser = argparse.ArgumentParser(description=f\"IDA Library usage example, idapro version: {idapro_version}, \"\n f\"kernel version: {kern_major}.{kern_minor}.{kern_build}, kernel libraries path: {kernel_path}\")\nparser.add_argument(\n \"-f\",\n \"--input-file\",\n help=\"Binary input file to be loaded\",\n type=str,\n required=True,\n default=None\n)\nargs = parser.parse_args()\n\n# Print banner with components versions\nprint(f\"{parser.description}\\n\")\n\n# Open database\nif idapro.open_database(args.input_file, True) == 0:\n # Extract minimum/maxim addresses\n min_ea = ida_ida.inf_get_min_ea()\n max_ea = ida_ida.inf_get_max_ea()\n print(f\"Addresses range: {hex(min_ea)} - {hex(max_ea)}\")\n\n # Print entry point\n entry_point = ida_entry.get_entry_ordinal(0)\n if entry_point != idaapi.BADADDR:\n entry_addr = ida_entry.get_entry(entry_point)\n print(f\"Entry point: {hex(entry_addr)}\")\n\n # Print some metadata\n print(f\"Metadata:\")\n print(f\" path: {idaapi.get_input_file_path()}\")\n print(f\" module: {idaapi.get_root_filename()}\")\n print(f\" base: {hex(idaapi.get_imagebase())}\")\n print(f\" filesize: {hex(ida_nalt.retrieve_input_file_size())}\")\n print(f\" md5: {ida_nalt.retrieve_input_file_md5()}\")\n print(f\" sha256: {ida_nalt.retrieve_input_file_sha256()}\")\n print(f\" crc32: {hex(ida_nalt.retrieve_input_file_crc32())}\")\n\n # Iterate functions\n for func_ea in idautils.Functions():\n f = ida_funcs.get_func(func_ea)\n print(f\"Function - name {f.name}, start ea {hex(f.start_ea)}, end ea {hex(f.end_ea)}\")\n\n for seg_ea in idautils.Segments():\n name = idc.get_segm_name(seg_ea)\n print(f\"Segment - name {name}\")\n\n # Iterate types\n til = ida_typeinf.get_idati()\n if til:\n max_ord = ida_typeinf.get_ordinal_limit(til)\n current_index = -1\n current_named_type = None\n\n while current_index < max_ord - 1:\n current_index += 1\n tinfo = ida_typeinf.tinfo_t()\n if tinfo.get_numbered_type(til, current_index):\n print(f\"Type - id {tinfo.get_tid()}\")\n\n while True:\n if current_named_type is None:\n current_named_type = ida_typeinf.first_named_type(til, ida_typeinf.NTF_TYPE)\n else:\n current_named_type = ida_typeinf.next_named_type(til, current_named_type, ida_typeinf.NTF_TYPE)\n\n if not current_named_type:\n break\n\n tinfo = ida_typeinf.tinfo_t()\n if tinfo.get_named_type(til, current_named_type):\n print(f\"Type - name {tinfo.get_type_name()}, id {tinfo.get_tid()}\")\n\n # Iterate comments\n for ea in idautils.Heads(min_ea, max_ea):\n cmt = idc.get_cmt(ea, 0)\n if cmt:\n print(f\"Comment - value {cmt}\")\n\n # Iterate strings\n for s in idautils.Strings():\n print(f\"String - value {s}\")\n\n for ea, name in idautils.Names():\n print(f\"Name - value {name}\")\n\n # Iterate basic blocks\n for func_ea in idautils.Functions():\n func = ida_funcs.get_func(func_ea)\n if func:\n fc = idaapi.FlowChart(func)\n for b in fc:\n print(f\"Basic block - start ea {hex(b.start_ea)}, end ea {hex(b.end_ea)}\")\n\n # Iterate binary instructions\n for ea in idautils.Heads(min_ea, max_ea):\n if ida_bytes.is_code(ida_bytes.get_flags(ea)):\n disasm = idc.generate_disasm_line(ea, 0)\n print(f\"Instruction - ea {hex(ea)}, asm {disasm}\")\n\n # Close database discarding the changes\n idapro.close_database(False)"
3
+
4
+ setup(
5
+ name="idapro",
6
+ version="0.0.3.dev1",
7
+ author="Hex-Rays SA",
8
+ author_email="support@hex-rays.com",
9
+ description="IDA Library Python module",
10
+ long_description=f"""
11
+ # IDA Library Python Module
12
+ \n**⚠️ This is a dev pre-release version. APIs may change without notice and pre-release versions may be deleted at any time.**
13
+
14
+
15
+ The IDA Library Python module enables running IDA Pro as an independent Python package outside the IDA UI environment, allowing for programmatic binary analysis and reverse engineering tasks.
16
+
17
+
18
+ ## Prerequisites
19
+
20
+ ### Environment Setup
21
+
22
+ Set the `IDADIR` environment variable to point to your IDA installation directory:
23
+
24
+ **Linux/macOS:**
25
+ ```bash
26
+ export IDADIR="/path/to/your/ida/installation"
27
+ ```
28
+
29
+ **Windows:**
30
+ ```cmd
31
+ set IDADIR="C:\Program Files\IDA Pro 9.1"
32
+ ```
33
+
34
+ **Example paths:**
35
+ - **macOS:** `/Applications/IDA Professional 9.1.app/Contents/MacOS/`
36
+ - **Windows:** `C:\Program Files\IDA Pro 9.1\`
37
+ - **Linux:** `/opt/ida-9.1/`
38
+
39
+ > **Note:** If you have already installed and configured the `idapro` Python package in the past using script provided with IDA installation package, setting `IDADIR` is not required.
40
+
41
+ ## Usage example:
42
+
43
+ ```python
44
+ {example_code}
45
+ ```
46
+
47
+ ## Troubleshooting
48
+
49
+ ### Common Issues
50
+
51
+ **ModuleNotFoundError: No module named 'idapro'**
52
+ - Ensure `IDADIR` is set correctly
53
+ - Verify IDA Pro is properly installed
54
+
55
+ **License Issues**
56
+ - Ensure you have a valid IDA Pro license
57
+ - Check that IDA can run normally in GUI mode first
58
+
59
+ ## API Reference
60
+
61
+ For detailed API documentation, refer to:
62
+ - IDA Python documentation at https://python.docs.hex-rays.com/
63
+ - Built-in help: `help(idapro)` after importing
64
+ - IDA Pro SDK documentation https://docs.hex-rays.com/developer-guide/c++-sdk
65
+
66
+ """,
67
+ long_description_content_type="text/markdown",
68
+ license="MIT",
69
+ classifiers=[
70
+ "Development Status :: 2 - Pre-Alpha",
71
+ "License :: OSI Approved :: MIT License",
72
+ "Programming Language :: Python :: 3",
73
+ "Operating System :: OS Independent",
74
+ "Topic :: Software Development :: Disassemblers",
75
+ ],
76
+ python_requires=">=3.8",
77
+ packages=["idapro"],
78
+ zip_safe=False,
79
+ )
idapro-0.0.0/PKG-INFO DELETED
@@ -1,5 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: idapro
3
- Version: 0.0.0
4
- Summary: Coming soon
5
- Author-email: Hex-Rays SA <support@hex-rays.com>
File without changes
@@ -1,5 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: idapro
3
- Version: 0.0.0
4
- Summary: Coming soon
5
- Author-email: Hex-Rays SA <support@hex-rays.com>
@@ -1,8 +0,0 @@
1
- [project]
2
- name = "idapro"
3
- version = "0.0.0"
4
- description = "Coming soon"
5
-
6
- [[project.authors]]
7
- name = "Hex-Rays SA"
8
- email = "support@hex-rays.com"
File without changes