diff --git a/README.md b/README.md index f342054..cbfc5d9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -# ida-scripts -Collection of IDA Pro/Hex-Rays scripts +# IDA configs +Collection of my IDA Pro/Hex-Rays scripts and plugins Tested on IDA7.0 since I am too broke to afford IDA7.1 + +I didn't write the ret-sync stuff, it's just a port for the new Python plugin API. diff --git a/cfg/ida.cfg b/cfg/ida.cfg new file mode 100644 index 0000000..8f8950c --- /dev/null +++ b/cfg/ida.cfg @@ -0,0 +1,1448 @@ +// IDA configuration file + +// +// PLEASE READ THIS NOTICE CAREFULLY +// --------------------------------- +// +// Configuration file is read 2 times. +// First pass is performed as soon as IDA is loaded +// Second pass is performed when IDA determines the processor type +// +// All processor specific tuning is located at the second part of this file. +// +// Please note that some parameters occur several times in the file: +// each occurence for different processor. +// +// User-specific tuning can be made in idauser.cfg file +// (see end of this file) +// +// You may temporarily change a configuration variable by using +// command line switches: -d and -D +// The -d switch is processed at the first configuration pass. +// The -D switch is processed at the second configuration pass. +// Example: +// ida -dVPAGESIZE=0x4000 -c newfile +// +// C-like preprocessor directives are allowed. +// You can use C-like constants in this file. +// + +//========================================================================= +// F I R S T P A S S +//========================================================================= +// +// First pass. +// Define file extension table, memory sizes, screen mode +// and OS specific parameters. +// +//------------------------------------------------------------------------- +#ifdef ____ // first pass of config starts here +// +// Default processor configuration table +// ------------------------------------- +// +// The default processor will be used if the processor type is +// not specified in the command line. +// Feel free to customize this table. +// +DEFAULT_PROCESSOR = { +/* Extension Processor */ + "com" : "" // IDA will try the specified + "exe" : "" // extensions if no extension is + "dll" : "" // given. + "drv" : "" + "sys" : "" + "bin" : "" // Empty processor means the default processor + "ovl" : "" + "ovr" : "" + "ov?" : "" + "nlm" : "" + "lan" : "" + "dsk" : "" + "obj" : "" + "prc" : "68000" // PalmPilot programs + "axf" : "arm" + "h68" : "68000" // MC68000 for *.H68 files + "i51" : "8051" // i8051 for *.I51 files + "sav" : "pdp11" // PDP-11 for *.SAV files + "rom" : "z80" // Z80 for *.ROM files + "cla*": "java" + "s19": "6811" + "epoc": "arm" + "o": "" + "*": "" // Default processor +} + +WORKDIR = "" // Work direcrtory. IDA will create + // temporary database files there. + // Set to a directory on a separate disk + // to improve open/close performance + // of huge databases. + +// Plugins to automatically launch when opening an existing idb file. +// Currently we autorun the 'windbg' plugin to display Windows Crash Dump files. +AUTORUN_PLUGINS = +{ +/* FileType Plugin and argument */ +#ifdef __NT__ + "windmp" : "windbg_user:-2" +#endif +} + +// +// Memory configuration parameters +// ------------------------------- +// NOTES: +// +// 1. DATABASE_MEMORY determines how much memory will be allocated +// for names, strings, xrefs, functions, etc. If it is == 0 then +// IDA uses the following alrogithm: +// +// DATABASE_MEMORY = new_file +// ? input_file_size * 4 +// : old_btree_size/2 +// IDA never allocates more than 128MB in this case. +// +// 2. page sizes (VPAGESIZE and NPAGESIZE) must be powers of 2. +// +// 3. if VPAGES == 0 then 32bit IDA reserves memory by the following +// alrogithm: +// +// VMEM = new_file +// ? input_file_size*4 +// : allocated_addressing_space; +// +// VPAGES = VMEM / VPAGESIZE +// +// 4. Here is the total amount of memory allocated when IDA starts: +// +// TOTAL = DATABASE_MEMORY + VPAGESIZE*VPAGES + NPAGESIZE*NPAGES +// + + +DATABASE_MEMORY = 0 // Size of btree buffer in bytes. +VPAGESIZE = 8192 // Virtual memory page size + // (effective for new bases only) + // 8192 => 128MB addressing space is the limit +VPAGES = 0 // Size of virtual memory window + // (in pages) +NPAGESIZE = 8192 // Name pointers page size + // (effective for new bases only) +NPAGES = 32 // how big will be the memory buffer? + // (each name uses 4 bytes) + // The default settings allow to keep + // in memory 2^16 names. The remaining + // names will be swapped to the disk. + +// limit the xref cache size to this amount of bytes +// (0 to disable the limit) +#ifdef __X64__ + XREF_CACHE_LIMIT = 0 +#else + XREF_CACHE_LIMIT = 1500000000 +#endif + + +// the following maps a character encoding, to one (or many) +// associated 'culture'(s). +// +// This is used to decide what codepoints should automatically be +// added to the sets of codepoints that contain the CURRENT_CULTURE +// entry, in case the IDB has a single-byte (and non-UTF-8) encoding. +// (See StrlitChars, etc... for more info.) +// +// Note: if a 'CULTURE' configuration directive is specified, it will +// override the culture(s) derived from the encoding. +// +// Note: the encodings below that consist of only a number, are considered +// windows ANSI codepages, and will map to multiple encodings whose +// names contain that codepage. E.g., 1252 will map to: "windows-1252", +// "windows1252", "cp1252", "1252". +ENCODING_CULTURES = + 1250: Central_Europe, + 1251: Cyrillic, + 1252: Latin_1, + 1253: Greek, + 1254: Turkish, + 1255: Hebrew, + 1256: Arabic, + 1257: Baltic, + 1258: Vietnam, + 874: Thai, + cp863: Latin_1 Greek; + + +//------------------------------------------------------------------------- +// The following drives the upgrade of pre-7.0 databases, regarding the +// conversion of non-ASCII user strings (comments, identifiers, etc...) +// This does not affect string literals in any way. +//------------------------------------------------------------------------- + +// In case UPGRADE_CPSTRINGS_SRCENC[A] (see below) is not specified, +// should IDA warn (in the "Output window") when it performed conversion +// of strings with what it believes might be the source encoding? +// (Note: if UPGRADE_CPSTRINGS_SRCENC[A] is specified, this has no effect.) +UPGRADE_CPSTRINGS_SILENT = NO + +// The source encoding for non-ASCII identifiers, comments, etc.. +// UPGRADE_CPSTRINGS_SRCENC = "CP855"; // cyrillic OEM codepage + +// Some bits of data were stored in a separate encoding than the +// comments (i.e., they were stored in the local ANSI codepage, +// not the local OEM codepage). This lets you specify that +// encoding. +// UPGRADE_CPSTRINGS_SRCENCA = "windows-1251"; // cyrillic ANSI codepage + +// NOTE: it's possible to pass config directives to IDA directly +// from the command line. The following terminal commands are +// therefore valid: +// +// * Have IDA to silently perform conversion, using whatever +// it thinks might be the source encoding (guessed from the system): +// $ ida -dUPGRADE_CPSTRINGS_SILENT=YES some695.idb +// +// * Have IDA to silently perform conversion, using Cyrillic +// OEM codepage as the source encoding: +// $ ida -dUPGRADE_CPSTRINGS_SRCENC=\"CP855\" some695.idb +// (notice the escaping of the CP855 string. It's necessary +// because config directives on the command line are parsed +// using the exact same C-style lexer as the config file, and +// thus double-quotes are expected around a string literal.) + +#else // first pass ends here + + +//========================================================================= +// +// S E C O N D P A S S +// +//========================================================================= +// Second pass starts here. +// At the second pass IDA defines a macro "____" +// For example, if the user specified 'z80' processor, +// then __Z80__ will be defined. +// (note that the processor name is converted to uppercase) +// Also, a processor module file name is used to create a macro +// "____". For example, IBM PC loader defines "__PC__" symbol. +// These macros can be used for processor specific tuning, for example: +// +// #ifdef __Z80__ +// MAX_AUTONAME_LEN = 8 +// #endif +// +//------------------------------------------------------------------------- +// +// General parameteres for all processors +// (processor specific parameters are below) +// +//------------------------------------------------------------------------- + +PACK_DATABASE = 1 // 0 - don't pack at all + // 1 - pack database (store) + // 2 - pack database (deflate) +CREATE_BACKUPS = NO // Create database backups +COLLECT_GARBAGE = NO // Collect garbage when saving the database +ABANDON_DATABASE = NO // Set to YES to not save database on exit (useful in batch mode) +STORE_USER_INFO = YES // Store information about the user + // who created the database in the database. + // Use DelUserInfo() IDC function to delete + // user info in existing databases. + +CHECK_MANUAL_ARGS = YES // Check equality of manual operands + // entered by Alt-F1 + +// Program to visualize graphs + +#ifdef __NT__ +// program to run after generating the graph. The filename is added at the end +GRAPH_VISUALIZER = "qwingraph.exe -remove -timelimit 10" +// format of graph files to generate. Possible values: "GDL" and "DOT" +GRAPH_FORMAT = "GDL" +// GRAPH_VISUALIZER = "C:\\PROGRA~2\\GRAPHV~1.3\\BIN\\dotty.exe" +// GRAPH_FORMAT = "DOT" +#else +#ifdef __LINUX__ +GRAPH_VISUALIZER = "qwingraph -remove -timelimit 10" +GRAPH_FORMAT = "GDL" +//GRAPH_VISUALIZER = "/usr/bin/dotty" +//GRAPH_FORMAT = "DOT" +#else # __MAC__ +GRAPH_VISUALIZER = "qwingraph -remove -timelimit 10" +GRAPH_FORMAT = "GDL" +#endif +#endif + +//------------------------------------------------------------------------- +// +// Analysis parameters +// +//------------------------------------------------------------------------- + +ENABLE_ANALYSIS = YES // Background analysis is enabled + +SHOW_INDICATOR = YES // Show background analysis indicator + +#define AF_CODE 0x00000001 // Trace execution flow +#define AF_MARKCODE 0x00000002 // Mark typical code sequences as code +#define AF_JUMPTBL 0x00000004 // Locate and create jump tables +#define AF_PURDAT 0x00000008 // Control flow to data segment is ignored +#define AF_USED 0x00000010 // Analyze and create all xrefs +#define AF_UNK 0x00000020 // Delete instructions with no xrefs +#define AF_PROCPTR 0x00000040 // Create function if data xref data->code32 exists +#define AF_PROC 0x00000080 // Create functions if call is present +#define AF_FTAIL 0x00000100 // Create function tails +#define AF_LVAR 0x00000200 // Create stack variables +#define AF_STKARG 0x00000400 // Propagate stack argument information +#define AF_REGARG 0x00000800 // Propagate register argument information +#define AF_TRACE 0x00001000 // Trace stack pointer +#define AF_VERSP 0x00002000 // Perform full SP-analysis. (\ph{verify_sp}) +#define AF_ANORET 0x00004000 // Perform 'no-return' analysis +#define AF_MEMFUNC 0x00008000 // Try to guess member function types +#define AF_TRFUNC 0x00010000 // Truncate functions upon code deletion +#define AF_STRLIT 0x00020000 // Create string literal if data xref exists +#define AF_CHKUNI 0x00040000 // Check for unicode strings +#define AF_FIXUP 0x00080000 // Create offsets and segments using fixup info +#define AF_DREFOFF 0x00100000 // Create offset if data xref to seg32 exists +#define AF_IMMOFF 0x00200000 // Convert 32bit instruction operand to offset +#define AF_DATOFF 0x00400000 // Automatically convert data to offsets +#define AF_FLIRT 0x00800000 // Use flirt signatures +#define AF_SIGCMT 0x01000000 // Append a signature name comment for recognized anonymous library functions +#define AF_SIGMLT 0x02000000 // Allow recognition of several copies of the same function +#define AF_HFLIRT 0x04000000 // Automatically hide library functions +#define AF_JFUNC 0x08000000 // Rename jump functions as j_... +#define AF_NULLSUB 0x10000000 // Rename empty functions as nullsub_... +#define AF_DODATA 0x20000000 // Coagulate data segs at the final pass +#define AF_DOCODE 0x40000000 // Coagulate code segs at the final pass +#define AF_FINAL 0x80000000 // Final pass of analysis +ANALYSIS = 0xDFFF9FF7ULL // This value is combination of the bits defined + // above + +#define AF2_DOEH 0x00000001 /// Handle EH information +#define AF2_DORTTI 0x00000002 /// Handle RTTI information +ANALYSIS2 = 0x00000003ULL // This value is combination of the bits defined + // above + +FLAT_OFF32 = NO // treat REF_OFF32 as 32-bit offset (otherwise try SEG16:OFF16 for 16bit segments) + +//------------------------------------------------------------------------- +// +// Text representation +// +//------------------------------------------------------------------------- + +OPCODE_BYTES = 0 // don't display instruction/data bytes + // The 'default' configuration in the registry may + // override this value +INDENTION = 16 // Indention of instructions + // The 'default' configuration in the registry may + // override this value +COMMENTS_INDENTION = 40 // Indention of short comments +MAX_TAIL = 16 // Tail depth (used to gather xref info) +MAX_XREF_LENGTH = 80 // Maximal length of line with cross-references +MAX_DATALINE_LENGTH = 70 // Data directives (db,dw, etc): + // max length of argument string +SHOW_AUTOCOMMENTS = NO // Display comments for every instruction + // Advanced users will turn this off + // Please note that there is another definition + // for IBM PC below +SHOW_BASIC_BLOCKS = NO // Generate an empty line at the end of a basic block +SHOW_BORDERS = YES // Borders between data/code +SHOW_EMPTYLINES = YES // Generate empty line to make disassembly more readable +SHOW_LINEPREFIXES = YES // Show line prefixes (like 1000:0000) +SHOW_SEGMENTS = YES // Show segments in addresses +USE_SEGMENT_NAMES = YES // Show segment names instead of numbers +SHOW_REPEATABLE_COMMENTS= YES // Show repeatable comments (disabling this increases IDA speed) +SHOW_SP = NO // Show stack pointer at the start of lines + // The 'default' configuration in the registry may + // override this value +SHOW_SUSPICIOUS = NO // Show marks (the red/orange color is bright enough) +SHOW_XREFS = 2 // Show 2 cross-references (the rest is accessible by Ctrl-X) +SHOW_XREF_FUNC = YES // Show function offsets in xrefs +SHOW_XREF_TYPES = YES // Show xref type marks +SHOW_XREF_VALUES = YES // If not, xrefs are displayed as "..." +SHOW_SEGXREFS = YES // Show segment part of addresses in cross-references +#if defined(__JAVA__) +SHOW_SOURCE_LINNUM = YES // Show source line numbers +#else +SHOW_SOURCE_LINNUM = NO // Show source line numbers +#endif +SHOW_TRYBLOCKS = YES // Show try block line information +SHOW_ASSUMES = YES // Generate 'assume' directives +SHOW_ORIGINS = YES // Generate 'org' directives +SHOW_REFCMTS = 1 // Show 1 reference to ASCII strings or demangled names + // (the rest is accessible by Ctrl-J) + +DEL_CODE_COMMENTS = YES // Delete a comment attached to an instruction + // when the instruction is deleted +MAX_ITEM_LINES = 25000 // Maximum number of lines for one item (one instruction or data) + +//------------------------------------------------------------------------- +// Colors +//------------------------------------------------------------------------- +#ifdef __GUI__ +//PROLOG_COLOR = 0xE0E0E0 // grey +//EPILOG_COLOR = 0xE0FFE0 // light green +//SWITCH_COLOR = 0xE0E0FF // pink +#endif + +//------------------------------------------------------------------------- +// +// Floating point numbers +// +//------------------------------------------------------------------------- +FPNUM_DIGITS = 0 // If non-zero, specifies the number of digits printed + // after the decimal point. The printed number may be + // truncated if necessary. + // If FPNUM_DIGITS is non-zero, FPNUM_LENGTH must be non-zero too + +FPNUM_LENGTH = 6 // If FP_DIGITS is non-zero: + // specifies the desired length of output string. + // IDA will print the number in regular (non-scientific) + // notation if possible. + // else + // controls the notation used to print the number: + // if the abs(number exponent) <= FPNUM_LENGTH + // print in regular notation + // else + // print in scientific notation + +// Example: to display numbers in reasonable range (0.00001..10000.0) nicely +// FPNUM_DIGITS=0 +// FPNUM_LENGTH=5 +// Too big and too small numbers will be printed using the scientific notation + +// Example: to display numbers nicely formatted with constant width (8) and +// constant decimal point position(3): +// FPNUM_DIGITS=3 +// FPNUM_LENGTH=8 +// IDA will print numbers in regular notation if possible. +// Attention, this setting will truncate all values to 3 digits after the decimal point + +// Example: print numbers in scientific notation +// FPNUM_DIGITS=0 +// FPNUM_LENGTH=0 + +// Example: forbidden combination: +// FPNUM_DIGITS=5 +// FPNUM_LENGTH=0 + +//------------------------------------------------------------------------- +// +// Text representation in the graph mode +// +//------------------------------------------------------------------------- +GRAPH_COMMENTS_INDENTION = 24 // Indention of short comments +GRAPH_INDENTION = 0 // Indention of instructions +GRAPH_MARGIN = 40 // Max node width +GRAPH_SHOW_LINEPREFIXES = NO // Show line prefixes (like 1000:0000) +GRAPH_SHOW_XREFS = 0 // Show no xrefs (use node title button for them) +GRAPH_OPCODE_BYTES = 0 // don't display instruction/data bytes + +//------------------------------------------------------------------------- +// +// ASCII strings & names +// +//------------------------------------------------------------------------- + +STRLIT_GENNAMES = YES // Generate names when making + // an ASCII string +STRLIT_TYPE_AUTO = YES // Should IDA mark generated ascii names + // as 'autogenerated'? + // Autogenerated names will be deleted + // when the ascii string is deleted + // Also, they are displayed with the + // same color as dummy names. +STRLIT_LINEBREAK = '\n' // This char forces IDA + // to start a new line +STRLIT_PREFIX = "a" // This prefix is used when a new + // name is generated + +#define STRTYPE_C 0 // C-style string. +#define STRTYPE_C_16 1 // Zero-terminated 16bit chars +#define STRTYPE_C_32 2 // Zero-terminated 32bit chars +#define STRTYPE_PASCAL 4 // Pascal-style, one-byte length prefix +#define STRTYPE_PASCAL_16 5 // Pascal-style, 16bit chars, one-byte length prefix +#define STRTYPE_LEN2 8 // Pascal-style, two-byte length prefix +#define STRTYPE_LEN2_16 9 // Pascal-style, 16bit chars, two-byte length prefix +#define STRTYPE_LEN4 12 // Pascal-style, two-byte length prefix +#define STRTYPE_LEN4_16 13 // Pascal-style, 16bit chars, two-byte length prefix +STRLIT_STYLE = STRTYPE_C // Default is C-style + +STRLIT_SERIAL = NO // Serial names are disabled +STRLIT_SERNUM = 0 // Number to start serial names +STRLIT_ZEROES = 0 // Number of leading zeroes in + // serial names +STRLIT_COMMENT = YES // Generate auto comment for + // ascii references. This option will + // display the beginning of ascii string + // at the instruction which refers + // to the string +STRLIT_SAVECASE = NO // Preserve case of ascii strings for identifiers + + // type of generated names: (dummy names) +#define NM_REL_OFF 0 +#define NM_PTR_OFF 1 +#define NM_NAM_OFF 2 +#define NM_REL_EA 3 +#define NM_PTR_EA 4 +#define NM_NAM_EA 5 +#define NM_EA 6 +#define NM_EA4 7 +#define NM_EA8 8 +#define NM_SHORT 9 +#define NM_SERIAL 10 +DUMMY_NAMES_TYPE = NM_EA + +MAX_AUTONAME_LEN = 15 // Maximal length of new autogenerated names + // (you may specify values up to 511) + // + // NOTE: As far as I know some assemblers can't handle such + // a long names. For example, Table Driven Assembler + // supports names' length up to 13. + // BE CAREFUL! + +// Types of names that must be included into the list of names +// (this list usually appears by pressing Ctrl-L) +// normal 1 +// public 2 +// auto 4 +// weak 8 + +LIST_NAMES = 0x07 // default: include normal, public, auto + +//------------------------------------------------------------------------- + +// Representation of demangled names +// There are two predefined forms of demangled names: short and long forms. +// Form of a demangled names is determined by combination of bits. +// Each bit inhibits or permits some part of the demangled name. + + // Pointer modifiers: +#define MNG_DEFNEAR 0x00000000 // inhibit near, display everything else +#define MNG_DEFNEARANY 0x00000001 // inhibit near/__ptr64, display everything else +#define MNG_DEFFAR 0x00000002 // inhibit far, display everything else +#define MNG_NOPTRTYP16 0x00000003 // inhibit everything (disables vc7-extensions) +#define MNG_DEFHUGE 0x00000004 // inhibit huge, display everything else +#define MNG_DEFPTR64 0x00000005 // inhibit __pt64, display everything else + // ATT: in 64bit must be + MNG_NOTYPE|MNG_NOCALLC +#define MNG_DEFNONE 0x00000006 // display all pointer modifiers +#define MNG_NOPTRTYP 0x00000007 // inhibit all pointer modifiers + +#define MNG_NODEFINIT 0x00000008 // Inhibit everything except the main name + // This flag is not recommended + // for __fastcall/__stdcall GCC3 names + // because there is a high probablity of + // incorrect demangling. Use it only when + // you are sure that the input is a + // cygwin/mingw function name +#define MNG_NOUNDERSCORE 0x00000010 // Inhibit underscores in __ccall, __pascal... + +#define MNG_NOTYPE 0x00000020 // Inhibit callc&based +#define MNG_NORETTYPE 0x00000040 // Inhibit return type of functions +#define MNG_NOBASEDT 0x00000080 // Inhibit base types + // NOTE: also inhibits "__linkproc__" +#define MNG_NOCALLC 0x00000100 // Inhibit __pascal/__ccall/etc +#define MNG_NOPOSTFC 0x00000200 // Inhibit postfix const +#define MNG_NOSCTYP 0x00000400 // Inhibit public/private/protected +#define MNG_NOTHROW 0x00000800 // Inhibit throw description +#define MNG_NOSTVIR 0x00001000 // Inhibit "static" & "virtual" +#define MNG_NOECSU 0x00002000 // Inhibit class/struct/union/enum +#define MNG_NOCSVOL 0x00004000 // Inhibit const/volatile/restrict + // NOTE: also inhibits "__unaligned" +#define MNG_NOCLOSUR 0x00008000 // Inhibit __closure for borland +#define MNG_NOUNALG 0x00010000 // Inhibit __unaligned (see NOCSVOL) +#define MNG_NOMANAGE 0x00020000 // Inhibit __pin/__box/__gc for ms(.net) +#define MNG_SHORT_S 0x00100000 // signed (int) is displayed as s(int) +#define MNG_SHORT_U 0x00200000 // unsigned (int) is displayed as u(int) +#define MNG_ZPT_SPACE 0x00400000 // Display space after comma in the arglist +#define MNG_DROP_IMP 0x00800000 // Inhibit __declspec(dllimport) +#define MNG_IGN_ANYWAY 0x02000000 // Ingore '_nn' at the end of name +#define MNG_IGN_JMP 0x04000000 // Ingore 'j_' at the beginning of name +#define MNG_MOVE_JMP 0x08000000 // Move 'j_' prefix to the demangled name + // If both MNG_IGN_JMP and MNG_MOVE_JMP + // are set then move the prefix only if + // the name was not truncated + +ShortNameForm = 0x0EA3BE67 // short form of demangled names +LongNameForm = 0x06400007 // long form of demangled names + +#define DEMNAM_CMNT 0 // comments +#define DEMNAM_NAME 1 // regular names +#define DEMNAM_NONE 2 // don't display + +DemangleNames = DEMNAM_CMNT // Show demangled names as comments + +DEMNAME_FIRST = NO // YES means that demangled name overrides + // type info if both are present + +//------------------------------------------------------------------------- +// +// Character translations and allowed character lists +// +//------------------------------------------------------------------------- + +// the following characters are allowed in strings, i.e. +// in order to find end of a string IDA looks for a character +// which doesn't belong to this array: +// Note about CURRENT_CULTURE: +// - if the IDB's default encoding for 1-byte/symbol strings, is not +// UTF-8, a "culture" will be derived from it. E.g., "windows-1252" +// will yield culture "Latin". +// - this cannot be done automatically for UTF-8, since UTF-8 covers +// the whole Unicode codepoints space. +// - regardless of whether a "culture" can be derived from the default +// encoding or not, this can be overriden by the CULTURE configuration +// property (see below) +// - the CURRENT_CULTURE directive tells IDA to consider all +// codepoints that are defined as part of that culture, as valid +// in the string literals. +// - this applies to codepoints >= 0x80 +// - there are 2 ways to mention a "culture": +// 1) the name of a .clt file in the cfg/ directory. E.g., "Latin" +// will correspond to the "clt_Latin.clt" file. In this case, +// the culture will contain all codepoints specified by the file. +// 2) the name of a Unicode "Block". In that case, the culture will +// contain all the letters (Lu, Ll & Lo) that this block contains. +// The list of blocks are available there: +// http://www.fileformat.info/info/unicode/block/index.htm , and +// spaces in the block names must be replaced with underscores +// in order to obtain culture names. +// (It is worth pointing out that, in the first case, the file can, +// itself, include cultures: either by file name or as Unicode block) +StrlitChars = + "\r\n\a\v\b\t\x1B" + " !\"#$%&'()*+,-./0123456789:;<=>?" + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" + "`abcdefghijklmnopqrstuvwxyz{|}~", + // Those should be part of the 'Latin_1_Supplement' culture + // u00A1, // INVERTED EXCLAMATION MARK + // u00BF, // INVERTED QUESTION MARK + u00A9, // COPYRIGHT SIGN + u00AE, // REGISTERED SIGN + u20AC, // EURO SIGN + u00B0, // DEGREE SIGN + u2013, // EN DASH + u2014, // EM DASH + + /// This would bring all the codepoints from the 'clt_Latin.clt' file + // Culture_Latin, + + /// This would bring all the _letters_ of the "Greek and Coptic" + /// Unicode block (there is no culture file with the name + /// 'clt_Greek_and_Coptic.clt') + // Culture_Greek_and_Coptic, + + CURRENT_CULTURE; + + +// The default 'culture' to use. Using -DCULTURE="foo" is a convenient way of +// specifying the culture for just one input file. +// CULTURE="Latin_1_Supplement"; // letters within range u+0080..u+00ff +// CULTURE="Cyrillic"; // letters within ranges u+0400..u+04FF, u+2DE0..u+2DFF, u+A640..u+A69F, u+1C80..u+1C8F, u+0500..u+052F +// CULTURE="Latin"; // all codepoints in clt_Latin.clt file +// CULTURE="all"; // all letters of all Unicode blocks, plus all codepoints in .clt files + + +// The default 1-byte encoding to use +// ENCODING="UTF-8" +// ENCODING="windows-1252" + + +// the following characters are allowed in user-defined names: + +NameChars = + "$?@" // asm specific character + "_0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz", + // This would enable common Chinese characters in identifiers: + // Culture_CJK_Unified_Ideographs, + CURRENT_CULTURE; + + +// the following characters are allowed in mangled names. +// they will be substituted with the SUBSTCHAR during output if names +// are output in a mangled form. + +MangleChars = "$:?([.)]" // watcom + "@$%?" // microsoft + "@$%&"; // borland + + +// the following characters are allowed in type names. + +TypeNameChars = + "_:$()`'{}" + "_0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + +//------------------------------------------------------------------------- +// Built-in C parser parameters +//------------------------------------------------------------------------- + +// Compiler-dependent settings: the folowing variables should be defined: +// HEADER_PATH - list of include directories separated by ';' +// PREDEFINED_MACROS - list of predefined macros +CC_PARMS = { + vc { // Visual C++ + HEADER_PATH = "/Program Files/Microsoft Visual Studio/VC98/include" + PREDEFINED_MACROS = "_cdecl=__cdecl;" + "_pascal=__pascal;" + "_huge=__huge;" + "_near=__near;" + "_far=__far;" + "__inline=;" + "_inline=;" + "inline=;" + "CM_WINNT;" + "MPR50;" + "_INTEGRAL_MAX_BITS=64;" + "_MSC_VER=1400;" + "_CHAR_UNSIGNED=1;" + "_M_IX86=300;" + "__MT__=1;" + "__TLS__=1;" + "_Windows=1;" + "__WIN32__=1;" + "_WIN32_WINNT=0x0500;" + "WINVER=0x0500;" + "_WIN32=1;" + "OLEDBVER=0x0250;" + "SECURITY_WIN32;" + "WIN32_SUPPORT;" + "DBNTWIN32;" + "W32SUT_32;" + } + gcc { // GNU C++ + HEADER_PATH = "/usr/include" + PREDEFINED_MACROS = "__GNUC__=4;" + "__CHAR_BIT__=8;" + "unix=1;" + "__unix=1;" + "__unix__=1;" + "__ELF__=1;" + } + bcc { // Borland C++ + PREDEFINED_MACROS = "__BORLANDC__=0x560;" + } + delphi { // Delphi + PREDEFINED_MACROS = "__BORLANDC__=0x550;" + } + watcom { // Watcom C++ + PREDEFINED_MACROS = "__WATCOMC__=1100;" + } + visage { // Visual Age C++ + HEADER_PATH = "/usr/include" + PREDEFINED_MACROS = "__IBMC__=1110;" + "__IBMCPP__=1110;" + } + default { + HEADER_PATH = "" + PREDEFINED_MACROS = "" + } +} + +// The namespace list is used to avoid failures caused by an heuristic rule +// that derives function types based on their names. For a name like A::B() +// it yields A::B(A*this). However, this rule should be turned off for namespace +// names, for example for std::terminate(). See also AF_MEMFUNC + +CPP_NAMESPACES = "std;stdext;tr1;tr2;boost;boost::system;_STL;ATL;QT;" + "__gnu_cxx;__cxxabiv1;_com_util;" + "allocators;chrono;Concurrency;concurrency;details;Details;" + "direct3d;errc;fast_math;graphics;io_errc;msl;Platform;" + "precise_math;regex_constants;threads;utilities;Windows;" + "System;Sysutils;Classes;Controls;ExtCtrls;Forms;Menus;Comobj;Mapi;" + "CDO;Gdiplus;DllExports;MSXML2;MSXML6;BDATuningModel;"; + + +// The maximum length of the list of trusted idb files. +// An idb file is considered as trusted if the user launched the debugger +// with it and saved the idb. +// If the current idb is marked as untrusted, IDA asks the user for a confirmation +// that s/he really wants to launch the debugger. +// The list of trusted databases (only md5 checksums of the idb header) +// is kept in %appdata%/Hex-Rays/IDA Pro/trusted_idb_list.bin +// If this parameter is zero, all idbs are considered as trusted. + +MAX_TRUSTED_IDB_COUNT = 1024 + +//------------------------------------------------------------------------- +// Processor specific parameters +//------------------------------------------------------------------------- +#ifdef __PC__ // INTEL 80x86 PROCESSORS + +// +// Location of Microsoft Debugging Engine Library (dbgeng.dll) +// This value is used by both the windmp (dump file loader) and the windbg +// debugger module. Please also refer to dbg_windbg.cfg +// (note: make sure there is a semicolon at the end) + +//DBGTOOLS = "C:\\Program Files\\Debugging Tools for Windows (x86)\\"; + +USE_FPP = YES // Floating Point Processor + // instructions are enabled + +// IBM PC specific analyzer options + +PC_ANALYZE_PUSH = YES // Convert immediate operand of "push" to offset + // + // In sequence + // + // push seg + // push num + // + // IDA will try to convert to offset. + // +PC_ANALYZE_NOP = NO // Convert db 90h after "jmp" to "nop" + // Now it is better to turn off this option + // because the final pass of the analysis will + // convert 90h to nops more intelligently. + // + // Sequence + // + // jmp short label + // db 90h + // + // will be converted to + // + // jmp short label + // nop + // +PC_ANALYZE_MOVOFF = YES // Convert immediate operand of "mov reg,..." to offset + // + // In sequence + // + // mov reg, num + // mov segreg, immseg + // + // where + // reg - any general register + // num - a number + // segreg - any segment register + // immseg - any form of operand representing a segment paragraph + // + // will be converted to an offset + // +PC_ANALYZE_MOVOFF2 = YES // Convert immediate operand of "mov memory,..." to offset + // + // In sequence + // + // mov x1, num + // mov x2, seg + // + // where + // x1,x2 - any references to memory + // + // will be converted to an offset + // +PC_ANALYZE_ZEROINS = NO // Disassemble zero opcode instructions + // + // These instructions include: + // + // 00 00 add [bx+si], al + // 00 00 add [eax], al + // + // Usually this options is disabled + // +PC_ANALYZE_BRTTI = YES // Advanced analysis of Borland's RTTI + // + // This option allows ida to test and create RTTI structures. + // The analisys is triggered by renaming a location. + // If the new name can be demangled as Borland's RTTI descriptor name + // then the analisys is performed. + // +PC_ANALYZE_UNKRTTI = YES // Check 'unknown_libname' for Borland's RTTI + // + // This option allows IDA to test locations named as unknown_libname + // for RTTI structures. This option is meaningful only if the advanced + // analysis of RTTI is allowed. + // +PC_ANALYZE_EXPFUNC = YES // Advanced analisys of catch/finally block + // + // This option allows ida to check catch/finally exception blocks + // +PC_ANALYZE_DIFBASE = NO // Allow references with different segment bases + // + // This option allows IDA to display a reference to a symbol even if + // the reference value is not equal to the symbol value. For example, + // to refer to symbol \"x\" at 0000:0100 with expression 0010:0000 + // +PC_ANALYZE_NOPREF = NO // Don't display redundant instruction prefixes + // + // This option makes the disassembly more readable by hiding the + // superfluous instruction prefixes which are not used in the + // instruction + // +PC_ANALYZE_VXD = YES // Interpret int 20 as VxDcall + // + // This option turns on interpretation of int 20h + // as a VxDcall/jump for 32-bit files + // +PC_ANALYZE_FPEMU = YES // Enable FPU emulation instructions + // + // This option turns on interpretation of int 3?h + // instructions as FPU emulation instructions + // +PC_ANALYZE_SHOWRIP = NO // Explicit RIP-addressing + // + // If this option is turned on, then RIP addressing is + // always represented with the RIP register + // + // mov rax, [rip+1234] + // + // Otherwise RIP addressing is replaced by the corresponding + // memory reference (when possible) + // This option is valid only for the 64-bit mode. + // + +PC_ANALYZE_NOSEH = NO // Disable SEH/EH analysis + // This option disables detection of Structured Exception (SEH) + // and C++ Exception (EH) handlers. + +PC_ANALYZE_INT3STOP = YES // Analyze 'int 3' instructions + // If enabled, try to determine if execution stops after an int 3 instruction. + // For example, in the following code int 3 is likely a guard + // added by compiler to protect against return from a noret function: + // + // call __CxxThrowException@8 + // int 3 + +PC_ANALYZE_MAX_SIMPLEX_SIZE = 10000 // Do not use the simplex method if the + // number of variables is greater than this. + // It takes too long. + +PE_MAKE_IDATA = YES // Create imports segment for PE files +PE_LOAD_RESOURCES = NO // Load resources for PE files +PE_CREATE_FLAT_GROUP = NO // Create FLAT group for PE files + + +SHOW_AUTOCOMMENTS = NO // Don't display comments for every instruction + +ANALYSIS = 0xDFFFFFF7ULL // Enable 'noret' analysis + // Enable SP analysis + +#endif // __PC__ +//------------------------------------------------------------------------- +#ifdef __JAVA__ +SHOW_BORDERS = NO // Borders between data/code +SHOW_LINEPREFIXES = NO // No Show line prefixes (1000:0000) +SHOW_SEGXREFS = NO // No Show segment part of addresses + // in cross-references +DUMMY_NAMES_TYPE = NM_SHORT // See 'dummy names' for explanations +MAX_DATALINE_LENGTH = 77 // Data directives (db,dw, etc): + // max length of argument string +SHOW_XREFS = 1 // Show 1 cross-reference +COMMENTS_INDENTION = 47 // Indention for on-line comments +// +// Table of characters which are allowed in class, field, and method names. +// This table is created dynamically by the java module. +// Java supports any unicode LetterOrDigit character as 'name'-character, +// but IDA curently does not support the unicode output. Theoretically it is +// possible to enable any character in the current codepage as 'namechar' but +// there will be a problem with IDA databases. A old database will look wrong +// if opened on a computer with a different codepage. For this reason +// only english letter, digits, '$' and '_' are allowed in the names. +// (see java langspec). +// +NameChars = ""; +// +// Table of characters which are allowed in ASCII strings, i.e. in +// CONSTANT_String arguments, Source File Name, SourceDebugExtension, etc. +// This table not used by the java module - currently IDA accepts only +// characters < 0x7F (english characters) and encoded unicode character +// for the CURRENT locale (cidition: the locale is NOT mbcs, which means +// that japanese, thai, etc will not work) +// +StrlitChars = ""; +// + +JAVA_MULTILINE_DEBUG = YES // Force a new line at every LF + // in the '.debug' directive + +JAVA_HIDE_STACKMAP = NO // Hide '.stack' verification areas + +JAVA_AUTO_STRING = NO // Make 'prompt' string after every + // LR in quoted strings + +JAVA_ASMFILE_CONVERT = YES // Create jasmin-compatible + // asm-file and change + // the encoding from OEM to ANSI + // (jasmin expects ANSI encoding) + +JAVA_ENABLE_ENCODING = YES // Convert unicode characters in + // strings constants to ascii + // characters (for the current + // locale). + +JAVA_NOPATH_ATTRIBUTE = NO // If 'YES', filename in '.attribute' + // directives is specified without path. + +// options for loader + +JAVA_UNKATTR_REQUEST = YES // If the loaded file contains 'unknown + // attributes' and the 'manual load' is off + // then IDA will ask your permission to + // store the attributes to an external + // file + +JAVA_UNKATTR_WARNING = YES // Include information of 'unknown + // attributes' (if they were not saved + // into external files) in the problem + // list + +JAVA_STARTASM_LIST = NO // Display mode for new java files: + // YES: listing mode + // NO: jasmin mode + +#endif // __JAVA__ + +//------------------------------------------------------------------------- + +#ifdef __ARM__ + +ANALYSIS = 0xDF8FFFF7ULL // Disable AF_IMMOFF, AF_DREFOFF, AF_DATOFF + // Enable 'noret' analysis, AF_VERSP + +NameChars = + ".$" + "_0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + +ARM_SIMPLIFY = YES // Simplify instructions and replace them + // by pseudo-instructions + +ARM_NO_PTR_DEREF = NO // Disable using of =label notation + // This notation makes disassembly cleaner + +ARM_USE_MACROS = YES // Use macro-instructions like MOVL + +ARM_NO_ARM_THUMB_SWITCH = NO // No automatic ARM-THUMB switch + +ARM_DISABLE_BL_JUMPS = NO // Disable detection of BL instructions used for long jumps (not calls) in Thumb mode + +ARM_DEFAULT_ARCHITECTURE = "metaarm"; // Default architecture when not set by the loader. For details see documentation. + +// ARM_DEFAULT_ARCHITECTURE = "ARMv7-A"; + +// for the vars below 0 means "no limit" +ARM_REGTRACK_VALS_SIZE = 100 // max number of possible values of register; +ARM_REGTRACK_OP_RECURS = 100 // max level of recursion when emulating + // the execution of instructions; +ARM_REGTRACK_BBLK_RECURS = 2000 // max level of recursion when unwinding + // the execution flow; +ARM_REGTRACK_CACHE_SIZE = 5000 // max size of the cache for one register; + +#endif // __ARM__ + +//------------------------------------------------------------------------- +#ifdef __TMS320C6__ +INDENTION = 8 // Indention of instructions +NameChars = + "$_0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; +ANALYSIS = 0xDFEF9FF7ULL // All except AF_DREFOFF +#endif // __TMS320C6__ + +//------------------------------------------------------------------------- +#ifdef __TMS320C54__ + +TMS320C54_IO = YES // Use I/O definitions from the configuration + // file in macro instructions. + +TMS320C54_MMR = YES // Replace addresses by an equivalent memory + // mapped register. + +TMS320C54_DSEG = 0x10000 // Default data segment address + +#endif // __TMS320C54__ + +//------------------------------------------------------------------------- +#ifdef __PPC__ // PowerPC processor + +NameChars = + "_0123456789." + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + // preserve the following characters in + // names (AIX assembler has .rename directive) +MangleChars = "!@#$%^&*()+-=[]\\{}|;':,/<>?`~ "; + +ANALYSIS = 0xDFFFFFB7ULL // Don't create function if data xref data->code32 exists + // (AIX XCOFF has many references from data + // segment to strings in the code segment) + // Enable 'noret' analysis + // Enable SP analysis + +DUMMY_NAMES_TYPE = NM_EA + +MAX_DATALINE_LENGTH = 250 // this stupid AIX assembler can't digest + // a string without a trailing zero + // and we are forced to display + // everything on one line + +PPC_LISOFF = NO // Aggressively convert lis/addi pairs to + // offsets (only if they refer to an + // existing address) + +PPC_CREATE_SUBI = NO // If enabled, IDA will replace addi + // instructions with negative values by + // subi pseudo-instructions + +// extra instructions to decode +// NB! AltiVec, SPE, VMX128 and Paired Singles are all mutually exclusive + +#define ISA_ALTIVEC 0x0001 // AltiVec SIMD instructions +#define ISA_SPE 0x0002 // SPE (Signal Processing Engine) instructions +#define ISA_VLE 0x0004 // VLE (variable-length encoding) instructions +#define ISA_VMX128 0x0003 // VMX128 SIMD instructions (Xbox360) +#define ISA_PAIRED 0x0008 // Paired Singles instructions (Gekko) +#define ISA_SERVER 0x0100 // ISA Server environment (otherwise embedded) + +PPC_ISA_SUPPORT = 0x0101 // This value is combination of the bits above + +// The following keywords can be used to specify TOC, SDA base, and MMIO base +// from idc scripts like this: ChangeConfig("PPC_TOC=0x123456"); +// PPC_TOC - TOC (r2) address in the AIX or 64-bit System V ABI or +// SDA2 address in the Embedded System V ABI +// PPC_SDA_BASE - SDA (r13) address in the System V ABI +// PPC_MMIO_BASE - MMIO base + +// how to show references with SDA register (r13), +// non-trivial values (SDA/SIMPLIFY) may be used in the Embedded +// environment only and when the SDA base is set +#define PPC_SDAREFS_NO 0 // as usual: (var - )(r13) +#define PPC_SDAREFS_SDA 1 // show @sda, do not show base: var@sda(r13) +#define PPC_SDAREFS_SIMPLIFY 2 // w/o base register: var +PPC_SDAREFS = PPC_SDAREFS_NO + +// for the vars below 0 means "no limit" +PPC_REGTRACK_VALS_SIZE = 10 // max number of possible values of register; +PPC_REGTRACK_OP_RECURS = 100 // max level of recursion when emulating + // the execution of instructions; +PPC_REGTRACK_BBLK_RECURS = 2000 // max level of recursion when unwinding + // the execution flow; +PPC_REGTRACK_CACHE_SIZE = 5000 // max size of the cache for one register; + +// ABI specification +#define PPC_ABI_RETSTRREG 0x0001 // Return structures smaller than 8 bytes in registers +#define PPC_ABI_LDBL_IS_DBL 0x0002 // long double is double +#define PPC_ABI_NOTALIGNUDT 0x0004 // the ABI of passing aggregates with 16-byte alignment has + // changed in GCC 5. It conforms the "64-bit PowerPC ELF ABI + // Supplement 1.9" now, set it for GCC4 only. +#define PPC_ABI_EMBEDDED 0x0008 // Embedded System V ABI as described in the "Power + // Architecture 32-bit Application Binary Interface Supplement + // 1.0 - Linux & Embedded". + +PPC_FIX_GNU_VLEADRELOC_BUG = NO // There is a bug in GNU toolchain for PPC. It swaps relocs + // R_PPC_VLE_HA16A and R_PPC_VLE_HA16D (and also some others). + // See https://sourceware.org/bugzilla/show_bug.cgi?id=20744 + // Set this var to process relocs R_PPC_VLE.*[AD] as GNU loader does. + +#endif // __PPC__ + +//------------------------------------------------------------------------- +#ifdef __80196__ // Intel 80196 processor + +DUMMY_NAMES_TYPE = NM_SHORT + +#endif // __80196__ + +//------------------------------------------------------------------------- +#ifdef __I51__ // Intel 8051, 80251 processors + +DUMMY_NAMES_TYPE = NM_SHORT + +#endif // __I51__ + +//------------------------------------------------------------------------- +#ifdef __PDP11__ // Digital PDP-11 processor + +// Use character translation? + +PDP_XLAT_ASCII = NO + +NameChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_"; + +#endif // __PDP11__ + +//------------------------------------------------------------------------- +#ifdef __SH3__ // Hitachi SH3 processor + +ANALYSIS = 0xDFFF9FB7ULL // Don't create function if data xref data->code32 exists + // (PE execs have many Unicode strings in the code segment) + +DUMMY_NAMES_TYPE = NM_EA + +SH3_INLINE_IMMVALS = YES // Put the immediates loaded from the literal pool into the instruction itself + +#endif // __SH3__ + +//------------------------------------------------------------------------- +#ifdef __MIPS__ // MIPS processor + +DUMMY_NAMES_TYPE = NM_EA + +MIPS_MNEMONIC = YES // Use mnemonic register names +MIPS_SIMPLIFY = YES // Simplify instructions and replace them + // by pseudo-instructions +MIPS_STRICT = NO // Strictly adhere to instruction specifications +MIPS_MACRO = YES // Use macros +MIPS_MACRO_RESPECT_XREFS = YES // When looking back for the "lui" instruction, + // stop when an xrefed instruction is found +MIPS_MACRO_HIDDEN_R1 = YES // Allow hidden modification of $1 in macros + +MIPS_SIMPLIFY_GP = YES // Simplify $gp expressions + +LOOKBACK = 16 // Look back up to 16 instructions to find + // LUI instruction + +#endif // __MIPS__ + +//------------------------------------------------------------------------- +#ifdef __PIC__ // PIC processor + +DUMMY_NAMES_TYPE = NM_NAM_OFF +PIC_MACRO = YES // Use macros + +#endif // __PIC__ + +//------------------------------------------------------------------------- +#ifdef __SPARC__ // SPARC processor + +ANALYSIS = 0xDFDF9FF7ULL// Disable AF_IMMOFF + +DUMMY_NAMES_TYPE = NM_EA + +SPARC_SIMPLIFY = YES // Simplify instructions and replace them + // by pseudo-instructions +SPARC_STRICT = NO // Strictly adhere to instruction specifications +SPARC_MACRO = YES // Use macros +SPARC_V8 = NO // V8 architecture disassembly + +LOOKBACK = 16 // Look back up to 16 instructions to find + // SETHI instruction +#endif // __SPARC__ + +//------------------------------------------------------------------------- +#ifdef __ALPHA__ // DEC Alpha processor + +DUMMY_NAMES_TYPE = NM_EA + +ALPHA_SIMPLIFY = YES // Simplify instructions and replace them + // by pseudo-instructions +ALPHA_STRICT = NO // Strictly adhere to instruction specifications +ALPHA_MACRO = YES // Use macros +ALPHA_MNEMONIC = NO // Use mnemonic register names + +LOOKBACK = 16 // Look back up to 16 instructions to find + // SETHI instruction + +#endif // __ALPHA__ + +//------------------------------------------------------------------------- +#ifdef __HPPA__ // HP PA-RISC processor + +DUMMY_NAMES_TYPE = NM_EA + +HPPA_SIMPLIFY = YES // Simplify instructions and replace them + // by pseudo-instructions +HPPA_MNEMONIC = NO // Use mnemonic register names +HPPA_PSW_W = NO // Consider programs as 64bit? + +LOOKBACK = 16 // Look back up to 16 instructions to find + // ADDIL/LDIL instructions + +NameChars = + "_0123456789." + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + +SHOW_BASIC_BLOCKS = YES // Generate an empty line at the end of basic blocks + +#endif // __HPPA__ + +//------------------------------------------------------------------------- +#ifdef __DSP56K__ // Motorola 56000 (5600x) processor + +DUMMY_NAMES_TYPE = NM_SHORT + +PACK_DATABASE = 2 // deflate + +#endif // __DSP56K__ + +//------------------------------------------------------------------------- +// Intel Itanium IA64 (module name in x64 builds is: IA) +#if !defined(__X64__) && defined(__IA64__) || defined(__X64__) && defined(__IA__) + +DUMMY_NAMES_TYPE = NM_EA + +NameChars = + "_0123456789." + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + +LOOKBACK = 16 // Look back up to 16 instructions to find + // memory reference addresses +#endif // __IA64__ + +//------------------------------------------------------------------------- +#ifdef __CLI__ // Microsoft.Net Common Language Infrastructure + +NameChars = + "$?@." // asm specific character + "_0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + +MangleChars = + "!#$%&'()*+,-./0123456789:;<=>?" + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_" + "`abcdefghijklmnopqrstuvwxyz{|}~", + u007F..u10FFFF & Category_Lo, + u007F..u10FFFF & Category_Ll, + u007F..u10FFFF & Category_Lu; + + +SHOW_BORDERS = NO +SHOW_SEGMENT_BORDERS = NO + +INDENTION = 4 // Indention of instructions +COMMENTS_INDENTION = 40 // Indention of short comments +SHOW_LINEPREFIXES = NO // Show line prefixes (like 1000:0000) + +#endif // __CLI__ + +//------------------------------------------------------------------------- +#ifdef __MC68__ // MC68K, 68xxx, 68000 + +ANALYSIS = 0xdfffdff7ULL // Enable 'noret' analysis + +MC68K_UNSIGNED_OPS = YES // Immediate operands are unsigned by default + +#endif // __MC68__ + +//------------------------------------------------------------------------- +#ifdef __MC6812__ // MC6812 + +#endif // __MC68__ + +//------------------------------------------------------------------------- +#ifdef __H8__ // H8 + +NameChars = + "$?" // no '@' character + "_0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + +#endif // __H8__ + +//------------------------------------------------------------------------- +#ifdef __H8500__ // H8/500 + +NameChars = + "$?" // no '@' character + "_0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + +H8500_MIXED_SIZE = YES + +#endif // __H8500__ + +//------------------------------------------------------------------------- +#ifdef __I960__ // Intel 960 + +I960_STRICT = YES + +#endif // __H8500__ + +//------------------------------------------------------------------------- +#ifdef __TRIMEDIA__ // TriMedia + +TRIMEDIA_PSEUDO = NO // Don't use pseudo instructions since + // the assembler doesn't understand them + +TRIMEDIA_GUARD0 = NO // Allow R0 as the guard + // If this option is on, IDA will disassemble instructions + // with R0 as the guard\ + +TRIMEDIA_ONENOP = YES // Display NOP cycle one 1 line + // If this option is on, IDA will display a cycle with all + // NOP operations on one line + +//ANALYSIS = 0xDFCF9FF7ULL + +#endif // __TRIMEDIA__ + +//------------------------------------------------------------------------- +#ifdef __F2MC__ // Fujitsu F2MC + +F2MC_MACRO = YES // Use macro instructions + +#endif // __F2MC__ + +//------------------------------------------------------------------------- +#ifdef __TMS32054__ // Texas Instruments TMS320C54 + +TMS320C54_IO = YES // Use I/O definitions +TMS320C54_MMR = YES // Detect memory mapped registers + +#endif // __TMS32054__ + +//------------------------------------------------------------------------- +#ifdef __TRICORE__ // Infineon TRICORE + +TRICORE_REGISTER_TRACKING = YES // Enable register tracking + +LOOKBACK = 16 // Look back up to 16 instructions to find + // memory reference addresses + +// The following 2 parameters are to be used with ChangeConfig() IDC function: + +// TRICORE_IORESP = 7 // The actions be carried out by TRICORE_DEVICE +// // Bit combination of: +// // 1 rename port names in memory +// // 2 respect "area" directives +// // 4 respect interrupt information +// TRICORE_DEVICE = "tc1766" // Device name (see tricore.cfg) + +#endif // __TMS32055__ + +//------------------------------------------------------------------------- +#ifdef __TMS32055__ // Texas Instruments TMS320C55 + +TMS320C55_IO = YES // Use I/O definitions +TMS320C55_MMR = YES // Detect memory mapped registers + +#endif // __TMS32055__ + +#endif // ____ second pass ends here +//------------------------------------------------------------------------- +// User specific parameters +//------------------------------------------------------------------------- +// +// If you don't want to modify IDA.CFG file then you can create a file called +// IDAUSER.CFG and place additional parameters there. +// +// The IDAUSER.CFG file should be placed in the following directory: +// - unix: $HOME/.idapro +// - windows: %APPDATA%\Hex-Rays\IDA Pro +// +// It will be called 2 times: in the first and second pass. +// You can check the pass using +// #ifdef ____ +// then it is the first pass +// #else +// it is the second pass +// #endif +// +// Some parameters must be defined in the first pass, some in the second. +// See examples in this file. +// +#softinclude // user defined macros can be + // defined in the 'idauser.cfg' file + // other parameters can be defined there too. diff --git a/cfg/idagui.cfg b/cfg/idagui.cfg new file mode 100644 index 0000000..30c8450 --- /dev/null +++ b/cfg/idagui.cfg @@ -0,0 +1,1679 @@ + +// Config file for the graphical mode user interface +// ************************************************* + +// Screen configuration +// -------------------- + +SCREEN_CURSOR = 0 // = 0 normal cursor + // = 1 block cursor + +RECENT_SCRIPTS_MODAL = NO // Open "Recent scripts" window as a modal window + +AUTOSAVE = 100 // After 100 user actions + // IDA flushes its buffers to disk + +// The windows version of IDA determines the directory +// automatically. The following parameter isn't needed anymore. +// WINDIR = "c:\\windows" // Default directory to look up for + // MS Windows DLL files + // IDA will search subdirs + // "dll" + // "system" + // "system32" + // of this dir automatically + +OS2DIR = "c:\\os2" // OS/2 main directory (is used to + // look up DLLs) + + +HELPFILE = "sample.hlp" // Name of help file used by Ctrl-F1 + // Please change it as shown below: +//HELPFILE = "WIN32.HLP" + + +ASK_EXIT_UNPACKED = YES // Ask confirmation if the user + // wants to exit the database without + // packing it + +ASK_EXIT = YES // Ask confirmation if the user + // wants to exit + +OPEN_DEFAULT_IDC_PATH = NO // YES: The dialog box to select an + // IDC script always starts in + // the IDC subdirectory + // NO: The dialog box opens in the + // current/last directory + +DISPLAY_COMMAND_LINE = YES // Display the expressions/IDC command line + // To turn on/off the command line, + // right click on the main toolbar after + // setting this parameter to YES + +#define CONFIRM_UNDEFINE_NO -1 // Never confirm +#define CONFIRM_UNDEFINE_YES 0 // Always confirm +#define CONFIRM_UNDEFINE_BLOCK 1 // Confirm only if an area has been selected + +CONFIRM_UNDEFINE_COMMAND = CONFIRM_UNDEFINE_YES // Confirm the "undefine" command +CONFIRM_SETFUNCEND_COMMAND = YES // Confirm the "set function end" command (E hotkey) + + +HISTORY_LENGTH = 10 // Maximum length of file->history + // Possible value is from 1 to 100 + + +// This can set global binary path mappings. +// However, they will be discarded in case the IDB has its own mappings +// DEBUG_BINARY_PATHS="/home/user/binaries;C:\\binaries;/home/user/binaries2;C:\\binaries2" +// +// Note: You might want to not be bothered for requests for +// a mapping for binaries in a particular directory. In that case, use the special "" token. E.g., +// DEBUG_BINARY_PATH="/home/user/binaries;C:\\binaries;/usr/lib;" + + +#ifdef __QT__ + +#ifdef __NT__ +EXTERNAL_EDITOR = "notepad.exe" +#endif +#ifdef __LINUX__ +EXTERNAL_EDITOR = "gedit" +#endif +#ifdef __MAC__ +EXTERNAL_EDITOR = "/Applications/TextEdit.app/Contents/MacOS/TextEdit" +#endif + +#endif + + +#ifdef __QT__ +// 1=YES and 0=NO overwrite the default (-1) behavior for individual dialogs +ASK_TEXT_ACCEPTS_TABS = -1 +#endif + +// Built-in window ids +#define BWN_EXPORTS 0x00000001 // exports +#define BWN_IMPORTS 0x00000002 // imports +#define BWN_NAMES 0x00000004 // names +#define BWN_FUNCS 0x00000008 // functions +#define BWN_STRINGS 0x00000010 // strings +#define BWN_SEGS 0x00000020 // segments +#define BWN_SEGREGS 0x00000040 // segment registers +#define BWN_SELS 0x00000080 // selectors +#define BWN_SIGNS 0x00000100 // signatures +#define BWN_TILS 0x00000200 // type libraries +#define BWN_LOCTYPS 0x00000400 // local types +#define BWN_CALLS 0x00000800 // function calls +#define BWN_PROBS 0x00001000 // problems +#define BWN_BPTS 0x00002000 // breakpoints +#define BWN_THREADS 0x00004000 // threads +#define BWN_MODULES 0x00008000 // modules +#define BWN_TRACE 0x00010000 // trace view +#define BWN_STACK 0x00020000 // call stack trace +#define BWN_XREFS 0x00040000 // xrefs +#define BWN_SEARCHS 0x00080000 // search results +#define BWN_FRAME 0x02000000 // function frame +#define BWN_NAVBAND 0x04000000 // navigation band +#define BWN_ENUMS 0x08000000 // enumerations +#define BWN_STRUCTS 0x10000000 // structures +#define BWN_DISASMS 0x20000000 // disassembly views +#define BWN_DUMPS 0x40000000 // hex dumps +#define BWN_NOTEPAD 0x80000000 // notepad + +CLOSED_BY_ESC = 0x1A000000 // Mask of all windows that are closed by Esc. + // If a windows is not closed by Esc, + // it can be closed by Alt-F3. + // default value 0x1A000000 - stack, enumerations, structures + // f.e. 0x9A0FFFFF - all windows but disasm/hexdump/navband can be closed by Esc) + +#ifdef __QT__ +OTHER_CLOSED_BY_ESC = YES // Behavior for all windows not specified by CLOSED_BY_ESC +TOOL_CLOSED_BY_ESC = NO // Behavior for tool windows like the Output window + +PROXIMITY_SHOW_DATA_REFS = YES // Display xrefs to data in proximity view? +PROXIMITY_HIDE_LIBRARIES = NO // Hide library functions in proximity view? +PROXIMITY_UNLIMITED_RECURSION = NO // Unlimited child recursion in proximity view? +PROXIMITY_RECURSE_LIBRARIES = NO // Show childs of library functions in proximity view? +PROXIMITY_SHOW_COLLAPSED_NODES = YES // Show collapsed parent/children (i.e., '+') nodes in proximity view? +PROXIMITY_MAX_PARENTS_RECURSION = 2 // Maximum level of parents recursion +PROXIMITY_MAX_CHILDS_RECURSION = 2 // Maximum level of childs recursion +PROXIMITY_MAX_NODES_PER_LEVEL = 0 // Maximum number of nodes to show per level + +// Specify Qt pixmap cache size, in MB. Bigger cache might speed rendering, +// but it's obviously at the expense of memory usage.. +// Defaults to a value computed from the display resolution. +// (E.g., ~= 30MB on a 1024x768 screen.) +// QT_PIXMAP_CACHE_SIZE = 100 + +// If set to NO, calling msg() causes a refresh of the output window at every call +MSG_DELAYED_UPDATE = YES +// Specify the limit for lines in the output window (0 - unlimited) +MSG_MAXIMUM_LINE_COUNT = 10000 +// Specify the percentage of the number of lines for cleaning when the limit is reached +MSG_LINE_CLEAN_PERCENT = 10 + +// By default, IDA uses the native OS file input dialogs. +// Uncomment the following to use Qt's implementation. +// NATIVE_FILE_DIALOG = NO + +// This can set global source path mappings. +// However, they will be discarded in case the IDB has its own mappings +// SOURCE_DEBUG_PATHS="C:\\src_dir1;C:\\dst_dir1;C:\\src_dir2;C:\\dst_dir2" + +#else +TAB_STYLE = "Themed" // One of Default, Enhanced, Flat, OfficeXP, Standard, Themed, VS2005 +#endif + +// +// Keyboard hotkey definitions +// --------------------------- +// + +#ifdef __QT__ +"NewInstance" = 0 // Open a new instance of IDA +#endif +"ReloadFile" = 0 // Reload the same input file +"LoadNewFile" = 0 // Load additional file into database +"LoadIdsFile" = 0 // Load IDS file +"LoadDbgFile" = 0 // Load DBG file +"LoadPdbFile" = 0 // Load PDB file +"LoadTdsFile" = 0 // Load TDS file +"LoadSigFile" = 0 // Load SIG file +"LoadHeaderFile" = "Ctrl-F9" // Load C header file +"RecentScripts" = "Alt-F9" // Recent scripts +"Execute" = "Alt-F7" // Execute script file +"ExecuteLine" = "Shift-F2" // Execute IDC line +"About" = 0 +"SaveBase" = "Ctrl-W" +"SaveBaseAs" = 0 +#ifdef __QT__ +"SaveBaseSnap" = "Ctrl-Shift-W" // Save database snapshot +#endif +"Abort" = 0 // Abort IDA, don't save changes +"Quit" = "Alt-X" // Quit to DOS, save changes +#ifdef __QT__ +"QuickStart" = 0 +#endif + +"ReanalyzeProgram" = 0 // Reanalyze the program + +"ProduceMap" = 0 // Produce MAP file +"ProduceAsm" = "Alt-F10" // Produce assembler text file +"ProduceInc" = 0 // Produce assembler include file +"ProduceLst" = 0 // Produce listing file +"ProduceHeader" = 0 // Produce header file from local types +"ProduceExe" = 0 // Produce executable file +"ProduceDiff" = 0 // Produce difference file +"ProduceHtml" = 0 // Produce HTML file +"ProduceFuncGdl" = 0 // Produce flow chart GDL +"ProduceCallGdl" = 0 // Produce call graph GDL +"DumpDatabase" = 0 // Dump database to IDC file + // This IDC file contains all + // information to recreate + // the database from scratch + // (executable file will be + // needed) +"DumpTypes" = 0 // Dump typeinfo to IDC file + +"JumpAsk" = 'g' +"JumpName" = "Ctrl-L" +"JumpSegment" = "Ctrl-S" +"JumpSegmentRegister" = "Ctrl-G" +"JumpQ" = "Ctrl-Q" +"JumpPosition" = "Ctrl-M" +"JumpXref" = "Ctrl-X" +"JumpXrefFrom" = "Ctrl-J" +"JumpOpXref" = "X" +"JumpFunction" = "Ctrl-P" +"JumpEntryPoint" = "Ctrl-E" +"JumpFileOffset" = 0 +"JumpError" = "Ctrl-F" + +"JumpEnter" = "Enter" // jump to address under cursor +"JumpEnterNew" = "Alt-Enter" // jump to address under cursor + // in a new window +"CenterInWindow" = "NumpadClear,Clear" +"Return" = "Esc" +"UndoReturn" = "Ctrl-Enter" // undo the last Esc +"EmptyStack" = 0 // make the jumps stack empty + +"SetDirection" = 0 +"MarkPosition" = "Alt-M" + +"FindAllSuspicious" = 0 +"JumpSuspicious" = "Ctrl-V" +"JumpCode" = "Alt-C" +"JumpData" = "Ctrl-D" +"JumpUnknown" = "Ctrl-U" +"JumpExplored" = "Ctrl-A" +"AskNextImmediate" = "Alt-I" +"JumpImmediate" = "Ctrl-I" +"AskNextText" = "Alt-T" +"JumpText" = "Ctrl-T" +"AskBinaryText" = "Alt-B" +"JumpBinaryText" = "Ctrl-B" +"JumpNotFunction" = 0 +"NavFlatPanUp" = "Ctrl+Up" +"NavFlatPanDown" = "Ctrl+Down" +"NavGraphJumpLinkedNeighborUp" = "Ctrl+Up" +"NavGraphJumpLinkedNeighborDown" = "Ctrl+Down" + +"NavJumpWindowTop" = "Ctrl+Home,Shift+Ctrl+Home" +"NavJumpWindowBottom" = "Ctrl+End,Shift+Ctrl+End" +"NavJumpHome" = "Home,Shift+Home" +"NavJumpEnd" = "End,Shift+End" +"NavJumpListingStart" = "Ctrl+PgUp,Shift+Ctrl+PgUp" +"NavJumpListingEnd" = "Ctrl+PgDown,Shift+Ctrl+PgDown" +"NavLeft" = "Left,Shift+Left" +"NavRight" = "Right,Shift+Right" +"NavWordLeft" = "Ctrl+Left,Shift+Ctrl+Left" +"NavWordRight" = "Ctrl+Right,Shift+Ctrl+Right" +"NavLineUp" = "Up,Shift+Up" +"NavLineDown" = "Down,Shift+Down" +"NavPageUp" = "PgUp,Shift+PgUp" +"NavPageDown" = "PgDown,Shift+PgDown" +"SearchHighlightUp" = "Alt+Up,Shift+Alt+Up" +"SearchHighlightDown" = "Alt+Down,Shift+Alt+Down" + + +"MakeAlignment" = 'L' +"ManualInstruction" = "Alt-F2" +"ColorInstruction" = 0 +"ToggleBorder" = 0 +"ToggleRenderer" = "Space" + +"MakeCode" = 'C' +"MakeData" = 'D' +"MakeStrlit" = 'A' +"MakeArray" = "Numpad*,*" +"MakeUnknown" = 'U' + +"MakeName" = 'N' +"ManualOperand" = "Alt-F1" + +"MakeFunction" = 'P' +"EditFunction" = "Alt-P" +"AppendFunctionTail" = 0 +"RemoveFunctionTail" = 0 +"DelFunction" = 0 +"FunctionEnd" = 'E' +"OpenStackVariables" = "Ctrl-K" // open stack variables window +"ChangeStackPointer" = "Alt-K" // change value of SP +"RenameRegister" = 'V' +"SetType" = 'Y' + +"MakeComment" = ':' +"MakeRptCmt" = ';' + +#ifdef __MAC__ +"MakeExtraLineA" = "I" +"MakeExtraLineB" = "Shift-I" +#else +"MakeExtraLineA" = "Ins" +"MakeExtraLineB" = "Shift-Ins" +#endif + +"OpNumber" = '#' +"OpHex" = 'Q' +"OpDecimal" = 'H' +"OpOctal" = 0 +"OpBinary" = 'B' +"ToggleLeadingZeroes" = 0 +"OpFloat" = 0 +"OpChar" = 'R' +"OpSegment" = 'S' +"OpOffset" = 'O' +"OpOffsetCs" = "Ctrl-O" +"OpAnyOffset" = "Alt-R" +"OpUserOffset" = "Ctrl-R" +"OpStructOffset" = 'T' +"OpStackVariable" = 'K' +"OpEnum" = 'M' +// commented out because the french/italian versions of windows complain. +// if you want, you may uncomment it - anyway it doesn't make big difference +//"ChangeSign" = "Shift+-" +//"BitwiseNegate" = '~' +"SetOpType" = 0 + +"CreateSegment" = 0 +"EditSegment" = "Alt-S" +"KillSegment" = 0 +"MoveSegment" = 0 +"RebaseProgram" = 0 +"SegmentTranslation" = 0 + +"SetSegmentRegister" = "Alt-G" +"SetSegmentRegisterDefault" = 0 + +#ifdef __QT__ +"OutputWindow" = "Alt-0" +"GraphOverview" = 0 +#endif +"ShowRegisters" = "Ctrl-Space" + +#ifdef __QT__ +"QuickView" = "Ctrl-1" +"QuickRunPlugins" = "Ctrl-3" +#endif +"OpenNotepad" = 0 +"WindowOpen" = 0 +"OpenFunctions" = "Shift-F3" // open functions window +"OpenExports" = 0 +"OpenImports" = 0 +"OpenNames" = "Shift-F4" +"OpenSignatures" = "Shift-F5" // open signatures window +"OpenSegments" = "Shift-F7" +"OpenSegmentRegisters" = "Shift-F8" +"OpenSelectors" = 0 +"OpenXrefs" = 0 +"OpenStructures" = "Shift-F9" // open structures window +"OpenEnums" = "Shift-F10" // open enums window +"OpenProblems" = 0 +"OpenTypeLibraries" = "Shift-F11" +"GraphFunc" = "F12" // display function flow-chart +"CallFlow" = "Ctrl-F12" // display function call graph +"PrintFlowLabels" = 0 +"ChartXrefsTo" = 0 // display referenced items +"ChartXrefsFrom" = 0 // display referencing items +"ChartXrefsUser" = 0 // display referenced/referencing items +"OpenStrings" = "Shift-F12" +"OpenCallers" = 0 // display function call list +"OpenLocalTypes" = "Shift-F1" + +"PatchByte" = 0 +"PatchWord" = 0 +"Assemble" = 0 +"ApplyPatches" = 0 // apply patches to input file + +"Options" = 0 // show the general options dialog +"SetColors" = 0 // show the colors configuration dialog +#ifdef __QT__ +"SetFont" = 0 // show the fonts configuration dialog +#endif +"SetStrlitStyle" = "Alt-A" // set strings style +"SetDirectives" = 0 // setup assembler directives +"ToggleDump" = 0 // show dump or normal view + +"SetNameType" = 0 // show the name representation type dialog +"SetupCompiler" = 0 // show the compiler setup dialog +"SetDemangledNames" = 0 + +"Calculate" = '?' +"ShowFlags" = 'F' +#ifdef __QT__ +"ShowSnapMan" = "Ctrl-Shift-T" // show the database snapshot manager +#endif +"SetupHidden" = 0 +"Hide" = "Ctrl-Numpad-" +"UnHide" = "Ctrl-Numpad+" +"HideAll" = 0 +"UnHideAll" = 0 +"DelHiddenRange" = 0 + +#ifdef __QT__ +#ifdef __MAC__ +"FullScreen" = "Meta-Shift-F" +#else +"FullScreen" = "F11" +#endif +#endif + +#ifdef __QT__ +"ShowHelp" = "F1" +#else +"KeyboardHelp" = 0 +#endif + +#ifdef __NT__ +"ExternalHelp" = "Ctrl-F1" +#endif + +#ifdef __QT__ +"WindowsList" = 0 +"WindowsListNext" = "Ctrl-Tab" +"WindowsListPrev" = "Ctrl-Shift-Tab" +#endif +"NextWindow" = "F6" +"PrevWindow" = "Shift-F6" +"CloseWindow" = "Alt-F3" + +"FocusCLI" = '.' // focus command line +"FocusCLI2" = "Ctrl-." // focus command line (from anywhere in IDA) + +#ifdef __QT__ +"BasicMode" = 0 +"AdvancedMode" = 0 +#endif + +// +// Structure manipulation commands +// + +#ifdef __MAC__ +"AddStruct" = "I" // add struct type +#else +"AddStruct" = "Ins" // add struct type +#endif +"DelStruct" = "Del" // del struct type +"ExpandStruct" = "Ctrl-E" // expand struct type +"ShrinkStruct" = "Ctrl-S" // shrink struct type +"EditStruct" = 0 // edit struct type +"DeclareStructVar" = "Alt-Q" // declare struct variable +"ZeroStructOffset" = "Ctrl-Z" // force zero field offset +"SelectUnionMember" = "Alt-Y" // select union member +"CreateStructFromData" = 0 // create struct from data +"CopyFieldsToPointers" = 0 // copy field info to pointers + +// +// Enum manipulation commands +// + +#ifdef __MAC__ +"AddEnum" = "I" // add enum +#else +"AddEnum" = "Ins" // add enum +#endif +"DelEnum" = "Del" // del enum +"EditEnum" = "Ctrl-E" // edit enum +"AddConst" = "N" // add new enum member +"EditConst" = "Ctrl-N" // edit enum member +"DelConst" = "U" // delete enum member + +// +// Debugger manipulation commands +// + +#ifdef __QT__ +"QuickDbgView" = "Ctrl-2" +#endif +"Debugger" = "Ctrl-Alt-C" // open debugger window +"ProcessStart" = "F9" // start a new process in the debugger +"ProcessPause" = 0 // pause the debugged process +"ProcessExit" = "Ctrl-F2" // terminate the debugged process +"ProcessAttach" = 0 // Attach to a process +"ProcessDetach" = 0 // Detach from the debugged process +"TakeSnapshot" = 0 // Take a memory snapshot to the database +"RefreshMemcfg" = 0 // Refresh memory +"ThreadStepInto" = "F7" // step into the current instruction +"ThreadStepOver" = "F8" // step over the current instruction +"ThreadRunUntilReturn" = "Ctrl-F7" // execute instructions until execution returns from the current function +"ThreadRunToCursor" = "F4" // execute instructions until cursor is reached +"ThreadSetCurrentIp" = "Ctrl-N" // set new EIP (execution pointer) +"Threads" = 0 // open threads window +"BreakpointAdd" = 0 // add a breakpoint +"BreakpointDel" = 0 // del a breakpoint +"BreakpointToggle" = "F2" // toggle a breakpoint +"BreakpointEdit" = 0 // edit breakpoint settings +"BreakpointEnable" = 0 +"BreakpointDisable" = 0 +"Breakpoints" = "Ctrl-Alt-B" // open breakpoints window +//"WatchList" = "Ctrl-Alt-W" // open the watch list +"AddWatch" = 0 // add watch +"DelWatch" = "Del" // del watch +"StackTrace" = "Ctrl-Alt-S" // open stack trace window +"TraceWindow" = 0 // open trace window +"ClearTrace" = 0 // clear trace window +"SetupTracing" = 0 // open setup tracing window +"ToggleTraceInstructions" = 0 // toggle instructions tracing +"ToggleTraceFunctions" = 0 // toggle functions tracing +"ExecTraceAdd" = 0 // add execution trace +"WriteTraceAdd" = 0 // add write trace +"ReadWriteTraceAdd" = 0 // add read/write trace +"SwitchDebugger" = 0 // switch the current debugger +#ifdef __QT__ +"SwitchToSource" = 0 // switch from disassembly to source view +#endif + +// Graph view commands + +"GraphZoomMode" = 0 // Switch to zoom mode +"GraphSelectMode" = 0 // Switch to select mode +"GraphMoveMode" = 0 // Switch to move mode +"GraphZoom100" = '1' // Zoom 100% +"GraphZoomFit" = 'W' // Fit window +"GraphZoomIn" = "Ctrl-Shift-Numpad+" // Zoom in +"GraphZoomOut" = "Ctrl-Shift-Numpad-" // Zoom out +"GraphSetupOptions" = 0 // Setup graph options +"GraphSetupColors" = 0 // Setup graph colors +"GraphPrint" = 0 // Print graph +"GraphLayout" = 0 // Layout graph +"GraphFlatView" = 0 // Switch to flat disassembly view +"GraphGraphView" = 0 // Switch to graph view +#ifdef __QT__ +"GraphProximityBack" = "Numpad+" // Back to previous view from proximity view +"GraphProximityView" = "Numpad-" // Switch to proximity view +#endif +"GraphGroup" = 0 // Group nodes +"GraphUngroup" = 0 // Ungroup nodes +"GraphHideGroup" = 0 // Hide group +"GraphUnHideGroup" = 0 // Unhide group +"GraphHideAllGroups" = 0 // Hide all groups +"GraphUnHideAllGroups" = 0 // Unhide all groups +"GraphColor" = 0 // Set node color +"GraphColor1" = 0 // Set node color 1 +"GraphColor2" = 0 // Set node color 2 +"GraphDefaultColor" = 0 // Set node color to default + +// Desktop +"LoadDesktop" = 0 +"SaveDesktop" = 0 +"ResetDesktop" = 0 +"DeleteDesktop" = 0 +"ResetHiddenMessages" = 0 +"WindowActivate1" = "Alt-1" +"WindowActivate2" = "Alt-2" +"WindowActivate3" = "Alt-3" +"WindowActivate4" = "Alt-4" +"WindowActivate5" = "Alt-5" +"WindowActivate6" = "Alt-6" +"WindowActivate7" = "Alt-7" +"WindowActivate8" = "Alt-8" +"WindowActivate9" = "Alt-9" + +// Miscellaneous + +"StringC" = 0 +"StringDOS" = 0 +"StringPascal1" = 0 +"StringPascal2" = 0 +"StringDelphi" = 0 +"StringUnicode" = 0 +"StringUnicodePascal2" = 0 +"StringUnicodePascal4" = 0 +"SearchNext" = 0 +"Function" = 0 +"LockHighlight" = 0 + +// +// Others +// ------ +// + +"Analysis" = 0 // +"Anchor" = "Alt+L" // +"CLICopyAddress" = 0 // +"CLICopySize" = 0 // +"ClearMark" = 0 // +"CloseBase" = 0 // +"CopyStruct" = 0 // Make a copy of structure/union type +"EditCopy" = "Ctrl+C" // +"FindAllErrors" = 0 // +"GraphCircleLayout" = 0 // +"GraphDigraphLayout" = 0 // +"GraphNewProximityView" = 0 // Open new proximity browser +"GraphOrthogonalLayout" = 0 // +"GraphPolarLayout" = 0 // +"GraphProximityAddGraph" = 0 // Expand children +"GraphProximityAddNode" = 0 // Add name +"GraphProximityAddParents" = 0 // Expand parents +"GraphProximityDelChilds" = 0 // Collapse children +"GraphProximityDelNode" = 0 // Hide node +"GraphProximityDelParents" = 0 // Collapse parents +"GraphProximityExpand" = 0 // Expand node +"GraphProximityExpandCurrent" = "+" // Expand current node +"GraphProximityFindPath" = 0 // Find path +"GraphProximityReset" = 0 // Reset graph +"GraphRadialLayout" = 0 // +"GraphSelectColor" = 0 // Select nodes with the same color as the current node +"GraphTreeLayout" = 0 // +"JumpNewDump" = 0 // +"JumpToIP" = 0 // +"LoadFile" = 0 // Load additional binary file +"Locals" = 0 // Open local variables window +"Modules" = 0 // Open modules window +"NewFile" = 0 // Create a new database +"OpenSourceFile" = 0 // Open a source file +"SelectAll" = 0 // +"SelectIdentifier" = "Shift+Enter" // +"SetupData" = "Alt+D" // +"SetupDebugger" = 0 // +"SetupProcess" = 0 // +"SetupSrcPaths" = 0 // Setup source paths +"ShortcutEditor" = 0 // Edit shortcuts +"StackView" = 0 // +"ToggleSourceDebug" = 0 // +"ToggleTraceBasicBlocks" = 0 // Toggle basic block tracing +"WatchList" = 0 // Open the watch list window +"WatchView" = 0 // Open a new watch window +"PatchedBytes" = "Ctrl+Alt+P" // Patched bytes +"ExportData" = "Shift+E" // Export data +"BuyIDA" = 0 +"Homepage" = 0 +"SupportForum" = 0 +"CheckFreeUpdate" = 0 +"BugReport" = 0 +"CommandPalette" = "Ctrl+Shift+P" // Open command palette +"RepeatLastPaletteCommand" = "Ctrl+Shift+R" // Repeat last command + +// +// Menus layout +// ------------ +// + +MENUS_LAYOUT = [ + { + "label" : "&File", + "name" : "File", + "actions" : [ + "NewInstance", + "LoadNewFile", + { + "label" : "&Load file", + "actions" : [ + "ReloadFile", + "LoadFile", + "LoadIdsFile", + "LoadPdbFile", + "LoadDbgFile", + "LoadTdsFile", + "LoadSigFile", + "LoadHeaderFile" + ] + }, + { + "label" : "&Produce file", + "actions" : [ + "ProduceMap", + "ProduceAsm", + "ProduceInc", + "ProduceLst", + "ProduceExe", + "ProduceDiff", + "ProduceHtml", + "ProduceFuncGdl", + "ProduceCallGdl", + "ProduceHeader", + "", + "DumpDatabase", + "DumpTypes" + ] + }, + "Execute", + "ExecuteLine", + "SaveBase", + "SaveBaseAs", + "SaveBaseSnap", + "CloseBase", + "", + "QuickStart", + "Quit" + ] + }, + { + "label" : "&Edit", + "name" : "Edit", + "actions" : [ + "EditCopy", + "Anchor", + "SelectAll", + "SelectIdentifier", + "", + "ExportData", + "", + "MakeCode", + "MakeData", + "DeclareStructVar", + { + "label" : "St&rings", + "name" : "Strings", + "icon" : 0, + "actions" : [ + "MakeStrlit", + "", + "StringC", + "StringDOS", + "StringPascal1", + "StringPascal2", + "StringDelphi", + "StringUnicode", + "StringUnicodePascal2", + "StringUnicodePascal4" + ] + }, + "MakeArray", + "MakeUnknown", + "MakeName", + "", + { + "label" : "&Operand type", + "actions" : [ + { + "label" : "&Offset", + "name" : "OpTypeOffset", + "icon" : 23, + "actions" : [ + "OpOffset", + "OpOffsetCs", + "OpAnyOffset", + "OpUserOffset", + "OpStructOffset" + ] + }, + { + "label" : "&Number", + "name" : "OpTypeNumber", + "icon" : 4, + "actions" : [ + "OpNumber", + "OpHex", + "OpDecimal", + "OpOctal", + "OpBinary", + "OpFloat", + "", + "ToggleLeadingZeroes" + ] + }, + "OpChar", + "OpSegment", + "OpEnum", + "OpStackVariable", + "ChangeSign", + "BitwiseNegate", + "ManualOperand", + "SetOpType" + ] + }, + { + "label" : "Co&mments", + "actions" : [ + "MakeComment", + "MakeRptCmt", + "MakeExtraLineA", + "MakeExtraLineB" + ] + }, + { + "label" : "&Segments", + "actions" : [ + "CreateSegment", + "EditSegment", + "KillSegment", + "MoveSegment", + "RebaseProgram", + "SegmentTranslation", + "SetSegmentRegister", + "SetSegmentRegisterDefault" + ] + }, + { + "label" : "S&tructs", + "actions" : [ + "DeclareStructVar", + "ZeroStructOffset", + "SelectUnionMember", + "CreateStructFromData", + "CopyFieldsToPointers" + ] + }, + { + "label" : "&Functions", + "actions" : [ + "MakeFunction", + "EditFunction", + "AppendFunctionTail", + "RemoveFunctionTail", + "DelFunction", + "FunctionEnd", + "OpenStackVariables", + "ChangeStackPointer", + "RenameRegister", + "SetType" + ] + }, + { + "label" : "&Patch program", + "actions" : [ + "PatchByte", + "PatchWord", + "Assemble", + "PatchedBytes", + "ApplyPatches" + ] + }, + { + "label" : "Ot&her", + "actions" : [ + "MakeAlignment", + "ManualInstruction", + "ColorInstruction", + "ToggleBorder" + ] + }, + { + "label" : "Plu&gins", + "name" : "Plugins", + "actions" : [] + } + ] + }, + { + "label" : "&Jump", + "name" : "Jump", + "actions" : [ + "JumpEnter", + "JumpEnterNew", + "Return", + "UndoReturn", + "EmptyStack", + "", + "JumpAsk", + "JumpName", + "JumpFunction", + "JumpSegment", + "JumpSegmentRegister", + "JumpQ", + "JumpXref", + "JumpXrefFrom", + "JumpOpXref", + "JumpEntryPoint", + "JumpFileOffset", + "", + "MarkPosition", + "JumpPosition", + "ClearMark" + ] + }, + { + "label" : "Searc&h", + "name" : "Search", + "actions" : [ + "JumpCode", + "JumpData", + "JumpExplored", + "JumpUnknown", + "AskNextImmediate", + "JumpImmediate", + "AskNextText", + "JumpText", + "AskBinaryText", + "JumpBinaryText", + "JumpNotFunction", + "JumpSuspicious", + "JumpError", + "FindAllSuspicious", + "FindAllErrors", + "", + "SetDirection" + ] + }, + { + "label" : "&View", + "name" : "View", + "actions" : [ + { + "label" : "&Open subviews", + "name" : "Subviews", + "actions" : [ + "QuickView", + "", + "WindowOpen", + "GraphNewProximityView", + "ToggleDump", + "", + "OpenExports", + "OpenImports", + "OpenNames", + "OpenFunctions", + "OpenStrings", + "", + "OpenSegments", + "OpenSegmentRegisters", + "OpenSelectors", + "", + "OpenSignatures", + "OpenTypeLibraries", + "", + "OpenStructures", + "OpenEnums", + "OpenLocalTypes", + "", + "OpenXrefs", + "OpenCallers", + "", + "OpenNotepad", + "OpenProblems", + "PatchedBytes" + ] + }, + { + "label" : "&Graphs", + "actions" : [ + "GraphFunc", + "PrintFlowLabels", + "", + "CallFlow", + "ChartXrefsTo", + "ChartXrefsFrom", + "ChartXrefsUser" + ] + }, + { + "label" : "&Toolbars", + "name" : "Toolbars", + "actions" : [] + }, + "Calculate", + "FullScreen", + "GraphOverview", + "RecentScripts", + "ShowSnapMan", + "", + "ShowRegisters", + "ShowFlags", + "", + "Hide", + "UnHide", + "HideAll", + "UnHideAll", + "DelHiddenRange", + "SetupHidden" + ] + }, + { + "label" : "", // The debugger menu labels are replaced automatically according to what menu is visible + "name" : "DebuggerSelected", + "visible_initially" : false, + "actions" : [ + "QuickDbgView", + "", + { + "label" : "&Debugger windows", + "name" : "DebuggerWindows", + "actions" : [ + "Debugger", + "Threads", + "Modules", + "Locals", + "StackView", + "StackTrace", + "WatchView" + ] + }, + { + "label" : "&Breakpoints", + "actions" : [ + "Breakpoints", + "BreakpointAdd", + "BreakpointDel" + ] + }, + { + "label" : "&Watches", + "actions" : [ + "WatchList", + "AddWatch", + "DelWatch" + ] + }, + { + "label" : "Tracin&g", + "actions" : [ + "TraceWindow", + "ClearTrace", + "", + "ToggleTraceInstructions", + "ToggleTraceBasicBlocks", + "ToggleTraceFunctions", + "", + "WriteTraceAdd", + "ReadWriteTraceAdd", + "ExecTraceAdd", + "", + "SetupTracing" + ] + }, + "", + "ProcessStart", + "ProcessAttach", + "SetupProcess", + "ProcessPause", + "ProcessExit", + "ProcessDetach", + "RefreshMemcfg", + "TakeSnapshot", + "", + "ThreadStepInto", + "ThreadStepOver", + "ThreadRunUntilReturn", + "ThreadRunToCursor", + "", + "SwitchToSource", + "ToggleSourceDebug", + "OpenSourceFile", + "", + "SetupDebugger", + "SwitchDebugger" + ] + }, + { + "label" : "", + "name" : "DebuggerUnselected", + "visible_initially" : false, + "actions" : [ + "SwitchDebugger" + ] + }, + { + "label" : "", + "name" : "DebuggerRunToAndAttach", + "actions" : [ + { + "label" : "&Run", + "name" : "DebuggerRunTo", + "actions" : [] + }, + { + "label" : "&Attach", + "name" : "DebuggerAttach", + "actions" : [] + } + ] + }, + { + "label" : "&Options", + "name" : "Options", + "actions" : [ + "Options", + "SetColors", + "SetFont", + "ShortcutEditor", + "CommandPalette", + "RepeatLastPaletteCommand", + "SetDirectives", + "SetNameType", + "SetDemangledNames", + "SetupCompiler", + "SetStrlitStyle", + "SetupCompiler", + "SetStrlitStyle", + "SetupData", + "SetupSrcPaths" + ] + }, + { + "label" : "&Windows", + "name" : "Windows", + "actions" : [ + "LoadDesktop", + "SaveDesktop", + "DeleteDesktop", + "ResetDesktop", + "", + "ResetHiddenMessages", + "", + "WindowsList", + "NextWindow", + "PrevWindow", + "CloseWindow", + "FocusCLI2", + "", + "OutputWindow", + "WindowActivate1", + "WindowActivate2", + "WindowActivate3", + "WindowActivate4", + "WindowActivate5", + "WindowActivate6", + "WindowActivate7", + "WindowActivate8", + "WindowActivate9" + ] + }, + { + "label" : "Help", + "name" : "Help", + "actions" : [ + "ShowHelp", +#ifdef __NT__ + "ExternalHelp", +#endif + "About", + "", + "BuyIDA", + "Homepage", + "SupportForum", + "CheckFreeUpdate", + "BugReport" + ] + }, + + // ------------------ + // "Structures" menus + // ------------------ + { + "label" : "&Edit", + "name" : "Struct:Edit", + "present_initially" : false, + "actions" : [ + "EditCopy", + "", + "AddStruct", + "CopyStruct", + "EditStruct", + "DelStruct", + "", + "ExpandStruct", + "ShrinkStruct", + "", + "MakeData", + "DeclareStructVar", + "MakeStrlit", + "MakeArray", + "MakeUnknown", + "MakeName", + "SetType", + "CreateStructFromData", + "", + { + "label" : "&Field type", + "name" : "FieldType", + "actions" : [ + { + "label" : "&Offset", + "icon" : 23, + "actions" : [ + "OpOffset", + "OpOffsetCs", + "OpUserOffset", + "OpStructOffset" + ] + }, + { + "label" : "&Number", + "icon" : 4, + "actions" : [ + "OpNumber", + "OpHex", + "OpDecimal", + "OpOctal", + "OpBinary", + "OpFloat" + ] + }, + "OpChar", + "OpSegment", + "OpEnum", + "ChangeSign", + "BitwiseNegate" + ] + } + ] + }, + { + "label" : "&Jump", + "name" : "Struct:Jump", + "present_initially" : false, + "actions" : [ + "JumpName", + "JumpXref", + "", + "MarkPosition", + "JumpPosition", + "ClearMark" + ] + }, + { + "label" : "Searc&h", + "name" : "Struct:Search", + "present_initially" : false, + "actions" : [ + "AskNextText", + "JumpText", + "", + "SetDirection" + ] + }, + + // ------------- + // "Enums" menus + // ------------- + { + "label" : "&Edit", + "name" : "Enum:Edit", + "present_initially" : false, + "actions" : [ + "EditCopy", + "", + "AddEnum", + "EditEnum", + "DelEnum", + "", + "AddConst", + "EditConst", + "DelConst", + "", + { + "label" : "Comments", + "actions" : [ + "MakeComment", + "MakeRptCmt" + ] + } + ] + }, + { + "label" : "&Jump", + "name" : "Enum:Jump", + "present_initially" : false, + "actions" : [ + "JumpName", + "", + "MarkPosition", + "JumpPosition", + "ClearMark" + ] + }, + { + "label" : "Searc&h", + "name" : "Enum:Search", + "present_initially" : false, + "actions" : [ + "AskNextText", + "JumpText", + "", + "SetDirection" + ] + } +] + + +// +// Toolbars layout +// --------------- +// + +TOOLBARS_LAYOUT = [ + { + "label" : "File", + "name" : "FileToolBar", + "basic_mode" : true, + "actions" : [ + "LoadNewFile", + "SaveBase" + ] + }, + { + "label" : "Jump", + "name" : "JumpToolBar", + "basic_mode" : true, + "actions" : [ + "Return", + "UndoReturn" + ] + }, + { + "label" : "Search", + "name" : "SearchToolBar", + "basic_mode" : true, + "actions" : [ + "AskNextImmediate", + "AskNextText", + "AskBinaryText", + "", + "SearchNext", + "", + "SetDirection", + "", + "LockHighlight" + ] + }, + { + "label" : "Hide/Unhide", + "name" : "HideToolBar", + "actions" : [ + "Hide", + "UnHide", + "DelHiddenRange" + ] + }, + { + "label" : "Analysis", + "name" : "AnalysisToolBar", + "basic_mode" : true, + "actions" : [ + "OpenProblems", + "Analysis" + ] + }, + { + "label" : "Views", + "name" : "ViewsToolBar", + "actions" : [ + "WindowOpen", + "ToggleDump", + "Debugger" + ] + }, + { + "label" : "Graph view", + "name" : "GraphViewToolBar", + "actions" : [ + "GraphFlatView", + "GraphGraphView", + "GraphProximityView", + "", + "GraphZoom100", + "GraphZoomFit", + "GraphLayout", + "GraphPrint", + "GraphSetupOptions", + "GraphSetupColors" + ] + }, + { + "label" : "Lists", + "name" : "ListsToolBar", + "actions" : [ + "OpenExports", + "OpenImports", + "OpenNames", + "OpenFunctions", + "OpenStrings" + ] + }, + { + "label" : "Signatures/Types", + "name" : "SignTypesToolBar", + "actions" : [ + "OpenSignatures", + "OpenTypeLibraries" + ] + }, + { + "label" : "Structures/Enumerations", + "name" : "StructEnumToolBar", + "actions" : [ + "OpenStructures", + "OpenEnums" + ] + }, + { + "label" : "Cross references", + "name" : "CrossReferencesToolBar", + "actions" : [ + "OpenXrefs", + "OpenCallers" + ] + }, + { + "label" : "Segments", + "name" : "SegmentsToolBar", + "actions" : [ + "OpenSegments", + "OpenSegmentRegisters", + "OpenSelectors" + ] + }, + "", // Toolbar break + { + "label" : "Edit", + "name" : "EditToolBar", + "basic_mode" : true, + "actions" : [ + "MakeCode", + "MakeData", + "DeclareStructVar", + "@MakeStrlit", + "MakeArray", + "MakeName", + "MakeUnknown" + ] + }, + { + "label" : "Operand type", + "name" : "OperandTypeToolBar", + "actions" : [ + "@OpOffset", + "@OpNumber", + "OpChar", + "OpSegment", + "OpEnum", + "OpStackVariable", + "ChangeSign", + "BitwiseNegate", + "ManualOperand" + ] + }, + { + "label" : "Utilities", + "name" : "UtilitiesToolBar", + "actions" : [ + "Calculate", + "OpenNotepad", + "ExecuteLine", + "Execute" + ] + }, + { + "label" : "Functions", + "name" : "FunctionsToolBar", + "actions" : [ + "Function", + "OpenStackVariables", + "SetType" + ] + }, + { + "label" : "Enumerations", + "name" : "EnumerationsToolBar", + "actions" : [ + "AddEnum", + "EditEnum", + "DelEnum", + "", + "AddConst", + "EditConst", + "DelConst" + ] + }, + { + "label" : "Structures", + "name" : "StructuresToolBar", + "actions" : [ + "AddStruct", + "CopyStruct", + "EditStruct", + "DelStruct", + "", + "ExpandStruct", + "ShrinkStruct" + ] + }, + { + "label" : "Comments", + "name" : "CommentsToolBar", + "actions" : [ + "MakeComment", + "MakeRptCmt", + "MakeExtraLineA", + "MakeExtraLineB" + ] + }, + { + "label" : "Graphs", + "name" : "GraphsToolBar", + "actions" : [ + "GraphFunc", + "CallFlow", + "ChartXrefsTo", + "ChartXrefsFrom", + "ChartXrefsUser" + ] + }, + "", // Toolbar break + { + "label" : "Debug", + "name" : "DebugToolBar", + "basic_mode" : true, + "actions" : [ + "ProcessStart", + "ProcessPause", + "ProcessExit", + "@DebuggerList", + "", + "SwitchToSource", + "ToggleSourceDebug" + ] + }, + { + "label" : "Debugger commands", + "name" : "DbgCommandsToolBar", + "actions" : [ + "ThreadStepInto", + "ThreadStepOver", + "ThreadRunUntilReturn", + "ThreadRunToCursor", + "", + "Threads", + "Modules" + ] + }, + { + "label" : "Breakpoints", + "name" : "BreakpointsToolBar", + "basic_mode" : true, + "actions" : [ + "Breakpoints", + "BreakpointAdd", + "BreakpointDel" + ] + }, + { + "label" : "Watches", + "name" : "WatchesToolBar", + "actions" : [ + "WatchList", + "AddWatch", + "DelWatch" + ] + }, + { + "label" : "Tracing", + "name" : "TracingToolBar", + "actions" : [ + "TraceWindow", + "", + "ToggleTraceInstructions", + "ToggleTraceFunctions", + "", + "StackTrace" + ] + } +] + + + +// +// File extension definitions +// -------------------------- +// + +// IDA extensions +#ifdef __EA64__ + #define IDB_EXT "*.i64;*.id0" +#else + #define IDB_EXT "*.id?" +#endif + +// Identifier, Name, Extension(s) +FILE_EXTENSIONS = { + // file formats: + // Windows + EXE_WIN, "PE Executables", "*.exe" + DLL_WIN, "PE Dynamic Libraries", "*.dll" + OCX_WIN, ".ocx PE ActiveX Controls", "*.ocx" + DRV_WIN, "PE/LE/NE Device Drivers", "*.sys;*.vxd;*.386;*.drv" + OBJ_WIN, "COFF/OMF Object Files", "*.obj" + LIB_WIN, "COFF/OMF Static Libraries", "*.lib" + // DOS + EXE_DOS, "MZ/LE/DJGPP-COFF/Watcom-W32RUN Executables", "*.exe" + EXE_COM_DOS, ".com Executables", "*.com" + DRV_DOS, ".sys Device Drivers", "*.sys" + OVR_DOS, ".ovr Overlay Files", "*.ovr" + OBJ_DOS, "OMF Object Files", "*.obj" + LIB_DOS, "OMF Static Libraries", "*.lib" + EXE_PHARLAP, ".exp PharLap Protected Mode Executables", "*.exp" + // Unix + EXE_UNIX, "ELF/COFF/A.OUT/QNX/SOM Executables", "*" + DLL_UNIX, "ELF/COFF Dynamic Libraries", "*.so;*.so.*" + OBJ_UNIX, "ELF/COFF/SOM Object Files", "*.o" + LIB_UNIX, "ELF/COFF Static Libraries", "*.a" + DLL_HPUX, ".sl HP-UX SOM Dynamic Libraries", "*.sl" + // Mac + EXE_MACOSX, "Mac OS X Mach-O Executables", "*" + DLL_MACOSX, "Mac OS X Mach-O Dynamic Libraries", "*.dylib" + EXE_MACOS, "Mac OS PEF Executables", "*" + OBJ_MACOSX, "Mac OS X Mach-O Object Files", "*.o" + LIB_MACOSX, "Mac OS X Mach-O Static Libraries", "*.a" + // Java + CLASS_JAVA, "Java Class Files", "*.cla*;*.cls" + ZIP_JAVA, ".jar/.zip Java Archives", "*.jar;*.zip" + // .NET + EXE_NET, ".NET Executables", "*.exe" + DLL_NET, ".NET Dynamic Libraries", "*.dll" + // various OS's + EXE_OS2, "OS/2 LX Executables", "*.exe" + DRV_NETWARE, "NetWare Loadable Modules", "*.nlm;*.lan;*.dsk" + EXE_BEOS, "BeOS ELF/PEF Executables", "*" + AMIGA, "Amiga Hunk Files", "*" + GEOS, "GeoWorks GEOS Files", "*.geo" + OS9, "OS-9 Object Files", "*" + EXE_FLEX, ".cmd Motorola FLEX OS Executables", "*.cmd" + EXE_RT11, ".sav PDP-11/RT-11 Executables", "*.sav" + // PDAs/handhelds + EXE_ARM, ".axf ARM Executables", "*.axf" + OBJ_ARM, "ARM Object Files", "*.o" + EXE_EPOC, ".app Symbian EPOC Executables", "*.app" + SIS_EPOC, ".sis Symbian EPOC Installation Files", "*.sis" + EXE_PALM, ".prc Palm Pilot Executables", "*.prc" + // consoles + EXE_XBOX, ".xbe Xbox Executables", "*.xbe" + EXE_N64, ".v64 Nintendo ROM Images", "*.v64" + ROM_NGB, ".bin Nintendo GameBoy ROM Images", "*.bin" + BIN_SPSX, ".bin Sony PlayStation BIOS Images", "*.bin" + EXE_SPSX, ".psx Sony PlayStation Executables", "*.psx" + OBJ_SPSX, "Sony PlayStation Object Files", "*.obj;*.o" + EXE_SDC, ".elf Sega Dreamcast ELF Executables", "*.elf" + // embedded + INTEL_HEX, ".hex Intel/MOS Hexadecimal Files", "*.hex" + S19_HEX, ".s19 Motorola S-record Hexadecimal Files", "*.s19" + OBJ_INTEL, "Intel OMF-386 Object Files", "*.obj" + MAS, ".p MAS Macro Assembler Code Files", "*.p" + SBN, ".sbn Structured Binary Format Files", "*.sbn" + // binary files + RAW_BIN, "Binary/Raw Files", "*.bin;*.raw" + ROM_BIN, "ROM Images", "*.rom" + DUMP_BIN, "Dump Files", "*.dmp;*.dump;*.mdmp" + // file categories (mainly used to define the default file filter): + ALL, "All Files", "*" + IDB, "IDA Databases", IDB_EXT + EXE, "Executable Files", EXE_* + DLL, "Dynamic Libraries", DLL_* + DRV, "Drivers", DRV_* + OBJLIB, "Object Files and Libraries", OBJ_*;LIB_* + JAVA, "Java Files", *_JAVA + NET, ".NET Files", *_NET + ARM, "ARM Files", *_ARM + EPOC, "Symbian EPOC Files", *_EPOC + SPSX, "Sony PlayStation Files", *_SPSX + HEX, "Hexadecimal Files", *_HEX + KNOWN, "All known file extensions", * +} + +// +// Default file filter (used by the Open command) +// + +DEFAULT_FILE_FILTER = { KNOWN ALL IDB EXE DLL DRV OBJLIB JAVA NET DRV_NETWARE GEOS EXE_FLEX EXE_RT11 ARM EPOC SPSX EXE_PALM EXE_XBOX EXE_N64 EXE_SDC HEX MAS SBN RAW_BIN ROM_BIN DUMP_BIN } + +//------------------------------------------------------------------------- +// User specific parameters +//------------------------------------------------------------------------- +// +// If you don't want to modify IDAGUI.CFG file then you can create a file +// called IDAUSERG.CFG and place additional parameters there. +// +// The IDAUSERG.CFG file should be placed in the IDA/CFG directory. +// +#softinclude diff --git a/ida.clr b/ida.clr new file mode 100644 index 0000000..9026e30 --- /dev/null +++ b/ida.clr @@ -0,0 +1,114 @@ +[DISASM] +000000 // +aaaaaa //Default color +f3c5ff //Regular comment +7e6082 //Repeatable comment +666666 //Automatic comment +ffffff //Instruction +b9ebeb //Dummy Data Name +b9ebeb //Regular Data Name +bbecff //Demangled Name +c0c0c0 //Punctuation +00d269 //Char constant in instruction +00ff00 //String constant in instruction +3250d2 //Numeric constant in instruction +4646ff //Void operand +7faaff //Code reference +617c7c //Data reference +3250d2 //Code reference to tail byte +008080 //Data reference to tail byte +3734ff //Error or problem +c0c0c0 //Line prefix +595959 //Binary line prefix bytes +f3c5ff //Extra line +ffaaff //Alternative operand +00d2ff //Hidden name +ffff00 //Library function name +0080ff //Local variable name +00d2ff //Dummy code name +00d69d //Assembler directive +7e07df //Macro +00d269 //String constant in data directive +00f379 //Char constant in data directive +3250d2 //Numeric constant in data directive +ababab //Keywords +adad73 //Register name +fd5aff //Imported name +7fffff //Segment name +00ffaa //Dummy unknown name +00d2ff //Regular code name +ffaaff //Regular unknown name +00ffff //Collapsed line +000000 //Max color number +2d2d2d //Line prefix: library function +4b4b4b //Line prefix: regular function +ffff00 //Line prefix: instruction +666666 //Line prefix: data +0000aa //Line prefix: unexplored +617c7c //Line prefix: externs +009d9d //Line prefix: current item +ff55ff //Line prefix: current line +000000 //Punctuation +00aaff //Opcode bytes +000000 //Manual operand +[NAVBAR] +429cc8 //Library function +8a7a43 //Regular function +319659 //Instruction +a1c8c8 //Data item +555555 //Unexplored +c86ac8 //External symbol +2b2bca //Errors +4a4a4a //Gaps +41ffa3 //Cursor +5c37ff //Address +[DEBUG] +ffd060 //Current IP +ffa0a0 //Current IP (+ enabled breakpoint) +408020 //Current IP (+ disabled breakpoint) +2d2d2d //Default background +000076 //Address (+ enabled breakpoint) +00ff00 //Address (+ disabled breakpoint) +004080 //Current IP (+ unavailable breakpoint) +0080ff //Address (+ unavailable breakpoint) +000000 //Registers +ff0000 //Registers (changed) +800080 //Registers (edited) +[ARROW] +34466c //Jump in current function +dede00 //Jump external to function +00aaff //Jump under the cursor +008000 //Jump target +ff4040 //Register target +[GRAPH] +787878 //Top color +4c4c4c //Bottom color +54585e //Normal title +f5f5f5 //Selected title +989faa //Current title +0400ff //Group frame +242424 //Node shadow +003900 //Highlight color 1 +00006d //Highlight color 2 +0000ff //Foreign node +cb4300 //Normal edge +00b400 //Yes edge +0000bc //No edge +ffaaaa //Highlighted edge +52a7c8 //Current edge +[MISC] +d4d4d4 //Message text +212121 //Message background +404080 //Patched bytes +0080ff //Unsaved changes +[OTHER] +4f6865 //Highlight color +3b4444 //Hint color +[SYNTAX] +ff0000 0 0 //Keyword 1 +800080 0 0 //Keyword 2 +0000ff 0 0 //Keyword 3 +00008b 0 0 //String +006400 0 1 //Comment +ff0000 1 0 //Preprocessor +8b8b00 1 0 //Number diff --git a/plugins/HexRaysCodeXplorer.dll b/plugins/HexRaysCodeXplorer.dll new file mode 100644 index 0000000..264810e Binary files /dev/null and b/plugins/HexRaysCodeXplorer.dll differ diff --git a/plugins/HexRaysCodeXplorer64.dll b/plugins/HexRaysCodeXplorer64.dll new file mode 100644 index 0000000..8e708be Binary files /dev/null and b/plugins/HexRaysCodeXplorer64.dll differ diff --git a/plugins/HexraysInvertIf32.dll b/plugins/HexraysInvertIf32.dll new file mode 100644 index 0000000..ccbd6c5 Binary files /dev/null and b/plugins/HexraysInvertIf32.dll differ diff --git a/plugins/HexraysInvertIf64.dll b/plugins/HexraysInvertIf64.dll new file mode 100644 index 0000000..f36e1d7 Binary files /dev/null and b/plugins/HexraysInvertIf64.dll differ diff --git a/plugins/IDASkins.dll b/plugins/IDASkins.dll new file mode 100644 index 0000000..9a1b62f Binary files /dev/null and b/plugins/IDASkins.dll differ diff --git a/plugins/IDASkins64.dll b/plugins/IDASkins64.dll new file mode 100644 index 0000000..083efa5 Binary files /dev/null and b/plugins/IDASkins64.dll differ diff --git a/plugins/IDA_ClassInformer_PlugIn.dll b/plugins/IDA_ClassInformer_PlugIn.dll new file mode 100644 index 0000000..461cd86 Binary files /dev/null and b/plugins/IDA_ClassInformer_PlugIn.dll differ diff --git a/plugins/IDA_ClassInformer_PlugIn64.dll b/plugins/IDA_ClassInformer_PlugIn64.dll new file mode 100644 index 0000000..bef542e Binary files /dev/null and b/plugins/IDA_ClassInformer_PlugIn64.dll differ diff --git a/plugins/IDA_FunctionStringAssociate_PlugIn32.dll b/plugins/IDA_FunctionStringAssociate_PlugIn32.dll new file mode 100644 index 0000000..83d4ca7 Binary files /dev/null and b/plugins/IDA_FunctionStringAssociate_PlugIn32.dll differ diff --git a/plugins/IDA_FunctionStringAssociate_PlugIn64.dll b/plugins/IDA_FunctionStringAssociate_PlugIn64.dll new file mode 100644 index 0000000..0903667 Binary files /dev/null and b/plugins/IDA_FunctionStringAssociate_PlugIn64.dll differ diff --git a/force_lvar_width.py b/plugins/force_lvar_width.py similarity index 74% rename from force_lvar_width.py rename to plugins/force_lvar_width.py index abde677..59ade0d 100644 --- a/force_lvar_width.py +++ b/plugins/force_lvar_width.py @@ -97,15 +97,32 @@ class hexrays_callback_info(object): return 0 -if idaapi.init_hexrays_plugin(): - i = hexrays_callback_info() - idaapi.register_action( - idaapi.action_desc_t( - force_width_actname, - "Force lvar width", - force_width_action_handler_t(i), - "Shift-W")) - idaapi.install_hexrays_callback(i.event_callback) -else: - print 'Force lvar width: hexrays is not available.' +class ForceLvarWidth(idaapi.plugin_t): + flags = idaapi.PLUGIN_PROC | idaapi.PLUGIN_HIDE + wanted_hotkey = "Shift-W" + comment = "Force lvar width plugin for Hex-Rays decompiler" + help = "There is no one to help you now" + wanted_name = "Hex-Rays lvar width forcer" + def init(self): + if idaapi.init_hexrays_plugin(): + i = hexrays_callback_info() + idaapi.register_action( + idaapi.action_desc_t( + force_width_actname, + "Force lvar width", + force_width_action_handler_t(i), + "Shift-W")) + idaapi.install_hexrays_callback(i.event_callback) + print 'Hex-Rays lvar width forcer by ecx86 loaded!' + else: + print 'Force lvar width: Hexrays is not available.' + + def term(self): + pass + + def run(self, arg): + pass + +def PLUGIN_ENTRY(): + return ForceLvarWidth() diff --git a/plugins/labeless_ida_70.dll b/plugins/labeless_ida_70.dll new file mode 100644 index 0000000..c489d42 Binary files /dev/null and b/plugins/labeless_ida_70.dll differ diff --git a/plugins/labeless_ida_70_64.dll b/plugins/labeless_ida_70_64.dll new file mode 100644 index 0000000..cd90778 Binary files /dev/null and b/plugins/labeless_ida_70_64.dll differ diff --git a/plugins/ret-sync.py b/plugins/ret-sync.py new file mode 100644 index 0000000..eafa102 --- /dev/null +++ b/plugins/ret-sync.py @@ -0,0 +1,4 @@ +from ret_sync_ext_ida import SyncPlugin + +def PLUGIN_ENTRY(): + return SyncPlugin.SyncPlugin() \ No newline at end of file diff --git a/plugins/ret_sync_ext_ida/SyncPlugin.py b/plugins/ret_sync_ext_ida/SyncPlugin.py new file mode 100644 index 0000000..b721c4b --- /dev/null +++ b/plugins/ret_sync_ext_ida/SyncPlugin.py @@ -0,0 +1,1124 @@ +# +# Copyright (C) 2016-2017, Alexandre Gazet. +# +# Copyright (C) 2012-2015, Quarkslab. +# +# This file is part of ret-sync. +# +# ret-sync is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os +import sys +import time +import traceback +import struct +import binascii +import base64 +import ctypes +import socket +import ConfigParser + +try: + import argparse +except: + print "[-] please make sure python's argparse module is available\n%s" % repr(sys.exc_info()) + sys.exit(0) + +import idc +import idaapi +import idautils +import ida_graph +import ida_kernwin +from idaapi import PluginForm + + +# Enable/disable logging JSON received in the IDA output window +DEBUG_JSON = False + +if sys.platform == 'win32': + PYTHON_BIN = 'python.exe' + PYTHON_PATH = os.path.normpath("C:\\Programs\\share\\Python27") + +elif sys.platform.startswith('linux') or sys.platform == 'darwin': + PYTHON_BIN = 'python' + PYTHON_PATH = os.path.normpath("/usr/bin") + +else: + print "[-] please fix PYTHON_PATH & PYTHON_BIN values, %s platform currently unknown" % sys.platform + sys.exit(0) + +if not os.path.exists(os.path.join(PYTHON_PATH, PYTHON_BIN)): + print "[-] please fix PYTHON_PATH value" + sys.exit(0) + + +site_packages = os.path.join(PYTHON_PATH, "lib", "site-packages") +if site_packages not in sys.path: + sys.path.insert(0, site_packages) + +try: + from PyQt5 import QtCore, QtWidgets + from PyQt5.QtCore import QProcess, QProcessEnvironment +except: + print "[-] failed to import Qt libs from PyQt5\n%s" % repr(sys.exc_info()) + sys.exit(0) + +try: + import json +except: + print "[-] failed to import json\n%s" % repr(sys.exc_info()) + sys.exit(0) + +# default value is current script's path +BROKER_PATH = os.path.join(os.path.normpath(os.path.dirname(__file__)), "broker.py") +if not os.path.exists(BROKER_PATH): + print "[-] broker path is not properly set, current value: <%s>" % BROKER_PATH + sys.exit(0) + +IDB_PATH = os.path.dirname(os.path.realpath(idc.GetIdbPath())) + +CONNECT_BROKER_MAX_ATTEMPT = 4 + +COL_GREEN = 0x33ff00 +COL_DEEP_PURPLE = 0xff44dd +COL_YLW = 0x23ffff +COL_BLUE_NAVY = 0x000080 +COL_GRAY = 0x808080 + +COL_CURLINE = COL_YLW +#COL_CURLINE = COL_BLUE_NAVY # renders better with some themes +COL_CBTRACE = COL_GREEN + +NETNODE_STORE = "$ SYNC_STORE" +NETNODE_INDEX = 0xFFC0DEFF + +DBG_DIALECTS = { + 'windbg': {'prefix': '!', 'si': 't', 'so': 'p', 'go': 'g', 'bp': 'bp ', 'hbp': 'ba e 1 ', 'bp1': 'bp /1 ', 'hbp1': 'ba e 1 /1 '}, + 'gdb': {'prefix': '', 'si': 'si', 'so': 'ni', 'go': 'continue', 'bp': 'b *', 'hbp': 'hb *', 'bp1': 'tb *', 'hbp1': 'thb *'}, + 'ollydbg2': {'prefix': '', 'si': 'si', 'so': 'so', 'go': 'go', 'bp': 'bp ', 'hbp': 'xxx ', 'bp1': 'xxx ', 'hbp1': 'xxx '}, + 'x64_dbg': {'prefix': '', 'si': 'sti', 'so': 'sto', 'go': 'go', 'bp': 'bp ', 'hbp': 'bph ', 'bp1': 'xxx ', 'hbp1': 'xxx '}, +} + +# -------------------------------------------------------------------------- + + +class RequestHandler(object): + + # color callback + def cb_color(self, ea): + idaapi.set_item_color(ea, COL_CBTRACE) + + # instruction step callback + def cb_curline(self, ea): + if self.prev_loc: + prev_ea, prev_color = self.prev_loc + cur_color = idaapi.get_item_color(prev_ea) + # race condition: block/instruction's color may have been modified + # after it was saved + if (cur_color != prev_color) and (cur_color != COL_CURLINE): + prev_color = cur_color + idaapi.set_item_color(prev_ea, prev_color) + + self.prev_loc = [ea, idaapi.get_item_color(ea)] + idaapi.set_item_color(ea, COL_CURLINE) + + def cb_restore_last_line(self): + if self.prev_loc: + ea, col = self.prev_loc + idaapi.set_item_color(ea, col) + + # support -a / --address switch + def addr_switch(self, offset, msg): + if (not msg) or (msg == ''): + return [offset, msg] + + try: + args = self.parser.parse_args(msg.split()) + except: + print "[*] failed to parse command" + return [None, msg] + + # no address switch supplied + if not args.address: + return [offset, msg] + + try: + addr = int(''.join(args.address), 16) + except: + print "[*] failed to parse address, should be hex" + return [None, msg] + + # make sure the address points to a valid instruction/data + head = idaapi.get_item_head(addr) + if head != addr: + print "[*] ambiguous address, did you mean 0x%x ?" % head + return [None, msg] + + return [addr, ' '.join(args.msg)] + + # check if address is within a valid segment + def is_safe(self, offset): + return not (idc.SegStart(offset) == idaapi.BADADDR) + + # rebase address with respect to local image base + def rebase(self, base, offset): + if base is not None: + # check for non-compliant debugger client + if base > offset: + print "[sync] unsafe addr" + return None + + if not (self.base == base): + offset = (offset - base) + self.base + + # update base address of remote module + if self.base_remote != base: + self.base_remote = base + + if not self.is_safe(offset): + print "[sync] unsafe addr" + return None + + return offset + + # rebase address with respect to remote image base + def rebase_remote(self, offset): + if not (self.base == self.base_remote): + offset = (offset - self.base) + self.base_remote + + return offset + + # demangle names + def demangle(self, name): + mask = idc.GetLongPrm(INF_SHORT_DN) + demangled = idc.Demangle(name, mask) + if demangled is None: + return name + else: + return demangled + + # prevent flooding debug engine with too much commands + # sync plugin does NOT wait for any sort of ack + # example: "^ Debuggee already running error in 'g'" + def notice_anti_flood(self): + time.sleep(0.1) + + # append comment and handle cmt's size limitation (near 1024) + def append_cmt(self, ea, cmt, rptble=False): + if len(cmt) > 1024: + print "[*] warning, comment needs to be splitted (from 0x%x)" % ea + nh = idaapi.next_head(ea, idaapi.BADADDR) + if nh == idaapi.BADADDR: + print "[*] failed to find next instruction candidate" + return + + self.append_cmt(nh, cmt[1024:], rptble) + cmt = cmt[:1024] + + idaapi.append_cmt(ea, cmt, rptble) + + # location request, update disassembly IDA view + def req_loc(self, hash): + offset, base = hash['offset'], hash.get('base') + ea = self.rebase(base, offset) + if not ea: + return + + if(self.color): + self.cb_color(ea) + + idaapi.jumpto(ea) + self.cb_curline(ea) + self.gm.center() + + # log command output request at addr + def req_cmd(self, hash): + msg_b64, offset, base = hash['msg'], hash['offset'], hash['base'] + msg = base64.b64decode(msg_b64) + ea = self.rebase(base, offset) + if not ea: + return + + print ("[*] cmd output added at 0x%x" % ea) + self.append_cmt(ea, str(msg)) + + # reset comment at addr + def req_rcmt(self, hash): + msg, offset, base = hash['msg'], hash['offset'], hash['base'] + offset, msg = self.addr_switch(offset, msg) + if not offset: + return + + ea = self.rebase(base, offset) + if not ea: + return + + idaapi.set_cmt(ea, str(''), False) + print ("[*] reset comment at 0x%x" % ea) + + # add comment request at addr + def req_cmt(self, hash): + msg, offset, base = hash['msg'], hash['offset'], hash['base'] + offset, msg = self.addr_switch(offset, msg) + if not offset: + return + + ea = self.rebase(base, offset) + if not ea: + return + + self.append_cmt(ea, str(msg)) + print ("[*] comment added at 0x%x" % ea) + + # add a function comment at addr + def req_fcmt(self, hash): + msg, offset, base = hash['msg'], hash['offset'], hash['base'] + offset, msg = self.addr_switch(offset, msg) + if not offset: + return + + ea = self.rebase(base, offset) + if not ea: + return + + func = idaapi.get_func(ea) + if not func: + print ("[*] could not find func for 0x%x" % ea) + return + + idaapi.set_func_cmt(func, str(msg), False) + print ("[*] function comment added at 0x%x" % ea) + + # add an address comment request at addr + def req_raddr(self, hash): + raddr, rbase, offset, base = hash['raddr'], hash['rbase'], hash['offset'], hash['base'] + ea = self.rebase(base, offset) + if not ea: + return + + if self.base_remote != rbase: + print("[*] could not rebase this address, not in module") + return + + addr = self.rebase(rbase, raddr) + if not addr: + return + + self.append_cmt(ea, "0x%x (rebased from 0x%x)" % (addr, raddr)) + print ("[*] comment added at 0x%x" % ea) + + # return current cursor in IDA Pro + def req_cursor(self, hash): + print("[*] request IDA Pro cursor position") + addr = idc.ScreenEA() + self.notice_broker("cmd", "\"cmd\":\"%s\"" % addr) + return + + # patch memory at specified address using info from debugger + def req_patch(self, hash): + addr, value, length = hash['addr'], hash['value'], hash['len'] + if length != 4 and length != 8: + print("[x] unsupported length: %d" % length) + return + if length == 4: + prev_value = Dword(addr) + if MakeDword(addr) != 1: + print("[x] MakeDword failed") + if PatchDword(addr, value) != 1: + print("[x] PatchDword failed") + if not idc.OpOff(addr, 0, 0): + print("[x] OpOff failed") + elif length == 8: + prev_value = Qword(addr) + if MakeQword(addr) != 1: + print("[x] MakeQword failed") + if PatchQword(addr, value) != 1: + print("[x] PatchQword failed") + if not idc.OpOff(addr, 0, 0): + print("[x] OpOff failed") + + print ("[*] patched 0x%x = 0x%x (previous was 0x%x)" % (addr, value, prev_value)) + + # return idb's symbol for a given address + def req_rln(self, hash): + raddr, rbase, offset, base = hash['raddr'], hash['rbase'], hash['offset'], hash['base'] + + print("[*] 0x%x - 0x%x - 0x%x - 0x%x" % (raddr, rbase, offset, base)) + + addr = self.rebase(rbase, raddr) + if not addr: + print("[*] could not rebase this address (0x%x)" % raddr) + return + + sym = idaapi.get_func_name(addr) + if sym: + sym = self.demangle(sym) + func = idaapi.get_func(addr) + if not func: + print ("[*] could not find func for 0x%x" % addr) + return + + lck = idaapi.lock_func(func) + + limits = idaapi.area_t() + if idaapi.get_func_limits(func, limits): + if limits.startEA != addr: + if (addr > limits.startEA): + sym = "%s%s0x%x" % (sym, "+", addr - limits.startEA) + else: + sym = "%s%s0x%x" % (sym, "-", limits.startEA - addr) + lck = None + else: + sym = idc.Name(addr) + if sym: + sym = self.demangle(sym) + + if sym: + self.notice_broker("cmd", "\"cmd\":\"%s\"" % sym) + print ("[*] resolved symbol: %s" % sym) + else: + print ("[*] could not resolve symbol for address 0x%x" % addr) + + # return address for a given idb's symbol + def req_rrln(self, hash): + sym, rbase, offset, base = hash['sym'], hash['rbase'], hash['offset'], hash['base'] + + print("[*] %s - 0x%x - 0x%x - 0x%x" % (sym, rbase, offset, base)) + + addr = idc.LocByName(sym) + if addr: + self.notice_broker("cmd", "\"cmd\":\"%s\"" % addr) + print ("[*] resolved address: %s" % addr) + else: + print ("[*] could not resolve address for symbol %s" % sym) + + # add label request at addr + def req_lbl(self, hash): + msg, offset, base = hash['msg'], hash['offset'], hash['base'] + offset, msg = self.addr_switch(offset, msg) + if not offset: + return + + ea = self.rebase(base, offset) + if not ea: + return + + flags = False + if str(msg).startswith('@@'): + flags = idaapi.SN_LOCAL + + idaapi.set_name(ea, str(msg), flags) + print ("[*] label added at 0x%x" % ea) + + # color request at addr + def req_bc(self, hash): + global COL_CBTRACE + msg, offset, base = hash['msg'], hash['offset'], hash['base'] + + if self.is_active: + ea = self.rebase(base, offset) + if not ea: + return + else: + ea = self.base + + if (msg == 'oneshot'): + print ("[*] color oneshot added at 0x%x" % ea) + # mark address as being colored + self.prev_loc = [ea, COL_CBTRACE] + elif (msg == 'on'): + print ("[*] color start from 0x%x" % ea) + self.color = True + self.prev_loc = [ea, COL_CBTRACE] + elif (msg == 'off'): + print ("[*] color end at 0x%x" % ea) + self.color = False + elif (msg == 'set'): + new_col = hash['rgb'] + if new_col > 0xffffff: + print ("[*] restoring color") + new_col = COL_GREEN + + COL_CBTRACE = new_col + print ("[*] set color to 0x%x" % COL_CBTRACE) + else: + print ("[*] invalid color request (%s)" % msg) + + # reload .bpcmds from idb + def req_bps_get(self, hash): + print ("[-] reload .bpcmds") + node = idaapi.netnode(NETNODE_INDEX) + if not node: + print ("[-] failed to open netnode store") + self.notice_broker("cmd", "\"cmd\":\"no blob\"") + return + + node.create(NETNODE_STORE) + blob = node.getblob(0, str(chr(1))) + + if not blob: + print (" -> no blob") + self.notice_broker("cmd", "\"cmd\":\" -> reloading .bpcmds: no blob\"") + return + + self.notice_broker("cmd", "\"cmd\":\"%s\"" % blob) + return + + # save .bpcmds to idb + def req_bps_set(self, hash): + blob = hash['msg'] + print ("[-] save .bpcmds") + node = idaapi.netnode(NETNODE_INDEX) + if not node: + print ("[-] failed to open netnode store") + self.notice_broker("cmd", "\"cmd\":\" -> failed to save .bpcmds") + return + + new = node.create(NETNODE_STORE) + if new == 0: + print (" -> creating new netnode store") + + out = node.setblob(str(blob), 0, str(chr(1))) + self.notice_broker("cmd", "\"cmd\":\" -> .bpcmds saved\"") + return + + # compare loaded module md5 with idb's input file md5 + def req_modcheck(self, hash): + md5, pdb = hash.get('md5'), hash.get('pdb') + remote = None + + if md5: + print ("[*] modcheck idb (md5)") + local = idc.GetInputMD5() + remote = (''.join(str(md5).encode("ascii").split())).upper() + elif pdb: + print ("[*] modcheck idb (pdb guid)") + msg = base64.b64decode(pdb) + local = DbgDirHlpr.read_rsds_codeview() + remote = DbgDirHlpr.parse_itoldyouso_output(msg) + + print (" -> remote: <%s>" % remote) + print (" -> local : <%s>" % local) + + if remote == "0": + res = "[!] warning, no Debug Directory" + elif local == remote: + res = "[+] module successfully matched" + else: + res = "[!] warning, modules mismatch" + + print res + self.notice_broker("cmd", "\"cmd\":\"%s\"" % res) + return + + # specify debugger dialect used to send commands + def req_set_dbg_dialect(self, hash): + global SyncForm + dialect = hash['dialect'] + if dialect in DBG_DIALECTS: + self.dbg_dialect = DBG_DIALECTS[dialect] + print "[sync] set debugger dialect to %s, enabling hotkeys" % dialect + SyncForm.init_hotkeys() + else: + SyncForm.uninit_hotkeys() + + # request from broker + def req_broker(self, hash): + subtype = hash['subtype'] + + if (subtype == 'msg'): + # simple message announcement + print ("[*] << broker << %s" % hash['msg']) + + elif(subtype == 'notice'): + # notice from broker + self.broker_port = int(hash['port']) + print ("[*] << broker << listening on port %d" % self.broker_port) + + for attempt in range(CONNECT_BROKER_MAX_ATTEMPT): + try: + host = socket.gethostbyname('localhost') + self.broker_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.broker_sock.connect((host, self.broker_port)) + break + except: + print "[sync] failed to connect to broker" + print sys.exc_info() + if self.broker_sock: + self.broker_sock.close() + self.broker_sock = None + time.sleep(0.1) + if (attempt == (CONNECT_BROKER_MAX_ATTEMPT - 1)): + self.announcement("[sync] failed to connect to broker (attempt %d)" % attempt) + sys.exit() + + # enable/disable idb, if disable it drops most sync requests + elif(subtype == 'enable_idb'): + self.is_active = True + print "[sync] idb is enabled" + + elif(subtype == 'disable_idb'): + self.is_active = False + self.cb_restore_last_line() + print "[sync] idb is disabled" + + # parse and execute request + # Note that sometimes we don't receive the whole request from the broker.py + # so parsing fails. One way for fixing this would be to fix broker.py to get + # everything until "\n" before proxying it but the way we do here is to read + # everything until "}" is received (end of json) + def parse_exec(self, req): + if self.prev_req: + if self.prev_req != "": + if DEBUG_JSON: + print "[+] JSON merge with request: \"%s\"" % req + + req = self.prev_req + req + self.prev_req = "" + if req == '': + return + if DEBUG_JSON: + print("parse_exec -> " + str(req)) + + if not (req[0:6] == '[sync]'): + print "\[<] bad hdr %s" % repr(req) + print '[-] Request dropped due to bad header' + return + + req_ = self.normalize(req, 6) + try: + hash = json.loads(req_) + except: + if DEBUG_JSON: + print "[-] Sync failed to parse json\n '%s'. Caching for next req..." % req_ + print "------------------------------------" + self.prev_req = req + return + + type = hash['type'] + if type not in self.req_handlers: + print ("[*] unknown request: %s" % type) + return + + req_handler = self.req_handlers[type] + + # few requests are handled even though idb is not enable + if type in ['broker', 'dialect', 'bc']: + req_handler(hash) + else: + if self.is_active: + req_handler(hash) + else: + print "[-] Drop the request because idb is not enabled" + return + + idaapi.refresh_idaview_anyway() + + def normalize(self, req, taglen): + req = req[taglen:] + req = req.replace("\\", "\\\\") + req = req.replace("\n", "") + return req + + # send a kill notice to the broker (then forwarded to the dispatcher) + def kill_notice(self): + self.notice_broker("kill") + + # send a bp command (F2) to the debugger (via the broker and dispatcher) + def bp_notice(self, oneshot=False): + if not self.is_active: + print "[sync] idb isn't enabled, bp can't be set" + return + + ea = idaapi.get_screen_ea() + offset = self.rebase_remote(ea) + cmd = "%s0x%x" % (self.dbg_dialect['bp1' if oneshot else 'bp'], offset) + + self.notice_broker("cmd", "\"cmd\":\"%s\"" % cmd) + print "[sync] >> set %s" % cmd + + # send a hardware bp command (Ctrl-F2) to the debugger (via the broker and dispatcher) + def hbp_notice(self, oneshot=False): + if not self.is_active: + print "[sync] idb isn't enabled, hbp can't be set" + return + + ea = idaapi.get_screen_ea() + offset = self.rebase_remote(ea) + cmd = "%s0x%x" % (self.dbg_dialect['hbp1' if oneshot else 'hbp'], offset) + + self.notice_broker("cmd", "\"cmd\":\"%s\"" % cmd) + print "[sync] >> set %s" % cmd + + # send a oneshot bp command (F3) to the debugger (via the broker and dispatcher) + def bp_oneshot_notice(self): + self.bp_notice(True) + + # send a oneshot hardware bp command (Ctrl-F3) to the debugger (via the broker and dispatcher) + def hbp_oneshot_notice(self): + self.hbp_notice(True) + + # export IDB's breakpoint (Ctrl-F1) to the debugger (via the broker and dispatcher) + def export_bp_notice(self): + if not self.dbg_dialect: + print "[sync] idb isn't synced yet, can't export bp" + return + + mod = self.name.split('.')[0].strip() + nbp = idc.GetBptQty() + + for i in range(nbp): + ea = idc.GetBptEA(i) + attrs = [idc.BPTATTR_TYPE, idc.BPTATTR_COND, idc.BPTATTR_FLAGS] + btype, cond, flags = [idc.GetBptAttr(ea, x) for x in attrs] + + if cond: + print "bp %d: conditional bp not supported" % i + else: + if ((btype in [idc.BPT_EXEC, idc.BPT_SOFT]) and + ((flags & idc.BPT_ENABLED) != 0)): + + offset = ea - self.base + bp = self.dbg_dialect['hbp' if (btype == idc.BPT_EXEC) else 'bp'] + cmd = "%s%s+0x%x" % (bp, mod, offset) + self.notice_broker("cmd", "\"cmd\":\"%s\"" % cmd) + print "bp %d: %s" % (i, cmd) + + print "[sync] export done" + + # send a translate command (Alt-F2) to the debugger (via the broker and dispatcher) + def translate_notice(self): + if not self.dbg_dialect: + print "[sync] idb isn't synced yet, can't translate" + return + + ea = idaapi.get_screen_ea() + mod = self.name.split('.')[0].strip() + cmd = self.dbg_dialect['prefix'] + "translate 0x%x 0x%x %s" % (self.base, ea, mod) + + self.notice_broker("cmd", "\"cmd\":\"%s\"" % cmd) + print "[sync] translate address 0x%x" % ea + + # send a go command (Alt-F5) to the debugger (via the broker and dispatcher) + def go_notice(self): + if not self.is_active: + print "[sync] idb isn't enabled, can't go" + return + + self.notice_broker("cmd", "\"cmd\":\"%s\"" % self.dbg_dialect['go']) + self.notice_anti_flood() + + # send a single trace command (F11) to the debugger (via the broker and dispatcher) + def si_notice(self): + if not self.is_active: + print "[sync] idb isn't enabled, can't trace" + return + + self.notice_broker("cmd", "\"cmd\":\"%s\"" % self.dbg_dialect['si']) + self.notice_anti_flood() + + # send a single step command (F10) to the debugger (via the broker and dispatcher) + def so_notice(self): + if not self.is_active: + print "[sync] idb isn't enabled, can't single step" + return + + self.notice_broker("cmd", "\"cmd\":\"%s\"" % self.dbg_dialect['so']) + self.notice_anti_flood() + + # send a notice message to the broker process + def notice_broker(self, type, args=None): + if not self.broker_sock: + return + + if args: + notice = "[notice]{\"type\":\"%s\",%s}\n" % (type, args) + else: + notice = "[notice]{\"type\":\"%s\"}\n" % (type) + + try: + self.broker_sock.sendall(notice) + except: + None + + def stop(self): + if self.broker_sock: + self.broker_sock.close() + self.broker_sock = None + + self.cb_restore_last_line() + idaapi.refresh_idaview_anyway() + self.is_active = False + print "[sync] idb is disabled" + + def __init__(self, parser): + self.color = False + self.prev_loc = None + self.prev_node = None + self.name = idaapi.get_root_filename() + print "[sync] name %s" % self.name + self.base = idaapi.get_imagebase() + print "[sync] module base 0x%x" % self.base + self.base_remote = None + self.gm = GraphManager() + self.parser = parser + self.broker_sock = None + self.is_active = False + self.dbg_dialect = None + self.req_handlers = { + 'broker': self.req_broker, + 'loc': self.req_loc, + 'cmd': self.req_cmd, + 'cmt': self.req_cmt, + 'rcmt': self.req_rcmt, + 'fcmt': self.req_fcmt, + 'raddr': self.req_raddr, + 'cursor': self.req_cursor, + 'patch': self.req_patch, + 'rln': self.req_rln, + 'rrln': self.req_rrln, + 'lbl': self.req_lbl, + 'bc': self.req_bc, + 'bps_get': self.req_bps_get, + 'bps_set': self.req_bps_set, + 'modcheck': self.req_modcheck, + 'dialect': self.req_set_dbg_dialect + } + self.prev_req = "" # used as a cache if json is not completely received + + +# -------------------------------------------------------------------------- + + +class Broker(QtCore.QProcess): + + def cb_on_error(self, error): + errors = ["Failed to start", "Crashed", "Timedout", + "Read error", "Write Error", "Unknown Error"] + print "[-] broker error: ", errors[error] + + def cb_broker_on_state_change(self, new_state): + states = ["Not running", "Starting", "Running"] + print "[*] broker new state: ", states[new_state] + if states[new_state] == "Not running": + print "[*] Check dispatcher.py.err if you think this is an error" + + def cb_broker_on_out(self): + # readAllStandardOutput() returns QByteArray + buffer = self.readAllStandardOutput().data().encode("ascii") + batch = buffer.split('\n') + for req in batch: + self.worker.parse_exec(req) + + def __init__(self, parser): + QtCore.QProcess.__init__(self) + + self.error.connect(self.cb_on_error) + self.readyReadStandardOutput.connect(self.cb_broker_on_out) + self.stateChanged.connect(self.cb_broker_on_state_change) + + # Create a request handler + self.worker = RequestHandler(parser) + +# -------------------------------------------------------------------------- + + +class DbgDirHlpr(object): + + @staticmethod + def read_rsds_codeview(): + guid = None + penode = idaapi.netnode() + penode.create(peutils_t.PE_NODE) + fpos = penode.altval(peutils_t.PE_ALT_DBG_FPOS) + + if (fpos == 0): + print "[*] No debug directory" + return guid + + input_file = idc.GetInputFilePath() + if not os.path.exists(input_file): + print "[*] input file not available" + else: + with open(input_file, 'r') as fd: + fd.seek(fpos) + raw = fd.read(0x1C) + + """ + typedef struct _IMAGE_DEBUG_DIRECTORY { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + DWORD Type; + DWORD SizeOfData; + DWORD AddressOfRawData; + DWORD PointerToRawData; + } IMAGE_DEBUG_DIRECTORY, *PIMAGE_DEBUG_DIRECTORY; + """ + dbgdir = struct.unpack('LLHHLLLL', raw) + # 2, IMAGE_DEBUG_TYPE_CODEVIEW + if not (dbgdir[4] == 2): + print "[*] not CODEVIEW data" + else: + fd.seek(dbgdir[7]) + if not (fd.read(4) == "RSDS"): + print "[*] unsupported CODEVIEW information format (%s)" % sig + else: + d1, d2, d3 = struct.unpack('LHH', fd.read(0x8)) + d4 = struct.unpack('>H', fd.read(0x2))[0] + d5 = binascii.hexlify(fd.read(0x6)).upper() + guid = "%08X-%04X-%04X-%04X-%s" % (d1, d2, d3, d4, d5) + + return guid + + @staticmethod + def parse_itoldyouso_output(res): + for line in res.splitlines(True): + line = line.strip() + if line.startswith('pdb sig: '): + return (line.split(':')[-1]).strip() + return None + + +# -------------------------------------------------------------------------- + + +class GraphManager(): + + def __init__(self): + self.prev_node = None + self.graph_viewer = ida_kernwin.get_current_viewer() + + def center(self): + curnode = ida_graph.viewer_get_curnode(self.graph_viewer) + + if not (self.prev_node == curnode): + ida_graph.viewer_center_on(self.graph_viewer, curnode) + self.prev_node = curnode + + return curnode + + +# -------------------------------------------------------------------------- + + +class SyncForm_t(PluginForm): + + def cb_broker_started(self): + print "[*] broker started" + self.btn.setText("Restart") + + def cb_broker_finished(self): + print "[*] broker finished" + if self.broker: + self.broker.worker.stop() + self.cb.stateChanged.disconnect(self.cb_change_state) + self.cb.toggle() + self.cb.stateChanged.connect(self.cb_change_state) + + self.btn.setText("Start") + + # send a kill notice to the broker + # wait at most 2sec for him to gently kill itself + def smooth_kill(self): + self.uninit_hotkeys() + if self.broker: + broker = self.broker + self.broker = None + broker.worker.cb_restore_last_line() + broker.worker.kill_notice() + broker.waitForFinished(1500) + + def init_broker(self): + print "[*] init_broker" + modname = self.input.text().encode('ascii', 'replace') + cmdline = u"\"%s\" -u \"%s\" --idb \"%s\"" % ( + os.path.join(PYTHON_PATH, PYTHON_BIN), + BROKER_PATH, modname) + print "[*] init broker,", cmdline + + self.broker = Broker(self.parser) + env = QProcessEnvironment.systemEnvironment() + env.insert("IDB_PATH", IDB_PATH) + env.insert("PYTHON_PATH", os.path.realpath(PYTHON_PATH)) + env.insert("PYTHON_BIN", PYTHON_BIN) + + try: + self.broker.started.connect(self.cb_broker_started) + self.broker.finished.connect(self.cb_broker_finished) + self.broker.setProcessEnvironment(env) + self.broker.start(cmdline) + except Exception as e: + print "[-] failed to start broker: %s\n%s" % (str(e), traceback.format_exc()) + return + + self.init_hotkeys() + self.broker.worker.name = modname + + def init_hotkeys(self): + if not self.hotkeys_ctx: + self.init_single_hotkey("F2", self.broker.worker.bp_notice) + self.init_single_hotkey("F3", self.broker.worker.bp_oneshot_notice) + self.init_single_hotkey("Ctrl-F2", self.broker.worker.hbp_notice) + self.init_single_hotkey("Ctrl-F3", self.broker.worker.hbp_oneshot_notice) + self.init_single_hotkey("Ctrl-F1", self.broker.worker.export_bp_notice) + self.init_single_hotkey("Alt-F2", self.broker.worker.translate_notice) + self.init_single_hotkey("Alt-F5", self.broker.worker.go_notice) + self.init_single_hotkey("F10", self.broker.worker.so_notice) + self.init_single_hotkey("F11", self.broker.worker.si_notice) + + def init_single_hotkey(self, key, fnCb): + ctx = idaapi.add_hotkey(key, fnCb) + if ctx is None: + print("[sync] failed to register hotkey %s", key) + del ctx + else: + self.hotkeys_ctx.append(ctx) + + def uninit_hotkeys(self): + if not self.hotkeys_ctx: + return + + for ctx in self.hotkeys_ctx: + if idaapi.del_hotkey(ctx): + del ctx + + self.hotkeys_ctx = [] + + def cb_btn_restart(self): + print "[sync] restarting broker." + if self.cb.checkState() == QtCore.Qt.Checked: + self.cb.toggle() + time.sleep(0.1) + self.cb.toggle() + + def cb_change_state(self, state): + if state == QtCore.Qt.Checked: + print "[*] sync enabled" + # Restart broker + self.hotkeys_ctx = [] + self.init_broker() + else: + if self.broker: + self.smooth_kill() + print "[*] sync disabled\n" + + def OnCreate(self, form): + print "[sync] form create" + + # Get parent widget + parent = self.FormToPyQtWidget(form) + + # Create checkbox + self.cb = QtWidgets.QCheckBox("Synchronization enable") + self.cb.move(20, 20) + self.cb.stateChanged.connect(self.cb_change_state) + + # Create label + label = QtWidgets.QLabel('Overwrite idb name:') + + name = idaapi.get_root_filename() + print "[sync] default idb name: %s" % name + # Check in conf for name overwrite + confpath = os.path.join(os.path.realpath(IDB_PATH), '.sync') + if os.path.exists(confpath): + print "[sync] found config file: %s" % confpath + config = ConfigParser.SafeConfigParser() + config.read(confpath) + if config.has_option(name, 'name'): + name = config.get(name, 'name') + print "[sync] overwrite idb name with %s" % name + + # Create input field + self.input = QtWidgets.QLineEdit(parent) + self.input.setText(name) + self.input.setMaxLength = 256 + self.input.setFixedWidth(300) + + # Create restart button + self.btn = QtWidgets.QPushButton('restart', parent) + self.btn.setToolTip('Restart broker.') + self.btn.clicked.connect(self.cb_btn_restart) + + # Create layout + layout = QtWidgets.QGridLayout() + layout.addWidget(self.cb) + layout.addWidget(label) + layout.addWidget(self.input) + layout.addWidget(self.btn, 2, 2) + layout.setColumnStretch(3, 1) + layout.setRowStretch(3, 1) + parent.setLayout(layout) + + # workaround: crash when instanciated in Broker.__init__ + # weird interaction with Qtxxx libraries ? + # File "C:\Python27\Lib\argparse.py", line 1584, in __init__ + # self._positionals = add_group(_('positional arguments')) + # File "C:\Python27\Lib\gettext.py", line 566, in gettext + # return dgettext(_current_domain, message) + # TypeError: 'NoneType' object is not callable + self.parser = argparse.ArgumentParser() + self.parser.add_argument("-a", "--address", nargs=1, action='store') + self.parser.add_argument('msg', nargs=argparse.REMAINDER) + + # Synchronization is enabled by default + self.cb.toggle() + + def OnClose(self, form): + print "[sync] form close" + self.smooth_kill() + global SyncForm + del SyncForm + + def Show(self): + return PluginForm.Show(self, "ret-sync", options=PluginForm.FORM_PERSIST) + + +# -------------------------------------------------------------------------- + +def main(): + if not idaapi.get_root_filename(): + print "[sync] please load a file/idb before" + return + + global SyncForm + + try: + SyncForm + except: + SyncForm = SyncForm_t() + SyncForm.Broker = None + + SyncForm.Show() + +class SyncPlugin(idaapi.plugin_t): + flags = 0 + wanted_hotkey = "" + comment = "ret-sync Plugin" + help = "" + wanted_name = "ret-sync Plugin" + + def init(self): + return idaapi.PLUGIN_OK + + def term(self): + pass + + def run(self, arg): + main() diff --git a/plugins/ret_sync_ext_ida/__init__.py b/plugins/ret_sync_ext_ida/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugins/ret_sync_ext_ida/broker.py b/plugins/ret_sync_ext_ida/broker.py new file mode 100644 index 0000000..e5e04eb --- /dev/null +++ b/plugins/ret_sync_ext_ida/broker.py @@ -0,0 +1,296 @@ +# +# Copyright (C) 2016, Alexandre Gazet. +# +# Copyright (C) 2012-2015, Quarkslab. +# +# This file is part of ret-sync. +# +# ret-sync is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Note that broker.py is executed by IDA Pro so it is not possible to see +# any output using print() or similar + +import os +import sys +import time +import re +import shlex +import argparse +import subprocess +import socket +import select +import binascii +import ConfigParser + +try: + import json +except: + print "[-] failed to import json\n%s" % repr(sys.exc_info()) + sys.exit(0) + + +RUN_DISPATCHER_MAX_ATTEMPT = 4 +HOST = "localhost" +PORT = 9100 + +# default value is current script's path +DISPATCHER_PATH = os.path.join(os.path.realpath(os.path.dirname(__file__)), "dispatcher.py") +if not os.path.exists(DISPATCHER_PATH): + print "[-] dispatcher path is not properly set, current value: <%s>" % DISPATCHER_PATH + sys.exit(0) + + +class Client(): + + def __init__(self, s): + self.sock = s + self.buffer = '' + + def feed(self, data): + batch = [] + self.buffer = ''.join([self.buffer, data]) + if self.buffer.endswith("\n"): + batch = [req for req in self.buffer.strip().split('\n') if req != ''] + self.buffer = '' + + return batch + + +class BrokerSrv(): + + def puts(self, msg): + print msg + sys.stdout.flush() + + def announcement(self, msg): + self.puts("[sync]{\"type\":\"broker\",\"subtype\":\"msg\",\"msg\":\"%s\"}\n" % msg) + + def notice_idb(self, msg): + self.puts("[sync]{\"type\":\"broker\",\"subtype\":\"notice\",\"port\":\"%d\"}\n" % msg) + + def notice_dispatcher(self, type, args=None): + if args: + notice = "[notice]{\"type\":\"%s\",%s}\n" % (type, args) + else: + notice = "[notice]{\"type\":\"%s\"}\n" % (type) + + self.notify_socket.sendall(notice) + + def bind(self): + self.srv_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.srv_sock.bind(('localhost', 0)) + self.srv_port = self.srv_sock.getsockname()[1] + + def run_dispatcher(self): + cmdline = "\"%s\" -u \"%s\"" % (os.path.join(PYTHON_PATH, PYTHON_BIN), DISPATCHER_PATH) + tokenizer = shlex.shlex(cmdline) + tokenizer.whitespace_split = True + args = [arg.replace('\"', '') for arg in list(tokenizer)] + + try: + proc = subprocess.Popen(args, shell=False, close_fds=True) + pid = proc.pid + except: + pid = None + self.announcement("failed to run dispatcher") + + time.sleep(0.2) + return pid + + def notify(self): + for attempt in range(RUN_DISPATCHER_MAX_ATTEMPT): + try: + self.notify_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.notify_socket.connect((HOST, PORT)) + break + except: + self.notify_socket.close() + if (attempt != 0): + self.announcement("failed to connect to dispatcher (attempt %d)" % (attempt)) + if (attempt == (RUN_DISPATCHER_MAX_ATTEMPT - 1)): + self.announcement("failed to connect to dispatcher, too much attempts, exiting...") + sys.exit() + + self.announcement("dispatcher not found, trying to run it") + pid = self.run_dispatcher() + if pid: + self.announcement("dispatcher now runs with pid: %d" % (pid)) + + time.sleep(0.1) + self.notice_dispatcher("new_client", "\"port\":%d,\"idb\":\"%s\"" % (self.srv_port, self.name)) + self.announcement('connected to dispatcher') + self.notice_idb(self.srv_port) + + def accept(self): + new_socket, addr = self.srv_sock.accept() + self.clients_list.append(Client(new_socket)) + self.opened_sockets.append(new_socket) + + def close(self, s): + client = [client for client in self.clients_list if (client.sock == s)] + if len(client) == 1: + self.clients_list.remove(client[0]) + s.close() + self.opened_sockets.remove(s) + + def recvall(self, client): + try: + data = client.sock.recv(4096) + if data == '': + raise + except: + self.announcement("dispatcher connection error, quitting") + sys.exit() + + return client.feed(data) + + def req_dispatcher(self, s, hash): + subtype = hash['subtype'] + if (subtype == 'msg'): + msg = hash['msg'] + self.announcement("dispatcher msg: %s" % msg) + + def req_cmd(self, s, hash): + cmd = hash['cmd'] + self.notice_dispatcher("cmd", "\"cmd\":\"%s\"" % cmd) + + def req_kill(self, s, hash): + self.notice_dispatcher("kill") + self.announcement("received kill notice") + for s in ([self.srv_sock] + self.opened_sockets): + s.close() + sys.exit() + + def parse_exec(self, s, req): + if not (req[0:8] == '[notice]'): + self.puts(req) + return + + req = self.normalize(req, 8) + + try: + hash = json.loads(req) + except: + print "[-] broker failed to parse json\n %s" % repr(req) + return + + type = hash['type'] + if not type in self.req_handlers: + print ("[*] broker unknown request: %s" % type) + return + + req_handler = self.req_handlers[type] + req_handler(s, hash) + + def normalize(self, req, taglen): + req = req[taglen:] + req = req.replace("\\", "\\\\") + req = req.replace("\n", "") + return req + + def handle(self, s): + client = [client for client in self.clients_list if (client.sock == s)] + if len(client) == 1: + batch = self.recvall(client[0]) + else: + self.announcement("socket error") + raise Exception("rabbit eating the cable") + + for req in batch: + if req != '': + self.parse_exec(s, req) + + def loop(self): + self.srv_sock.listen(5) + while True: + rlist, wlist, xlist = select.select([self.srv_sock] + self.opened_sockets, [], []) + + if not rlist: + self.announcement("socket error: select") + raise Exception("rabbit eating the cable") + + for s in rlist: + if s is self.srv_sock: + self.accept() + else: + self.handle(s) + + def __init__(self, name): + self.name = name + self.opened_sockets = [] + self.clients_list = [] + self.pat = re.compile('dbg disconnected') + self.req_handlers = { + 'dispatcher': self.req_dispatcher, + 'cmd': self.req_cmd, + 'kill': self.req_kill + } + + +def err_log(msg): + fd = open("%s.err" % __file__, 'w') + fd.write(msg) + fd.close() + +if __name__ == "__main__": + + try: + PYTHON_PATH = os.environ['PYTHON_PATH'] + PYTHON_BIN = os.environ['PYTHON_BIN'] + except Exception as e: + err_log("broker failed to retreive PYTHON_PATH or PYTHON_BIN value.") + sys.exit() + + parser = argparse.ArgumentParser() + parser.add_argument('--idb', nargs=1, action='store') + args = parser.parse_args() + + if not args.idb: + print "[sync] no idb argument" + sys.exit() + + for loc in ['IDB_PATH', 'USERPROFILE', 'HOME']: + if loc in os.environ: + confpath = os.path.join(os.path.realpath(os.environ[loc]), '.sync') + if os.path.exists(confpath): + config = ConfigParser.SafeConfigParser({'port': PORT, 'host': HOST}) + config.read(confpath) + PORT = config.getint("INTERFACE", 'port') + HOST = config.get("INTERFACE", 'host') + break + + server = BrokerSrv(args.idb[0]) + + try: + server.bind() + except Exception as e: + server.announcement("failed to bind") + err_log(repr(e)) + sys.exit() + + try: + server.notify() + except Exception as e: + server.announcement("failed to notify dispatcher") + err_log(repr(e)) + sys.exit() + + try: + server.loop() + except Exception as e: + server.announcement("broker stop") + err_log(repr(e)) diff --git a/plugins/ret_sync_ext_ida/dispatcher.py b/plugins/ret_sync_ext_ida/dispatcher.py new file mode 100644 index 0000000..9f1ab44 --- /dev/null +++ b/plugins/ret_sync_ext_ida/dispatcher.py @@ -0,0 +1,463 @@ +# +# Copyright (C) 2016, Alexandre Gazet. +# +# Copyright (C) 2012-2014, Quarkslab. +# +# This file is part of ret-sync. +# +# ret-sync is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os +import os.path as altpath +import sys +import socket +import select +import base64 +import binascii +import re +import ConfigParser +import traceback + +HOST = 'localhost' +PORT = 9100 + +try: + import json +except: + print "[-] failed to import json\n%s" % repr(sys.exc_info()) + sys.exit(0) + + +class Client(): + + def __init__(self, s_client, s_srv, name): + self.client_sock = s_client + self.srv_sock = s_srv + self.name = name + self.enabled = False + self.buffer = '' + + def close(self): + self.enabled = False + if self.client_sock: + self.client_sock.close() + if self.srv_sock: + self.srv_sock.close() + + def feed(self, data): + batch = [] + self.buffer = ''.join([self.buffer, data]) + if self.buffer.endswith("\n"): + batch = [req for req in self.buffer.strip().split('\n') if req != ''] + self.buffer = '' + + return batch + + +class DispatcherSrv(): + + def __init__(self): + self.idb_clients = [] + self.dbg_client = None + self.srv_socks = [] + self.opened_socks = [] + + self.current_dbg = None + self.current_dialect = 'unknown' + self.current_idb = None + self.current_module = None + + self.sync_mode_auto = True + self.disconn_pat = re.compile('dbg disconnected') + self.req_handlers = { + 'new_client': self.req_new_client, + 'new_dbg': self.req_new_dbg, + 'dbg_quit': self.req_dbg_quit, + 'idb_n': self.req_idb_n, + 'idb_list': self.req_idb_list, + 'module': self.req_module, + 'sync_mode': self.req_sync_mode, + 'cmd': self.req_cmd, + 'bc': self.req_bc, + 'kill': self.req_kill + } + + def bind(self, host, port): + self.dbg_srv_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.dbg_srv_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.dbg_srv_sock.bind((host, port)) + self.srv_socks.append(self.dbg_srv_sock) + + if not (socket.gethostbyname(host) == '127.0.0.1'): + self.localhost_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.localhost_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.localhost_sock.bind(('localhost', port)) + self.srv_socks.append(self.localhost_sock) + + def accept(self, s): + new_socket, addr = s.accept() + self.opened_socks.append(new_socket) + + def listen(self): + for s in self.srv_socks: + s.listen(5) + + def close(self, s): + s.close() + self.opened_socks.remove(s) + + def loop(self): + self.listen() + self.announcement("dispatcher listening") + + while True: + rlist, wlist, xlist = select.select(self.srv_socks + self.opened_socks, [], []) + + if not rlist: + self.announcement("socket error: select") + raise Exception("rabbit eating the cable") + + for s in rlist: + if s in self.srv_socks: + self.accept(s) + else: + self.handle(s) + + def handle(self, s): + client = self.sock_to_client(s) + for req in self.recvall(client): + self.parse_exec(s, req) + + # find client object for its srv socket + def sock_to_client(self, s): + if self.current_dbg and (s == self.current_dbg.srv_sock): + client = self.current_dbg + else: + clist = [client for client in self.idb_clients if (client.srv_sock == s)] + if not clist: + client = Client(None, s, None) + self.idb_clients.append(client) + else: + client = clist[0] + + return client + + # buffered readline like function + def recvall(self, client): + try: + data = client.srv_sock.recv(4096) + if data == '': + raise + except: + if client == self.current_dbg: + self.broadcast("debugger closed the connection") + self.dbg_quit() + else: + self.client_quit(client.srv_sock) + self.broadcast("a client quit, nb client(s) left: %d" % len(self.idb_clients)) + + return [] + + return client.feed(data) + + # parse and execute requests from clients (idbs or dbg) + def parse_exec(self, s, req): + if not (req[0:8] == '[notice]'): + # this is a normal [sync] request from debugger, forward it + self.forward(req) + # receive 'dbg disconnected', socket can be closed + if re.search(self.disconn_pat, req): + self.close(s) + return + + req = self.normalize(req, 8) + try: + hash = json.loads(req) + except: + print "[-] dispatcher failed to parse json\n %s\n" % req + return + + type = hash['type'] + if not type in self.req_handlers: + print ("[*] dispatcher unknown request: %s" % type) + return + + req_handler = self.req_handlers[type] + req_handler(s, hash) + + def normalize(self, req, taglen): + req = req[taglen:] + req = req.replace("\\", "\\\\") + req = req.replace("\n", "") + return req + + def puts(self, msg, s): + s.sendall(msg) + + # dispatcher announcements are forwarded to the idb + def announcement(self, msg, s=None): + if not s: + if not self.current_idb: + return + s = self.current_idb.client_sock + + try: + s.sendall("[notice]{\"type\":\"dispatcher\",\"subtype\":\"msg\",\"msg\":\"%s\"}\n" % msg) + except: + return + + # send message to all connected idb clients + def broadcast(self, msg): + for idbc in self.idb_clients: + self.announcement(msg, idbc.client_sock) + + # send dbg message to currently active idb client + def forward(self, msg, s=None): + if not s: + if not self.current_idb: + return + s = self.current_idb.client_sock + + if s: + s.sendall(msg + "\n") + + # send dbg message to all idb clients + def forward_all(self, msg, s=None): + for idbc in self.idb_clients: + self.forward(msg, idbc.client_sock) + + # disable current idb and enable new idb matched from current module name + def switch_idb(self, new_idb): + msg = "[sync]{\"type\":\"broker\",\"subtype\":\"%s\"}\n" + if (not self.current_idb == new_idb) & (self.current_idb.enabled): + self.current_idb.client_sock.sendall(msg % "disable_idb") + self.current_idb.enabled = False + + if new_idb: + new_idb.client_sock.sendall(msg % "enable_idb") + self.current_idb = new_idb + new_idb.enabled = True + + # a new idb client connects to the dispatcher via its broker + def req_new_client(self, srv_sock, hash): + port, name = hash['port'], hash['idb'] + try: + client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + client_sock.connect(('localhost', port)) + self.opened_socks.append(client_sock) + except: + self.opened_socks.remove(srv_sock) + srv_sock.close() + return + + # check if an idb client is already registered with the same name + conflicting = [client for client in self.idb_clients if (client.name == name)] + + # promote to idb client + new_client = self.sock_to_client(srv_sock) + new_client.client_sock = client_sock + new_client.name = name + self.broadcast("add new client (listening on port %d), nb client(s): %d" % (port, len(self.idb_clients))) + + if conflicting: + self.broadcast("conflicting name: %s !" % new_client.name) + + if not self.current_idb: + self.current_idb = new_client + + # if new client match current module name, then enable it + if self.current_module == name: + self.switch_idb(new_client) + + # inform new client about debugger's dialect + self.dbg_dialect(new_client) + + # clean state when a client is quiting + def client_quit(self, s): + self.opened_socks.remove(s) + # remove exiting client from the list of active clients + for idbc in [idbc for idbc in self.idb_clients if (idbc.srv_sock == s)]: + self.idb_clients.remove(idbc) + self.opened_socks.remove(idbc.client_sock) + idbc.close() + + # no more clients, let's kill ourself + if not self.idb_clients: + for s in self.srv_socks: + s.close() + sys.exit() + + # determine if debugger is Windows specific + def is_windows_dbg(self, dialect): + return (dialect in ['windbg', 'x64_dbg', 'ollydbg2']) + + # a new debugger client connects to the dispatcher + def req_new_dbg(self, s, hash): + msg = hash['msg'] + if self.current_dbg: + self.dbg_quit() + + # promote to dbg client + self.current_dbg = self.sock_to_client(s) + self.current_dbg.client_sock = s + self.idb_clients.remove(self.current_dbg) + + self.broadcast("new debugger client: %s" % msg) + + # store dbb's dialect + if 'dialect' in hash: + self.current_dialect = hash['dialect'] + + # case when IDA is on a linux/bsd host and connected to remote windows + # use ntpath instead of posixpath + if sys.platform.startswith('linux') or sys.platform == 'darwin': + if self.is_windows_dbg(self.current_dialect): + global altpath + import ntpath as altpath + + self.dbg_dialect() + + # inform client about debugger's dialect + def dbg_dialect(self, client=None): + msg = "[sync]{\"type\":\"dialect\",\"dialect\":\"%s\"}\n" % self.current_dialect + if client: + client.client_sock.sendall(msg) + else: + for idbc in self.idb_clients: + idbc.client_sock.sendall(msg) + + # debugger client disconnect from the dispatcher + def req_dbg_quit(self, s, hash): + msg = hash['msg'] + self.broadcast("debugger quit: %s" % msg) + self.dbg_quit() + + # clean state when debugger is quiting + def dbg_quit(self): + self.opened_socks.remove(self.current_dbg.srv_sock) + self.current_dbg.close() + self.current_dbg = None + self.current_module = None + self.switch_idb(None) + self.current_dialect = 'unknown' + + # handle kill notice from a client, exit properly if no more client + def req_kill(self, s, hash): + self.client_quit(s) + self.broadcast("received a kill notice from client, %d client(s) left" % len(self.idb_clients)) + + # send list of currently connected idb clients + def req_idb_list(self, s, hash): + clist = "> currently connected idb(s):\n" + if not self.idb_clients: + clist += " no idb client yet\n" + else: + for i in range(len(self.idb_clients)): + clist += (" [%d] %s\n" % (i, self.idb_clients[i].name)) + + s.sendall(clist) + + # manually set current active idb to idb n from idb list + def req_idb_n(self, s, hash): + idb = hash['idb'] + try: + idbn = int(idb) + except: + s.sendall("> n should be a decimal value") + return + + try: + idbc = self.idb_clients[idbn] + except: + s.sendall("> %d is invalid (see idblist)" % idbn) + return + + self.switch_idb(idbc) + s.sendall("> current idb set to %d" % idbn) + + # dbg notice that its current module has changed + def req_module(self, s, hash): + modpath = hash['path'] + self.current_module = modname = altpath.basename(modpath) + matching = [idbc for idbc in self.idb_clients if (idbc.name.lower() == modname.lower())] + + if not self.sync_mode_auto: + self.broadcast("sync_mode_auto off") + return + + if len(matching) == 1: + # matched is set as active + self.switch_idb(matching[0]) + else: + if not len(matching): + msg = "mod request has no match for %s" + else: + msg = "ambiguous mod request, too many matches for %s" + + self.broadcast(msg % modname) + # no match current idb (if existing) is disabled + if self.current_idb.enabled: + self.switch_idb(None) + + # sync mode tells if idb switch is automatic or manual + def req_sync_mode(self, s, hash): + mode = hash['auto'] + self.broadcast("sync mode auto set to %s" % mode) + self.sync_mode_auto = (mode == "on") + + # bc request should be forwarded to all idbs + def req_bc(self, s, hash): + msg = "[sync]%s" % json.dumps(hash) + self.forward_all(msg) + + def req_cmd(self, s, hash): + cmd = hash['cmd'] + self.current_dbg.client_sock.sendall("%s\n" % cmd) + + +def err_log(msg): + fd = open("%s.err" % __file__, 'w') + fd.write(msg) + fd.close() + +if __name__ == "__main__": + + server = DispatcherSrv() + + for loc in ['IDB_PATH', 'USERPROFILE', 'HOME']: + if loc in os.environ: + confpath = os.path.join(os.path.realpath(os.environ[loc]), '.sync') + if os.path.exists(confpath): + config = ConfigParser.SafeConfigParser({'host': HOST, 'port': PORT}) + config.read(confpath) + HOST = config.get("INTERFACE", 'host') + PORT = config.getint("INTERFACE", 'port') + server.announcement("configuration file loaded") + break + + try: + server.bind(HOST, PORT) + except Exception as e: + err_log("dispatcher failed to bind on %s:%s\n-> %s" % (HOST, PORT, repr(e))) + sys.exit() + + try: + server.loop() + except Exception as e: + err_log("dispatcher failed\n-> %s" % repr(e)) + server.announcement("dispatcher stop") diff --git a/idbdumpowner.py b/scripts/idbdumpowner.py similarity index 100% rename from idbdumpowner.py rename to scripts/idbdumpowner.py diff --git a/idbupdateowner.py b/scripts/idbupdateowner.py similarity index 100% rename from idbupdateowner.py rename to scripts/idbupdateowner.py diff --git a/skin/ida-default/manifest.xml b/skin/ida-default/manifest.xml new file mode 100644 index 0000000..aa81ab9 --- /dev/null +++ b/skin/ida-default/manifest.xml @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/skin/ida-default/stylesheet.qss b/skin/ida-default/stylesheet.qss new file mode 100644 index 0000000..581d521 --- /dev/null +++ b/skin/ida-default/stylesheet.qss @@ -0,0 +1,20 @@ +CustomIDAMemo { + font-family: ""; + font-size: ; + font-style: ; + font-weight: ; +} + +IDAView { + font-family: ""; + font-size: ; + font-style: ; + font-weight: ; +} + +hexview_t { + font-family: ""; + font-size: ; + font-style: ; + font-weight: ; +} \ No newline at end of file diff --git a/skin/idaskins-dark/icons/expand.png b/skin/idaskins-dark/icons/expand.png new file mode 100644 index 0000000..848dbe1 Binary files /dev/null and b/skin/idaskins-dark/icons/expand.png differ diff --git a/skin/idaskins-dark/icons/spacer.png b/skin/idaskins-dark/icons/spacer.png new file mode 100644 index 0000000..ac74398 Binary files /dev/null and b/skin/idaskins-dark/icons/spacer.png differ diff --git a/skin/idaskins-dark/manifest.xml b/skin/idaskins-dark/manifest.xml new file mode 100644 index 0000000..aa1ea5b --- /dev/null +++ b/skin/idaskins-dark/manifest.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/skin/idaskins-dark/preview.png b/skin/idaskins-dark/preview.png new file mode 100644 index 0000000..5ac6db8 Binary files /dev/null and b/skin/idaskins-dark/preview.png differ diff --git a/skin/idaskins-dark/stylesheet.qss b/skin/idaskins-dark/stylesheet.qss new file mode 100644 index 0000000..c32a7e6 --- /dev/null +++ b/skin/idaskins-dark/stylesheet.qss @@ -0,0 +1,225 @@ +QWidget { + background-color: #363636; + color: #ddd; +} + +QCheckBox { + background-color: rgba(0, 0, 0, 0); +} + +QTextEdit { + background-color: #2d2d2d; + border: 1px solid #363636; + border-radius: 2px; +} + +QMenuBar, QMenuBar::item { + background-color: #444444; + color: #ddd; +} + +QMenu::item:selected { + background-color: #2A2A2A; +} + +QLineEdit { + border: 1px solid #474747; + min-height: 20px; + border-radius: 2px; +} + +QLineEdit:hover, QLineEdit:focus { + border: 1px solid #00aaaa; +} + +QTabBar::tab { + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0 #555555, stop: 1 #444444); +} + +QTabBar::tab:selected { + background-color: #777777; +} + +QTableView { + border: 1px solid #474747; + background-color: #2d2d2d; +} + +QHeaderView::section { + background-color: #444; + border: none; + border-left: 1px solid #666; + border-right: 1px solid #333; + padding-top: 3px; + padding-left: 4px; + min-height: 20px; +} + +QTableCornerButton::section { + background: #222; + border: 2px outset #222; + } + +IDAView, hexview_t, CustomIDAMemo { + border: none; +} + +CustomIDAMemo, EditContainer { + font-family: ""; + font-size: ; + font-style: ; + font-weight: ; +} + +IDAView { + font-family: ""; + font-size: ; + font-style: ; + font-weight: ; +} + +hexview_t { + font-family: ""; + font-size: ; + font-style: ; + font-weight: ; +} + +/* TODO: DEBUG_REGISTERS, OUTPUT_WINDOW */ + +QScrollBar { + background-color: #363636; + width: 20px; + height: 20px; + margin: 0 0 0 0; +} + +QScrollBar::sub-line, QScrollBar::add-line { + width: 0; + height: 0; +} + +QScrollBar::add-page, QScrollBar::sub-page { + background: none; +} + +QScrollBar::handle:vertical { + min-height: 20px; +} + +QScrollBar::handle:horizontal { + min-width: 20px; +} + +QScrollBar::handle { + background-color: #585858; + margin: 3px; + border-radius: 7px; +} + +QToolBar { + border: none; +} + +QPushButton { + border: 1px solid #077; + text-align: center; + min-height: 20px; + min-width: 50px; + padding: 0 6px 0 6px; + border-radius: 2px; +} + +QPushButton:hover, QPushButton:default { + border: 1px solid #0aa; +} + +QPushButton:pressed { + border: 1px solid #0ee; +} + +QComboBox { + border: 1px solid #474747; + border-radius: 2px; +} + +QComboBox > QLineEdit, QComboBox > QLineEdit:hover, QComboBox > QLineEdit:focus { + border: none; + min-height: default; +} + +QComboBox:hover, QComboBox:focus { + border: 1px solid #00aaaa; +} + +QComboBox::drop-down { + subcontrol-origin: padding; + subcontrol-position: top right; + width: 15px; + + border-left-width: 1px; + border-left-color: #666; + border-left-style: solid; +} + +QComboBox::down-arrow { + image: url(/icons/expand.png); +} + +/* Close, maximize and undock button for dock widgets */ +IDADockWidget > QWidget > QAbstractButton { + background-color: #666; + border-radius: 3px; +} + +QRadioButton, QLabel, QCheckBox { + background: transparent; +} + +TNavBand > QPushButton, RegJumpButton { + min-height: 0; + min-width: 0; + padding: 0 0 0 0; + border: none; +} + +EditContainer, ChooserContainer, QGroupBox, QListView, QTreeView { + border: 1px solid #606060; + border-radius: 2px; +} + +QGroupBox { + margin-top: 5px; +} + +QGroupBox::title { + subcontrol-origin: margin; + subcontrol-position: top center; +} + +/* Remove border from IDC/Python switch button */ +CLIWidget > QGroupBox > QPushButton, +CLIWidget > QGroupBox > QPushButton:hover, +CLIWidget > QGroupBox > QPushButton:focus { + border: none; +} + +CLIWidget > QGroupBox { + margin-top: 0; +} + +QTreeView::item:selected, QListView::item:selected, QTableView::item:selected { + background-color: #474747; + color: #ddd; +} + +QToolTip, QTipLabel { + border: 1px solid #AA5500; + border-radius: 3px; + background: #111111; + color: #ddd; + margin: 0; + padding: 0; +} +