/* Capstone Disassembly Engine */ /* By Nguyen Anh Quynh , 2013-2019 */ #if defined(CAPSTONE_HAS_OSXKERNEL) #include #include #else #include #endif #include #include #include "utils.h" // count number of positive members in a list. // NOTE: list must be guaranteed to end in 0 unsigned int count_positive(const uint16_t *list) { unsigned int c; for (c = 0; list[c] > 0; c++); return c; } // count number of positive members in a list. // NOTE: list must be guaranteed to end in 0 unsigned int count_positive8(const unsigned char *list) { unsigned int c; for (c = 0; list[c] > 0; c++); return c; } char *cs_strdup(const char *str) { size_t len = strlen(str) + 1; void *new = cs_mem_malloc(len); if (new == NULL) return NULL; return (char *)memmove(new, str, len); } // we need this since Windows doesn't have snprintf() int cs_snprintf(char *buffer, size_t size, const char *fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = cs_vsnprintf(buffer, size, fmt, ap); va_end(ap); return ret; } bool arr_exist8(unsigned char *arr, unsigned char max, unsigned int id) { int i; for (i = 0; i < max; i++) { if (arr[i] == id) return true; } return false; } bool arr_exist(uint16_t *arr, unsigned char max, unsigned int id) { int i; for (i = 0; i < max; i++) { if (arr[i] == id) return true; } return false; } /// Reads 4 bytes in the endian order specified in MI->cs->mode. uint32_t readBytes32(MCInst *MI, const uint8_t *Bytes) { assert(MI && Bytes); uint32_t Insn; if (MODE_IS_BIG_ENDIAN(MI->csh->mode)) Insn = (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | ((uint32_t)Bytes[0] << 24); else Insn = ((uint32_t)Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0); return Insn; } /// Reads 2 bytes in the endian order specified in MI->cs->mode. uint16_t readBytes16(MCInst *MI, const uint8_t *Bytes) { assert(MI && Bytes); uint16_t Insn; if (MODE_IS_BIG_ENDIAN(MI->csh->mode)) Insn = (Bytes[0] << 8) | Bytes[1]; else Insn = (Bytes[1] << 8) | Bytes[0]; return Insn; } /// @brief Appends the string @p src to the string @p str. @p src is put to lower case. /// @param str The string to append to. /// @param str_size The lengt of @p str /// @param src The string to append. void append_to_str_lower(char *str, size_t str_size, const char *src) { char *dest = strchr(str, '\0'); if (dest - str >= str_size) { assert("str_size does not match actual string length." && 0); return; } int i = dest - str; for (int j = 0; (i < str_size) && (j < strlen(src)); ++i, ++j) { str[i] = tolower(src[j]); } str[i] = '\0'; }