Skip to content

Commit 7e92f6a

Browse files
gssincla-gcopybara-github
authored andcommitted
Update BinExport to work with both IDA8.x and IDA9 SDKs
PiperOrigin-RevId: 745123129 Change-Id: I1bf58e70c2d78d65cba3ef5b27d0932773c6ced8
1 parent b77ade3 commit 7e92f6a

File tree

3 files changed

+180
-96
lines changed

3 files changed

+180
-96
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ Install the latest stable version of CMake:
265265
```bash
266266
wget https://github.com/Kitware/CMake/releases/download/v3.25.1/cmake-3.25.1-linux-x86_64.sh
267267
mkdir ${HOME}/cmake
268-
sh cmake-3.25.1-Linux-x86_64.sh --prefix=${HOME}/cmake --exclude-subdir
268+
sh cmake-3.25.1-linux-x86_64.sh --prefix=${HOME}/cmake --exclude-subdir
269269
export PATH=${HOME}/cmake/bin:${PATH}
270270
```
271271

cmake/FindIdaSdk.cmake

Lines changed: 167 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2011-2024 Google LLC
1+
# Copyright 2011-2025 Google LLC
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License");
44
# you may not use this file except in compliance with the License.
@@ -32,6 +32,7 @@
3232
# This module reads hints about search locations from variables:
3333
#
3434
# IdaSdk_ROOT_DIR - Preferred installation prefix
35+
# IdaSdk_ASSUME_VERSION8 - Force the module to use IDA 8.x SDK
3536
#
3637
# Example (this assumes Windows):
3738
#
@@ -81,6 +82,24 @@ find_package_handle_standard_args(IdaSdk
8182
FAIL_MESSAGE "IDA SDK not found, try setting IdaSdk_ROOT_DIR"
8283
)
8384

85+
# Determine the IDA SDK version
86+
set(IDA_SDK_VERSION 999) # Preload to IDA9 as a fail-safe
87+
if(NOT IdaSdk_ASSUME_VERSION8)
88+
find_file(version_file "pro.h" ${IdaSdk_INCLUDE_DIRS})
89+
if(EXISTS ${version_file})
90+
file(STRINGS "${version_file}" contents REGEX "#define IDA_SDK_VERSION ")
91+
if(contents MATCHES "#define IDA_SDK_VERSION[ ]+([0-9]+)")
92+
set(IDA_SDK_VERSION "${CMAKE_MATCH_1}")
93+
endif()
94+
else()
95+
message(STATUS "unable to find IDA Version file: ${version_file}")
96+
endif()
97+
else()
98+
set(IDA_SDK_VERSION 840)
99+
endif()
100+
101+
message(STATUS "IDA_SDK_VERSION = ${IDA_SDK_VERSION}")
102+
84103
# Define some platform specific variables for later use.
85104
set(_so "${CMAKE_SHARED_LIBRARY_SUFFIX}")
86105
set(_so64 "64${CMAKE_SHARED_LIBRARY_SUFFIX}") # An additional "64"
@@ -104,90 +123,138 @@ if(APPLE)
104123

105124
# Not using find_library(), as static-lib search might be enforced in
106125
# calling project.
107-
_ida_get_libpath_suffixes(_ida64_x64_suffixes "x64_mac_clang_64")
108-
find_path(IdaSdk_LIBPATH64_X64 libida64.dylib
109-
PATHS "${IdaSdk_DIR}/lib" PATH_SUFFIXES ${_ida64_x64_suffixes}
110-
NO_DEFAULT_PATH REQUIRED
111-
)
112-
_ida_get_libpath_suffixes(_ida64_arm64_suffixes "arm64_mac_clang_64")
113-
find_path(IdaSdk_LIBPATH64_ARM64 libida64.dylib
114-
PATHS "${IdaSdk_DIR}/lib" PATH_SUFFIXES ${_ida64_arm64_suffixes}
115-
NO_DEFAULT_PATH REQUIRED
116-
)
117-
if(NOT TARGET ida64_universal)
118-
set(_ida64_universal_lib
119-
"${CMAKE_CURRENT_BINARY_DIR}/libida64_universal.dylib"
120-
CACHE INTERNAL ""
126+
if(IDA_SDK_VERSION LESS 900)
127+
_ida_get_libpath_suffixes(_ida64_x64_suffixes "x64_mac_clang_64")
128+
find_path(IdaSdk_LIBPATH64_X64 libida64.dylib
129+
PATHS "${IdaSdk_DIR}/lib" PATH_SUFFIXES ${_ida64_x64_suffixes}
130+
NO_DEFAULT_PATH REQUIRED
121131
)
122-
# Create a new "universal" library to allow the linker to select the
123-
# correct one per architecture. Ideally, Hex Rays would just compile
124-
# libida64.dylib as a universal bundle.
125-
add_custom_target(ida64_universal
126-
DEPENDS "${IdaSdk_LIBPATH64_ARM64}/libida64.dylib"
127-
"${IdaSdk_LIBPATH64_X64}/libida64.dylib"
128-
BYPRODUCTS "${_ida64_universal_lib}"
129-
COMMAND lipo -create "${IdaSdk_LIBPATH64_ARM64}/libida64.dylib"
130-
"${IdaSdk_LIBPATH64_X64}/libida64.dylib"
131-
-output "${_ida64_universal_lib}"
132+
_ida_get_libpath_suffixes(_ida64_arm64_suffixes "arm64_mac_clang_64")
133+
find_path(IdaSdk_LIBPATH64_ARM64 libida64.dylib
134+
PATHS "${IdaSdk_DIR}/lib" PATH_SUFFIXES ${_ida64_arm64_suffixes}
135+
NO_DEFAULT_PATH REQUIRED
132136
)
133-
endif()
134-
add_library(ida64 SHARED IMPORTED)
135-
add_dependencies(ida64 ida64_universal)
136-
set_target_properties(ida64 PROPERTIES
137-
IMPORTED_LOCATION "${_ida64_universal_lib}"
138-
)
139-
140-
_ida_get_libpath_suffixes(_ida32_x64_suffixes "x64_mac_clang_32")
141-
find_path(IdaSdk_LIBPATH32_X64 libida.dylib
142-
PATHS "${IdaSdk_DIR}/lib" PATH_SUFFIXES ${_ida32_x64_suffixes}
143-
NO_DEFAULT_PATH REQUIRED
144-
)
145-
_ida_get_libpath_suffixes(_ida32_arm64_suffixes "arm64_mac_clang_32")
146-
find_path(IdaSdk_LIBPATH32_ARM64 libida.dylib
147-
PATHS "${IdaSdk_DIR}/lib" PATH_SUFFIXES ${_ida32_arm64_suffixes}
148-
NO_DEFAULT_PATH REQUIRED
149-
)
150-
if(NOT TARGET ida32_universal)
151-
set(_ida32_universal_lib
152-
"${CMAKE_CURRENT_BINARY_DIR}/libida32_universal.dylib"
153-
CACHE INTERNAL ""
137+
if(NOT TARGET ida64_universal)
138+
set(_ida64_universal_lib
139+
"${CMAKE_CURRENT_BINARY_DIR}/libida64_universal.dylib"
140+
CACHE INTERNAL ""
141+
)
142+
# Create a new "universal" library to allow the linker to select the
143+
# correct one per architecture. Ideally, Hex Rays would just compile
144+
# libida64.dylib as a universal bundle.
145+
add_custom_target(ida64_universal
146+
DEPENDS "${IdaSdk_LIBPATH64_ARM64}/libida64.dylib"
147+
"${IdaSdk_LIBPATH64_X64}/libida64.dylib"
148+
BYPRODUCTS "${_ida64_universal_lib}"
149+
COMMAND lipo -create "${IdaSdk_LIBPATH64_ARM64}/libida64.dylib"
150+
"${IdaSdk_LIBPATH64_X64}/libida64.dylib"
151+
-output "${_ida64_universal_lib}"
152+
)
153+
endif()
154+
add_library(ida64 SHARED IMPORTED)
155+
add_dependencies(ida64 ida64_universal)
156+
set_target_properties(ida64 PROPERTIES
157+
IMPORTED_LOCATION "${_ida64_universal_lib}"
158+
)
159+
_ida_get_libpath_suffixes(_ida32_x64_suffixes "x64_mac_clang_32")
160+
find_path(IdaSdk_LIBPATH32_X64 libida.dylib
161+
PATHS "${IdaSdk_DIR}/lib" PATH_SUFFIXES ${_ida32_x64_suffixes}
162+
NO_DEFAULT_PATH REQUIRED
154163
)
155-
add_custom_target(ida32_universal
156-
DEPENDS "${IdaSdk_LIBPATH32_ARM64}/libida.dylib"
157-
"${IdaSdk_LIBPATH32_X64}/libida.dylib"
158-
BYPRODUCTS "${_ida32_universal_lib}"
159-
COMMAND lipo -create "${IdaSdk_LIBPATH32_ARM64}/libida.dylib"
160-
"${IdaSdk_LIBPATH32_X64}/libida.dylib"
161-
-output "${_ida32_universal_lib}"
164+
_ida_get_libpath_suffixes(_ida32_arm64_suffixes "arm64_mac_clang_32")
165+
find_path(IdaSdk_LIBPATH32_ARM64 libida.dylib
166+
PATHS "${IdaSdk_DIR}/lib" PATH_SUFFIXES ${_ida32_arm64_suffixes}
167+
NO_DEFAULT_PATH REQUIRED
162168
)
169+
if(NOT TARGET ida32_universal)
170+
set(_ida32_universal_lib
171+
"${CMAKE_CURRENT_BINARY_DIR}/libida32_universal.dylib"
172+
CACHE INTERNAL ""
173+
)
174+
add_custom_target(ida32_universal
175+
DEPENDS "${IdaSdk_LIBPATH32_ARM64}/libida.dylib"
176+
"${IdaSdk_LIBPATH32_X64}/libida.dylib"
177+
BYPRODUCTS "${_ida32_universal_lib}"
178+
COMMAND lipo -create "${IdaSdk_LIBPATH32_ARM64}/libida.dylib"
179+
"${IdaSdk_LIBPATH32_X64}/libida.dylib"
180+
-output "${_ida32_universal_lib}"
181+
)
182+
endif()
183+
add_library(ida32 SHARED IMPORTED)
184+
add_dependencies(ida32 ida32_universal)
185+
set_target_properties(ida32 PROPERTIES
186+
IMPORTED_LOCATION "${_ida32_universal_lib}"
187+
)
188+
else() # IDA SDK 9.0+
189+
_ida_get_libpath_suffixes(_ida64_x64_suffixes "x64_mac_clang_64")
190+
find_path(IdaSdk_LIBPATH64_X64 libida.dylib
191+
PATHS "${IdaSdk_DIR}/lib" PATH_SUFFIXES ${_ida64_x64_suffixes}
192+
NO_DEFAULT_PATH REQUIRED
193+
)
194+
_ida_get_libpath_suffixes(_ida64_arm64_suffixes "arm64_mac_clang_64")
195+
find_path(IdaSdk_LIBPATH64_ARM64 libida.dylib
196+
PATHS "${IdaSdk_DIR}/lib" PATH_SUFFIXES ${_ida64_arm64_suffixes}
197+
NO_DEFAULT_PATH REQUIRED
198+
)
199+
if(NOT TARGET ida64_universal)
200+
set(_ida64_universal_lib
201+
"${CMAKE_CURRENT_BINARY_DIR}/libida_universal.dylib"
202+
CACHE INTERNAL ""
203+
)
204+
# Create a new "universal" library to allow the linker to select the
205+
# correct one per architecture. Ideally, Hex Rays would just compile
206+
# libida64.dylib as a universal bundle.
207+
add_custom_target(ida64_universal
208+
DEPENDS "${IdaSdk_LIBPATH64_ARM64}/libida.dylib"
209+
"${IdaSdk_LIBPATH64_X64}/libida.dylib"
210+
BYPRODUCTS "${_ida64_universal_lib}"
211+
COMMAND lipo -create "${IdaSdk_LIBPATH64_ARM64}/libida.dylib"
212+
"${IdaSdk_LIBPATH64_X64}/libida.dylib"
213+
-output "${_ida64_universal_lib}"
214+
)
215+
endif()
216+
add_library(ida SHARED IMPORTED)
217+
add_dependencies(ida ida64_universal)
218+
set_target_properties(ida PROPERTIES
219+
IMPORTED_LOCATION "${_ida64_universal_lib}"
220+
)
221+
163222
endif()
164-
add_library(ida32 SHARED IMPORTED)
165-
add_dependencies(ida32 ida32_universal)
166-
set_target_properties(ida32 PROPERTIES
167-
IMPORTED_LOCATION "${_ida32_universal_lib}"
168-
)
223+
169224
elseif(UNIX)
170225
set(IdaSdk_PLATFORM __LINUX__)
171226

172-
_ida_get_libpath_suffixes(_ida64_suffixes "x64_linux_gcc_64")
173-
find_path(IdaSdk_LIBPATH64 libida64.so
174-
PATHS "${IdaSdk_DIR}/lib" PATH_SUFFIXES ${_ida64_suffixes}
175-
NO_DEFAULT_PATH REQUIRED
176-
)
177-
add_library(ida64 SHARED IMPORTED)
178-
set_target_properties(ida64 PROPERTIES
179-
IMPORTED_LOCATION "${IdaSdk_LIBPATH64}/libida64.so"
180-
)
227+
if(IDA_SDK_VERSION LESS 900)
228+
_ida_get_libpath_suffixes(_ida64_suffixes "x64_linux_gcc_64")
229+
find_path(IdaSdk_LIBPATH64 libida64.so
230+
PATHS "${IdaSdk_DIR}/lib" PATH_SUFFIXES ${_ida64_suffixes}
231+
NO_DEFAULT_PATH REQUIRED
232+
)
233+
add_library(ida64 SHARED IMPORTED)
234+
set_target_properties(ida64 PROPERTIES
235+
IMPORTED_LOCATION "${IdaSdk_LIBPATH64}/libida64.so"
236+
)
237+
_ida_get_libpath_suffixes(_ida32_suffixes "x64_linux_gcc_32")
238+
find_path(IdaSdk_LIBPATH32 libida.so
239+
PATHS "${IdaSdk_DIR}/lib" PATH_SUFFIXES ${_ida32_suffixes}
240+
NO_DEFAULT_PATH REQUIRED
241+
)
242+
add_library(ida32 SHARED IMPORTED)
243+
set_target_properties(ida32 PROPERTIES
244+
IMPORTED_LOCATION "${IdaSdk_LIBPATH32}/libida.so"
245+
)
246+
else()
247+
_ida_get_libpath_suffixes(_ida64_suffixes "x64_linux_gcc_64")
248+
find_path(IdaSdk_LIBPATH64 libida.so
249+
PATHS "${IdaSdk_DIR}/lib" PATH_SUFFIXES ${_ida64_suffixes}
250+
NO_DEFAULT_PATH REQUIRED
251+
)
252+
add_library(ida64 SHARED IMPORTED)
253+
set_target_properties(ida64 PROPERTIES
254+
IMPORTED_LOCATION "${IdaSdk_LIBPATH64}/libida.so"
255+
)
256+
endif()
181257

182-
_ida_get_libpath_suffixes(_ida32_suffixes "x64_linux_gcc_32")
183-
find_path(IdaSdk_LIBPATH32 libida.so
184-
PATHS "${IdaSdk_DIR}/lib" PATH_SUFFIXES ${_ida32_suffixes}
185-
NO_DEFAULT_PATH REQUIRED
186-
)
187-
add_library(ida32 SHARED IMPORTED)
188-
set_target_properties(ida32 PROPERTIES
189-
IMPORTED_LOCATION "${IdaSdk_LIBPATH32}/libida.so"
190-
)
191258
elseif(WIN32)
192259
set(IdaSdk_PLATFORM __NT__)
193260

@@ -200,14 +267,16 @@ elseif(WIN32)
200267
set_target_properties(ida64 PROPERTIES IMPORTED_LOCATION "${IdaSdk_LIB64}")
201268
set_target_properties(ida64 PROPERTIES IMPORTED_IMPLIB "${IdaSdk_LIB64}")
202269

203-
_ida_get_libpath_suffixes(_ida32_suffixes "x64_win_vc_32")
204-
find_library(IdaSdk_LIB32 ida
205-
PATHS "${IdaSdk_DIR}/lib" PATH_SUFFIXES ${_ida32_suffixes}
206-
NO_DEFAULT_PATH REQUIRED
207-
)
208-
add_library(ida32 SHARED IMPORTED)
209-
set_target_properties(ida32 PROPERTIES IMPORTED_LOCATION "${IdaSdk_LIB32}")
210-
set_target_properties(ida32 PROPERTIES IMPORTED_IMPLIB "${IdaSdk_LIB32}")
270+
if(IDA_SDK_VERSION LESS 900)
271+
_ida_get_libpath_suffixes(_ida32_suffixes "x64_win_vc_32")
272+
find_library(IdaSdk_LIB32 ida
273+
PATHS "${IdaSdk_DIR}/lib" PATH_SUFFIXES ${_ida32_suffixes}
274+
NO_DEFAULT_PATH REQUIRED
275+
)
276+
add_library(ida32 SHARED IMPORTED)
277+
set_target_properties(ida32 PROPERTIES IMPORTED_LOCATION "${IdaSdk_LIB32}")
278+
set_target_properties(ida32 PROPERTIES IMPORTED_IMPLIB "${IdaSdk_LIB32}")
279+
endif()
211280
else()
212281
message(FATAL_ERROR "Unsupported system type: ${CMAKE_SYSTEM_NAME}")
213282
endif()
@@ -222,7 +291,8 @@ function(_ida_common_target_settings t ea64)
222291
__X64__
223292
__IDP__
224293
USE_DANGEROUS_FUNCTIONS
225-
USE_STANDARD_FILE_FUNCTIONS)
294+
USE_STANDARD_FILE_FUNCTIONS
295+
IDA_SDK_VERSION=${IDA_SDK_VERSION})
226296
target_include_directories(${t} PUBLIC "${IdaSdk_INCLUDE_DIRS}")
227297
endfunction()
228298

@@ -286,8 +356,10 @@ function(add_ida_library name)
286356
cmake_parse_arguments(PARSE_ARGV 1 opt "NOEA32;NOEA64" "" "")
287357
_ida_check_bitness(opt_NOEA32 opt_NOEA64)
288358

289-
if(NOT DEFINED(opt_NOEA32))
290-
_ida_library(${name} FALSE ${opt_UNPARSED_ARGUMENTS})
359+
if(IDA_SDK_VERSION LESS 900)
360+
if(NOT DEFINED(opt_NOEA32))
361+
_ida_library(${name} FALSE ${opt_UNPARSED_ARGUMENTS})
362+
endif()
291363
endif()
292364
if(NOT DEFINED(opt_NOEA64))
293365
_ida_library(${name} TRUE ${opt_UNPARSED_ARGUMENTS})
@@ -298,8 +370,10 @@ function(add_ida_plugin name)
298370
cmake_parse_arguments(PARSE_ARGV 1 opt "NOEA32;NOEA64" "" "")
299371
_ida_check_bitness(opt_NOEA32 opt_NOEA64)
300372

301-
if(NOT opt_NOEA32)
302-
_ida_plugin(${name} FALSE plugins/exports.def ${opt_UNPARSED_ARGUMENTS})
373+
if(IDA_SDK_VERSION LESS 900)
374+
if(NOT opt_NOEA32)
375+
_ida_plugin(${name} FALSE plugins/exports.def ${opt_UNPARSED_ARGUMENTS})
376+
endif()
303377
endif()
304378
if(NOT opt_NOEA64)
305379
_ida_plugin(${name} TRUE plugins/exports.def ${opt_UNPARSED_ARGUMENTS})
@@ -310,8 +384,10 @@ function(add_ida_loader name)
310384
cmake_parse_arguments(PARSE_ARGV 1 opt "NOEA32;NOEA64" "" "")
311385
_ida_check_bitness(opt_NOEA32 opt_NOEA64)
312386

313-
if(NOT opt_NOEA32)
314-
_ida_plugin(${name} FALSE ldr/exports.def ${opt_UNPARSED_ARGUMENTS})
387+
if(IDA_SDK_VERSION LESS 900)
388+
if(NOT opt_NOEA32)
389+
_ida_plugin(${name} FALSE ldr/exports.def ${opt_UNPARSED_ARGUMENTS})
390+
endif()
315391
endif()
316392
if(NOT opt_NOEA64)
317393
_ida_plugin(${name} TRUE ldr/exports.def ${opt_UNPARSED_ARGUMENTS})

util/idb_export.cc

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,24 @@ void IdbExporter::AddDatabase(std::string path) {
5353

5454
absl::Status ExportDatabase(const std::string& idb_path,
5555
const IdbExporter::Options& options) {
56-
const bool is_64bit = absl::EndsWithIgnoreCase(idb_path, kIdbExtension64);
5756
// Check existence first to avoid running IDA needlessly.
5857
if (!FileExists(idb_path)) {
5958
return absl::NotFoundError(absl::StrCat("File not found: " + idb_path));
6059
}
6160

62-
#ifdef _WIN32
63-
const std::string ida_exe = is_64bit ? "ida64.exe" : "ida.exe";
61+
#if IDA_SDK_VERSION < 900
62+
const bool is_64bit = absl::EndsWithIgnoreCase(idb_path, kIdbExtension64);
63+
#ifdef _WIN32
64+
const std::string ida_exe = is_64bit ? "ida64.exe" : "ida.exe";
65+
#else
66+
const std::string ida_exe = is_64bit ? "ida64" : "ida";
67+
#endif
6468
#else
65-
const std::string ida_exe = is_64bit ? "ida64" : "ida";
69+
#ifdef _WIN32
70+
const std::string ida_exe = "ida.exe";
71+
#else
72+
const std::string ida_exe = "ida";
73+
#endif
6674
#endif
6775
std::vector<std::string> args;
6876
args.push_back(JoinPath(options.ida_dir, ida_exe));

0 commit comments

Comments
 (0)