Skip to content
Snippets Groups Projects
SMPStaticAnalyzer.cpp 140 KiB
Newer Older
OptCategory[NN_pmaxuw] = 1;               // Maximum of Packed Word Integers
OptCategory[NN_pminsb] = 1;               // Minimum of Packed Signed Byte Integers
OptCategory[NN_pminsd] = 1;               // Minimum of Packed Signed Dword Integers
OptCategory[NN_pminud] = 1;               // Minimum of Packed Unsigned Dword Integers
OptCategory[NN_pminuw] = 1;               // Minimum of Packed Word Integers
OptCategory[NN_pmovsxbw] = 1;             // Packed Move with Sign Extend
OptCategory[NN_pmovsxbd] = 1;             // Packed Move with Sign Extend
OptCategory[NN_pmovsxbq] = 1;             // Packed Move with Sign Extend
OptCategory[NN_pmovsxwd] = 1;             // Packed Move with Sign Extend
OptCategory[NN_pmovsxwq] = 1;             // Packed Move with Sign Extend
OptCategory[NN_pmovsxdq] = 1;             // Packed Move with Sign Extend
OptCategory[NN_pmovzxbw] = 1;             // Packed Move with Zero Extend
OptCategory[NN_pmovzxbd] = 1;             // Packed Move with Zero Extend
OptCategory[NN_pmovzxbq] = 1;             // Packed Move with Zero Extend
OptCategory[NN_pmovzxwd] = 1;             // Packed Move with Zero Extend
OptCategory[NN_pmovzxwq] = 1;             // Packed Move with Zero Extend
OptCategory[NN_pmovzxdq] = 1;             // Packed Move with Zero Extend
OptCategory[NN_pmuldq] = 1;               // Multiply Packed Signed Dword Integers
OptCategory[NN_pmulld] = 1;               // Multiply Packed Signed Dword Integers and Store Low Result
OptCategory[NN_ptest] = 1;                // Logical Compare
OptCategory[NN_roundpd] = 1;              // Round Packed Double Precision Floating-Point Values
OptCategory[NN_roundps] = 1;              // Round Packed Single Precision Floating-Point Values
OptCategory[NN_roundsd] = 1;              // Round Scalar Double Precision Floating-Point Values
OptCategory[NN_roundss] = 1;              // Round Scalar Single Precision Floating-Point Values

// SSSE4.2 instructions
OptCategory[NN_crc32] = 2;                // Accumulate CRC32 Value
OptCategory[NN_pcmpestri] = 2;            // Packed Compare Explicit Length Strings, Return Index
OptCategory[NN_pcmpestrm] = 2;            // Packed Compare Explicit Length Strings, Return Mask
OptCategory[NN_pcmpistri] = 2;            // Packed Compare Implicit Length Strings, Return Index
OptCategory[NN_pcmpistrm] = 2;            // Packed Compare Implicit Length Strings, Return Mask
OptCategory[NN_pcmpgtq] = 1;              // Compare Packed Data for Greater Than
OptCategory[NN_popcnt] = 2;               // Return the Count of Number of Bits Set to 1

// AMD SSE4a instructions

OptCategory[NN_extrq] = 1;                // Extract Field From Register
OptCategory[NN_insertq] = 1;              // Insert Field
OptCategory[NN_movntsd] = 0;              // Move Non-Temporal Scalar Double-Precision Floating-Point
OptCategory[NN_movntss] = 0;              // Move Non-Temporal Scalar Single-Precision Floating-Point
OptCategory[NN_lzcnt] = 2;                // Leading Zero Count

// xsave/xrstor instructions

OptCategory[NN_xgetbv] = 8;               // Get Value of Extended Control Register
OptCategory[NN_xrstor] = 0;               // Restore Processor Extended States
OptCategory[NN_xsave] = 1;                // Save Processor Extended States
OptCategory[NN_xsetbv] = 1;               // Set Value of Extended Control Register

// Intel Safer Mode Extensions (SMX)

OptCategory[NN_getsec] = 1;               // Safer Mode Extensions (SMX) Instruction

// AMD-V Virtualization ISA Extension

OptCategory[NN_clgi] = 0;                 // Clear Global Interrupt Flag
OptCategory[NN_invlpga] = 1;              // Invalidate TLB Entry in a Specified ASID
OptCategory[NN_skinit] = 1;               // Secure Init and Jump with Attestation
OptCategory[NN_stgi] = 0;                 // Set Global Interrupt Flag
OptCategory[NN_vmexit] = 1;               // Stop Executing Guest, Begin Executing Host
OptCategory[NN_vmload] = 0;               // Load State from VMCB
OptCategory[NN_vmmcall] = 1;              // Call VMM
OptCategory[NN_vmrun] = 1;                // Run Virtual Machine
OptCategory[NN_vmsave] = 0;               // Save State to VMCB

// VMX+ instructions

OptCategory[NN_invept] = 1;               // Invalidate Translations Derived from EPT
OptCategory[NN_invvpid] = 1;              // Invalidate Translations Based on VPID

// Intel Atom instructions

OptCategory[NN_movbe] = 3;                // Move Data After Swapping Bytes

// Intel AES instructions

OptCategory[NN_aesenc] = 1;                // Perform One Round of an AES Encryption Flow
OptCategory[NN_aesenclast] = 1;            // Perform the Last Round of an AES Encryption Flow
OptCategory[NN_aesdec] = 1;                // Perform One Round of an AES Decryption Flow
OptCategory[NN_aesdeclast] = 1;            // Perform the Last Round of an AES Decryption Flow
OptCategory[NN_aesimc] = 1;                // Perform the AES InvMixColumn Transformation
OptCategory[NN_aeskeygenassist] = 1;       // AES Round Key Generation Assist

// Carryless multiplication

OptCategory[NN_pclmulqdq] = 1;            // Carry-Less Multiplication Quadword

#endif // 599 < IDA_SDK_VERSION

OptCategory[NN_last] = 1;

  return;

} // end InitOptCategory()

// Initialize the StackAlteration[] array to define how opcodes
//   adjust the stack pointer.
void InitStackAlteration(void) {
	// Default category is 0; most instructions do not alter the stack pointer.
	(void) memset(StackAlteration, 0, sizeof(StackAlteration));

	// Many arithmetic instructions could alter the stack pointer. We will have to
	//  examine each instruction that performs addition, subtraction, logical AND, etc.,
	//  to determine if the stack pointer was the DEF operand. We cannot use a purely
	//  table driven approach to compute stack pointer alteration. The table is used for
	//  the deterministic cases, e.g. push, pop, call, return. Because of variability on
	//  a few of these instructions, a value of 1 in the table below is a trigger to investigate RTLs
	//  that might or might not alter the stack pointer, e.g. add, subtract, etc., or that might
	//  have operand-dependent effects on the stack pointer.

StackAlteration[NN_add] = 1;                  // Addition; check operands for stack pointer
StackAlteration[NN_adc] = 1;                  // Addition; check operands for stack pointer ; RARE for stack pointer
StackAlteration[NN_and] = 1;                  // Logical AND; check operands for stack pointer
StackAlteration[NN_call] = -4;                // Call Procedure; -4, but return cancels it to zero
StackAlteration[NN_callfi] = -8;              // Indirect Call Far Procedure; -8, but far return cancels it to zero
StackAlteration[NN_callni] = -4;              // Indirect Call Near Procedure; -4, but return cancels it to zero
StackAlteration[NN_enterw] = 1;              // Make Stack Frame for Procedure Parameters  **
StackAlteration[NN_enter] = 1;               // Make Stack Frame for Procedure Parameters  **
StackAlteration[NN_enterd] = 1;              // Make Stack Frame for Procedure Parameters  **
StackAlteration[NN_enterq] = 1;              // Make Stack Frame for Procedure Parameters  **
StackAlteration[NN_int] = 0;                 // Call to Interrupt Procedure
StackAlteration[NN_into] = 0;                // Call to Interrupt Procedure if Overflow Flag = 1
StackAlteration[NN_int3] = 0;                // Trap to Debugger
StackAlteration[NN_iretw] = 6;               // Interrupt Return
StackAlteration[NN_iret] = 12;                // Interrupt Return
StackAlteration[NN_iretd] = 12;               // Interrupt Return (use32)
StackAlteration[NN_iretq] = 40;               // Interrupt Return (use64)  ??? check this when we port to 64-bit
StackAlteration[NN_lea] = 1;                 // Load Effective Address (can be used for basic arithmetic assignments)
StackAlteration[NN_leavew] = 1;              // High Level Procedure Exit        **
StackAlteration[NN_leave] = 1;               // High Level Procedure Exit        **
StackAlteration[NN_leaved] = 1;              // High Level Procedure Exit        **
StackAlteration[NN_leaveq] = 1;              // High Level Procedure Exit        **
StackAlteration[NN_mov] = 1;                 // Move Data ; could be esp := ebp (deallocate stack frame) or esp := ebx (unknown)
StackAlteration[NN_pop] = 4;                 // Pop a word from the Stack
StackAlteration[NN_popaw] = 14;               // Pop all General Registers
StackAlteration[NN_popa] = 28;                // Pop all General Registers
StackAlteration[NN_popad] = 28;               // Pop all General Registers (use32)
StackAlteration[NN_popaq] = 56;               // Pop all General Registers (use64)
StackAlteration[NN_popfw] = 2;               // Pop Stack into Flags Register         **
StackAlteration[NN_popf] = 4;                // Pop Stack into Flags Register         **
StackAlteration[NN_popfd] = 4;               // Pop Stack into Eflags Register        **
StackAlteration[NN_popfq] = 8;               // Pop Stack into Rflags Register        **
StackAlteration[NN_push] = -4;                // Push Operand onto the Stack
StackAlteration[NN_pushaw] = -14;              // Push all General Registers
StackAlteration[NN_pusha] = -28;               // Push all General Registers
StackAlteration[NN_pushad] = -28;              // Push all General Registers (use32)
StackAlteration[NN_pushaq] = -56;              // Push all General Registers (use64)
StackAlteration[NN_pushfw] = -2;              // Push Flags Register onto the Stack
StackAlteration[NN_pushf] = -4;               // Push Flags Register onto the Stack
StackAlteration[NN_pushfd] = -4;              // Push Flags Register onto the Stack (use32)
StackAlteration[NN_pushfq] = -8;              // Push Flags Register onto the Stack (use64)
StackAlteration[NN_retn] = 1;                // Return Near from Procedure (usually 4 bytes)
StackAlteration[NN_retf] = 1;                // Return Far from Procedure (usually 8 bytes)
StackAlteration[NN_sub] = 1;                  // Subtraction; check operands for stack pointer
StackAlteration[NN_sbb] = 1;                  // Subtraction; check operands for stack pointer ; RARE for stack pointer

//
//      486 instructions
//


//
//      Pentium instructions
//


//
//      Pentium Pro instructions
//


//
//      FPP instructions
//


//
//      80387 instructions
//

//
//      Instructions added 28.02.96
//

StackAlteration[NN_loadall] = 0;             // Load the entire CPU state from ES:EDI ?? Cannot find in Intel manuals

//
//      MMX instructions
//


//
//      Undocumented Deschutes processor instructions
//

//      Pentium II instructions

StackAlteration[NN_sysenter] = 0;            // Fast Transition to System Call Entry Point
StackAlteration[NN_sysexit] = 0;             // Fast Transition from System Call Entry Point

//      3DNow! instructions


//      Pentium III instructions


// Pentium III Pseudo instructions

// AMD K7 instructions

// Revisit AMD if we port to it.

// Undocumented FP instructions (thanks to norbert.juffa@adm.com)

// Pentium 4 instructions


// AMD syscall/sysret instructions  NOTE: not AMD, found in Intel manual

StackAlteration[NN_syscall] = 0;             // Low latency system call
StackAlteration[NN_sysret] = 0;              // Return from system call

// AMD64 instructions    NOTE: not AMD, found in Intel manual

// New Pentium instructions (SSE3)


// Missing AMD64 instructions  NOTE: also found in Intel manual

// SSE3 instructions

// SSSE3 instructions


// VMX instructions

#if 599 < IDA_SDK_VERSION

// Added with x86-64

// Geode LX 3DNow! extensions

// SSE2 pseudoinstructions


// SSSE4.1 instructions


// SSSE4.2 instructions

// AMD SSE4a instructions

// xsave/xrstor instructions

// Intel Safer Mode Extensions (SMX)

// AMD-V Virtualization ISA Extension

// VMX+ instructions

// Intel Atom instructions

// Intel AES instructions

// Carryless multiplication

#endif // 599 < IDA_SDK_VERSION

StackAlteration[NN_last] = 0;

  return;

} // end InitStackAlteration()