idalib: remove custom idalib loading

This commit is contained in:
Willi Ballenthin
2026-05-11 08:52:47 +02:00
committed by Willi Ballenthin
parent b5f81e30f0
commit 9ba497f6f7
5 changed files with 25 additions and 129 deletions
-99
View File
@@ -12,13 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import sys
import json
import logging
import importlib.util
from typing import Optional
from pathlib import Path
logger = logging.getLogger(__name__)
@@ -28,97 +23,3 @@ def is_idalib_installed() -> bool:
return importlib.util.find_spec("idapro") is not None
except ModuleNotFoundError:
return False
def get_idalib_user_config_path() -> Optional[Path]:
"""Get the path to the user's config file based on platform following IDA's user directories."""
# derived from `py-activate-idalib.py` from IDA v9.0 Beta 4
if sys.platform == "win32":
# On Windows, use the %APPDATA%\Hex-Rays\IDA Pro directory
config_dir = Path(os.getenv("APPDATA")) / "Hex-Rays" / "IDA Pro"
else:
# On macOS and Linux, use ~/.idapro
config_dir = Path.home() / ".idapro"
# Return the full path to the config file (now in JSON format)
user_config_path = config_dir / "ida-config.json"
if not user_config_path.exists():
return None
return user_config_path
def find_idalib() -> Optional[Path]:
config_path = get_idalib_user_config_path()
if not config_path:
logger.error("IDA Pro user configuration does not exist, please make sure you've installed idalib properly.")
return None
config = json.loads(config_path.read_text(encoding="utf-8"))
try:
ida_install_dir = Path(config["Paths"]["ida-install-dir"])
except KeyError:
logger.error(
"IDA Pro user configuration does not contain location of IDA Pro installation, please make sure you've installed idalib properly."
)
return None
if not ida_install_dir.exists():
return None
libname = {
"win32": "idalib.dll",
"linux": "libidalib.so",
"linux2": "libidalib.so",
"darwin": "libidalib.dylib",
}[sys.platform]
if not (ida_install_dir / "ida.hlp").is_file():
return None
if not (ida_install_dir / libname).is_file():
return None
idalib_path = ida_install_dir / "idalib" / "python"
if not idalib_path.exists():
return None
if not (idalib_path / "idapro" / "__init__.py").is_file():
return None
return idalib_path
def has_idalib() -> bool:
if is_idalib_installed():
logger.debug("found installed IDA idalib API")
return True
logger.debug("IDA idalib API not installed, searching...")
idalib_path = find_idalib()
if not idalib_path:
logger.debug("failed to find IDA idalib installation")
logger.debug("found IDA idalib API: %s", idalib_path)
return idalib_path is not None
def load_idalib() -> bool:
try:
import idapro
return True
except ImportError:
idalib_path = find_idalib()
if not idalib_path:
return False
sys.path.append(idalib_path.absolute().as_posix())
try:
import idapro # noqa: F401 unused import
return True
except ImportError:
return False
+2 -5
View File
@@ -386,11 +386,8 @@ def get_extractor(
elif backend == BACKEND_IDA:
import capa.features.extractors.ida.idalib as idalib
if not idalib.has_idalib():
raise RuntimeError("cannot find IDA idalib module.")
if not idalib.load_idalib():
raise RuntimeError("failed to load IDA idalib module.")
if not idalib.is_idalib_installed():
raise RuntimeError("idalib not available.")
import idapro
import ida_auto
+8 -3
View File
@@ -22,7 +22,7 @@ import rich
import rich.table
import capa.main
from capa.features.extractors.ida.idalib import find_idalib, load_idalib, is_idalib_installed
from capa.features.extractors.ida.idalib import is_idalib_installed
from capa.features.extractors.binja.find_binja_api import find_binaryninja, load_binaryninja, is_binaryninja_installed
logger = logging.getLogger(__name__)
@@ -101,9 +101,14 @@ def main(argv=None):
row.append("-")
else:
row.append("False")
row.append(str(find_idalib() is not None))
row.append("False")
row.append(str(load_idalib()))
does_idalib_load = False
try:
import idapro # noqa: F401 [imported but unused]
except ImportError:
does_idalib_load = True
row.append(str(does_idalib_load))
table.add_row(*row)
rich.print(table)
+2 -5
View File
@@ -894,11 +894,8 @@ def get_idalib_extractor(path: Path):
import capa.features.extractors.ida.idalib as idalib
import capa.features.extractors.ida.extractor
if not idalib.has_idalib():
raise RuntimeError("cannot find IDA idalib module.")
if not idalib.load_idalib():
raise RuntimeError("failed to load IDA idalib module.")
if not idalib.is_idalib_installed():
raise RuntimeError("idalib is not available.")
_check_stale_idalib_files(path)
+13 -17
View File
@@ -16,30 +16,26 @@ import logging
import pytest
import fixtures
import capa.features.extractors.ida.idalib as idalib
from capa.features.file import FunctionName
from capa.features.insn import API
from capa.features.common import Characteristic
logger = logging.getLogger(__name__)
idalib_present = idalib.has_idalib()
if idalib_present:
try:
if True:
# in order to use idalib, we have to import the idapro package
# which manipulates the search path as a side effect.
# we have to do this before importing ida_* packages.
# but isort wants to put idapro after ida_kernwin, so we use
# this dumb branch to keep the ordering correct.
import idapro # noqa: F401 [imported but unused]
import ida_kernwin
try:
if True:
# in order to use idalib, we have to import the idapro package
# which manipulates the search path as a side effect.
# we have to do this before importing ida_* packages.
# but isort wants to put idapro after ida_kernwin, so we use
# this dumb branch to keep the ordering correct.
import idapro # noqa: F401 [imported but unused]
import ida_kernwin
kernel_version: str = ida_kernwin.get_kernel_version()
except ImportError:
idalib_present = False
kernel_version = "0.0"
else:
kernel_version: str = ida_kernwin.get_kernel_version()
idalib_present = True
except ImportError:
idalib_present = False
kernel_version = "0.0"