From d76fb9c45eb991439c3d81abaae9badae874922d Mon Sep 17 00:00:00 2001 From: Camden Smallwood Date: Thu, 5 Mar 2026 20:14:38 -0500 Subject: [PATCH] Refactor for cross platform and add ida-cmake support (needs linux and windows testing) --- .gitignore | 2 + CMakeLists.txt | 90 ++++++++ Compat.h | 567 +++++++++++++++++++++++++++++++++++++++++++++++++ Main.cpp | 413 +++++++++++++++-------------------- Main.h | 31 +-- MainDialog.cpp | 39 ++-- MainDialog.h | 11 +- RTTI.cpp | 419 ++++++++++++++++++------------------ RTTI.h | 74 ++++--- StdAfx.h | 40 +++- Vftable.cpp | 33 +-- Vftable.h | 8 +- dialog.ui | 328 ++++++++++++---------------- 13 files changed, 1292 insertions(+), 763 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 Compat.h diff --git a/.gitignore b/.gitignore index 58203dc..c893c01 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,5 @@ x64/ # Plug-intro AnimBannerWidget.h + +build/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..6c640b6 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,90 @@ +cmake_minimum_required(VERSION 3.27 FATAL_ERROR) + +project(ida_class_informer) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_C_STANDARD 11) + +include($ENV{IDASDK}/ida-cmake/bootstrap.cmake) +find_package(idasdk REQUIRED) +find_package(Qt6 REQUIRED COMPONENTS Core Widgets) +set(CMAKE_AUTOMOC ON) + +set(SOURCES + Main.cpp + MainDialog.cpp + RTTI.cpp + Vftable.cpp +) + +set(HEADERS + StdAfx.h + Compat.h + Main.h + MainDialog.h + RTTI.h + Vftable.h +) + +set(UI_FILES + dialog.ui +) + +set(QRC_FILES + ClassInformerRes.qrc +) + +qt6_wrap_ui(UI_HEADERS ${UI_FILES}) +qt6_add_resources(QRC_SOURCES ${QRC_FILES} OPTIONS --no-zstd) + +# Use Homebrew Qt for headers/moc/uic/rcc but link against IDA's namespaced Qt frameworks +set(IDA_APP_FRAMEWORKS "/Applications/IDA Professional 9.2.app/Contents/Frameworks") + +ida_add_plugin(class_informer + SOURCES + ${SOURCES} + ${QRC_SOURCES} + ${UI_HEADERS} + INCLUDES + "${CMAKE_SOURCE_DIR}" + "${CMAKE_CURRENT_BINARY_DIR}" + LIBRARIES + "${IDA_APP_FRAMEWORKS}/QtCore.framework/Versions/A/QtCore" + "${IDA_APP_FRAMEWORKS}/QtGui.framework/Versions/A/QtGui" + "${IDA_APP_FRAMEWORKS}/QtWidgets.framework/Versions/A/QtWidgets" + DEFINES + QT_NAMESPACE=QT + QT_NO_VERSION_TAGGING +) + +# Still need Qt header include paths from Homebrew +target_include_directories(class_informer PRIVATE + ${Qt6Core_INCLUDE_DIRS} + ${Qt6Widgets_INCLUDE_DIRS} + ${Qt6Gui_INCLUDE_DIRS} +) + +# On macOS, rewrite Qt framework paths and rpaths so IDA's bundled Qt is used at runtime +if(APPLE) + add_custom_command(TARGET class_informer POST_BUILD + COMMAND install_name_tool -change + "/opt/homebrew/opt/qtbase/lib/QtWidgets.framework/Versions/A/QtWidgets" + "@rpath/QtWidgets.framework/Versions/A/QtWidgets" + "$" + COMMAND install_name_tool -change + "/opt/homebrew/opt/qtbase/lib/QtGui.framework/Versions/A/QtGui" + "@rpath/QtGui.framework/Versions/A/QtGui" + "$" + COMMAND install_name_tool -change + "/opt/homebrew/opt/qtbase/lib/QtCore.framework/Versions/A/QtCore" + "@rpath/QtCore.framework/Versions/A/QtCore" + "$" + COMMAND install_name_tool -delete_rpath + "/opt/homebrew/opt/qt/lib" + "$" 2>/dev/null || true + COMMAND install_name_tool -add_rpath + "@loader_path/../Frameworks" + "$" || true + COMMENT "Rewriting Qt framework paths to @rpath for IDA compatibility" + ) +endif() diff --git a/Compat.h b/Compat.h new file mode 100644 index 0000000..6104623 --- /dev/null +++ b/Compat.h @@ -0,0 +1,567 @@ + +// Cross-platform compatibility layer +// Replaces: Utility.h, undname.h, WaitBoxEx.h, IdaOgg.h, SegSelect.h +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +// IDA SDK +#include +#include +#include +#include +#include + +// ============================================================================ +// Windows type replacements +// ============================================================================ +#ifndef _WIN32 +typedef int32_t BOOL; +typedef uint32_t UINT32; +typedef uint64_t UINT64; +typedef int32_t INT32; +typedef int64_t INT64; +typedef uint16_t WORD; +typedef uint32_t DWORD; +typedef char* LPSTR; +typedef const char* LPCSTR; +typedef int32_t* PINT32; +typedef uint32_t* PDWORD; + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef NULL +#define NULL nullptr +#endif + +#define RGB(r,g,b) ((uint32_t)(((uint8_t)(r)) | (((uint32_t)(uint8_t)(g)) << 8) | (((uint32_t)(uint8_t)(b)) << 16))) +#define MAKEWORD(lo, hi) ((WORD)(((uint8_t)(lo)) | (((WORD)(uint8_t)(hi)) << 8))) +#define ZeroMemory(p, sz) memset((p), 0, (sz)) + +// SAL annotations (no-ops on non-MSVC) +#define __in +#define __out +#define __in_opt +#define __out_bcount(s) + +// MSVC safe string replacements +inline int sprintf_s(char* buf, size_t bufSize, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + int r = vsnprintf(buf, bufSize, fmt, args); + va_end(args); + return r; +} + +inline int _snprintf_s(char* buf, size_t bufSize, size_t maxCount, const char* fmt, ...) { + (void)maxCount; + va_list args; + va_start(args, fmt); + int r = vsnprintf(buf, bufSize, fmt, args); + va_end(args); + return r; +} + +inline int vsnprintf_s(char* buf, size_t bufSize, size_t maxCount, const char* fmt, va_list args) { + (void)maxCount; + return vsnprintf(buf, bufSize, fmt, args); +} + +inline errno_t strncpy_s(char* dest, size_t destSize, const char* src, size_t count) { + if (!dest || destSize == 0) return -1; + size_t n = (count < destSize - 1) ? count : destSize - 1; + strncpy(dest, src, n); + dest[n] = '\0'; + return 0; +} + +inline errno_t strncat_s(char* dest, size_t destSize, const char* src, size_t count) { + if (!dest || destSize == 0) return -1; + size_t dlen = strlen(dest); + size_t remaining = destSize - dlen - 1; + size_t n = (count < remaining) ? count : remaining; + strncat(dest, src, n); + return 0; +} + +inline char* _strlwr(char* str) { + for (char* p = str; *p; ++p) *p = (char)tolower((unsigned char)*p); + return str; +} + +inline errno_t strcpy_s(char* dest, size_t destSize, const char* src) { + if (!dest || destSize == 0) return -1; + strncpy(dest, src, destSize - 1); + dest[destSize - 1] = '\0'; + return 0; +} + +inline char* _itoa(int val, char* buf, int radix) { + if (radix == 10) { snprintf(buf, 64, "%d", val); return buf; } + if (radix == 16) { snprintf(buf, 64, "%x", val); return buf; } + snprintf(buf, 64, "%d", val); + return buf; +} + +#endif // !_WIN32 + +// Sign-extend uint32_t to int64_t (reinterpret as signed 32-bit then widen) +#define TO_INT64(_uint32) ((int64_t)(int32_t)(_uint32)) + +// ============================================================================ +// Common macros (needed on all platforms) +// ============================================================================ +#ifndef SIZESTR +#define SIZESTR(s) (sizeof(s) - 1) +#endif + +#ifndef _countof +#define _countof(arr) (sizeof(arr) / sizeof((arr)[0])) +#endif + +#ifndef IS_VALID_ADDR +#define IS_VALID_ADDR(ea) ((ea) != 0 && (ea) != BADADDR) +#endif + +#ifndef ALIGN + #ifdef _MSC_VER + #define ALIGN(n) __declspec(align(n)) + #else + #define ALIGN(n) __attribute__((aligned(n))) + #endif +#endif + +// _ASSERT: use cassert in debug, no-op in release +#ifdef _DEBUG + #define _ASSERT(expr) assert(expr) +#else + #define _ASSERT(expr) ((void)0) +#endif + +// CATCH macro for exception handling +#define CATCH() catch (...) { msg("** Exception in %s()! ***\n", __FUNCTION__); } + +// __LOC2__ for pragma message (MSVC only, no-op elsewhere) +#ifdef _MSC_VER + #define __LOC2__ __FILE__ "(" QSTRINGIZE(__LINE__) ")" + #define QSTRINGIZE(x) QSTRINGIZE2(x) + #define QSTRINGIZE2(x) #x +#endif + +// EA_32 type +typedef uint32_t EA_32; + +// ============================================================================ +// Timestamp / timing utilities +// ============================================================================ +typedef double TIMESTAMP; + +inline TIMESTAMP GetTimeStamp() +{ + return (double)clock() / (double)CLOCKS_PER_SEC; +} + +inline const char* TimeString(TIMESTAMP t) +{ + static char buf[64]; + if (t < 60.0) + snprintf(buf, sizeof(buf), "%.2f seconds", t); + else if (t < 3600.0) + snprintf(buf, sizeof(buf), "%.1f minutes", t / 60.0); + else + snprintf(buf, sizeof(buf), "%.1f hours", t / 3600.0); + return buf; +} + +// ============================================================================ +// Number/string formatting utilities +// ============================================================================ +inline const char* NumberCommaString(size_t n, char* buf) +{ + // Simple: just format with commas + char tmp[32]; + snprintf(tmp, sizeof(tmp), "%zu", n); + int len = (int)strlen(tmp); + int commas = (len - 1) / 3; + int total = len + commas; + buf[total] = '\0'; + int j = total - 1; + for (int i = len - 1, c = 0; i >= 0; i--, c++) { + if (c > 0 && c % 3 == 0) + buf[j--] = ','; + buf[j--] = tmp[i]; + } + return buf; +} + +inline const char* byteSizeString(asize_t size) +{ + static char buf[64]; + if (size < 1024) + snprintf(buf, sizeof(buf), "%u bytes", (unsigned)size); + else if (size < 1024 * 1024) + snprintf(buf, sizeof(buf), "%.1f KB", size / 1024.0); + else + snprintf(buf, sizeof(buf), "%.1f MB", size / (1024.0 * 1024.0)); + return buf; +} + +// Version string utilities +#ifndef MAKE_SEMANTIC_VERSION +#define VERSION_RELEASE 0 +#define MAKE_SEMANTIC_VERSION(type, major, minor, patch) \ + (((uint32_t)(major) << 16) | ((uint32_t)(minor) << 8) | (uint32_t)(patch)) +#endif + +inline qstring& GetVersionString(uint32_t ver, qstring& out) +{ + out.sprnt("%d.%d.%d", (ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF); + return out; +} + +// Format string for EA display with leading zeros +inline void GetEaFormatString(ea_t maxAddr, char* fmt) +{ + int digits = 0; + ea_t tmp = maxAddr; + while (tmp > 0) { digits++; tmp >>= 4; } + if (digits < 8) digits = 8; + if (digits > 16) digits = 16; +#ifdef __EA64__ + snprintf(fmt, 20, "%%0%d" FMT_64 "X", digits); +#else + snprintf(fmt, 20, "%%0%dX", digits); +#endif +} + +// ============================================================================ +// Binary pattern search wrapper +// ============================================================================ +inline ea_t findBinary(ea_t startEA, ea_t endEA, const char* pattern) +{ + compiled_binpat_vec_t bv; + if (!parse_binpat_str(&bv, startEA, pattern, 16)) + return BADADDR; + return bin_search(startEA, endEA, bv, BIN_SEARCH_FORWARD); +} +#define FIND_BINARY(start, end, pattern) findBinary(start, end, pattern) + +// ============================================================================ +// Platform abstraction (replaces Utility.h plat object) +// ============================================================================ +struct PlatformInfo +{ + bool is64; + int ptrSize; + + void Configure() + { + is64 = inf_is_64bit(); + ptrSize = is64 ? 8 : 4; + } + + ea_t getEa(ea_t addr) const + { + return is64 ? get_64bit(addr) : (ea_t)get_32bit(addr); + } + + ea_t getEa32(ea_t addr) const + { + return (ea_t)get_32bit(addr); + } + + bool isEa(flags_t flags) const + { + return is64 ? is_qword(flags) : is_dword(flags); + } + + bool isBadAddress(ea_t addr) const + { + return (addr == 0 || addr == BADADDR); + } +}; + +// Global platform instance +inline PlatformInfo& getPlatform() +{ + static PlatformInfo p; + return p; +} +#define plat getPlatform() + +// ============================================================================ +// WaitBox replacement (uses IDA's built-in wait box) +// ============================================================================ +namespace WaitBox +{ + inline void show(const char* /*title*/, const char* message, ...) + { + show_wait_box("%s", message); + } + + inline void hide() + { + hide_wait_box(); + } + + inline bool updateAndCancelCheck(int = 0) + { + return user_cancelled(); + } + + inline bool isUpdateTime() + { + // Throttle UI updates to avoid overhead + static clock_t last = 0; + clock_t now = clock(); + if ((now - last) > (CLOCKS_PER_SEC / 5)) // ~200ms + { + last = now; + return true; + } + return false; + } + + inline void processIdaEvents() + { + // Allow IDA to process pending UI events + request_refresh(IWID_ALL); + } +} + +// ============================================================================ +// SegSelect replacement (segment selection dialog using IDA's chooser) +// ============================================================================ +namespace SegSelect +{ + using segments = std::vector; + enum { DATA_HINT = 1, RDATA_HINT = 2 }; + + // Segment chooser that allows multi-selection + struct SegChooser : public chooser_multi_t + { + static const int widths_[]; + static const char *const header_[]; + + segments* result; + std::vector allSegs; + int hints; + + SegChooser(segments* out, int h, const char* ttl) + : chooser_multi_t(CH_MODAL | CH_KEEP, 4, widths_, header_, ttl), + result(out), hints(h) + { + for (int i = 0; i < get_segm_qty(); i++) + { + if (segment_t* seg = getnseg(i)) + allSegs.push_back(*seg); + } + } + + size_t idaapi get_count() const override { return allSegs.size(); } + + void idaapi get_row(qstrvec_t* cols, int* /*icon*/, chooser_item_attrs_t* /*attrs*/, + size_t n) const override + { + const segment_t& seg = allSegs[n]; + qstring name; + get_segm_name(&name, &seg); + + (*cols)[0] = name; + (*cols)[1].sprnt("%llX", (uint64_t)seg.start_ea); + (*cols)[2].sprnt("%llX", (uint64_t)seg.end_ea); + + switch (seg.type) + { + case SEG_DATA: (*cols)[3] = "DATA"; break; + case SEG_CODE: (*cols)[3] = "CODE"; break; + case SEG_BSS: (*cols)[3] = "BSS"; break; + default: (*cols)[3] = "OTHER"; break; + } + } + }; + + inline const int SegChooser::widths_[] = { 16, 16, 16, 8 }; + inline const char *const SegChooser::header_[] = { "Segment", "Start", "End", "Type" }; + + inline void select(segments& segs, int hints, const char* title) + { + SegChooser ch(&segs, hints, title); + + // Build default selection based on hints + sizevec_t deflt; + for (size_t i = 0; i < ch.allSegs.size(); i++) + { + bool preSelect = false; + if (hints & DATA_HINT) + preSelect |= (ch.allSegs[i].type == SEG_DATA); + if (hints & RDATA_HINT) + { + qstring name; + get_segm_name(&name, &ch.allSegs[i]); + qstrlwr(name.begin()); + preSelect |= (name.find("rdata") != qstring::npos); + } + if (preSelect) + deflt.push_back(i); + } + + ssize_t ret = ch.choose(deflt); + if (ret > 0) + { + // deflt now contains the user's selection + segs.clear(); + for (size_t idx : deflt) + { + if (idx < ch.allSegs.size()) + segs.push_back(ch.allSegs[idx]); + } + } + } +} + +// ============================================================================ +// OggPlay replacement (audio stubs - no audio on non-Windows) +// ============================================================================ +namespace OggPlay +{ + inline void endPlay() {} + inline void playFromMemory(const void*, size_t, bool) {} +} + +// ============================================================================ +// __unDName replacement using IDA's demangler +// ============================================================================ + +// Flags matching MSVC's undname constants +#ifndef UNDNAME_COMPLETE +#define UNDNAME_COMPLETE 0x00000 +#define UNDNAME_NO_LEADING_UNDERSCORES 0x00001 +#define UNDNAME_NO_MS_KEYWORDS 0x00002 +#define UNDNAME_NO_FUNCTION_RETURNS 0x00004 +#define UNDNAME_NO_ALLOCATION_MODEL 0x00008 +#define UNDNAME_NO_ALLOCATION_LANGUAGE 0x00010 +#define UNDNAME_NO_MS_THISTYPE 0x00020 +#define UNDNAME_NO_CV_THISTYPE 0x00040 +#define UNDNAME_NO_THISTYPE 0x00060 +#define UNDNAME_NO_ACCESS_SPECIFIERS 0x00080 +#define UNDNAME_NO_THROW_SIGNATURES 0x00100 +#define UNDNAME_NO_MEMBER_TYPE 0x00200 +#define UNDNAME_NO_RETURN_UDT_MODEL 0x00400 +#define UNDNAME_32_BIT_DECODE 0x00800 +#define UNDNAME_NAME_ONLY 0x01000 +#define UNDNAME_TYPE_ONLY 0x02000 +#define UNDNAME_HAVE_PARAMETERS 0x04000 +#define UNDNAME_NO_ECSU 0x08000 +#define UNDNAME_NO_IDENT_CHAR_CHECK 0x10000 +#endif + +typedef void* (*_Alloc)(uint32_t); +typedef void (*_Free)(void*); + +inline void* mallocWrap(uint32_t size) { return malloc(size); } + +// Decode MSVC type descriptor names (e.g. "?AVClassName@Namespace@@") +// These have the format: ?A[V|U|W4|T]name@scope@...@@ +// Returns the decoded name in result, or false if not a type descriptor +static inline bool decodeMsvcTypeDescriptor(const char* name, qstring& result) +{ + if (!name || name[0] != '?' || name[1] != 'A') + return false; + + const char* p = name + 2; + + // Skip type tag: V=class, U=struct, T=union, W4=enum + if (*p == 'V' || *p == 'U' || *p == 'T') + p++; + else if (*p == 'W' && *(p+1) == '4') + p += 2; + else + return false; + + // Parse name@scope@...@@ -> scope::...::name + // Collect components separated by '@', terminated by '@@' + std::vector parts; + while (*p && !(*p == '@' && *(p+1) == '@')) + { + const char* start = p; + while (*p && *p != '@') + p++; + if (p > start) + parts.push_back(qstring(start, p - start)); + if (*p == '@') + p++; + } + + if (parts.empty()) + return false; + + // Build result in reverse order (innermost scope last in mangled form) + result.clear(); + for (int i = (int)parts.size() - 1; i >= 0; i--) + { + if (!result.empty()) + result.append("::"); + result.append(parts[i]); + } + return true; +} + +// Cross-platform __unDName replacement +// Handles both full mangled names (via IDA's demangler) and MSVC type +// descriptors (via our own decoder, since IDA's demangler doesn't handle those) +inline char* __unDName(char* buffer, const char* name, int sizeBuffer, + _Alloc /*allocator*/, _Free /*_free*/, uint32_t flags) +{ + qstring result; + bool decoded = false; + + // Try MSVC type descriptor format first (used with UNDNAME_TYPE_ONLY) + if (flags & UNDNAME_TYPE_ONLY) + decoded = decodeMsvcTypeDescriptor(name, result); + + // Fall back to IDA's demangler for full mangled names + if (!decoded) + { + uint32_t inhibit = MNG_SHORT_FORM; + if (demangle_name(&result, name, inhibit, DQT_FULL) < 0) + return nullptr; + decoded = true; + } + + // If UNDNAME_NO_ECSU requested, strip "class ", "struct ", "union ", "enum " prefix + if (decoded && (flags & UNDNAME_NO_ECSU)) + { + const char* s = result.c_str(); + if (strncmp(s, "class ", 6) == 0) result.remove(0, 6); + else if (strncmp(s, "struct ", 7) == 0) result.remove(0, 7); + else if (strncmp(s, "union ", 6) == 0) result.remove(0, 6); + else if (strncmp(s, "enum ", 5) == 0) result.remove(0, 5); + } + + if (decoded && !result.empty()) + { + if (buffer) + { + qstrncpy(buffer, result.c_str(), sizeBuffer); + return buffer; + } + else + { + char* s = (char*)malloc(result.length() + 1); + if (s) strcpy(s, result.c_str()); + return s; + } + } + return nullptr; +} diff --git a/Main.cpp b/Main.cpp index 9dd7ec4..2657653 100644 --- a/Main.cpp +++ b/Main.cpp @@ -1,14 +1,11 @@ // Class Informer -#include "stdafx.h" +#include "StdAfx.h" #include "Main.h" #include "Vftable.h" #include "RTTI.h" #include "MainDialog.h" #include -// -#include -#include // Netnode constants const static char NETNODE_NAME[] = {"$ClassInformer_node"}; @@ -27,10 +24,10 @@ enum NETINDX struct TBLENTRY { ea_t vft; - WORD methods; - WORD flags; - WORD strSize; - char str[MAXSPECSIZE - (sizeof(ea_t) + (sizeof(WORD) * 3))]; // Note: IDA MAXSTR = 1024 + uint16_t methods; + uint16_t flags; + uint16_t strSize; + char str[MAXSPECSIZE - (sizeof(ea_t) + (sizeof(uint16_t) * 3))]; // Note: IDA MAXSTR = 1024 }; #pragma pack(pop) static_assert(sizeof(TBLENTRY) == MAXSPECSIZE); @@ -42,16 +39,15 @@ static const bgcolor_t NOT_PARENT_COLOR = GRAY(235); // === Function Prototypes === static void cacheSegments(); -static BOOL processStaticTables(); +static bool processStaticTables(); static void showEndStats(); -static BOOL gatherRttiDataSet(SegSelect::segments &segs); +static bool gatherRttiDataSet(SegSelect::segments &segs); // === Data === static TIMESTAMP s_startTime = 0; -static HMODULE myModuleHandle = NULL; -static UINT32 staticCCtorCnt = 0, staticCppCtorCnt = 0, staticCDtorCnt = 0; -static UINT32 startingFuncCount = 0, staticCtorDtorCnt = 0; -static BOOL initResourcesOnce = FALSE; +static uint32_t staticCCtorCnt = 0, staticCppCtorCnt = 0, staticCDtorCnt = 0; +static uint32_t startingFuncCount = 0, staticCtorDtorCnt = 0; +static bool initResourcesOnce = false; static int chooserIcon = 0; static netnode *netNode = NULL; static std::vector segmentCache; @@ -64,15 +60,15 @@ extern eaSet superSet, colSet, vftSet; // "_initterm*" Static ctor/dtor pattern container struct INITTERM_ARGPAT { - LPCSTR pattern; - UINT32 start, end; + const char *pattern; + uint32_t start, end; }; std::vector initTermArgPatterns; // Options -BOOL g_optionPlaceStructs = TRUE; -BOOL g_optionProcessStatic = TRUE; -BOOL g_optionAudioOnDone = TRUE; +bool g_optionPlaceStructs = true; +bool g_optionProcessStatic = true; +bool g_optionAudioOnDone = true; static void freeWorkingData() { @@ -98,7 +94,6 @@ plugmod_t* idaapi init() char procName[IDAINFO_PROCNAME_SIZE + 1] = { 0 }; if(inf_get_procname(procName, sizeof(procName)) && (strncmp(procName, "metapc", IDAINFO_PROCNAME_SIZE) == 0)) { - GetModuleHandleEx((GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS), (LPCTSTR) &init, &myModuleHandle); return PLUGIN_KEEP; } @@ -123,7 +118,7 @@ void idaapi term() } Q_CLEANUP_RESOURCE(ClassInformerRes); - initResourcesOnce = FALSE; + initResourcesOnce = false; } } CATCH() @@ -143,14 +138,14 @@ static void newNetnodeStore() netNode->altset_idx8(NIDX_COUNT, 0, NN_DATA_TAG); } -static WORD getStoreVersion(){ return((WORD) netNode->altval_idx8(NIDX_VERSION, NN_DATA_TAG)); } -static UINT32 getTableCount(){ return(netNode->altval_idx8(NIDX_COUNT, NN_DATA_TAG)); } -static BOOL setTableCount(UINT32 count){ return(netNode->altset_idx8(NIDX_COUNT, count, NN_DATA_TAG)); } -static BOOL getTableEntry(TBLENTRY &entry, UINT32 index){ return(netNode->supval(index, &entry, sizeof(TBLENTRY), NN_TABLE_TAG) > 0); } -static BOOL setTableEntry(TBLENTRY &entry, UINT32 index){ return(netNode->supset(index, &entry, (offsetof(TBLENTRY, str) + entry.strSize), NN_TABLE_TAG)); } +static uint16_t getStoreVersion(){ return((uint16_t) netNode->altval_idx8(NIDX_VERSION, NN_DATA_TAG)); } +static uint32_t getTableCount(){ return((uint32_t)netNode->altval_idx8(NIDX_COUNT, NN_DATA_TAG)); } +static bool setTableCount(uint32_t count){ return(netNode->altset_idx8(NIDX_COUNT, count, NN_DATA_TAG)); } +static bool getTableEntry(TBLENTRY &entry, uint32_t index){ return(netNode->supval(index, &entry, sizeof(TBLENTRY), NN_TABLE_TAG) > 0); } +static bool setTableEntry(TBLENTRY &entry, uint32_t index){ return(netNode->supset(index, &entry, (offsetof(TBLENTRY, str) + entry.strSize), NN_TABLE_TAG)); } // Add an entry to the vftable list -void addTableEntry(UINT32 flags, ea_t vft, int methodCount, LPCSTR format, ...) +void addTableEntry(uint32_t flags, ea_t vft, int methodCount, const char *format, ...) { TBLENTRY e; e.vft = vft; @@ -159,11 +154,11 @@ void addTableEntry(UINT32 flags, ea_t vft, int methodCount, LPCSTR format, ...) va_list vl; va_start(vl, format); - vsnprintf_s(e.str, sizeof(e.str), SIZESTR(e.str), format, vl); + vsnprintf(e.str, sizeof(e.str), format, vl); va_end(vl); - e.strSize = (WORD) (strlen(e.str) + 1); + e.strSize = (uint16_t) (strlen(e.str) + 1); - UINT32 count = getTableCount(); + uint32_t count = getTableCount(); setTableEntry(e, count); setTableCount(++count); } @@ -171,7 +166,7 @@ void addTableEntry(UINT32 flags, ea_t vft, int methodCount, LPCSTR format, ...) // RTTI list chooser static const char LBTITLE[] = { "[Class Informer]" }; -static const UINT32 LBCOLUMNCOUNT = 5; +static const uint32_t LBCOLUMNCOUNT = 5; static const int LBWIDTHS[LBCOLUMNCOUNT] = { (8 | CHCOL_HEX), (4 | CHCOL_DEC), 3, 19, 500 }; static const char *const LBHEADER[LBCOLUMNCOUNT] = { @@ -188,9 +183,9 @@ class rtti_chooser : public chooser_multi_t rtti_chooser() : chooser_multi_t(CH_QFTYP_DEFAULT, LBCOLUMNCOUNT, LBWIDTHS, LBHEADER, LBTITLE) { // Create a minimal hex address format string w/leading zero - UINT32 count = getTableCount(); + uint32_t count = getTableCount(); ea_t largestAddres = 0; - for (UINT32 i = 0; i < count; i++) + for (uint32_t i = 0; i < count; i++) { TBLENTRY e; e.vft = 0; getTableEntry(e, i); @@ -219,7 +214,7 @@ class rtti_chooser : public chooser_multi_t { // Generate the line TBLENTRY e; - getTableEntry(e, (UINT32)n); + getTableEntry(e, (uint32_t)n); // vft address qstrvec_t &cols = *cols_; @@ -241,12 +236,12 @@ class rtti_chooser : public chooser_multi_t cols[2] = flags; // Type - LPCSTR tag = strchr(e.str, '@'); + const char *tag = strchr(e.str, '@'); if (tag) { char buffer[MAXSTR]; - int pos = (tag - e.str); - if (pos > SIZESTR(buffer)) pos = SIZESTR(buffer); + int pos = (int)(tag - e.str); + if (pos > (int)SIZESTR(buffer)) pos = (int)SIZESTR(buffer); memcpy(buffer, e.str, pos); buffer[pos] = 0; cols[3] = buffer; @@ -279,7 +274,7 @@ class rtti_chooser : public chooser_multi_t if (n < get_count()) { TBLENTRY e; - getTableEntry(e, (UINT32)n); + getTableEntry(e, (uint32_t)n); jumpto(e.vft); } return NOTHING_CHANGED; @@ -296,7 +291,7 @@ class rtti_chooser : public chooser_multi_t // Locate Qt widget by class name -static QWidget *findChildByClass(QWidgetList &wl, LPCSTR className) +static QWidget *findChildByClass(QWidgetList &wl, const char *className) { Q_FOREACH(QWidget *w, wl) { @@ -314,7 +309,7 @@ void customizeChooseWindow() try { QApplication::processEvents(); - + // Mod the chooser view QWidgetList pl = QApplication::activeWindow()->findChildren("[Class Informer]"); if (QWidget *dw = findChildByClass(pl, "TChooser")) @@ -338,8 +333,8 @@ void customizeChooseWindow() tv->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); // Tweak the row height - UINT32 count = getTableCount(); - for (UINT32 row = 0; row < count; row++) + uint32_t count = getTableCount(); + for (uint32_t row = 0; row < count; row++) tv->setRowHeight(row, 24); } else @@ -358,7 +353,7 @@ bool idaapi run(size_t arg) if (!auto_is_ok()) { msg("** Class Informer: Must wait for IDA to finish processing before starting plug-in! **\n*** Aborted ***\n\n"); - return TRUE; + return true; } WaitBox::processIdaEvents(); @@ -367,7 +362,7 @@ bool idaapi run(size_t arg) if (!initResourcesOnce) { - initResourcesOnce = TRUE; + initResourcesOnce = true; QResource::registerResource(":/resources.qrc"); QFile file(QT_RES_PATH "icon.png"); @@ -380,24 +375,24 @@ bool idaapi run(size_t arg) OggPlay::endPlay(); freeWorkingData(); - g_optionAudioOnDone = TRUE; - g_optionProcessStatic = TRUE; - g_optionPlaceStructs = TRUE; - startingFuncCount = (UINT32) get_func_qty(); + g_optionAudioOnDone = true; + g_optionProcessStatic = true; + g_optionPlaceStructs = true; + startingFuncCount = (uint32_t) get_func_qty(); staticCppCtorCnt = staticCCtorCnt = staticCtorDtorCnt = staticCDtorCnt = 0; colList.clear(); // Create storage netnode - if(!(netNode = new netnode(NETNODE_NAME, SIZESTR(NETNODE_NAME), TRUE))) + if(!(netNode = new netnode(NETNODE_NAME, SIZESTR(NETNODE_NAME), true))) { - _ASSERT(FALSE); - return TRUE; + _ASSERT(false); + return true; } // Read existing storage if any - UINT32 tableCount = getTableCount(); - WORD storageVersion = getStoreVersion(); - BOOL storageExists = (tableCount > 0); + uint32_t tableCount = getTableCount(); + uint16_t storageVersion = getStoreVersion(); + bool storageExists = (tableCount > 0); // Ask if we should use storage or process again if (storageExists) @@ -406,13 +401,13 @@ bool idaapi run(size_t arg) if (storageVersion != DB_FORMAT_VERSION) { msg("* Storage version mismatch, must rescan *\n"); - storageExists = FALSE; + storageExists = false; } else storageExists = (ask_yn(1, "TITLE Class Informer \nHIDECANCEL\nUse previously stored result? ") == 1); } - BOOL aborted = FALSE; + bool aborted = false; if(!storageExists) { newNetnodeStore(); @@ -422,11 +417,11 @@ bool idaapi run(size_t arg) if (cmp != COMP_MS) { msg("** IDA reports target compiler: \"%s\"\n", get_compiler_name(cmp)); - int iResult = ask_buttons(NULL, NULL, NULL, 0, "TITLE Class Informer\nHIDECANCEL\nIDA reports this IDB's compiler as: \"%s\" \n\nThis plug-in only understands MS Visual C++ targets.\nRunning it on other targets (like Borland© compiled, etc.) will have unpredicted results. \n\nDo you want to continue anyhow?", get_compiler_name(cmp)); + int iResult = ask_buttons(NULL, NULL, NULL, 0, "TITLE Class Informer\nHIDECANCEL\nIDA reports this IDB's compiler as: \"%s\" \n\nThis plug-in only understands MS Visual C++ targets.\nRunning it on other targets (like Borland compiled, etc.) will have unpredicted results. \n\nDo you want to continue anyhow?", get_compiler_name(cmp)); if (iResult != 1) { msg("- Aborted -\n\n"); - return TRUE; + return true; } } @@ -436,7 +431,7 @@ bool idaapi run(size_t arg) { msg("- Canceled -\n\n"); freeWorkingData(); - return TRUE; + return true; } WaitBox::show("Class Informer", "Please wait..", "url(" QT_RES_PATH "progress-style.qss)", QT_RES_PATH "icon.png"); @@ -446,10 +441,10 @@ bool idaapi run(size_t arg) try { // Add RTTI type definitions to IDA once per session - static BOOL createStructsOnce = FALSE; + static bool createStructsOnce = false; if (g_optionPlaceStructs && !createStructsOnce) { - createStructsOnce = TRUE; + createStructsOnce = true; RTTI::addDefinitionsToIda(); } @@ -485,12 +480,12 @@ bool idaapi run(size_t arg) if (file.open(QFile::ReadOnly)) { QByteArray ba = file.readAll(); - OggPlay::playFromMemory((const PVOID)ba.constData(), ba.size(), TRUE); + OggPlay::playFromMemory((const void *)ba.constData(), ba.size(), true); } } } - showEndStats(); + showEndStats(); } } } @@ -501,7 +496,7 @@ bool idaapi run(size_t arg) if (aborted) { msg("- Aborted -\n\n"); - return TRUE; + return true; } } @@ -517,7 +512,7 @@ bool idaapi run(size_t arg) } CATCH() - return TRUE; + return true; } // Print out end stats @@ -526,9 +521,9 @@ static void showEndStats() try { msg("\n-------------------------------------------------\n"); - char buffer[32]; + char buffer[32]; msg("RTTI vftables located: %s\n", NumberCommaString(getTableCount(), buffer)); - UINT32 functionsFixed = ((UINT32) get_func_qty() - startingFuncCount); + uint32_t functionsFixed = ((uint32_t) get_func_qty() - startingFuncCount); if(functionsFixed) msg("Missing functions fixed: %s\n", NumberCommaString(functionsFixed, buffer)); @@ -541,11 +536,11 @@ static void showEndStats() // ================================================================================================ // Fix/create label and comment C/C++ initializer tables -static void setIntializerTable(ea_t start, ea_t end, BOOL isCpp) +static void setIntializerTable(ea_t start, ea_t end, bool isCpp) { try { - if (UINT32 count = ((end - start) / plat.ptrSize)) + if (uint32_t count = ((end - start) / plat.ptrSize)) { // Set table elements as pointers ea_t ea = start; @@ -565,9 +560,9 @@ static void setIntializerTable(ea_t start, ea_t end, BOOL isCpp) { char name[MAXSTR]; if (isCpp) - sprintf_s(name, sizeof(name), "__xc_a_%d", staticCppCtorCnt); + snprintf(name, sizeof(name), "__xc_a_%d", staticCppCtorCnt); else - sprintf_s(name, sizeof(name), "__xi_a_%d", staticCCtorCnt); + snprintf(name, sizeof(name), "__xi_a_%d", staticCCtorCnt); setName(start, name); } @@ -576,9 +571,9 @@ static void setIntializerTable(ea_t start, ea_t end, BOOL isCpp) { char name[MAXSTR]; if (isCpp) - sprintf_s(name, sizeof(name), "__xc_z_%d", staticCppCtorCnt); + snprintf(name, sizeof(name), "__xc_z_%d", staticCppCtorCnt); else - sprintf_s(name, sizeof(name), "__xi_z_%d", staticCCtorCnt); + snprintf(name, sizeof(name), "__xi_z_%d", staticCCtorCnt); setName(end, name); } @@ -598,14 +593,14 @@ static void setIntializerTable(ea_t start, ea_t end, BOOL isCpp) if (isCpp) { char comment[MAXSTR]; - sprintf_s(comment, sizeof(comment), "%d C++ static ctors (#classinformer)", count); - setComment(start, comment, TRUE); + snprintf(comment, sizeof(comment), "%d C++ static ctors (#classinformer)", count); + setComment(start, comment, true); } else { char comment[MAXSTR]; - sprintf_s(comment, sizeof(comment), "%d C initializers (#classinformer)", count); - setComment(start, comment, TRUE); + snprintf(comment, sizeof(comment), "%d C initializers (#classinformer)", count); + setComment(start, comment, true); } } @@ -623,7 +618,7 @@ static void setTerminatorTable(ea_t start, ea_t end) { try { - if (UINT32 count = ((end - start) / plat.ptrSize)) + if (uint32_t count = ((end - start) / plat.ptrSize)) { // Set table elements as pointers ea_t ea = start; @@ -643,7 +638,7 @@ static void setTerminatorTable(ea_t start, ea_t end) if (!hasName(start)) { char name[MAXSTR]; - _snprintf_s(name, sizeof(name), SIZESTR(name), "__xt_a_%d", staticCDtorCnt); + snprintf(name, sizeof(name), "__xt_a_%d", staticCDtorCnt); setName(start, name); } @@ -651,7 +646,7 @@ static void setTerminatorTable(ea_t start, ea_t end) if (!hasName(end)) { char name[MAXSTR]; - _snprintf_s(name, sizeof(name), SIZESTR(name), "__xt_z_%d", staticCDtorCnt); + snprintf(name, sizeof(name), "__xt_z_%d", staticCDtorCnt); setName(end, name); } @@ -664,8 +659,8 @@ static void setTerminatorTable(ea_t start, ea_t end) if (!hasComment(start)) { char comment[MAXSTR]; - _snprintf_s(comment, sizeof(comment), SIZESTR(comment), "%d C terminators (#classinformer)", count); - setComment(start, comment, TRUE); + snprintf(comment, sizeof(comment), "%d C terminators (#classinformer)", count); + setComment(start, comment, true); } staticCDtorCnt++; @@ -679,7 +674,7 @@ static void setCtorDtorTable(ea_t start, ea_t end) { try { - if (UINT32 count = ((end - start) / plat.ptrSize)) + if (uint32_t count = ((end - start) / plat.ptrSize)) { // Set table elements as pointers ea_t ea = start; @@ -699,7 +694,7 @@ static void setCtorDtorTable(ea_t start, ea_t end) if (!hasName(start)) { char name[MAXSTR]; - _snprintf_s(name, sizeof(name), SIZESTR(name), "__x?_a_%d", staticCtorDtorCnt); + snprintf(name, sizeof(name), "__x?_a_%d", staticCtorDtorCnt); setName(start, name); } @@ -707,7 +702,7 @@ static void setCtorDtorTable(ea_t start, ea_t end) if (!hasName(end)) { char name[MAXSTR]; - _snprintf_s(name, sizeof(name), SIZESTR(name), "__x?_z_%d", staticCtorDtorCnt); + snprintf(name, sizeof(name), "__x?_z_%d", staticCtorDtorCnt); setName(end, name); } @@ -720,8 +715,8 @@ static void setCtorDtorTable(ea_t start, ea_t end) if (!hasComment(start)) { char comment[MAXSTR]; - _snprintf_s(comment, sizeof(comment), SIZESTR(comment), "%d C initializers/terminators (#classinformer)", count); - setComment(start, comment, TRUE); + snprintf(comment, sizeof(comment), "%d C initializers/terminators (#classinformer)", count); + setComment(start, comment, true); } staticCtorDtorCnt++; @@ -742,21 +737,21 @@ static void processRegisterInitterm(ea_t start, ea_t end, ea_t call) if ((startSeg && endSeg) && (startSeg == endSeg)) { if (start > end) - swap_t(start, end); + std::swap(start, end); msg(" %llX to %llX CTOR table.\n", start, end); - setIntializerTable(start, end, TRUE); + setIntializerTable(start, end, true); if(!hasComment(call)) - setComment(call, "_initterm", TRUE); + setComment(call, "_initterm", true); } else msg(" ** Bad address range of %llX, %llX for \"_initterm\" type ** .\n", start, end); } } -static UINT32 doInittermTable(func_t *func, ea_t start, ea_t end, LPCSTR name) +static uint32_t doInittermTable(func_t *func, ea_t start, ea_t end, const char *name) { - UINT32 found = FALSE; + uint32_t found = false; if ((start != BADADDR) && (end != BADADDR)) { @@ -766,7 +761,7 @@ static UINT32 doInittermTable(func_t *func, ea_t start, ea_t end, LPCSTR name) if ((startSeg && endSeg) && (startSeg == endSeg)) { if (start > end) - swap_t(start, end); + std::swap(start, end); // Try to determine if we are in dtor or ctor section if (func) @@ -782,8 +777,8 @@ static UINT32 doInittermTable(func_t *func, ea_t start, ea_t end, LPCSTR name) if (strstr(funcName, "cinit") || strstr(funcName, "tmaincrtstartup") || strstr(funcName, "start")) { msg(" %llX to %llX CTOR table.\n", start, end); - setIntializerTable(start, end, TRUE); - found = TRUE; + setIntializerTable(start, end, true); + found = true; } else // Exit/dtor function? @@ -791,7 +786,7 @@ static UINT32 doInittermTable(func_t *func, ea_t start, ea_t end, LPCSTR name) { msg(" %llX to %llX DTOR table.\n", start, end); setTerminatorTable(start, end); - found = TRUE; + found = true; } } } @@ -801,7 +796,7 @@ static UINT32 doInittermTable(func_t *func, ea_t start, ea_t end, LPCSTR name) // Fall back to generic assumption msg(" %llX to %llX CTOR/DTOR table.\n", start, end); setCtorDtorTable(start, end); - found = TRUE; + found = true; } } else @@ -814,11 +809,11 @@ static UINT32 doInittermTable(func_t *func, ea_t start, ea_t end, LPCSTR name) } // Process _initterm function -// Returns TRUE if at least one found -static BOOL processInitterm(ea_t address, LPCSTR name) +// Returns true if at least one found +static bool processInitterm(ea_t address, const char *name) { msg("%llX process initterm: \"%s\" \n", address, name); - UINT32 count = 0; + uint32_t count = 0; // Walk xrefs ea_t xref = get_first_fcref_to(address); @@ -848,9 +843,9 @@ static BOOL processInitterm(ea_t address, LPCSTR name) break; } - BOOL matched = FALSE; - UINT32 patternCount = (UINT32) initTermArgPatterns.size(); - for (UINT32 i = 0; (i < patternCount) && !matched; i++) + bool matched = false; + uint32_t patternCount = (uint32_t) initTermArgPatterns.size(); + for (uint32_t i = 0; (i < patternCount) && !matched; i++) { ea_t match = FIND_BINARY(instruction2, xref, initTermArgPatterns[i].pattern); if (match != BADADDR) @@ -863,44 +858,24 @@ static BOOL processInitterm(ea_t address, LPCSTR name) } else { - UINT32 startOffset = get_32bit(instruction1 + initTermArgPatterns[i].start); - UINT32 endOffset = get_32bit(instruction2 + initTermArgPatterns[i].end); + uint32_t startOffset = get_32bit(instruction1 + initTermArgPatterns[i].start); + uint32_t endOffset = get_32bit(instruction2 + initTermArgPatterns[i].end); - start = (instruction1 + 7 + *((PINT32) &startOffset)); // TODO: 7 is hard coded instruction length, put this in arg2pat table? - end = (instruction2 + 7 + *((PINT32) &endOffset)); + start = (instruction1 + 7 + *((int32_t *) &startOffset)); // TODO: 7 is hard coded instruction length, put this in arg2pat table? + end = (instruction2 + 7 + *((int32_t *) &endOffset)); } msg(" %llX Two instruction pattern match #%d\n", match, i); count += doInittermTable(func, start, end, name); - matched = TRUE; + matched = true; break; } } - // 3 instruction - /* - searchStart = prev_head(searchStart, BADADDR); - if (searchStart == BADADDR) - break; - if (func && (searchStart < func->start_ea)) - break; - - if (func && (searchStart < func->start_ea)) - { - msg(" %llX arg3 outside of contained function **\n", func->start_ea); - break; - } - - .text:10008F78 push offset unk_1000B1B8 - .text:10008F7D push offset unk_1000B1B0 - .text:10008F82 mov dword_1000F83C, 1 - "68 ?? ?? ?? ?? 68 ?? ?? ?? ?? C7 05 ?? ?? ?? ?? ?? ?? ?? ??" - */ - if (!matched) msg(" ** arguments not located!\n"); - } while (FALSE); + } while (false); } else msg(" %llX ** \"%s\" xref is not code! **\n", xref, name); @@ -939,7 +914,7 @@ static void cacheSegments() { if (segment_t *seg = getnseg(i)) { - UINT32 type = 0; + uint32_t type = 0; if (seg->type == SEG_DATA) type |= _DATA_SEG; else @@ -993,8 +968,8 @@ const SEGMENT *FindCachedSegment(ea_t addr) } // Process global/static ctor & dtor tables. -// Returns TRUE if user aborted -static BOOL processStaticTables() +// Returns true if user aborted +static bool processStaticTables() { staticCppCtorCnt = staticCCtorCnt = staticCtorDtorCnt = staticCDtorCnt = 0; @@ -1021,7 +996,7 @@ static BOOL processStaticTables() } // Locate _initterm() and _initterm_e() functions - static LPCSTR inittermNames[] = { "_initterm", "_initterm_e" }; + static const char *inittermNames[] = { "_initterm", "_initterm_e" }; std::map inittermMap; for (size_t i = 0; i < _countof(inittermNames); i++) { @@ -1046,63 +1021,18 @@ static BOOL processStaticTables() } } - // There are cases there there are local enumerated versions like "_initterm_0", etc., that we could handle - // So keeping the loop here for future expansion - #if 0 - UINT32 funcCount = (UINT32) get_func_qty(); - for (UINT32 i = 0; i < funcCount; i++) - { - if (func_t *func = getn_func(i)) - { - qstring qstr; - if (get_long_name(&qstr, func->start_ea) > 0) - { - char name[MAXSTR]; - strncpy_s(name, MAXSTR, qstr.c_str(), (MAXSTR - 1)); - - int len = (int) strlen(name); - if (len >= SIZESTR("_cinit")) - { - if (strcmp((name + (len - SIZESTR("_cinit"))), "_cinit") == 0) - { - // Skip stub functions - if (func->size() > 16) - { - msg("%llX C: \"%s\", %d bytes.\n", func->start_ea, name, func->size()); - _ASSERT(cinitFunc == NULL); - cinitFunc = func; - } - } - else - if ((len >= SIZESTR("_initterm")) && (strcmp((name + (len - SIZESTR("_initterm"))), "_initterm") == 0)) - { - msg("%llX I: \"%s\", %d bytes.\n", func->start_ea, name, func->size()); - inittermMap[func->start_ea] = name; - } - else - if ((len >= SIZESTR("_initterm_e")) && (strcmp((name + (len - SIZESTR("_initterm_e"))), "_initterm_e") == 0)) - { - msg("%llX E: \"%s\", %d bytes.\n", func->start_ea, name, func->size()); - inittermMap[func->start_ea] = name; - } - } - } - } - } - #endif - if(WaitBox::isUpdateTime()) if (WaitBox::updateAndCancelCheck()) - return(TRUE); + return(true); // Look for import versions { - static LPCSTR imports[] = + static const char *imports[] = { "__imp__initterm", "__imp__initterm_e" }; - for (UINT32 i = 0; i < _countof(imports); i++) + for (uint32_t i = 0; i < _countof(imports); i++) { ea_t adress = get_name_ea(BADADDR, imports[i]); if (adress != BADADDR) @@ -1121,8 +1051,8 @@ static BOOL processStaticTables() { struct CREPAT { - LPCSTR pattern; - UINT32 start, end, call; + const char *pattern; + uint32_t start, end, call; } static const ALIGN(16) pat[] = { // TODO: Add more patterns as they are located @@ -1130,7 +1060,7 @@ static BOOL processStaticTables() { "BE ?? ?? ?? ?? 8B C6 BF ?? ?? ?? ?? 3B C7 59 73 0F 8B 06 85 C0 74 02 FF D0 83 C6 04 3B F7 72 F1", 1, 8, 0x17}, }; - for (UINT32 i = 0; i < _countof(pat); i++) + for (uint32_t i = 0; i < _countof(pat); i++) { ea_t match = FIND_BINARY(cinitFunc->start_ea, cinitFunc->end_ea, pat[i].pattern); while (match != BADADDR) @@ -1147,7 +1077,7 @@ static BOOL processStaticTables() msg(" \n"); if (WaitBox::isUpdateTime()) if (WaitBox::updateAndCancelCheck()) - return(TRUE); + return(true); // Generate _initterm argument pattern table if (plat.is64) @@ -1170,23 +1100,23 @@ static BOOL processStaticTables() if (processInitterm(address, name.c_str())) if (WaitBox::isUpdateTime()) if (WaitBox::updateAndCancelCheck()) - return(TRUE); + return(true); } if (WaitBox::isUpdateTime()) if (WaitBox::updateAndCancelCheck()) - return(TRUE); + return(true); } CATCH() - return(FALSE); + return(false); } // ================================================================================================ -// Return TRUE if address as a anterior comment -inline BOOL hasAnteriorComment(ea_t ea) +// Return true if address as a anterior comment +inline bool hasAnteriorComment(ea_t ea) { return (get_first_free_extra_cmtidx(ea, E_PREV) != E_PREV); } @@ -1196,8 +1126,8 @@ void fixDword(ea_t ea) { if (!is_dword(get_flags(ea))) { - setUnknown(ea, sizeof(DWORD)); - create_dword(ea, sizeof(DWORD), TRUE); + setUnknown(ea, sizeof(uint32_t)); + create_dword(ea, sizeof(uint32_t), true); auto_wait(); } } @@ -1210,8 +1140,8 @@ void fixEa(ea_t ea) // 32bit if (!is_dword(get_flags(ea))) { - setUnknown(ea, sizeof(UINT32)); - create_dword(ea, sizeof(UINT32), TRUE); + setUnknown(ea, sizeof(uint32_t)); + create_dword(ea, sizeof(uint32_t), true); auto_wait(); } } @@ -1220,25 +1150,25 @@ void fixEa(ea_t ea) // If already a QWORD size value here it's good if (!is_qword(get_flags(ea))) { - setUnknown(ea, sizeof(UINT64)); - create_qword(ea, sizeof(UINT64), TRUE); + setUnknown(ea, sizeof(uint64_t)); + create_qword(ea, sizeof(uint64_t), true); auto_wait(); } } } // Get IDA EA bit value with verification -BOOL getVerifyEa(ea_t ea, ea_t &rValue) +bool getVerifyEa(ea_t ea, ea_t &rValue) { // Location valid? if (IS_VALID_ADDR(ea)) { // Get ea_t value rValue = plat.getEa(ea); - return TRUE; + return true; } - return FALSE; + return false; } // Address should be a code function @@ -1264,18 +1194,18 @@ void fixFunction(ea_t ea) // http://en.wikipedia.org/wiki/Name_mangling // http://en.wikipedia.org/wiki/Visual_C%2B%2B_name_mangling // http://www.agner.org/optimize/calling_conventions.pdf -BOOL getPlainTypeName(__in LPCSTR mangled, __out_bcount(MAXSTR) LPSTR outStr) +bool getPlainTypeName(const char *mangled, char *outStr) { outStr[0] = outStr[MAXSTR - 1] = 0; - // Use CRT function for type names + // Use demangler for type names if (mangled[0] == '.') { __unDName(outStr, mangled + 1, MAXSTR, mallocWrap, free, (UNDNAME_32_BIT_DECODE | UNDNAME_TYPE_ONLY | UNDNAME_NO_ECSU)); if ((outStr[0] == 0) || (strcmp((mangled + 1), outStr) == 0)) { msg("** getPlainClassName:__unDName() failed to unmangle! input: \"%s\"\n", mangled); - return FALSE; + return false; } } else @@ -1286,29 +1216,29 @@ BOOL getPlainTypeName(__in LPCSTR mangled, __out_bcount(MAXSTR) LPSTR outStr) if (result < 0) { //msg("** getPlainClassName:demangle_name2() failed to unmangle! result: %d, input: \"%s\"\n", result, mangled); - return FALSE; + return false; } // No inhibit flags will drop this strncpy_s(outStr, MAXSTR, qstr.c_str(), (MAXSTR - 1)); - if (LPSTR ending = strstr(outStr, "::`vftable'")) + if (char *ending = strstr(outStr, "::`vftable'")) *ending = 0; } - return TRUE; + return true; } // Set name for address -void setName(ea_t ea, __in LPCSTR name) -{ +void setName(ea_t ea, const char *name) +{ set_name(ea, name, (SN_NON_AUTO | SN_NOWARN | SN_NOCHECK | SN_FORCE)); //msg("setName: %llX \"%s\"\n", ea, name); } // Set comment at address -void setComment(ea_t ea, LPCSTR comment, BOOL rptble) -{ +void setComment(ea_t ea, const char *comment, bool rptble) +{ set_cmt(ea, comment, rptble); //msg("setComment: %llX \"%s\"\n", ea, comment); } @@ -1319,19 +1249,19 @@ void setAnteriorComment(ea_t ea, const char *format, ...) va_list va; va_start(va, format); vadd_extra_line(ea, 0, format, va); - va_end(va); + va_end(va); //msg("setAnteriorComment: %llX\n", ea); } // Scan segment for COLs -static BOOL scanSeg4Cols(segment_t *seg) +static bool scanSeg4Cols(segment_t *seg) { qstring name; if (get_segm_name(&name, seg) <= 0) name = "???"; msg("N: \"%s\", %llX - %llX, S: %s.\n", name.c_str(), seg->start_ea, seg->end_ea, byteSizeString(seg->size())); - UINT32 newCount = 0, existingCount = 0; + uint32_t newCount = 0, existingCount = 0; WaitBox::processIdaEvents(); size_t colSize = (plat.is64 ? sizeof(RTTI::_RTTICompleteObjectLocator_64) : sizeof(RTTI::_RTTICompleteObjectLocator_32)); @@ -1398,25 +1328,25 @@ static BOOL scanSeg4Cols(segment_t *seg) else { // TODO: Should we check stray BCDs? - // Each value would have to be tested for a valid type_def and the pattern is pretty ambiguous. + // Each value would have to be tested for a valid type_def and the pattern is pretty ambiguous. } } else { - if (colSet.find(ptr) != colSet.end()) - existingCount++; + if (colSet.find(ptr) != colSet.end()) + existingCount++; } } if(ptr % 1000) if (WaitBox::isUpdateTime()) if (WaitBox::updateAndCancelCheck()) - return TRUE; + return true; ptr += (ea_t) plat.ptrSize; } } - + if (newCount) { char numBuffer[32]; @@ -1427,11 +1357,11 @@ static BOOL scanSeg4Cols(segment_t *seg) char numBuffer[32]; msg(" Existing: %s\n", NumberCommaString(existingCount, numBuffer)); } - return FALSE; + return false; } // Locate COL by descriptor list -static BOOL findCols(SegSelect::segments &segs) +static bool findCols(SegSelect::segments &segs) { try { @@ -1442,7 +1372,7 @@ static BOOL findCols(SegSelect::segments &segs) for (auto &seg: segs) { if (scanSeg4Cols(&seg)) - return FALSE; + return false; } } else @@ -1455,7 +1385,7 @@ static BOOL findCols(SegSelect::segments &segs) if (seg->type == SEG_DATA) { if (scanSeg4Cols(seg)) - return FALSE; + return false; } } } @@ -1471,21 +1401,21 @@ static BOOL findCols(SegSelect::segments &segs) colList.clear(); } CATCH() - return FALSE; + return false; } // Locate virtual function tables (vftable) -static BOOL scanSeg4Vftables(segment_t *seg) +static bool scanSeg4Vftables(segment_t *seg) { qstring name; if (get_segm_name(&name, seg) <= 0) name = "???"; msg("N: \"%s\", %llX - %llX, S: %s.\n", name.c_str(), seg->start_ea, seg->end_ea, byteSizeString(seg->size())); - UINT32 foundCount = 0; + uint32_t foundCount = 0; WaitBox::processIdaEvents(); - if (seg->size() >= plat.ptrSize) + if (seg->size() >= (asize_t)plat.ptrSize) { // The default for vftable alignment is native pointer size ea_t startEA = ((seg->start_ea + plat.ptrSize) & ~((ea_t) plat.ptrSize - 1)); @@ -1505,7 +1435,7 @@ static BOOL scanSeg4Vftables(segment_t *seg) if (vftSet.find(vfptr) != vftSet.end()) { // Yes, process it now - RTTI::processVftable(vfptr, colEa, TRUE); + RTTI::processVftable(vfptr, colEa, true); foundCount++; } else @@ -1516,7 +1446,7 @@ static BOOL scanSeg4Vftables(segment_t *seg) if (methodSeg && (methodSeg->type & _CODE_SEG)) { // Yes, see if vftable here - foundCount += (UINT32) RTTI::processVftable(vfptr, colEa); + foundCount += (uint32_t) RTTI::processVftable(vfptr, colEa); } } } @@ -1524,7 +1454,7 @@ static BOOL scanSeg4Vftables(segment_t *seg) if(ptr % 1000) if (WaitBox::isUpdateTime()) if (WaitBox::updateAndCancelCheck()) - return TRUE; + return true; } } @@ -1532,11 +1462,11 @@ static BOOL scanSeg4Vftables(segment_t *seg) { char numBuffer[32]; msg(" Found: %s\n", NumberCommaString(foundCount, numBuffer)); - } - return FALSE; + } + return false; } -static BOOL findVftables(SegSelect::segments &segs) +static bool findVftables(SegSelect::segments &segs) { try { @@ -1548,7 +1478,7 @@ static BOOL findVftables(SegSelect::segments &segs) for (auto &seg: segs) { if (scanSeg4Vftables(&seg)) - return FALSE; + return false; } } else @@ -1562,7 +1492,7 @@ static BOOL findVftables(SegSelect::segments &segs) if (seg->type == SEG_DATA) { if (scanSeg4Vftables(seg)) - return FALSE; + return false; } } } @@ -1572,14 +1502,14 @@ static BOOL findVftables(SegSelect::segments &segs) WaitBox::processIdaEvents(); } CATCH() - return FALSE; + return false; } // ================================================================================================ // Gather RTTI data set -static BOOL gatherRttiDataSet(SegSelect::segments &segs) +static bool gatherRttiDataSet(SegSelect::segments &segs) { // Free RTTI working data on return struct OnReturn { ~OnReturn(){ RTTI::freeWorkingData(); };} onReturn; @@ -1591,25 +1521,25 @@ static BOOL gatherRttiDataSet(SegSelect::segments &segs) msg("-------------------------------------------------\n"); WaitBox::processIdaEvents(); if(RTTI::gatherKnownRttiData()) - return TRUE; + return true; // ==== Find and process Complete Object Locators (COL) msg("\nScanning for for Complete Object Locators:\n"); msg("-------------------------------------------------\n"); WaitBox::processIdaEvents(); if(findCols(segs)) - return TRUE; + return true; // ==== Find and process vftables msg("\nScanning for Virtual Function Tables:\n"); msg("-------------------------------------------------\n"); WaitBox::processIdaEvents(); if(findVftables(segs)) - return TRUE; + return true; } CATCH() - return FALSE; + return false; } @@ -1620,7 +1550,10 @@ static char _help[] = ""; static char _name[] = "Class Informer"; // Plug-in description block -__declspec(dllexport) plugin_t PLUGIN = +#ifdef _MSC_VER +__declspec(dllexport) +#endif +plugin_t PLUGIN = { IDP_INTERFACE_VERSION, // IDA version plug-in is written for PLUGIN_FIX /*PLUGIN_PROC*/, // Plug-in flags diff --git a/Main.h b/Main.h index bd9e19f..f60e86f 100644 --- a/Main.h +++ b/Main.h @@ -2,49 +2,50 @@ // Class Informer #pragma once +#include -extern BOOL getVerifyEa(ea_t ea, ea_t &rValue); -extern BOOL hasAnteriorComment(ea_t ea); -extern void addTableEntry(UINT32 flags, ea_t vft, int methodCount, LPCSTR format, ...); -extern BOOL getPlainTypeName(__in LPCSTR mangled, __out_bcount(MAXSTR) LPSTR outStr); +extern bool getVerifyEa(ea_t ea, ea_t &rValue); +extern bool hasAnteriorComment(ea_t ea); +extern void addTableEntry(uint32_t flags, ea_t vft, int methodCount, const char * format, ...); +extern bool getPlainTypeName(const char * mangled, char * outStr); extern void fixDword(ea_t ea); extern void fixEa(ea_t ea); extern void fixFunction(ea_t eaFunc); -extern void setName(ea_t ea, __in LPCSTR name); -extern void setComment(ea_t ea, LPCSTR comment, BOOL rptble); +extern void setName(ea_t ea, const char * name); +extern void setComment(ea_t ea, const char * comment, bool rptble); extern void setAnteriorComment(ea_t ea, const char *format, ...); inline void setUnknown(ea_t ea, int size) { del_items(ea, DELIT_EXPAND, size); } // Return TRUE if there is a name at address that is not a dumbly name -inline BOOL hasName(ea_t ea) { return has_name(get_flags(ea)); } +inline bool hasName(ea_t ea) { return has_name(get_flags(ea)); } // Return TRUE if there is a comment at address -inline BOOL hasComment(ea_t ea) { return has_cmt(get_flags(ea)); } +inline bool hasComment(ea_t ea) { return has_cmt(get_flags(ea)); } // Get IDA 32 bit value with IDB existence verification -template BOOL getVerify32(ea_t eaPtr, T& rValue) +template bool getVerify32(ea_t eaPtr, T& rValue) { // Location valid? if (IS_VALID_ADDR(eaPtr)) { // Get 32bit value rValue = (T) get_32bit(eaPtr); - return TRUE; + return true; } - return FALSE; + return false; } // Segment cache container -const UINT32 _CODE_SEG = (1 << 0); -const UINT32 _DATA_SEG = (1 << 1); +const uint32_t _CODE_SEG = (1 << 0); +const uint32_t _DATA_SEG = (1 << 1); struct SEGMENT { ea_t start, end; // Start and end VA of the segment - UINT32 type; // Either SEG_CODE, SEG_DATA, or both for the corner case of a IDB with just one segment. + uint32_t type; // Either SEG_CODE, SEG_DATA, or both for the corner case of a IDB with just one segment. char name[8 + 1]; // PE header format is 8 max }; extern const SEGMENT *FindCachedSegment(ea_t addr); -extern BOOL g_optionPlaceStructs; +extern bool g_optionPlaceStructs; diff --git a/MainDialog.cpp b/MainDialog.cpp index 390c865..7a2b3e6 100644 --- a/MainDialog.cpp +++ b/MainDialog.cpp @@ -1,22 +1,19 @@ // Main Dialog -#include "stdafx.h" +#include "StdAfx.h" #include "MainDialog.h" -#ifdef SPECIAL_EDITION -#include "AnimBannerWidget.h" -#endif #include -MainDialog::MainDialog(BOOL &optionPlaceStructs, BOOL &optionProcessStatic, BOOL &optionAudioOnDone, SegSelect::segments &segs, qstring &version, size_t animSwitch) : QDialog(QApplication::activeWindow()) +MainDialog::MainDialog(bool &optionPlaceStructs, bool &optionProcessStatic, bool &optionAudioOnDone, SegSelect::segments &segs, qstring &version, size_t /*animSwitch*/) : QDialog(QApplication::activeWindow()) { Ui::MainCIDialog::setupUi(this); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); buttonBox->addButton("CONTINUE", QDialogButtonBox::AcceptRole); buttonBox->addButton("CANCEL", QDialogButtonBox::RejectRole); - #define INITSTATE(obj,state) obj->setCheckState((state == TRUE) ? Qt::Checked : Qt::Unchecked); + #define INITSTATE(obj,state) obj->setCheckState((state) ? Qt::Checked : Qt::Unchecked); INITSTATE(checkBox1, optionPlaceStructs); INITSTATE(checkBox2, optionProcessStatic); INITSTATE(checkBox3, optionAudioOnDone); @@ -28,24 +25,12 @@ MainDialog::MainDialog(BOOL &optionPlaceStructs, BOOL &optionProcessStatic, BOOL setStyleSheet(QTextStream(&file).readAll()); this->segs = &segs; - this->setWindowTitle(QString("Class Informer %1").arg(version.c_str())); + this->setWindowTitle(QString("Class Informer ") + QString(version.c_str())); - // TODO: Compile switch the animated banner code in. So for a private version it's there, for the public version it's not. - // And for the private version have a switch to "run()" to not show the banner. - - // Setup banner widget static or animated + // Setup banner widget - static banner QRect bannerGeometry(0, 0, 292, 74); QWidget *bannerWidget = NULL; - #ifdef SPECIAL_EDITION - #pragma message(__LOC2__ " >> Special edition build <<") - if (animSwitch != 2) - { - // Instance the animated version of the banner - bannerWidget = new AnimBannerWidget(this, animSwitch == 1); - } - else - #endif { // Create the static banner (QLabel) QLabel *image = new QLabel(this); @@ -57,8 +42,8 @@ MainDialog::MainDialog(BOOL &optionPlaceStructs, BOOL &optionProcessStatic, BOOL image->setToolTip(QString::fromUtf8("")); #endif bannerWidget = image; - } - bannerWidget->setGeometry(bannerGeometry); + } + bannerWidget->setGeometry(bannerGeometry); } // On choose segments @@ -67,10 +52,10 @@ void MainDialog::segmentSelect() SegSelect::select(*this->segs, (SegSelect::DATA_HINT | SegSelect::RDATA_HINT), "Choose segments to scan"); } -// Do main dialog, return TRUE if canceled -BOOL doMainDialog(BOOL &optionPlaceStructs, BOOL &optionProcessStatic, BOOL &optionAudioOnDone, __out SegSelect::segments &segs, qstring &version, size_t animSwitch) +// Do main dialog, return true if canceled +bool doMainDialog(bool &optionPlaceStructs, bool &optionProcessStatic, bool &optionAudioOnDone, SegSelect::segments &segs, qstring &version, size_t animSwitch) { - BOOL result = TRUE; + bool result = true; MainDialog *dlg = new MainDialog(optionPlaceStructs, optionProcessStatic, optionAudioOnDone, segs, version, animSwitch); if (dlg->exec()) { @@ -79,8 +64,8 @@ BOOL doMainDialog(BOOL &optionPlaceStructs, BOOL &optionProcessStatic, BOOL &opt CHECKSTATE(checkBox2, optionProcessStatic); CHECKSTATE(checkBox3, optionAudioOnDone); #undef CHECKSTATE - result = FALSE; + result = false; } delete dlg; return(result); -} \ No newline at end of file +} diff --git a/MainDialog.h b/MainDialog.h index f7940ec..efe0b28 100644 --- a/MainDialog.h +++ b/MainDialog.h @@ -2,9 +2,8 @@ // Main Dialog #pragma once -#include "stdafx.h" +#include "StdAfx.h" #include -#include #include "ui_dialog.h" @@ -12,14 +11,14 @@ class MainDialog : public QDialog, public Ui::MainCIDialog { Q_OBJECT public: - MainDialog(BOOL &optionPlaceStructs, BOOL &optionProcessStatic, BOOL &optionAudioOnDone, SegSelect::segments &segs, qstring &version, size_t animSwitch); + MainDialog(bool &optionPlaceStructs, bool &optionProcessStatic, bool &optionAudioOnDone, SegSelect::segments &segs, qstring &version, size_t animSwitch); -private: +private: SegSelect::segments *segs; private slots: void segmentSelect(); }; -// Do main dialog, return TRUE if canceled -BOOL doMainDialog(BOOL &optionPlaceStructs, BOOL &optionProcessStatic, BOOL &optionAudioOnDone, __out SegSelect::segments &segs, qstring &version, size_t animSwitch); +// Do main dialog, return true if canceled +bool doMainDialog(bool &optionPlaceStructs, bool &optionProcessStatic, bool &optionAudioOnDone, SegSelect::segments &segs, qstring &version, size_t animSwitch); diff --git a/RTTI.cpp b/RTTI.cpp index 2031d66..8482223 100644 --- a/RTTI.cpp +++ b/RTTI.cpp @@ -1,30 +1,29 @@ // Run-Time Type Information (RTTI) support -#include "stdafx.h" +#include "StdAfx.h" #include "Main.h" #include "RTTI.h" #include "Vftable.h" -#include // const Name::`vftable' -static LPCSTR FORMAT_RTTI_VFTABLE_PREFIX = "??_7"; -static LPCSTR FORMAT_RTTI_VFTABLE = "??_7%s6B@"; +static const char *FORMAT_RTTI_VFTABLE_PREFIX = "??_7"; +static const char *FORMAT_RTTI_VFTABLE ="??_7%s6B@"; // type 'RTTI Type Descriptor' -static LPCSTR FORMAT_RTTI_TYPE = "??_R0?%s@8"; +static const char * FORMAT_RTTI_TYPE = "??_R0?%s@8"; // 'RTTI Base Class Descriptor at (a,b,c,d)' -static LPCSTR FORMAT_RTTI_BCD = "??_R1%s%s%s%s%s8"; +static const char * FORMAT_RTTI_BCD = "??_R1%s%s%s%s%s8"; // `RTTI Base Class Array' -static LPCSTR FORMAT_RTTI_BCA = "??_R2%s8"; +static const char * FORMAT_RTTI_BCA = "??_R2%s8"; // 'RTTI Class Hierarchy Descriptor' -static LPCSTR FORMAT_RTTI_CHD = "??_R3%s8"; +static const char * FORMAT_RTTI_CHD = "??_R3%s8"; // 'RTTI Complete Object Locator' -static LPCSTR FORMAT_RTTI_COL_PREFIX = "??_R4"; -static LPCSTR FORMAT_RTTI_COL = "??_R4%s6B@"; +static const char * FORMAT_RTTI_COL_PREFIX = "??_R4"; +static const char * FORMAT_RTTI_COL = "??_R4%s6B@"; // Skip type_info tag for class/struct mangled name strings #define SKIP_TD_TAG(_str) ((_str) + SIZESTR(".?Ax")) @@ -33,7 +32,7 @@ static LPCSTR FORMAT_RTTI_COL = "??_R4%s6B@"; struct bcdInfo { char m_name[MAXSTR]; - UINT32 m_attribute; + uint32_t m_attribute; RTTI::PMD m_pmd; }; typedef std::vector bcdList; @@ -50,11 +49,11 @@ eaSet colSet; // _RTTICompleteObjectLocator "Complete Object Locator" (COL) s eaSet superSet; // Combined for faster scanning #define IN_SUPER(_addr) (superSet.find(_addr) != superSet.end()) -#define TO_INT64(_uint32) ((INT64) *((PINT32) &_uint32)) +// TO_INT64 defined in Compat.h namespace RTTI { - void getBCDInfo(ea_t col, __out bcdList& nameList, __out UINT32& numBaseClasses); + void getBCDInfo(ea_t col, bcdList& nameList, uint32_t& numBaseClasses); }; void RTTI::freeWorkingData() @@ -69,7 +68,7 @@ void RTTI::freeWorkingData() } // Make a mangled number string for labeling -static LPSTR mangleNumber(UINT32 number, __out_bcount(64) LPSTR buffer) +static char * mangleNumber(uint32_t number, char * buffer) { // // 0 = A@ @@ -78,7 +77,7 @@ static LPSTR mangleNumber(UINT32 number, __out_bcount(64) LPSTR buffer) // 0x0..0xF = 'A'..'P' // Can only get unsigned inputs - int num = *((PINT32) &number); + int num = *((int32_t*) &number); if (num == 0) return strcpy(buffer, "A@"); else @@ -120,7 +119,7 @@ static LPSTR mangleNumber(UINT32 number, __out_bcount(64) LPSTR buffer) // Return a short label indicating the CHD inheritance type by attributes // TODO: Consider CHD_AMBIGUOUS? -static LPCSTR attributeLabel(UINT32 attributes) +static const char * attributeLabel(uint32_t attributes) { switch (attributes & 3) { @@ -147,7 +146,7 @@ static void typeDump(tinfo_t &tinf) } // Look for existing type from a list of names -static tid_t GetKnownTypeID(LPCSTR names[], int namesCount, asize_t expectedTypeSize) +static tid_t GetKnownTypeID(const char * names[], int namesCount, asize_t expectedTypeSize) { for (int i = 0; i < namesCount; i++) { @@ -177,7 +176,7 @@ static tid_t GetKnownTypeID(LPCSTR names[], int namesCount, asize_t expectedType void RTTI::addDefinitionsToIda() { // std::type_info, aka "_TypeDescriptor" and "_RTTITypeDescriptor" in CRT source, class representation - static LPCSTR type_info_names[] = + static const char * type_info_names[] = { "type_info", "??_Rtype_info_std@@3Vtype_info@@A", /*std::type_info*/ @@ -192,7 +191,7 @@ void RTTI::addDefinitionsToIda() // Not found so create it if (s_type_info_ID == BADADDR) { - LPCSTR def = R"DEF( + const char * def = R"DEF( // RTTI std::type_info class (#classinformer) struct type_info { @@ -220,11 +219,11 @@ void RTTI::addDefinitionsToIda() } // PDM - static LPCSTR pdm_names[] = { "_PDM", "PDM" }; + static const char * pdm_names[] = { "_PDM", "PDM" }; s_PMD_ID = GetKnownTypeID(pdm_names, _countof(pdm_names), sizeof(PMD)); if (s_PMD_ID == BADADDR) { - LPCSTR def = R"DEF( + const char * def = R"DEF( // RTTI Base class descriptor displacement container (#classinformer) struct PMD { @@ -244,11 +243,11 @@ void RTTI::addDefinitionsToIda() } // _RTTIClassHierarchyDescriptor - static LPCSTR chd_names[] = { "_s__RTTIClassHierarchyDescriptor", "__RTTIClassHierarchyDescriptor", "_RTTIClassHierarchyDescriptor", "RTTIClassHierarchyDescriptor" }; - s_ClassHierarchyDescriptor_ID = GetKnownTypeID(chd_names, _countof(chd_names), (sizeof(_RTTIClassHierarchyDescriptor) + (plat.is64 ? sizeof(UINT32) : 0))); // The 64bit one in the CRT source shows it's a pointer while it's an int offset in binary + static const char * chd_names[] = { "_s__RTTIClassHierarchyDescriptor", "__RTTIClassHierarchyDescriptor", "_RTTIClassHierarchyDescriptor", "RTTIClassHierarchyDescriptor" }; + s_ClassHierarchyDescriptor_ID = GetKnownTypeID(chd_names, _countof(chd_names), (sizeof(_RTTIClassHierarchyDescriptor) + (plat.is64 ? sizeof(uint32_t) : 0))); // The 64bit one in the CRT source shows it's a pointer while it's an int offset in binary if (s_ClassHierarchyDescriptor_ID == BADADDR) { - LPCSTR def; + const char * def; if (!plat.is64) { // 32bit @@ -288,11 +287,11 @@ void RTTI::addDefinitionsToIda() } // _RTTIBaseClassDescriptor - static LPCSTR bcd_names[] = { "_s__RTTIBaseClassDescriptor", "__RTTIBaseClassDescriptor", "_RTTIBaseClassDescriptor", "RTTIBaseClassDescriptor" }; - s_BaseClassDescriptor_ID = GetKnownTypeID(bcd_names, _countof(bcd_names), (sizeof(_RTTIBaseClassDescriptor) + (plat.is64 ? sizeof(UINT64) : 0))); + static const char * bcd_names[] = { "_s__RTTIBaseClassDescriptor", "__RTTIBaseClassDescriptor", "_RTTIBaseClassDescriptor", "RTTIBaseClassDescriptor" }; + s_BaseClassDescriptor_ID = GetKnownTypeID(bcd_names, _countof(bcd_names), (sizeof(_RTTIBaseClassDescriptor) + (plat.is64 ? sizeof(uint64_t) : 0))); if (s_BaseClassDescriptor_ID == BADADDR) { - LPCSTR def; + const char * def; if (!plat.is64) { // 32bit @@ -334,11 +333,11 @@ void RTTI::addDefinitionsToIda() } // _RTTICompleteObjectLocator - static LPCSTR col_names[] = { "_s__RTTICompleteObjectLocator2", "_s__RTTICompleteObjectLocator", "__RTTICompleteObjectLocator", "_RTTICompleteObjectLocator", "RTTICompleteObjectLocator" }; + static const char * col_names[] = { "_s__RTTICompleteObjectLocator2", "_s__RTTICompleteObjectLocator", "__RTTICompleteObjectLocator", "_RTTICompleteObjectLocator", "RTTICompleteObjectLocator" }; s_CompleteObjectLocator_ID = GetKnownTypeID(col_names, _countof(col_names), (sizeof(_RTTICompleteObjectLocator) + (plat.is64 ? 16 : 0))); if (s_CompleteObjectLocator_ID == BADADDR) { - LPCSTR def; + const char * def; if (!plat.is64) { // 32bit @@ -383,17 +382,17 @@ void RTTI::addDefinitionsToIda() // Place an RTTI structure by type ID add address w/optional name -// Returns TRUE if structure was placed, else FLASE it was already set -static BOOL tryStructRTTI(ea_t ea, tid_t tid, __in_opt LPSTR typeName = NULL, BOOL bHasChd = FALSE) +// Returns true if structure was placed, else FLASE it was already set +static bool tryStructRTTI(ea_t ea, tid_t tid, char * typeName = NULL, bool bHasChd = false) { if (tid == BADADDR) { - _ASSERT(FALSE); - return FALSE; + _ASSERT(false); + return false; } - #define put32(ea) create_dword(ea, sizeof(EA_32), TRUE) - #define put64(ea) create_qword(ea, sizeof(ea_t), TRUE) + #define put32(ea) create_dword(ea, sizeof(EA_32), true) + #define put64(ea) create_qword(ea, sizeof(ea_t), true) // type_info if(tid == s_type_info_ID) @@ -404,12 +403,12 @@ static BOOL tryStructRTTI(ea_t ea, tid_t tid, __in_opt LPSTR typeName = NULL, BO if (!hasName(ea)) { _ASSERT(typeName != NULL); - UINT32 nameLen = (UINT32) (strlen(typeName) + 1); - UINT32 structSize = (offsetof(RTTI::type_info_32, _M_d_name) + nameLen); + uint32_t nameLen = (uint32_t) (strlen(typeName) + 1); + uint32_t structSize = (offsetof(RTTI::type_info_32, _M_d_name) + nameLen); // Place struct setUnknown(ea, structSize); - BOOL result = FALSE; + bool result = false; if (g_optionPlaceStructs) result = create_struct(ea, structSize, s_type_info_ID); if (!result) @@ -425,7 +424,7 @@ static BOOL tryStructRTTI(ea_t ea, tid_t tid, __in_opt LPSTR typeName = NULL, BO if (end % 4) create_align(end, (4 - (end % 4)), 0); - return TRUE; + return true; } } else @@ -434,12 +433,12 @@ static BOOL tryStructRTTI(ea_t ea, tid_t tid, __in_opt LPSTR typeName = NULL, BO if (!hasName(ea)) { _ASSERT(typeName != NULL); - UINT32 nameLen = (UINT32) (strlen(typeName) + 1); - UINT32 structSize = (offsetof(RTTI::type_info_64, _M_d_name) + nameLen); + uint32_t nameLen = (uint32_t) (strlen(typeName) + 1); + uint32_t structSize = (offsetof(RTTI::type_info_64, _M_d_name) + nameLen); // Place struct setUnknown(ea, structSize); - BOOL result = FALSE; + bool result = false; if (g_optionPlaceStructs && (s_type_info_ID > 5)) result = create_struct(ea, structSize, s_type_info_ID); if (!result) @@ -450,16 +449,16 @@ static BOOL tryStructRTTI(ea_t ea, tid_t tid, __in_opt LPSTR typeName = NULL, BO } // sh!ft: End should be aligned - #pragma message(__LOC2__ " >> Should be align 8? Do we really even need this?") + // TODO: Should be align 8? ea_t end = (ea + offsetof(RTTI::type_info_64, _M_d_name) + nameLen); if (end % 4) create_align(end, (4 - (end % 4)), 0); - return TRUE; + return true; } } - return FALSE; + return false; } // _RTTIClassHierarchyDescriptor @@ -468,7 +467,7 @@ static BOOL tryStructRTTI(ea_t ea, tid_t tid, __in_opt LPSTR typeName = NULL, BO if (!hasName(ea)) { setUnknown(ea, sizeof(RTTI::_RTTIClassHierarchyDescriptor)); - BOOL result = FALSE; + bool result = false; if (g_optionPlaceStructs) result = create_struct(ea, sizeof(RTTI::_RTTIClassHierarchyDescriptor), s_ClassHierarchyDescriptor_ID); if (!result) @@ -479,10 +478,10 @@ static BOOL tryStructRTTI(ea_t ea, tid_t tid, __in_opt LPSTR typeName = NULL, BO put32(ea + offsetof(RTTI::_RTTIClassHierarchyDescriptor, baseClassArray)); } - return TRUE; + return true; } - return FALSE; + return false; } // PMD @@ -491,7 +490,7 @@ static BOOL tryStructRTTI(ea_t ea, tid_t tid, __in_opt LPSTR typeName = NULL, BO if (!hasName(ea)) { setUnknown(ea, sizeof(RTTI::PMD)); - BOOL result = FALSE; + bool result = false; if (g_optionPlaceStructs) result = create_struct(ea, sizeof(RTTI::PMD), s_PMD_ID); if (!result) @@ -501,10 +500,10 @@ static BOOL tryStructRTTI(ea_t ea, tid_t tid, __in_opt LPSTR typeName = NULL, BO put32(ea + offsetof(RTTI::PMD, vdisp)); } - return TRUE; + return true; } - return FALSE; + return false; } // _RTTICompleteObjectLocator @@ -516,7 +515,7 @@ static BOOL tryStructRTTI(ea_t ea, tid_t tid, __in_opt LPSTR typeName = NULL, BO if (!hasName(ea)) { setUnknown(ea, sizeof(RTTI::_RTTICompleteObjectLocator_32)); - BOOL result = FALSE; + bool result = false; if (g_optionPlaceStructs) result = create_struct(ea, sizeof(RTTI::_RTTICompleteObjectLocator_32), s_CompleteObjectLocator_ID); if (!result) @@ -528,7 +527,7 @@ static BOOL tryStructRTTI(ea_t ea, tid_t tid, __in_opt LPSTR typeName = NULL, BO put32(ea + offsetof(RTTI::_RTTICompleteObjectLocator_32, classDescriptor)); } - return TRUE; + return true; } } else @@ -537,7 +536,7 @@ static BOOL tryStructRTTI(ea_t ea, tid_t tid, __in_opt LPSTR typeName = NULL, BO if (!hasName(ea)) { setUnknown(ea, sizeof(RTTI::_RTTICompleteObjectLocator_64)); - BOOL result = FALSE; + bool result = false; if (g_optionPlaceStructs) result = create_struct(ea, sizeof(RTTI::_RTTICompleteObjectLocator_64), s_CompleteObjectLocator_ID); if (!result) @@ -550,11 +549,11 @@ static BOOL tryStructRTTI(ea_t ea, tid_t tid, __in_opt LPSTR typeName = NULL, BO put32(ea + offsetof(RTTI::_RTTICompleteObjectLocator_64, objectBase)); } - return TRUE; + return true; } } - return FALSE; + return false; } // _RTTIBaseClassDescriptor @@ -567,7 +566,7 @@ static BOOL tryStructRTTI(ea_t ea, tid_t tid, __in_opt LPSTR typeName = NULL, BO if (!hasName(ea)) { setUnknown(ea, sizeof(RTTI::_RTTIBaseClassDescriptor)); - BOOL result = FALSE; + bool result = false; if (g_optionPlaceStructs) result = create_struct(ea, sizeof(RTTI::_RTTIBaseClassDescriptor), s_BaseClassDescriptor_ID); if (!result) @@ -578,22 +577,22 @@ static BOOL tryStructRTTI(ea_t ea, tid_t tid, __in_opt LPSTR typeName = NULL, BO //if (bHasChd) put32(ea + offsetof(RTTI::_RTTIBaseClassDescriptor, classDescriptor)); if (bHasChd) - setComment((ea + offsetof(RTTI::_RTTIBaseClassDescriptor, classDescriptor)), "BCD_HASPCHD set", TRUE); + setComment((ea + offsetof(RTTI::_RTTIBaseClassDescriptor, classDescriptor)), "BCD_HASPCHD set", true); } - return TRUE; + return true; } - return FALSE; + return false; } - _ASSERT(FALSE); - return FALSE; + _ASSERT(false); + return false; } // Read ASCII string from IDB at address -static int getIdaString(ea_t ea, __out LPSTR buffer, int bufferSize) +static int getIdaString(ea_t ea, char * buffer, int bufferSize) { buffer[0] = 0; @@ -601,7 +600,7 @@ static int getIdaString(ea_t ea, __out LPSTR buffer, int bufferSize) auto it = stringCache.find(ea); if (it != stringCache.end()) { - LPCSTR str = it->second.c_str(); + const char * str = it->second.c_str(); int len = (int) strlen(str); if (len > bufferSize) len = bufferSize; @@ -644,17 +643,17 @@ static int getIdaString(ea_t ea, __out LPSTR buffer, int bufferSize) // Get type name into a buffer // type_info assumed to be valid -int RTTI::type_info::getName(ea_t typeInfo, __out LPSTR buffer, int bufferSize) +int RTTI::type_info::getName(ea_t typeInfo, char * buffer, int bufferSize) { return getIdaString(typeInfo + (plat.is64 ? offsetof(type_info_64, _M_d_name) : offsetof(type_info_32, _M_d_name)), buffer, bufferSize); } // A valid type_info/TypeDescriptor at pointer? -BOOL RTTI::type_info::isValid(ea_t typeInfo) +bool RTTI::type_info::isValid(ea_t typeInfo) { - // TRUE if we've already seen it + // true if we've already seen it if (tdSet.find(typeInfo) != tdSet.end()) - return TRUE; + return true; if (IS_VALID_ADDR(typeInfo)) { @@ -672,11 +671,11 @@ BOOL RTTI::type_info::isValid(ea_t typeInfo) } } - return FALSE; + return false; } // -// Returns TRUE if known typename at address -BOOL RTTI::type_info::isTypeName(ea_t name) +// Returns true if known typename at address +bool RTTI::type_info::isTypeName(ea_t name) { // Should start with a period if (get_byte(name) == '.') @@ -686,14 +685,14 @@ BOOL RTTI::type_info::isTypeName(ea_t name) if (getIdaString(name, buffer, SIZESTR(buffer))) { // Should be valid if it properly demangles - if (LPSTR s = __unDName(NULL, buffer+1 /*skip the '.'*/, 0, mallocWrap, free, (UNDNAME_32_BIT_DECODE | UNDNAME_TYPE_ONLY))) + if (char * s = __unDName(NULL, buffer+1 /*skip the '.'*/, 0, mallocWrap, free, (UNDNAME_32_BIT_DECODE | UNDNAME_TYPE_ONLY))) { free(s); - return TRUE; + return true; } } } - return FALSE; + return false; } // Put struct and place name at address @@ -724,23 +723,23 @@ void RTTI::type_info::tryStruct(ea_t typeInfo) } else { - _ASSERT(FALSE); + _ASSERT(false); } } // --------------------------- Complete Object Locator --------------------------- -// Return TRUE if address is a valid RTTI structure -BOOL RTTI::_RTTICompleteObjectLocator::isValid(ea_t col) +// Return true if address is a valid RTTI structure +bool RTTI::_RTTICompleteObjectLocator::isValid(ea_t col) { // True if already known if (colSet.find(col) != colSet.end()) - return TRUE; + return true; if (IS_VALID_ADDR(col)) { // Check signature - UINT32 signature = -1; + uint32_t signature = -1; if (getVerify32((col + offsetof(_RTTICompleteObjectLocator, signature)), signature)) { if (!plat.is64) @@ -756,7 +755,7 @@ BOOL RTTI::_RTTICompleteObjectLocator::isValid(ea_t col) if (_RTTIClassHierarchyDescriptor::isValid(classDescriptor)) { //msg("%llX %llX %llX\n", col, typeInfo, classDescriptor); - return TRUE; + return true; } } } @@ -767,19 +766,19 @@ BOOL RTTI::_RTTICompleteObjectLocator::isValid(ea_t col) if (signature == 1) { // TODO: Can any of these be zero and still be valid? - UINT32 objectLocator32 = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, objectBase)); - INT64 objectLocator64 = TO_INT64(objectLocator32); + uint32_t objectLocator32 = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, objectBase)); + int64_t objectLocator64 = TO_INT64(objectLocator32); if (objectLocator64 != 0) { - UINT32 tdOffset32 = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, typeDescriptor)); - INT64 tdOffset64 = TO_INT64(tdOffset32); + uint32_t tdOffset32 = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, typeDescriptor)); + int64_t tdOffset64 = TO_INT64(tdOffset32); if (tdOffset64 != 0) { - UINT32 cdOffset32 = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, classDescriptor)); - INT64 cdOffset64 = TO_INT64(cdOffset32); + uint32_t cdOffset32 = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, classDescriptor)); + int64_t cdOffset64 = TO_INT64(cdOffset32); if (cdOffset64 != 0) { - INT64 colBase64 = ((INT64) col - objectLocator64); + int64_t colBase64 = ((int64_t) col - objectLocator64); ea_t typeInfo = (ea_t) (colBase64 + tdOffset64); if (type_info_64::isValid(typeInfo)) { @@ -787,7 +786,7 @@ BOOL RTTI::_RTTICompleteObjectLocator::isValid(ea_t col) if (_RTTIClassHierarchyDescriptor::isValid(classDescriptor, colBase64)) { //msg("%llX %llX %llX\n", col, typeInfo, classDescriptor); - return TRUE; + return true; } } } @@ -798,18 +797,18 @@ BOOL RTTI::_RTTICompleteObjectLocator::isValid(ea_t col) } } - return FALSE; + return false; } // Same as above but from an already validated type_info perspective -BOOL RTTI::_RTTICompleteObjectLocator_32::isValid2(ea_t col) +bool RTTI::_RTTICompleteObjectLocator_32::isValid2(ea_t col) { // True if already known if (colSet.find(col) != colSet.end()) - return TRUE; + return true; // 'signature' should be zero - UINT32 signature = -1; + uint32_t signature = -1; if (getVerify32((col + offsetof(_RTTICompleteObjectLocator_32, signature)), signature)) { if (signature == 0) @@ -821,15 +820,15 @@ BOOL RTTI::_RTTICompleteObjectLocator_32::isValid2(ea_t col) } } - return FALSE; + return false; } // Place full COL hierarchy structures if they don't already exist -BOOL RTTI::_RTTICompleteObjectLocator::tryStruct(ea_t col) +bool RTTI::_RTTICompleteObjectLocator::tryStruct(ea_t col) { // Place it once if (colSet.find(col) != colSet.end()) - return TRUE; + return true; // If it doesn't have a name, IDA's analyzer missed it if (!hasName(col)) @@ -856,14 +855,14 @@ BOOL RTTI::_RTTICompleteObjectLocator::tryStruct(ea_t col) else { // 64bit offsets plus objectBase - UINT32 tdOffset32 = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, typeDescriptor)); - INT64 tdOffset64 = TO_INT64(tdOffset32); - UINT32 cdOffset32 = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, classDescriptor)); - INT64 cdOffset64 = TO_INT64(cdOffset32); - UINT32 objectLocator32 = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, objectBase)); - INT64 objectLocator64 = TO_INT64(objectLocator32); + uint32_t tdOffset32 = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, typeDescriptor)); + int64_t tdOffset64 = TO_INT64(tdOffset32); + uint32_t cdOffset32 = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, classDescriptor)); + int64_t cdOffset64 = TO_INT64(cdOffset32); + uint32_t objectLocator32 = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, objectBase)); + int64_t objectLocator64 = TO_INT64(objectLocator32); - INT64 colBase64 = ((INT64) col - objectLocator64); + int64_t colBase64 = ((int64_t) col - objectLocator64); ea_t typeInfo = (ea_t) (colBase64 + tdOffset64); type_info::tryStruct(typeInfo); @@ -876,7 +875,7 @@ BOOL RTTI::_RTTICompleteObjectLocator::tryStruct(ea_t col) { char buffer[64]; sprintf_s(buffer, sizeof(buffer), "0x%llX", typeInfo); - setComment(ea, buffer, TRUE); + setComment(ea, buffer, true); } ea = (col + offsetof(_RTTICompleteObjectLocator_64, classDescriptor)); @@ -884,30 +883,30 @@ BOOL RTTI::_RTTICompleteObjectLocator::tryStruct(ea_t col) { char buffer[64]; sprintf_s(buffer, sizeof(buffer), "0x%llX", classDescriptor); - setComment(ea, buffer, TRUE); + setComment(ea, buffer, true); } } - return TRUE; + return true; } - return FALSE; + return false; } // --------------------------- Base Class Descriptor --------------------------- -// Return TRUE if address is a valid BCD -BOOL RTTI::_RTTIBaseClassDescriptor::isValid(ea_t bcd, INT64 colBase64) +// Return true if address is a valid BCD +bool RTTI::_RTTIBaseClassDescriptor::isValid(ea_t bcd, int64_t colBase64) { - // TRUE if already known + // true if already known if (bcdSet.find(bcd) != bcdSet.end()) - return TRUE; + return true; if (IS_VALID_ADDR(bcd)) { // Check attributes flags first - UINT32 attributes = -1; + uint32_t attributes = -1; if (getVerify32((bcd + offsetof(_RTTIBaseClassDescriptor, attributes)), attributes)) { // Valid flags are the lower byte only @@ -922,19 +921,19 @@ BOOL RTTI::_RTTIBaseClassDescriptor::isValid(ea_t bcd, INT64 colBase64) else { // When 64bit plus COL bass ea_t - UINT32 tdOffset32 = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor)); - INT64 tdOffset64 = TO_INT64(tdOffset32); + uint32_t tdOffset32 = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor)); + int64_t tdOffset64 = TO_INT64(tdOffset32); return type_info_64::isValid((ea_t) (colBase64 + tdOffset64)); } } } } - return FALSE; + return false; } // Put BCD structure at address -void RTTI::_RTTIBaseClassDescriptor::tryStruct(ea_t bcd, __out_bcount(MAXSTR) LPSTR baseClassName, INT64 colBase64) +void RTTI::_RTTIBaseClassDescriptor::tryStruct(ea_t bcd, char * baseClassName, int64_t colBase64) { // Only place it once if (bcdSet.find(bcd) != bcdSet.end()) @@ -949,8 +948,8 @@ void RTTI::_RTTIBaseClassDescriptor::tryStruct(ea_t bcd, __out_bcount(MAXSTR) LP else { // When 64bit plus COL bass ea_t - UINT32 tdOffset32 = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor)); - INT64 tdOffset64 = TO_INT64(tdOffset32); + uint32_t tdOffset32 = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor)); + int64_t tdOffset64 = TO_INT64(tdOffset32); typeInfo = (ea_t) (colBase64 + tdOffset64); } @@ -964,7 +963,7 @@ void RTTI::_RTTIBaseClassDescriptor::tryStruct(ea_t bcd, __out_bcount(MAXSTR) LP if (IS_VALID_ADDR(bcd)) { - UINT32 attributes = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, attributes)); + uint32_t attributes = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, attributes)); //msg("BCD: 0x%llX\n", bcd); tryStructRTTI(bcd, s_BaseClassDescriptor_ID, NULL, ((attributes & BCD_HASPCHD) > 0)); @@ -984,21 +983,21 @@ void RTTI::_RTTIBaseClassDescriptor::tryStruct(ea_t bcd, __out_bcount(MAXSTR) LP { // EA_64 fixDword(chdOffset); - UINT32 chdOffset32 = get_32bit(chdOffset); - INT64 chdOffset64 = TO_INT64(chdOffset32); + uint32_t chdOffset32 = get_32bit(chdOffset); + int64_t chdOffset64 = TO_INT64(chdOffset32); chd = (ea_t) (colBase64 + chdOffset64); if (!hasComment(chdOffset)) { char buffer[32]; sprintf_s(buffer, sizeof(buffer), "0x%llX", chd); - setComment(chdOffset, buffer, TRUE); + setComment(chdOffset, buffer, true); } } if (IS_VALID_ADDR(chd)) _RTTIClassHierarchyDescriptor::tryStruct(chd, colBase64); else - _ASSERT(FALSE); + _ASSERT(false); } // Place type_info struct @@ -1011,7 +1010,7 @@ void RTTI::_RTTIBaseClassDescriptor::tryStruct(ea_t bcd, __out_bcount(MAXSTR) LP else { // When 64bit plus COL bass ea_t - UINT32 tdOffset = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor)); + uint32_t tdOffset = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor)); typeInfo = (colBase64 + (ea_t)tdOffset); } type_info::tryStruct(typeInfo); @@ -1028,7 +1027,7 @@ void RTTI::_RTTIBaseClassDescriptor::tryStruct(ea_t bcd, __out_bcount(MAXSTR) LP if (!hasComment(ea)) { qstring s(""); - BOOL b = 0; + bool b = 0; #define ATRIBFLAG(_flag) { if (attributes & _flag) { if (b) s += " | "; s += #_flag; b = 1; } } ATRIBFLAG(BCD_NOTVISIBLE); ATRIBFLAG(BCD_AMBIGUOUS); @@ -1038,7 +1037,7 @@ void RTTI::_RTTIBaseClassDescriptor::tryStruct(ea_t bcd, __out_bcount(MAXSTR) LP ATRIBFLAG(BCD_NONPOLYMORPHIC); ATRIBFLAG(BCD_HASPCHD); #undef ATRIBFLAG - setComment(ea, s.c_str(), TRUE); + setComment(ea, s.c_str(), true); } } @@ -1059,36 +1058,36 @@ void RTTI::_RTTIBaseClassDescriptor::tryStruct(ea_t bcd, __out_bcount(MAXSTR) LP } } else - _ASSERT(FALSE); + _ASSERT(false); } // --------------------------- Class Hierarchy Descriptor --------------------------- // Return true if address is a valid CHD structure -BOOL RTTI::_RTTIClassHierarchyDescriptor::isValid(ea_t chd, INT64 colBase64) +bool RTTI::_RTTIClassHierarchyDescriptor::isValid(ea_t chd, int64_t colBase64) { - // TRUE is already known + // true is already known if (chdSet.find(chd) != chdSet.end()) - return(TRUE); + return(true); if (IS_VALID_ADDR(chd)) { // signature should be zero statically - UINT32 signature = -1; + uint32_t signature = -1; if (getVerify32((chd + offsetof(_RTTIClassHierarchyDescriptor, signature)), signature)) { if (signature == 0) { // Check attributes flags - UINT32 attributes = -1; + uint32_t attributes = -1; if (getVerify32((chd + offsetof(_RTTIClassHierarchyDescriptor, attributes)), attributes)) { // Valid flags are the lower nibble only if ((attributes & 0xFFFFFFF0) == 0) { // Should have at least one base class - UINT32 numBaseClasses = 0; + uint32_t numBaseClasses = 0; if (getVerify32((chd + offsetof(_RTTIClassHierarchyDescriptor, numBaseClasses)), numBaseClasses)) { if (numBaseClasses >= 1) @@ -1109,14 +1108,14 @@ BOOL RTTI::_RTTIClassHierarchyDescriptor::isValid(ea_t chd, INT64 colBase64) else { // When 64bit plus COL bass ea_t - UINT32 baseClassArrayOffset32 = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, baseClassArray)); - INT64 baseClassArrayOffset64 = TO_INT64(baseClassArrayOffset32); + uint32_t baseClassArrayOffset32 = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, baseClassArray)); + int64_t baseClassArrayOffset64 = TO_INT64(baseClassArrayOffset32); baseClassArray = (ea_t) (colBase64 + baseClassArrayOffset64); if (IS_VALID_ADDR(baseClassArray)) { // When 64bit plus COL bass ea_t - UINT32 baseClassDescriptor32 = get_32bit(baseClassArray); - INT64 baseClassDescriptor64 = (TO_INT64(baseClassDescriptor32) + colBase64); + uint32_t baseClassDescriptor32 = get_32bit(baseClassArray); + int64_t baseClassDescriptor64 = (TO_INT64(baseClassDescriptor32) + colBase64); return RTTI::_RTTIBaseClassDescriptor::isValid((ea_t) baseClassDescriptor64, colBase64); } } @@ -1128,11 +1127,11 @@ BOOL RTTI::_RTTIClassHierarchyDescriptor::isValid(ea_t chd, INT64 colBase64) } } - return FALSE; + return false; } // Put CHD structure at address -void RTTI::_RTTIClassHierarchyDescriptor::tryStruct(ea_t chd, INT64 colBase64) +void RTTI::_RTTIClassHierarchyDescriptor::tryStruct(ea_t chd, int64_t colBase64) { // Only place it once per address if (chdSet.find(chd) != chdSet.end()) @@ -1147,25 +1146,25 @@ void RTTI::_RTTIClassHierarchyDescriptor::tryStruct(ea_t chd, INT64 colBase64) tryStructRTTI(chd, s_ClassHierarchyDescriptor_ID); // Place attributes comment - UINT32 attributes = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, attributes)); + uint32_t attributes = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, attributes)); if (!g_optionPlaceStructs && attributes) { ea_t ea = (chd + offsetof(_RTTIClassHierarchyDescriptor, attributes)); if (!hasComment(ea)) { qstring s(""); - BOOL b = 0; + bool b = 0; #define ATRIBFLAG(_flag) { if (attributes & _flag) { if (b) s += " | "; s += #_flag; b = 1; } } ATRIBFLAG(CHD_MULTINH); ATRIBFLAG(CHD_VIRTINH); ATRIBFLAG(CHD_AMBIGUOUS); #undef ATRIBFLAG - setComment(ea, s.c_str(), TRUE); + setComment(ea, s.c_str(), true); } } // ---- Place BCD's ---- - UINT32 numBaseClasses = 0; + uint32_t numBaseClasses = 0; if (getVerify32((chd + offsetof(_RTTIClassHierarchyDescriptor, numBaseClasses)), numBaseClasses)) { // Get pointer @@ -1178,7 +1177,7 @@ void RTTI::_RTTIClassHierarchyDescriptor::tryStruct(ea_t chd, INT64 colBase64) else { // 64bit plus COL bass ea_t - UINT32 baseClassArrayOffset = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, baseClassArray)); + uint32_t baseClassArrayOffset = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, baseClassArray)); baseClassArray = (colBase64 + (ea_t) baseClassArrayOffset); ea_t ea = (chd + offsetof(_RTTIClassHierarchyDescriptor, baseClassArray)); @@ -1186,7 +1185,7 @@ void RTTI::_RTTIClassHierarchyDescriptor::tryStruct(ea_t chd, INT64 colBase64) { char buffer[32]; _snprintf_s(buffer, sizeof(buffer), SIZESTR(buffer), "0x%llX", baseClassArray); - setComment(ea, buffer, TRUE); + setComment(ea, buffer, true); } } @@ -1216,7 +1215,7 @@ void RTTI::_RTTIClassHierarchyDescriptor::tryStruct(ea_t chd, INT64 colBase64) } } - for (UINT32 i = 0; i < numBaseClasses; i++, baseClassArray += sizeof(UINT32)) + for (uint32_t i = 0; i < numBaseClasses; i++, baseClassArray += sizeof(uint32_t)) { fixDword(baseClassArray); @@ -1228,12 +1227,12 @@ void RTTI::_RTTIClassHierarchyDescriptor::tryStruct(ea_t chd, INT64 colBase64) { // Add index comment to to it if (numBaseClasses == 1) - setComment(baseClassArray, " BaseClass", FALSE); + setComment(baseClassArray, " BaseClass", false); else { char ptrComent[MAXSTR]; _snprintf_s(ptrComent, sizeof(ptrComent), SIZESTR(ptrComent), format, i); - setComment(baseClassArray, ptrComent, FALSE); + setComment(baseClassArray, ptrComent, false); } } @@ -1245,8 +1244,8 @@ void RTTI::_RTTIClassHierarchyDescriptor::tryStruct(ea_t chd, INT64 colBase64) else { // EA_64 - UINT32 bcdOffset32 = get_32bit(baseClassArray); - INT64 bcdOffset64 = TO_INT64(bcdOffset32); + uint32_t bcdOffset32 = get_32bit(baseClassArray); + int64_t bcdOffset64 = TO_INT64(bcdOffset32); ea_t bcd = (ea_t) (colBase64 + bcdOffset64); if (!hasComment(baseClassArray)) @@ -1256,13 +1255,13 @@ void RTTI::_RTTIClassHierarchyDescriptor::tryStruct(ea_t chd, INT64 colBase64) { char buffer[MAXSTR]; sprintf_s(buffer, sizeof(buffer), " BaseClass 0x%llX", bcd); - setComment(baseClassArray, buffer, FALSE); + setComment(baseClassArray, buffer, false); } else { char buffer[MAXSTR]; _snprintf_s(buffer, sizeof(buffer), SIZESTR(buffer), format, i, bcd); - setComment(baseClassArray, buffer, FALSE); + setComment(baseClassArray, buffer, false); } } @@ -1309,20 +1308,20 @@ void RTTI::_RTTIClassHierarchyDescriptor::tryStruct(ea_t chd, INT64 colBase64) } } else - _ASSERT(FALSE); + _ASSERT(false); } else - _ASSERT(FALSE); + _ASSERT(false); } else - _ASSERT(FALSE); + _ASSERT(false); } // --------------------------- Vftable --------------------------- // Get list of base class descriptor info -static void RTTI::getBCDInfo(ea_t col, __out bcdList &list, __out UINT32 &numBaseClasses) +void RTTI::getBCDInfo(ea_t col, bcdList &list, uint32_t &numBaseClasses) { numBaseClasses = 0; @@ -1340,7 +1339,7 @@ static void RTTI::getBCDInfo(ea_t col, __out bcdList &list, __out UINT32 &numBas ea_t baseClassArray = plat.getEa32(chd + offsetof(_RTTIClassHierarchyDescriptor, baseClassArray)); if(baseClassArray && (baseClassArray != BADADDR)) { - for(UINT32 i = 0; i < numBaseClasses; i++, baseClassArray += sizeof(UINT32)) + for(uint32_t i = 0; i < numBaseClasses; i++, baseClassArray += sizeof(uint32_t)) { // Get next BCD ea_t bcd = get_32bit(baseClassArray); @@ -1351,13 +1350,13 @@ static void RTTI::getBCDInfo(ea_t col, __out bcdList &list, __out UINT32 &numBas type_info_32::getName(typeInfo, bi->m_name, SIZESTR(bi->m_name)); // Add info to list - UINT32 mdisp = get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, mdisp))); - UINT32 pdisp = get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, pdisp))); - UINT32 vdisp = get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, vdisp))); + uint32_t mdisp = get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, mdisp))); + uint32_t pdisp = get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, pdisp))); + uint32_t vdisp = get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, vdisp))); // As signed int - bi->m_pmd.mdisp = *((PINT32) &mdisp); - bi->m_pmd.pdisp = *((PINT32) &pdisp); - bi->m_pmd.vdisp = *((PINT32) &vdisp); + bi->m_pmd.mdisp = *((int32_t*) &mdisp); + bi->m_pmd.pdisp = *((int32_t*) &pdisp); + bi->m_pmd.vdisp = *((int32_t*) &vdisp); bi->m_attribute = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, attributes)); //msg(" BN: [%d] \"%s\", ATB: %04X\n", i, szBuffer1, get_32bit((ea_t) &pBCD->attributes)); @@ -1370,11 +1369,11 @@ static void RTTI::getBCDInfo(ea_t col, __out bcdList &list, __out UINT32 &numBas else { // 64bit version - UINT32 cdOffset32 = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, classDescriptor)); - INT64 cdOffset64 = TO_INT64(cdOffset32); - UINT32 objectLocator32 = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, objectBase)); - INT64 objectLocator64 = TO_INT64(objectLocator32); - INT64 colBase64 = ((INT64) col - objectLocator64); + uint32_t cdOffset32 = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, classDescriptor)); + int64_t cdOffset64 = TO_INT64(cdOffset32); + uint32_t objectLocator32 = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, objectBase)); + int64_t objectLocator64 = TO_INT64(objectLocator32); + int64_t colBase64 = ((int64_t) col - objectLocator64); ea_t chd = (ea_t) (colBase64 + cdOffset64); if(chd) @@ -1384,31 +1383,31 @@ static void RTTI::getBCDInfo(ea_t col, __out bcdList &list, __out UINT32 &numBas list.resize(numBaseClasses); // Get pointer - UINT32 bcaOffset32 = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, baseClassArray)); - INT64 bcaOffset64 = TO_INT64(bcaOffset32); + uint32_t bcaOffset32 = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, baseClassArray)); + int64_t bcaOffset64 = TO_INT64(bcaOffset32); ea_t baseClassArray = (ea_t) (colBase64 + bcaOffset64); if(IS_VALID_ADDR(baseClassArray)) { - for(UINT32 i = 0; i < numBaseClasses; i++, baseClassArray += sizeof(UINT32)) + for(uint32_t i = 0; i < numBaseClasses; i++, baseClassArray += sizeof(uint32_t)) { - UINT32 bcdOffset32 = get_32bit(baseClassArray); - INT64 bcdOffset64 = TO_INT64(bcdOffset32); + uint32_t bcdOffset32 = get_32bit(baseClassArray); + int64_t bcdOffset64 = TO_INT64(bcdOffset32); ea_t bcd = (ea_t) (colBase64 + bcdOffset64); - UINT32 tdOffset32 = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor)); - INT64 tdOffset64 = TO_INT64(tdOffset32); + uint32_t tdOffset32 = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, typeDescriptor)); + int64_t tdOffset64 = TO_INT64(tdOffset32); ea_t typeInfo = (ea_t) (colBase64 + tdOffset64); bcdInfo *bi = &list[i]; type_info_64::getName(typeInfo, bi->m_name, SIZESTR(bi->m_name)); // Add info to list - UINT32 mdisp = get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, mdisp))); - UINT32 pdisp = get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, pdisp))); - UINT32 vdisp = get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, vdisp))); + uint32_t mdisp = get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, mdisp))); + uint32_t pdisp = get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, pdisp))); + uint32_t vdisp = get_32bit(bcd + (offsetof(_RTTIBaseClassDescriptor, pmd) + offsetof(PMD, vdisp))); // As signed int - bi->m_pmd.mdisp = *((PINT32) &mdisp); - bi->m_pmd.pdisp = *((PINT32) &pdisp); - bi->m_pmd.vdisp = *((PINT32) &vdisp); + bi->m_pmd.mdisp = *((int32_t*) &mdisp); + bi->m_pmd.pdisp = *((int32_t*) &pdisp); + bi->m_pmd.vdisp = *((int32_t*) &vdisp); bi->m_attribute = get_32bit(bcd + offsetof(_RTTIBaseClassDescriptor, attributes)); //msg(" BN: [%d] \"%s\", ATB: %04X\n", i, szBuffer1, get_32bit((ea_t) &pBCD->attributes)); @@ -1424,10 +1423,10 @@ static void RTTI::getBCDInfo(ea_t col, __out bcdList &list, __out UINT32 &numBas // ====================================================================================== // Process RTTI vftable info -// Returns TRUE if if vftable and wasn't named on entry -BOOL RTTI::processVftable(ea_t vft, ea_t col, BOOL known) +// Returns true if if vftable and wasn't named on entry +bool RTTI::processVftable(ea_t vft, ea_t col, bool known) { - BOOL result = FALSE; + bool result = false; ea_t chd = BADADDR; ea_t typeInfo = BADADDR; @@ -1440,9 +1439,9 @@ BOOL RTTI::processVftable(ea_t vft, ea_t col, BOOL known) else { // 64bit offsets relative to objectBase - UINT32 tdOffset = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, typeDescriptor)); - UINT32 chdOffset = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, classDescriptor)); - UINT32 objectLocator = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, objectBase)); + uint32_t tdOffset = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, typeDescriptor)); + uint32_t chdOffset = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, classDescriptor)); + uint32_t objectLocator = get_32bit(col + offsetof(_RTTICompleteObjectLocator_64, objectBase)); ea_t colBase = (col - (ea_t) objectLocator); typeInfo = (colBase + (ea_t) tdOffset); @@ -1459,15 +1458,15 @@ BOOL RTTI::processVftable(ea_t vft, ea_t col, BOOL known) char demangledColName[MAXSTR]; getPlainTypeName(colName, demangledColName); - UINT32 chdAttributes = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, attributes)); - UINT32 offset = get_32bit(col + offsetof(_RTTICompleteObjectLocator, offset)); + uint32_t chdAttributes = get_32bit(chd + offsetof(_RTTIClassHierarchyDescriptor, attributes)); + uint32_t offset = get_32bit(col + offsetof(_RTTICompleteObjectLocator, offset)); // Parse BCD info bcdList list; - UINT32 numBaseClasses; + uint32_t numBaseClasses; getBCDInfo(col, list, numBaseClasses); - BOOL sucess = FALSE, isTopLevel = FALSE; + bool sucess = false, isTopLevel = false; qstring cmt; // ======= Simple or no inheritance @@ -1476,7 +1475,7 @@ BOOL RTTI::processVftable(ea_t vft, ea_t col, BOOL known) // Set the vftable name if (!hasName(vft)) { - result = TRUE; + result = true; // Decorate raw name as a vftable. I.E. const Name::`vftable' char decorated[MAXSTR]; @@ -1501,10 +1500,10 @@ BOOL RTTI::processVftable(ea_t vft, ea_t col, BOOL known) getPlainTypeName(list[0].m_name, plainName); cmt.sprnt("%s%s: ", ((list[0].m_name[3] == 'V') ? "" : "struct "), plainName); placed++; - isTopLevel = ((strcmp(list[0].m_name, colName) == 0) ? TRUE : FALSE); + isTopLevel = ((strcmp(list[0].m_name, colName) == 0) ? true : false); // Child object hierarchy - for (UINT32 i = 1; i < numBaseClasses; i++) + for (uint32_t i = 1; i < numBaseClasses; i++) { // Append name getPlainTypeName(list[i].m_name, plainName); @@ -1520,13 +1519,13 @@ BOOL RTTI::processVftable(ea_t vft, ea_t col, BOOL known) { // Plain, no inheritance object(s) cmt.sprnt("%s%s: ", ((colName[3] == 'V') ? "" : "struct "), demangledColName); - isTopLevel = TRUE; + isTopLevel = true; } if (placed > 1) cmt += ';'; - sucess = TRUE; + sucess = true; } // ======= Multiple inheritance, and, or, virtual inheritance hierarchies else @@ -1539,12 +1538,12 @@ BOOL RTTI::processVftable(ea_t vft, ea_t col, BOOL known) { _ASSERT(strcmp(colName, list[0].m_name) == 0); bi = &list[0]; - isTopLevel = TRUE; + isTopLevel = true; } else { // Get our object BCD level by matching COL offset to displacement - for (UINT32 i = 0; i < numBaseClasses; i++) + for (uint32_t i = 0; i < numBaseClasses; i++) { if (list[i].m_pmd.mdisp == offset) { @@ -1558,7 +1557,7 @@ BOOL RTTI::processVftable(ea_t vft, ea_t col, BOOL known) if (!bi) { //msg("** %llX MI COL class offset: %X(%d) not in BCD.\n", vft, offset, offset); - for (UINT32 i = 0; i < numBaseClasses; i++) + for (uint32_t i = 0; i < numBaseClasses; i++) { if (list[i].m_pmd.pdisp != -1) { @@ -1579,7 +1578,7 @@ BOOL RTTI::processVftable(ea_t vft, ea_t col, BOOL known) // Set the vft name if (!hasName(vft)) { - result = TRUE; + result = true; char decorated[MAXSTR]; _snprintf_s(decorated, sizeof(decorated), SIZESTR(decorated), FORMAT_RTTI_VFTABLE, SKIP_TD_TAG(colName)); @@ -1601,7 +1600,7 @@ BOOL RTTI::processVftable(ea_t vft, ea_t col, BOOL known) placed++; // Concatenate forward child hierarchy - for (UINT32 i = 1; i < numBaseClasses; i++) + for (uint32_t i = 1; i < numBaseClasses; i++) { getPlainTypeName(list[i].m_name, plainName); cmt.cat_sprnt("%s%s, ", ((list[i].m_name[3] == 'V') ? "" : "struct "), plainName); @@ -1619,7 +1618,7 @@ BOOL RTTI::processVftable(ea_t vft, ea_t col, BOOL known) // Set vftable name if (!hasName(vft)) { - result = TRUE; + result = true; char decorated[MAXSTR]; strcpy(decorated, FORMAT_RTTI_VFTABLE_PREFIX); @@ -1675,7 +1674,7 @@ BOOL RTTI::processVftable(ea_t vft, ea_t col, BOOL known) if (placed > 1) cmt += ';'; - sucess = TRUE; + sucess = true; } else msg("%llX ** Couldn't find a BCD for MI/VI hierarchy!\n", vft); @@ -1694,7 +1693,7 @@ BOOL RTTI::processVftable(ea_t vft, ea_t col, BOOL known) if (!hasAnteriorComment(colPtr)) setAnteriorComment(colPtr, "\n; %s %s", ((colName[3] == 'V') ? "class" : "struct"), cmt.c_str()); - result = TRUE; + result = true; } } else @@ -1726,7 +1725,7 @@ BOOL RTTI::processVftable(ea_t vft, ea_t col, BOOL known) // New strategy: Since IDA's own internal RTTI system is so good now at leat at version 9, we'll // first gather all the IDA defined ones into cache. -BOOL RTTI::gatherKnownRttiData() +bool RTTI::gatherKnownRttiData() { try { @@ -1734,10 +1733,10 @@ BOOL RTTI::gatherKnownRttiData() #define PATE(_prefix, _verify, _eaSet) { _prefix, _verify, _eaSet } struct PATCE { - LPCSTR prefix; - LPCSTR verify; + const char * prefix; + const char * verify; eaSet *set; - } __declspec(align(32)) rttiTypePatterns[] = + } ALIGN(32) rttiTypePatterns[] = { PATE("??_R0", "`RTTI Type Descriptor'", &tdSet), PATE("??_R1", "`RTTI Base Class Descriptor", &bcdSet), @@ -1752,7 +1751,7 @@ BOOL RTTI::gatherKnownRttiData() for (size_t i = 0; i < nameCount; i++) { // Next name - LPCSTR name = get_nlist_name(i); + const char * name = get_nlist_name(i); for (size_t j = 0; j < _countof(rttiTypePatterns); j++) { // Match a known RTTI type pattern? @@ -1776,7 +1775,7 @@ BOOL RTTI::gatherKnownRttiData() if(i % 1000) if (WaitBox::isUpdateTime()) if (WaitBox::updateAndCancelCheck()) - return TRUE; + return true; } TIMESTAMP endTime = (GetTimeStamp() - startTime); char buf1[32], buf2[32], buf3[32], buf4[32]; @@ -1791,5 +1790,5 @@ BOOL RTTI::gatherKnownRttiData() for (const eaSet *sp: all) superSet.insert(sp->begin(), sp->end()); } CATCH() - return FALSE; + return false; } diff --git a/RTTI.h b/RTTI.h index 411b00d..7af3ca3 100644 --- a/RTTI.h +++ b/RTTI.h @@ -9,28 +9,32 @@ namespace RTTI // std::type_info, aka "_TypeDescriptor" and "_RTTITypeDescriptor" in CRT source, class representation struct type_info { - static BOOL isValid(ea_t typeInfo); - static BOOL isTypeName(ea_t name); - static int getName(ea_t typeInfo, __out LPSTR bufffer, int bufferSize); + static bool isValid(ea_t typeInfo); + static bool isTypeName(ea_t name); + static int getName(ea_t typeInfo, char * buffer, int bufferSize); static void tryStruct(ea_t typeInfo); }; + #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4200) // nonstandard extension used: zero-sized array in struct/union - struct __declspec(novtable) type_info_32 : type_info + #endif + struct type_info_32 : type_info { EA_32 vfptr; // 00 type_info class vftable EA_32 _M_data; // 04 NULL until loaded at runtime. char _M_d_name[]; // 08 Mangled name (prefix: .?AV=classes, .?AU=structs) }; - struct __declspec(novtable) type_info_64 : type_info + struct type_info_64 : type_info { ea_t vfptr; // 00 type_info class vftable ea_t _M_data; // 08 NULL until loaded at runtime. char _M_d_name[]; // 10 Mangled name (prefix: .?AV=classes, .?AU=structs) }; + #ifdef _MSC_VER #pragma warning(pop) + #endif // Pointer to Member Data: generalized pointer-to-member descriptor struct PMD @@ -43,41 +47,41 @@ namespace RTTI // "Base Class Descriptor" (BCD) // Describes all base classes together with information to derived class access dynamically // attributes flags - const UINT32 BCD_NOTVISIBLE = 0x01; - const UINT32 BCD_AMBIGUOUS = 0x02; - const UINT32 BCD_PRIVORPROTINCOMPOBJ = 0x04; - const UINT32 BCD_PRIVORPROTBASE = 0x08; - const UINT32 BCD_VBOFCONTOBJ = 0x10; - const UINT32 BCD_NONPOLYMORPHIC = 0x20; - const UINT32 BCD_HASPCHD = 0x40; // pClassDescriptor field is present + const uint32_t BCD_NOTVISIBLE = 0x01; + const uint32_t BCD_AMBIGUOUS = 0x02; + const uint32_t BCD_PRIVORPROTINCOMPOBJ = 0x04; + const uint32_t BCD_PRIVORPROTBASE = 0x08; + const uint32_t BCD_VBOFCONTOBJ = 0x10; + const uint32_t BCD_NONPOLYMORPHIC = 0x20; + const uint32_t BCD_HASPCHD = 0x40; // pClassDescriptor field is present // struct _RTTIBaseClassDescriptor { int typeDescriptor; // 00 Image relative offset of TypeDescriptor. Pointer EA_32 for 32bit, offset added to COL base ea_t for 64bit - UINT32 numContainedBases; // 04 Number of nested classes following in the Base Class Array + uint32_t numContainedBases; // 04 Number of nested classes following in the Base Class Array PMD pmd; // 08 Pointer-to-member displacement info - UINT32 attributes; // 0C Flags + uint32_t attributes; // 0C Flags int classDescriptor; // 10 Image relative offset of _RTTIClassHierarchyDescriptor. If "attributes" & BCD_HASPCHD - static BOOL isValid(ea_t bcd, INT64 colBase64 = NULL); - static void tryStruct(ea_t bcd, __out_bcount(MAXSTR) LPSTR baseClassName, INT64 colBase64 = NULL); + static bool isValid(ea_t bcd, int64_t colBase64 = 0); + static void tryStruct(ea_t bcd, char * baseClassName, int64_t colBase64 = 0); }; // "Class Hierarchy Descriptor" (CHD) describes the inheritance hierarchy of a class; shared by all COLs for the class // attributes flags - const UINT32 CHD_MULTINH = 0x01; // Multiple inheritance - const UINT32 CHD_VIRTINH = 0x02; // Virtual inheritance - const UINT32 CHD_AMBIGUOUS = 0x04; // Ambiguous inheritance + const uint32_t CHD_MULTINH = 0x01; // Multiple inheritance + const uint32_t CHD_VIRTINH = 0x02; // Virtual inheritance + const uint32_t CHD_AMBIGUOUS = 0x04; // Ambiguous inheritance struct _RTTIClassHierarchyDescriptor { - UINT32 signature; // 00 Zero until loaded - UINT32 attributes; // 04 Flags - UINT32 numBaseClasses; // 08 Number of classes in the following 'baseClassArray' + uint32_t signature; // 00 Zero until loaded + uint32_t attributes; // 04 Flags + uint32_t numBaseClasses; // 08 Number of classes in the following 'baseClassArray' int baseClassArray; // 0C _RTTIBaseClassArray*. Pointer EA_32 for 32bit, offset added to COL base ea_t for 64bit - static BOOL isValid(ea_t chd, INT64 colBase64 = NULL); - static void tryStruct(ea_t chd, INT64 colBase64 = NULL); + static bool isValid(ea_t chd, int64_t colBase64 = 0); + static void tryStruct(ea_t chd, int64_t colBase64 = 0); }; #if 0 @@ -94,32 +98,32 @@ namespace RTTI // "Complete Object Locator" (COL) location of the complete object from a specific vftable pointer struct _RTTICompleteObjectLocator { - UINT32 signature; // 00 32bit zero, 64bit one, until loaded - UINT32 offset; // 04 Offset of this vftable in the complete class - UINT32 cdOffset; // 08 Constructor displacement offset + uint32_t signature; // 00 32bit zero, 64bit one, until loaded + uint32_t offset; // 04 Offset of this vftable in the complete class + uint32_t cdOffset; // 08 Constructor displacement offset int typeDescriptor; // 0C (type_info *) of the complete class. Pointer EA_32 for 32bit, offset added to ea_t for 64bit int classDescriptor; // 10 (_RTTIClassHierarchyDescriptor *) Describes inheritance hierarchy. Pointer EA_32 for 32bit, offset added to ea_t for 64bit - static BOOL isValid(ea_t col); - static BOOL tryStruct(ea_t col); + static bool isValid(ea_t col); + static bool tryStruct(ea_t col); }; - struct __declspec(novtable) _RTTICompleteObjectLocator_32 : _RTTICompleteObjectLocator + struct _RTTICompleteObjectLocator_32 : _RTTICompleteObjectLocator { - static BOOL isValid2(ea_t col); + static bool isValid2(ea_t col); }; - struct __declspec(novtable) _RTTICompleteObjectLocator_64 : _RTTICompleteObjectLocator + struct _RTTICompleteObjectLocator_64 : _RTTICompleteObjectLocator { int objectBase; // 14 Object base offset (base = ptr col - objectBase) }; #pragma pack(pop) - const WORD IS_TOP_LEVEL = 0x8000; + const uint16_t IS_TOP_LEVEL = 0x8000; void freeWorkingData(); void addDefinitionsToIda(); - BOOL gatherKnownRttiData(); - BOOL processVftable(ea_t eaTable, ea_t col, BOOL known = FALSE); + bool gatherKnownRttiData(); + bool processVftable(ea_t eaTable, ea_t col, bool known = false); } diff --git a/StdAfx.h b/StdAfx.h index 924c256..eac4955 100644 --- a/StdAfx.h +++ b/StdAfx.h @@ -2,27 +2,34 @@ // Common includes and defines #pragma once +#ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #define WINVER 0x0A00 // _WIN32_WINNT_WIN10 #define _WIN32_WINNT 0x0A00 #include +#include +#include +#include +#endif + #include #include #include -#include #include -#include -#include +#ifdef _MSC_VER #pragma intrinsic(memset, memcpy, strcat, strcmp, strcpy, strlen, abs, fabs, labs, atan, atan2, tan, sqrt, sin, cos) +#endif -// IDA SDK +// IDA SDK (must be included BEFORE Qt to avoid qstrlen/qstrncmp redefinition) #define USE_DANGEROUS_FUNCTIONS #define USE_STANDARD_FILE_FUNCTIONS +#ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4244) // conversion from 'ssize_t' to 'int', possible loss of data #pragma warning(disable:4267) // conversion from 'size_t' to 'uint32', possible loss of data #pragma warning(disable:4018) // warning C4018: '<': signed/unsigned mismatch +#endif #include #include #include @@ -30,9 +37,18 @@ #include #include #include +#ifdef _MSC_VER #pragma warning(pop) +#endif -// Qt SDK +// Rename Qt's qstr* functions to avoid conflict with IDA SDK's pro.h +#define qstrlen qt_qstrlen +#define qstrncmp qt_qstrncmp +#define qstrncpy qt_qstrncpy +#define qstrcmp qt_qstrcmp +#define qstrdup qt_qstrdup + +// Qt SDK (after IDA SDK headers) #include #include #include @@ -43,13 +59,15 @@ #include #include #include -// IDA SDK Qt libs -#pragma comment(lib, "Qt6Core.lib") -#pragma comment(lib, "Qt6Gui.lib") -#pragma comment(lib, "Qt6Widgets.lib") -#include "Utility.h" -#include "undname.h" +#undef qstrlen +#undef qstrncmp +#undef qstrncpy +#undef qstrcmp +#undef qstrdup + +// Cross-platform compatibility layer +#include "Compat.h" #include #include diff --git a/Vftable.cpp b/Vftable.cpp index 54395ea..612ad92 100644 --- a/Vftable.cpp +++ b/Vftable.cpp @@ -1,14 +1,14 @@ // Virtual function table parsing support -#include "stdafx.h" +#include "StdAfx.h" #include "Main.h" #include "Vftable.h" #include "RTTI.h" // Attempt to get information of and fix vftable at address. -// Return TRUE along with info if valid vftable parsed at address -BOOL vftable::getTableInfo(ea_t ea, vtinfo &info) +// Return true along with info if valid vftable parsed at address +bool vftable::getTableInfo(ea_t ea, vtinfo &info) { // Start of a vft should have an xref and a name (auto, or user, etc). // Ideal flags 32bit: FF_DWRD, FF_0OFF, FF_REF, FF_NAME, FF_DATA, FF_IVL @@ -16,7 +16,7 @@ BOOL vftable::getTableInfo(ea_t ea, vtinfo &info) flags_t flags = get_flags(ea); if(has_xref(flags) && has_any_name(flags) && (plat.isEa(flags) || is_unknown(flags))) { - ZeroMemory(&info, sizeof(info)); + memset(&info, 0, sizeof(info)); // Get raw (auto-generated mangled, or user named) vft name //if (!get_name(BADADDR, ea, info.name, SIZESTR(info.name))) @@ -25,17 +25,14 @@ BOOL vftable::getTableInfo(ea_t ea, vtinfo &info) // Attempt to determine the vft's method count ea_t start = info.start = ea; - while (TRUE) + while (true) { // Should be an pointer sized offset to a function here (could be unknown if dirty IDB) // Ideal flags for 32bit: FF_DWRD, FF_0OFF, FF_REF, FF_NAME, FF_DATA, FF_IVL //dumpFlags(ea); flags_t indexFlags = get_flags(ea); if (!(plat.isEa(indexFlags) || is_unknown(indexFlags))) - { - //msg(" ******* 1\n"); break; - } // Look at what this (assumed vftable index) points too ea_t memberPtr = plat.getEa(ea); @@ -44,8 +41,6 @@ BOOL vftable::getTableInfo(ea_t ea, vtinfo &info) // vft's some times have a trailing zero pointer (alignment, or?), fix it if (memberPtr == 0) fixEa(ea); - - //msg(" ******* 2\n"); break; } @@ -58,14 +53,10 @@ BOOL vftable::getTableInfo(ea_t ea, vtinfo &info) const SEGMENT *methodSeg = FindCachedSegment(memberPtr); if (methodSeg && (methodSeg->type & _CODE_SEG)) { - #pragma message(__LOC2__ " >> Catch this 2nd chance fix case") - _ASSERT(FALSE); - //msg(" ******* 3\n"); - //break; + _ASSERT(false); } else { - //msg(" ******* 3.5\n"); break; } } @@ -74,17 +65,11 @@ BOOL vftable::getTableInfo(ea_t ea, vtinfo &info) { // If we see a ref after first index it's probably the beginning of the next vft or something else if (has_xref(indexFlags)) - { - //msg(" ******* 4\n"); break; - } // If we see a COL here it must be the start of another vftable if (RTTI::_RTTICompleteObjectLocator::isValid(memberPtr)) - { - //msg(" ******* 5\n"); break; - } } // As needed fix ea_t pointer, and, or, missing code and function def here @@ -97,11 +82,9 @@ BOOL vftable::getTableInfo(ea_t ea, vtinfo &info) if ((info.methodCount = ((ea - start) / plat.ptrSize)) > 0) { info.end = ea; - //msg(" vftable: %llX-%llX, methods: %d\n", rtInfo.eaStart, rtInfo.eaEnd, rtInfo.uMethods); - return TRUE; + return true; } } - //dumpFlags(ea); - return FALSE; + return false; } diff --git a/Vftable.h b/Vftable.h index 12f4b03..aa66393 100644 --- a/Vftable.h +++ b/Vftable.h @@ -7,12 +7,12 @@ namespace vftable // vftable info container struct vtinfo { - ea_t start, end; // union { EA_32 ea_t} addresses + ea_t start, end; // addresses int methodCount; //char name[MAXSTR]; }; - BOOL getTableInfo(ea_t ea, vtinfo &info); + bool getTableInfo(ea_t ea, vtinfo &info); - // Returns TRUE if mangled name prefix indicates a vftable - inline BOOL isValid(LPCSTR name){ return(*((PDWORD) name) == 0x375F3F3F /*"??_7"*/); } + // Returns true if mangled name prefix indicates a vftable + inline bool isValid(const char *name){ return(*((const uint32_t *) name) == 0x375F3F3F /*"??_7"*/); } } diff --git a/dialog.ui b/dialog.ui index 9315ba6..05e48f9 100644 --- a/dialog.ui +++ b/dialog.ui @@ -2,32 +2,6 @@ MainCIDialog - - - 0 - 0 - 292 - 311 - - - - - 0 - 0 - - - - - 292 - 311 - - - - - 292 - 311 - - Class Informer @@ -35,176 +9,150 @@ :/res/icon.png:/res/icon.png - - - true - - - - 120 - 272 - 156 - 24 - - - - Qt::Horizontal - - - QDialogButtonBox::NoButton - - - false - - - - - - 15 - 94 - 121 - 17 - - - - - Noto Sans - 10 - - - - - - - Place structures - - - - - - 15 - 122 - 256 - 17 - - - - - Noto Sans - 10 - - - - - - - Process static initializers && terminators - - - - - - 15 - 148 - 151 - 17 - - - - - Noto Sans - 10 - - - - - - - Audio on completion - - - - - - 15 - 225 - 141 - 16 - - - - - Noto Sans - 10 - - - - QFrame::Sunken - - - <a href="https://github.com/kweatherman/IDA_ClassInformer_PlugIn" style="color:#AA00FF;">Class Informer</a> - - - Qt::AutoText - - - true - - - - - - 0 - 0 - 292 - 74 - - - - - - - - - - Qt::PlainText - - - Qt::NoTextInteraction - - - - - - 15 - 186 - 129 - 27 - - - - - Noto Sans - 10 - - - - <html><head/><body><p>Optionally select wich segments to scan for strings.</p></body></html> - - - SELECT SEGMENTS - - - false - - + + + 8 + + 0 + 0 + 0 + 8 + + + + + 292 + 74 + + + + + + + Qt::PlainText + + + Qt::NoTextInteraction + + + + + + 15 + 15 + + + + + 10 + + + + Place structures + + + + + + + + 10 + + + + Process static initializers && terminators + + + + + + + + 10 + + + + Audio on completion + + + + + + + + 10 + + + + + 0 + 0 + + + + <html><head/><body><p>Optionally select wich segments to scan for strings.</p></body></html> + + + SELECT SEGMENTS + + + false + + + + + + + + 10 + + + + <a href="https://github.com/kweatherman/IDA_ClassInformer_PlugIn" style="color:#AA00FF;">Class Informer</a> + + + Qt::AutoText + + + true + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::NoButton + + + false + + + + -