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.
- idapro-0.0.3.dev1/LICENSE +21 -0
- idapro-0.0.3.dev1/PKG-INFO +213 -0
- idapro-0.0.3.dev1/README.md +69 -0
- idapro-0.0.3.dev1/idapro/__init__.py +118 -0
- idapro-0.0.3.dev1/idapro/config.py +82 -0
- idapro-0.0.3.dev1/idapro.egg-info/PKG-INFO +213 -0
- {idapro-0.0.0 → idapro-0.0.3.dev1}/idapro.egg-info/SOURCES.txt +5 -1
- idapro-0.0.3.dev1/idapro.egg-info/not-zip-safe +1 -0
- idapro-0.0.3.dev1/setup.py +79 -0
- idapro-0.0.0/PKG-INFO +0 -5
- idapro-0.0.0/idapro/__init__.py +0 -0
- idapro-0.0.0/idapro.egg-info/PKG-INFO +0 -5
- idapro-0.0.0/pyproject.toml +0 -8
- {idapro-0.0.0 → idapro-0.0.3.dev1}/idapro.egg-info/dependency_links.txt +0 -0
- {idapro-0.0.0 → idapro-0.0.3.dev1}/idapro.egg-info/top_level.txt +0 -0
- {idapro-0.0.0 → idapro-0.0.3.dev1}/setup.cfg +0 -0
|
@@ -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
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -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
idapro-0.0.0/idapro/__init__.py
DELETED
|
File without changes
|
idapro-0.0.0/pyproject.toml
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|