Skip to content
This repository has been archived by the owner on Sep 23, 2019. It is now read-only.

Commit

Permalink
Began work on IDA 7.0 support
Browse files Browse the repository at this point in the history
- Support to build as 64-bit
- Renamed `IDA_ARCH_64` to `IDA_EA_64`
  - Better distinction from `IDA_BINARY_64`
- Added new plugin extensions
- Added new executable name
- Began adding support for linkage against Qt libs that newly ship with the SDK
  - Not quite working, yet
  • Loading branch information
athre0z committed Jul 29, 2017
1 parent 127b217 commit 4e7167a
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 67 deletions.
17 changes: 10 additions & 7 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@ def get_cmake_gen(target_version):
if os.name == 'posix':
return 'Unix Makefiles'
elif os.name == 'nt':
return 'Visual Studio ' + (
gen = 'Visual Studio ' + (
'10' if target_version[0] <= 6 and target_version[1] <= 8 else '14'
)
return (gen + ' Win64') if target_version >= (7, 0) else gen
else:
assert False

Expand Down Expand Up @@ -93,8 +94,9 @@ def get_install_solution_arguments():

)
target_args.add_argument(
'--arch', '-a', required=False, choices=[32, 64], type=int,
help='The IDA architecture to build for. If omitted, build both.'
'--ea', required=False, choices=[32, 64], type=int,
help='The IDA variant (ida/ida64, sizeof(ea_t) == 4/8) to build for. '
'If omitted, build both.'
)

parser.add_argument(
Expand Down Expand Up @@ -141,8 +143,8 @@ def print_usage(error=None):
#
# Build targets
#
for arch in (args.arch,) if args.arch else (32, 64):
build_dir = 'build-{}.{}-{}'.format(*(target_version + (arch,)))
for ea in (args.ea,) if args.ea else (32, 64):
build_dir = 'build-{}.{}-{}'.format(*(target_version + (ea,)))
try:
os.mkdir(build_dir)
except OSError as e:
Expand All @@ -155,14 +157,15 @@ def print_usage(error=None):
'-DIDA_SDK=' + args.ida_sdk,
'-G', get_cmake_gen(target_version),
'-DIDA_VERSION={}{:02}'.format(*target_version),
'-DIDA_BINARY_64=' + ('ON' if target_version >= (7, 0) else 'OFF')
]

if args.idaq_path:
cmake_cmd.append('-DIDA_INSTALL_DIR=' + args.idaq_path)
cmake_cmd.append('-DCMAKE_INSTALL_PREFIX=' + args.idaq_path)

if arch == 64:
cmake_cmd.append('-DIDA_ARCH_64=TRUE')
if ea == 64:
cmake_cmd.append('-DIDA_EA_64=TRUE')

cmake_cmd.append('..')

Expand Down
166 changes: 106 additions & 60 deletions cmake/IDA.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ cmake_policy(SET CMP0054 NEW)
# Overridable options #
# =============================================================================================== #

set(IDA_ARCH_64 OFF CACHE BOOL "Build for 64 bit IDA" )
set(IDA_SDK "" CACHE PATH "Path to IDA SDK" )
set(IDA_INSTALL_DIR "" CACHE PATH "Install path of IDA" )
set(IDA_VERSION 690 CACHE INT "IDA Version to build for (e.g. 6.9 is 690).")
set(IDA_ENABLE_QT_SUPPORT OFF CACHE BOOL "Enable support for building plugins with Qt")
set(IDA_BINARY_64 OFF CACHE BOOL "Build a 64 bit binary (IDA >= 7.0)" )
set(IDA_EA_64 OFF CACHE BOOL "Build for 64 bit IDA (ida64, sizeof(ea_t) == 8)")
set(IDA_SDK "" CACHE PATH "Path to IDA SDK" )
set(IDA_INSTALL_DIR "" CACHE PATH "Install path of IDA" )
set(IDA_VERSION 690 CACHE INT "IDA Version to build for (e.g. 6.9 is 690)." )
set(IDA_ENABLE_QT_SUPPORT OFF CACHE BOOL "Enable support for building plugins with Qt" )

# =============================================================================================== #
# General preparation #
Expand All @@ -44,14 +45,20 @@ set(ida_cmakelist_path ${CMAKE_CURRENT_LIST_DIR})

# Library dependencies and include pathes
if (WIN32)
if (IDA_ARCH_64)
set(ida_lib_path_arch "64")
if (IDA_EA_64)
set(ida_lib_path_ea "64")
else ()
set(ida_lib_path_arch "32")
set(ida_lib_path_ea "32")
endif ()

if (IDA_BINARY_64)
set(ida_lib_path_binarch "x64")
else ()
set(ida_lib_path_binarch "x64")
endif ()

# On Windows, we use HR's lib files shipped with the SDK.
set(IDA_LIB_DIR "${IDA_SDK}/lib/x86_win_vc_${ida_lib_path_arch}"
set(IDA_LIB_DIR "${IDA_SDK}/lib/${ida_lib_path_binarch}_win_vc_${ida_lib_path_ea}"
CACHE PATH "IDA SDK library path" FORCE)

message(STATUS "IDA library path: ${IDA_LIB_DIR}")
Expand All @@ -67,11 +74,13 @@ if (WIN32)
list(APPEND ida_libraries ${IDA_PRO_LIBRARY})
endif ()
elseif (UNIX)
set(CMAKE_C_FLAGS "-m32" CACHE STRING "C compiler flags" FORCE)
set(CMAKE_CXX_FLAGS "-m32" CACHE STRING "C++ compiler flags" FORCE)
if (NOT IDA_BINARY_64)
set(CMAKE_C_FLAGS "-m32" CACHE STRING "C compiler flags" FORCE)
set(CMAKE_CXX_FLAGS "-m32" CACHE STRING "C++ compiler flags" FORCE)
endif ()

# On unixoid platforms, we link against IDA directly.
if (IDA_ARCH_64)
if (IDA_EA_64)
find_library(IDA_IDA_LIBRARY NAMES "ida64" PATHS ${IDA_INSTALL_DIR} REQUIRED)
else ()
find_library(IDA_IDA_LIBRARY NAMES "ida" PATHS ${IDA_INSTALL_DIR} REQUIRED)
Expand All @@ -96,32 +105,35 @@ if (IDA_ENABLE_QT_SUPPORT)
set(ida_qt_major 5)
endif ()

# On macOS, we can look up the path of each Qt library inside the IDA installation.
if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
foreach(qtlib Gui;Core;Widgets)
file(GLOB_RECURSE qtlibpaths "${IDA_INSTALL_DIR}/../Frameworks/Qt${qtlib}")
# Typically we will find exactly 2 paths to the libfile on macOS because of
# how the framework versioning works. Either one is fine, so pick the first.
# On unixes, we link against the Qt libs that ship with IDA.
# On Windows with IDA versions >= 7.0, link against .libs in IDA SDK.
if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
(${CMAKE_SYSTEM_NAME} STREQUAL "Windows" AND NOT ${IDA_VERSION} LESS 700))
if (ida_qt_major EQUAL 5)
set(ida_qt_libs "Gui;Core;Widgets;PrintSupport")
else ()
set(ida_qt_libs "Gui;Core")
endif ()

if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
set(ida_qt_glob_path "${IDA_INSTALL_DIR}/../Frameworks/Qt@QTLIB@")
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set(ida_qt_glob_path "${IDA_INSTALL_DIR}/libQt5@QTLIB@.so*")
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
set(ida_qt_glob_path "${IDA_SDK}/lib/x64_win_qt/Qt5@QTLIB@.lib")
endif ()

foreach(cur_lib ${ida_qt_libs})
string(REPLACE "@QTLIB@" ${cur_lib} cur_glob_path ${ida_qt_glob_path})
file(GLOB_RECURSE qtlibpaths ${cur_glob_path})
# On some platforms, we will find more than one libfile here.
# Either one is fine, just pick the first.
foreach(p ${qtlibpaths})
set(IDA_Qt${qtlib}_LIBRARY ${p} CACHE FILEPATH "Path to IDA's Qt${qtlib}")
set(IDA_Qt${cur_lib}_LIBRARY ${p} CACHE FILEPATH "Path to IDA's Qt${cur_lib}")
break()
endforeach()
endforeach()
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
if (ida_qt_major EQUAL 5)
foreach(qtlib Gui;Core;Widgets)
set(IDA_Qt${qtlib}_LIBRARY
"${IDA_INSTALL_DIR}/libQt5${qtlib}.so.5"
CACHE FILEPATH "Path to IDA's Qt ${qtlib}")
endforeach()
else ()
foreach(qtlib Gui;Core)
set(IDA_Qt${qtlib}_LIBRARY
"${IDA_INSTALL_DIR}/libQt{qtlib}.so.4"
CACHE FILEPATH "Path to IDA's Qt ${qtlib}")
endforeach()
endif()
endif()
endif ()

# Locate Qt.
if (ida_qt_major EQUAL 4)
Expand Down Expand Up @@ -158,31 +170,59 @@ function (add_ida_plugin plugin_name)

target_include_directories(${plugin_name} PUBLIC "${IDA_SDK}/include")

if (IDA_BINARY_64)
target_compile_definitions(${plugin_name} PUBLIC "__X64__")
endif ()

# OS specific stuff.
if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
target_compile_definitions(${plugin_name} PUBLIC "__NT__")

if (IDA_ARCH_64)
set(plugin_extension ".p64")
else()
set(plugin_extension ".plw")
endif()
if (IDA_BINARY_64)
if (IDA_EA_64)
set(plugin_extension "64.dll")
else ()
set(plugin_extension ".dll")
endif ()
else ()
if (IDA_EA_64)
set(plugin_extension ".p64")
else()
set(plugin_extension ".plw")
endif()
endif ()
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
target_compile_definitions(${plugin_name} PUBLIC "__MAC__")

if (IDA_ARCH_64)
set(plugin_extension ".pmc64")
else()
set(plugin_extension ".pmc")
endif()
if (IDA_BINARY_64)
if (IDA_EA_64)
set(plugin_extension "64.dylib")
else ()
set(plugin_extension ".dylib")
endif ()
else ()
if (IDA_EA_64)
set(plugin_extension ".pmc64")
else()
set(plugin_extension ".pmc")
endif()
endif ()
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
target_compile_definitions(${plugin_name} PUBLIC "__LINUX__")

if (IDA_ARCH_64)
set(plugin_extension ".plx64")
else()
set(plugin_extension ".plx")
endif()
if (IDA_BINARY_64)
if (IDA_EA_64)
set(plugin_extension "64.so")
else ()
set(plugin_extension ".so")
endif ()
else ()
if (IDA_EA_64)
set(plugin_extension ".plx64")
else()
set(plugin_extension ".plx")
endif()
endif ()
endif ()

# Suppress "lib" prefix on Unix and alter the file extension.
Expand All @@ -191,7 +231,7 @@ function (add_ida_plugin plugin_name)
SUFFIX ${plugin_extension}
OUTPUT_NAME ${plugin_name})

if (IDA_ARCH_64)
if (IDA_EA_64)
target_compile_definitions(${plugin_name} PUBLIC "__EA64__")
endif ()

Expand All @@ -204,10 +244,18 @@ function (add_ida_plugin plugin_name)
# When generating for Visual Studio,
# generate user file for convenient debugging support.
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
if (IDA_ARCH_64)
set(idaq_exe "idaq64.exe")
if (IDA_VERSION LESS 700)
if (IDA_EA_64)
set(idaq_exe "idaq64.exe")
else ()
set(idaq_exe "idaq.exe")
endif ()
else ()
set(idaq_exe "idaq.exe")
if (IDA_EA_64)
set(idaq_exe "ida64.exe")
else ()
set(idaq_exe "ida.exe")
endif ()
endif ()

file(
Expand Down Expand Up @@ -263,26 +311,24 @@ function (add_ida_qt_plugin plugin_name)
# Link against Qt.
if (ida_qt_major EQUAL 4)
foreach (qtlib Core;Gui)
target_link_libraries(${CMAKE_PROJECT_NAME} "Qt4::Qt${qtlib}")
# On macs, we need to link to the frameworks in the IDA application folder
if ((${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") OR
(${CMAKE_SYSTEM_NAME} STREQUAL "Linux"))
# If we have a QtCore override path, we have override pathes for all libs.
if (DEFINED IDA_QtCore_LIBRARY)
set_target_properties(
"Qt4::Qt${qtlib}"
PROPERTIES
IMPORTED_LOCATION_RELEASE "${IDA_Qt${qtlib}_LIBRARY}")
endif ()
target_link_libraries(${CMAKE_PROJECT_NAME} "Qt4::Qt${qtlib}")
endforeach()
else ()
foreach (qtlib Core;Gui;Widgets)
target_link_libraries(${CMAKE_PROJECT_NAME} "Qt5::${qtlib}")
if ((${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") OR
(${CMAKE_SYSTEM_NAME} STREQUAL "Linux"))
if (DEFINED IDA_QtCore_LIBRARY)
set_target_properties(
"Qt5::${qtlib}"
PROPERTIES
IMPORTED_LOCATION_RELEASE "${IDA_Qt${qtlib}_LIBRARY}")
endif ()
target_link_libraries(${CMAKE_PROJECT_NAME} "Qt5::${qtlib}")
endforeach()
endif ()
endfunction ()

0 comments on commit 4e7167a

Please sign in to comment.