常见宏定义

Sunday, October 30, 2022
本文共1341字
3分钟阅读时长
pwn , ida ,

All serious daring starts from within. — Harriet Beecher Stowe

本文转载自IDA逆向常用宏定义_丑大狗的博客-CSDN博客

/*

This file [contains](https://so.csdn.net/so/search?q=contains&spm=1001.2101.3001.7020) definitions used by the Hex-Rays decompiler output.  
It has type definitions and convenience macros to make the  
output more readable.

Copyright © 2007-2011 Hex-Rays

*/

#if defined(**GNUC**)  
typedef long long ll;  
typedef unsigned long long ull;  
#define __int64 long long  
#define __int32 int  
#define __int16 short  
#define __int8 char  
#define MAKELL(num) num ## LL  
#define FMT_64 “ll”  
#elif defined(_MSC_VER)  
typedef __int64 ll;  
typedef unsigned __int64 ull;  
#define MAKELL(num) num ## i64  
#define FMT_64 “I64”  
#elif defined (**BORLANDC**)  
typedef __int64 ll;  
typedef unsigned __int64 ull;  
#define MAKELL(num) num ## i64  
#define FMT_64 “L”  
#else  
#error “unknown compiler”  
#endif  
typedef unsigned int uint;  
typedef unsigned char uchar;  
typedef unsigned short ushort;  
typedef unsigned long ulong;

typedef char int8;  
typedef signed char sint8;  
typedef unsigned char uint8;  
typedef short int16;  
typedef signed short sint16;  
typedef unsigned short uint16;  
typedef int int32;  
typedef signed int sint32;  
typedef unsigned int uint32;  
typedef ll int64;  
typedef ll sint64;  
typedef ull uint64;

// Partially defined types:  
#define _BYTE uint8  
#define _WORD uint16  
#define _DWORD uint32  
#define _QWORD uint64  
#if !defined(_MSC_VER)  
#define _LONGLONG __int128  
#endif

#ifndef _WINDOWS_  
typedef int8 BYTE;  
typedef int16 WORD;  
typedef int32 DWORD;  
typedef int32 LONG;  
#endif  
typedef int64 QWORD;  
#ifndef __cplusplus  
typedef int bool; // we want to use bool in our C programs  
#endif

// Some convenience macros to make partial accesses nicer  
// first unsigned macros:  
#define LOBYTE(x) (_((_BYTE_)&(x))) // low byte  
#define LOWORD(x) (_((_WORD_)&(x))) // low word  
#define LODWORD(x) (_((_DWORD_)&(x))) // low dword  
#define HIBYTE(x) (_((_BYTE_)&(x)+1))  
#define HIWORD(x) (_((_WORD_)&(x)+1))  
#define HIDWORD(x) (_((_DWORD_)&(x)+1))  
#define BYTEn(x, n) (_((_BYTE_)&(x)+n))  
#define WORDn(x, n) (_((_WORD_)&(x)+n))  
#define BYTE1(x) BYTEn(x, 1) // byte 1 (counting from 0)  
#define BYTE2(x) BYTEn(x, 2)  
#define BYTE3(x) BYTEn(x, 3)  
#define BYTE4(x) BYTEn(x, 4)  
#define BYTE5(x) BYTEn(x, 5)  
#define BYTE6(x) BYTEn(x, 6)  
#define BYTE7(x) BYTEn(x, 7)  
#define BYTE8(x) BYTEn(x, 8)  
#define BYTE9(x) BYTEn(x, 9)  
#define BYTE10(x) BYTEn(x, 10)  
#define BYTE11(x) BYTEn(x, 11)  
#define BYTE12(x) BYTEn(x, 12)  
#define BYTE13(x) BYTEn(x, 13)  
#define BYTE14(x) BYTEn(x, 14)  
#define BYTE15(x) BYTEn(x, 15)  
#define WORD1(x) WORDn(x, 1)  
#define WORD2(x) WORDn(x, 2) // third word of the object, unsigned  
#define WORD3(x) WORDn(x, 3)  
#define WORD4(x) WORDn(x, 4)  
#define WORD5(x) WORDn(x, 5)  
#define WORD6(x) WORDn(x, 6)  
#define WORD7(x) WORDn(x, 7)

// now signed macros (the same but with sign extension) 
#define SLOBYTE(x) (_((int8_)&(x)))  
#define SLOWORD(x) (_((int16_)&(x)))  
#define SLODWORD(x) (_((int32_)&(x)))  
#define SHIBYTE(x) (_((int8_)&(x)+1))  
#define SHIWORD(x) (_((int16_)&(x)+1))  
#define SHIDWORD(x) (_((int32_)&(x)+1))  
#define SBYTEn(x, n) (_((int8_)&(x)+n))  
#define SWORDn(x, n) (_((int16_)&(x)+n))  
#define SBYTE1(x) SBYTEn(x, 1)  
#define SBYTE2(x) SBYTEn(x, 2)  
#define SBYTE3(x) SBYTEn(x, 3)  
#define SBYTE4(x) SBYTEn(x, 4)  
#define SBYTE5(x) SBYTEn(x, 5)  
#define SBYTE6(x) SBYTEn(x, 6)  
#define SBYTE7(x) SBYTEn(x, 7)  
#define SBYTE8(x) SBYTEn(x, 8)  
#define SBYTE9(x) SBYTEn(x, 9)  
#define SBYTE10(x) SBYTEn(x, 10)  
#define SBYTE11(x) SBYTEn(x, 11)  
#define SBYTE12(x) SBYTEn(x, 12)  
#define SBYTE13(x) SBYTEn(x, 13)  
#define SBYTE14(x) SBYTEn(x, 14)  
#define SBYTE15(x) SBYTEn(x, 15)  
#define SWORD1(x) SWORDn(x, 1)  
#define SWORD2(x) SWORDn(x, 2)  
#define SWORD3(x) SWORDn(x, 3)  
#define SWORD4(x) SWORDn(x, 4)  
#define SWORD5(x) SWORDn(x, 5)  
#define SWORD6(x) SWORDn(x, 6)  
#define SWORD7(x) SWORDn(x, 7)

// Helper functions to represent some assembly instructions.

#ifdef __cplusplus

// Fill memory block with an integer value  
inline void memset32(void *ptr, uint32 value, int count)  
{  
uint32 *p = (uint32 *)ptr;  
for ( int i=0; i < count; i++ )  
*p++ = value;  
}

// Generate a reference to pair of operands  
template int16 **PAIR**( int8 high, T low) { return ((( int16)high) << sizeof(high)*8) | uint8(low); }  
template int32 **PAIR**( int16 high, T low) { return ((( int32)high) << sizeof(high)*8) | uint16(low); }  
template int64 **PAIR**( int32 high, T low) { return ((( int64)high) << sizeof(high)*8) | uint32(low); }  
template uint16 **PAIR**(uint8 high, T low) { return (((uint16)high) << sizeof(high)*8) | uint8(low); }  
template uint32 **PAIR**(uint16 high, T low) { return (((uint32)high) << sizeof(high)*8) | uint16(low); }  
template uint64 **PAIR**(uint32 high, T low) { return (((uint64)high) << sizeof(high)*8) | uint32(low); }

// rotate left  
template T **ROL**(T value, uint count)  
{  
const uint nbits = sizeof(T) * 8;  
count %= nbits;

T high = value >> (nbits - count);  
value <<= count;  
value |= high;  
return value;  
}

// rotate right  
template T **ROR**(T value, uint count)  
{  
const uint nbits = sizeof(T) * 8;  
count %= nbits;

T low = value << (nbits - count);  
value >>= count;  
value |= low;  
return value;  
}

// carry flag of left shift  
template int8 **MKCSHL**(T value, uint count)  
{  
const uint nbits = sizeof(T) * 8;  
count %= nbits;

return (value >> (nbits-count)) & 1;  
}

// carry flag of right shift  
template int8 **MKCSHR**(T value, uint count)  
{  
return (value >> (count-1)) & 1;  
}

// sign flag  
template int8 **SETS**(T x)  
{  
if ( sizeof(T) == 1 )  
return int8(x) < 0;  
if ( sizeof(T) == 2 )  
return int16(x) < 0;  
if ( sizeof(T) == 4 )  
return int32(x) < 0;  
return int64(x) < 0;  
}

// overflow flag of subtraction (x-y)  
template<class T, class U> int8 **OFSUB**(T x, U y)  
{  
if ( sizeof(T) < sizeof(U) )  
{  
U x2 = x;  
int8 sx = **SETS**(x2);  
return (sx ^ **SETS**(y)) & (sx ^ **SETS**(x2-y));  
}  
else  
{  
T y2 = y;  
int8 sx = **SETS**(x);  
return (sx ^ **SETS**(y2)) & (sx ^ **SETS**(x-y2));  
}  
}

// overflow flag of addition (x+y)  
template<class T, class U> int8 **OFADD**(T x, U y)  
{  
if ( sizeof(T) < sizeof(U) )  
{  
U x2 = x;  
int8 sx = **SETS**(x2);  
return ((1 ^ sx) ^ **SETS**(y)) & (sx ^ **SETS**(x2+y));  
}  
else  
{  
T y2 = y;  
int8 sx = **SETS**(x);  
return ((1 ^ sx) ^ **SETS**(y2)) & (sx ^ **SETS**(x+y2));  
}  
}

// carry flag of subtraction (x-y)  
template<class T, class U> int8 **CFSUB**(T x, U y)  
{  
int size = sizeof(T) > sizeof(U) ? sizeof(T) : sizeof(U);  
if ( size == 1 )  
return uint8(x) < uint8(y);  
if ( size == 2 )  
return uint16(x) < uint16(y);  
if ( size == 4 )  
return uint32(x) < uint32(y);  
return uint64(x) < uint64(y);  
}

// carry flag of addition (x+y)  
template<class T, class U> int8 **CFADD**(T x, U y)  
{  
int size = sizeof(T) > sizeof(U) ? sizeof(T) : sizeof(U);  
if ( size == 1 )  
return uint8(x) > uint8(x+y);  
if ( size == 2 )  
return uint16(x) > uint16(x+y);  
if ( size == 4 )  
return uint32(x) > uint32(x+y);  
return uint64(x) > uint64(x+y);  
}

#else  
// The following definition is not quite correct because it always returns  
// uint64. The above C++ functions are good, though.  
#define **PAIR**(high, low) (((uint64)(high)<<sizeof(high)*8) | low)  
// For C, we just provide macros, they are not quite correct.  
#define **ROL**(x, y) **rotl**(x, y) // Rotate left  
#define **ROR**(x, y) **rotr**(x, y) // Rotate right  
#define **CFSHL**(x, y) invalid_operation // Generate carry flag for (x<<y)  
#define **CFSHR**(x, y) invalid_operation // Generate carry flag for (x>>y)  
#define **CFADD**(x, y) invalid_operation // Generate carry flag for (x+y)  
#define **CFSUB**(x, y) invalid_operation // Generate carry flag for (x-y)  
#define **OFADD**(x, y) invalid_operation // Generate overflow flag for (x+y)  
#define **OFSUB**(x, y) invalid_operation // Generate overflow flag for (x-y)  
#endif

// No definition for rcl/rcr because the carry flag is unknown  
#define **RCL**(x, y) invalid_operation // Rotate left thru carry  
#define **RCR**(x, y) invalid_operation // Rotate right thru carry  
#define **MKCRCL**(x, y) invalid_operation // Generate carry flag for a RCL  
#define **MKCRCR**(x, y) invalid_operation // Generate carry flag for a RCR  
#define **SETP**(x, y) invalid_operation // Generate parity flag for (x-y)

// In the decompilation listing there are some objects declarared as _UNKNOWN  
// because we could not determine their types. Since the C compiler does not  
// accept void item declarations, we replace them by anything of our choice,  
// for example a char:

#define _UNKNOWN char

#ifdef _MSC_VER  
#define snprintf _snprintf  
#define vsnprintf _vsnprintf  
#endif