217 lines
4.3 KiB
C
217 lines
4.3 KiB
C
/* Capstone testing regression */
|
|
/* By Do Minh Tuan <tuanit96@gmail.com>, 02-2019 */
|
|
|
|
#include <assert.h>
|
|
#include <stdarg.h>
|
|
#include <capstone/platform.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <ctype.h>
|
|
#include <setjmp.h>
|
|
#include "cmocka.h"
|
|
#include "helper.h"
|
|
|
|
char *cs_strndup(const char *s, size_t n)
|
|
{
|
|
if (!s) {
|
|
return NULL;
|
|
}
|
|
size_t l = cs_strnlen(s, n);
|
|
if (l == SIZE_MAX) {
|
|
return NULL;
|
|
}
|
|
char *out = calloc(sizeof(char), l + 1);
|
|
if (!out) {
|
|
return NULL;
|
|
}
|
|
memcpy(out, s, l);
|
|
return out;
|
|
}
|
|
|
|
void add_str(char **src, const char *format, ...)
|
|
{
|
|
char *tmp;
|
|
size_t len1, len2;
|
|
va_list args;
|
|
|
|
tmp = (char *)malloc(sizeof(char) * 1000);
|
|
va_start(args, format);
|
|
vsprintf(tmp, format, args);
|
|
va_end(args);
|
|
|
|
len1 = strlen(*src);
|
|
len2 = strlen(tmp);
|
|
|
|
*src = (char *)realloc(*src, sizeof(char) * (len1 + len2 + 10));
|
|
memcpy(*src + len1, tmp, len2 + 1);
|
|
free(tmp);
|
|
}
|
|
|
|
void replace_hex(char *src, size_t src_len)
|
|
{
|
|
char *tmp, *result, *found, *origin, *orig_found;
|
|
int valid;
|
|
unsigned long long int value;
|
|
char *tmp_tmp;
|
|
|
|
result = (char *)malloc(sizeof(char));
|
|
result[0] = '\0';
|
|
tmp = strdup(src);
|
|
origin = tmp;
|
|
|
|
while ((found = strstr(tmp, "0x")) != NULL) {
|
|
orig_found = found;
|
|
found += 2;
|
|
value = 0;
|
|
valid = 0;
|
|
|
|
tmp_tmp = cs_strndup(tmp, orig_found - tmp);
|
|
while (*found != '\0' && isxdigit(*found)) {
|
|
valid = 1;
|
|
if (*found >= 'a' && *found <= 'f')
|
|
value = value * 0x10 + (*found - 'a' + 10);
|
|
else if (*found >= 'A' && *found <= 'F')
|
|
value = value * 0x10 + (*found - 'A' + 10);
|
|
else
|
|
value = value * 0x10 + (*found - '0');
|
|
found++;
|
|
}
|
|
|
|
if (valid == 1)
|
|
add_str(&result, "%s%llu", tmp_tmp, value);
|
|
else
|
|
add_str(&result, "%s0x", tmp_tmp);
|
|
tmp = found;
|
|
free(tmp_tmp);
|
|
}
|
|
|
|
add_str(&result, "%s", tmp);
|
|
if (strlen(result) >= src_len) {
|
|
free(result);
|
|
free(origin);
|
|
fprintf(stderr,
|
|
"[ Error ] --- Buffer Overflow in replace_hex()\n");
|
|
_fail(__FILE__, __LINE__);
|
|
}
|
|
|
|
strcpy(src, result);
|
|
free(result);
|
|
free(origin);
|
|
}
|
|
|
|
void replace_negative(char *src, size_t src_len, size_t arch_bits)
|
|
{
|
|
char *tmp, *result, *found, *origin, *orig_found;
|
|
int cnt, valid;
|
|
char *value, *tmp_tmp;
|
|
uint16_t tmp_short;
|
|
uint32_t tmp_int;
|
|
uint64_t tmp_long;
|
|
|
|
result = (char *)malloc(sizeof(char));
|
|
result[0] = '\0';
|
|
tmp = strdup(src);
|
|
origin = tmp;
|
|
|
|
while ((found = strstr(tmp, "-")) != NULL) {
|
|
orig_found = found;
|
|
found++;
|
|
valid = 0;
|
|
|
|
value = strdup("-");
|
|
cnt = 2;
|
|
|
|
while (*found != '\0' && isdigit(*found)) {
|
|
valid = 1;
|
|
value = (char *)realloc(value, cnt + 1);
|
|
value[cnt - 1] = *found;
|
|
value[cnt] = '\0';
|
|
cnt++;
|
|
found++;
|
|
}
|
|
|
|
tmp_tmp = cs_strndup(tmp, orig_found - tmp);
|
|
if (valid == 1) {
|
|
*orig_found = '\0';
|
|
if (arch_bits == 16) {
|
|
sscanf(value, "%hu", &tmp_short);
|
|
add_str(&result, "%s%hu", tmp_tmp, tmp_short);
|
|
} else if (arch_bits == 32) {
|
|
sscanf(value, "%" PRIu32, &tmp_int);
|
|
add_str(&result, "%s%" PRIu32, tmp_tmp,
|
|
tmp_int);
|
|
} else if (arch_bits == 64) {
|
|
sscanf(value, "%" PRIu64, &tmp_long);
|
|
add_str(&result, "%s%" PRIu64, tmp_tmp,
|
|
tmp_long);
|
|
}
|
|
|
|
} else
|
|
add_str(&result, "%s-", tmp_tmp);
|
|
|
|
tmp = found;
|
|
free(value);
|
|
free(tmp_tmp);
|
|
}
|
|
|
|
add_str(&result, "%s", tmp);
|
|
if (strlen(result) >= src_len) {
|
|
fprintf(stderr,
|
|
"[ Error ] --- Buffer Overflow in replace_negative()\n");
|
|
free(result);
|
|
free(origin);
|
|
_fail(__FILE__, __LINE__);
|
|
}
|
|
|
|
strcpy(src, result);
|
|
free(result);
|
|
free(origin);
|
|
}
|
|
|
|
void trim_str(char *str)
|
|
{
|
|
char tmp[MAX_ASM_TXT_MEM];
|
|
int start, end, j, i;
|
|
|
|
start = 0;
|
|
end = strlen(str) - 1;
|
|
j = 0;
|
|
while (start < strlen(str) && isspace(str[start]))
|
|
start++;
|
|
while (end >= 0 && isspace(str[end]))
|
|
end--;
|
|
|
|
for (i = start; i <= end; ++i)
|
|
tmp[j++] = str[i];
|
|
|
|
tmp[j] = '\0';
|
|
strcpy(str, tmp);
|
|
|
|
return;
|
|
}
|
|
|
|
/// Normalizes the usage of spaces in the given string.
|
|
/// It does:
|
|
/// - Replaces '\t' with '\s'
|
|
/// - Replace '\s\s+' with a single space.
|
|
void norm_spaces(char *str)
|
|
{
|
|
assert(str);
|
|
char *space_ptr = NULL;
|
|
while ((space_ptr = strstr(str, "\t")) != NULL) {
|
|
*space_ptr = ' ';
|
|
}
|
|
while ((space_ptr = strstr(str, " ")) != NULL) {
|
|
memmove(space_ptr, space_ptr + 1, strlen(space_ptr));
|
|
}
|
|
return;
|
|
}
|
|
|
|
void str_to_lower(char *str)
|
|
{
|
|
assert(str);
|
|
for (size_t i = 0; i < strlen(str); ++i)
|
|
str[i] = tolower(str[i]);
|
|
}
|