static void _log_stacktrace(bson *b) { uintptr_t addrs[RETADDRCNT], count; char number[20], sym[512]; bson_append_start_array(b, "s"); count = stacktrace(NULL, addrs, RETADDRCNT); for (uint32_t idx = 4; idx < count; idx++) { ultostr(idx-4, number, 10); symbol((const uint8_t *) addrs[idx], sym, sizeof(sym)-32); if(sym[0] != 0) { our_snprintf(sym + our_strlen(sym), sizeof(sym) - our_strlen(sym), " @ "); } our_snprintf(sym + our_strlen(sym), sizeof(sym) - our_strlen(sym), "%p", (const uint8_t *) addrs[idx]); bson_append_string(b, number, sym); } bson_append_finish_array(b); }
int symbol(const uint8_t *addr, char *sym, uint32_t length) { int len; *sym = 0; const uint8_t *mod = module_from_address(addr); if(mod == NULL) { return -1; } const wchar_t *module_name = get_module_file_name((HMODULE) mod); symbol_t s; s.address = (uintptr_t) addr; s.lower_address = s.higher_address = 0; s.lower_funcname = s.higher_funcname = NULL; symbol_enumerate_module((HMODULE) mod, &_symbol_callback, &s); if(s.lower_address != 0) { len = our_snprintf(sym, length, "%s+%p", s.lower_funcname, (uintptr_t) addr - s.lower_address); sym += len, length -= len; } if(s.higher_address != 0) { if(s.lower_address != 0) { *sym++ = ' ', length--; } len = our_snprintf(sym, length, "%s-%p", s.higher_funcname, s.higher_address - (uintptr_t) addr); sym += len, length -= len; } if(module_name != NULL) { if(s.lower_address != 0 || s.higher_address != 0) { *sym++ = ' ', length--; } while (length-- > 20 && *module_name != 0 && *module_name != '.') { *sym++ = tolower(*module_name++); } our_snprintf(sym, length, "+%p", addr - mod); } return 0; }
int disasm(const void *addr, char *str) { if(g_capstone == 0) { pipe("CRITICAL:Capstone has not been initialized yet!"); return *str = 0, 0; } cs_insn *insn; size_t count = cs_disasm_ex(g_capstone, addr, 16, (uintptr_t) addr, 1, &insn); if(count == 0) return -1; our_snprintf(str, DISASM_BUFSIZ, "%s %s", insn->mnemonic, insn->op_str); cs_free(insn, count); return 0; }
void unit_test_io(void) { char buf[512]; wchar_t wbuf[512]; ssize_t res; /* test wide char conversion */ res = our_snprintf(buf, BUFFER_SIZE_ELEMENTS(buf), "%S", L"wide string"); EXPECT(res == (ssize_t) strlen("wide string"), true); EXPECT(strcmp(buf, "wide string"), 0); res = our_snprintf(buf, BUFFER_SIZE_ELEMENTS(buf), "%ls", L"wide string"); EXPECT(res == (ssize_t) strlen("wide string"), true); EXPECT(strcmp(buf, "wide string"), 0); res = our_snprintf(buf, BUFFER_SIZE_ELEMENTS(buf), "%.3S", L"wide string"); EXPECT(res == (ssize_t) strlen("wid"), true); EXPECT(strcmp(buf, "wid"), 0); res = our_snprintf(buf, 4, "%S", L"wide string"); EXPECT(res == -1, true); EXPECT(buf[4], ' '); /* ' ' from prior calls: no NULL written since hit max */ buf[4] = '\0'; EXPECT(strcmp(buf, "wide"), 0); /* test float */ res = our_snprintf(buf, BUFFER_SIZE_ELEMENTS(buf), "%3.1f", 42.9f); EXPECT(res == (ssize_t) strlen("42.9"), true); EXPECT(strcmp(buf, "42.9"), 0); /* XXX: add more */ /* test all-wide */ res = our_snprintf_wide(wbuf, BUFFER_SIZE_ELEMENTS(wbuf), L"%d%s%3.1f", -42, L"wide string", 42.9f); EXPECT(res == (ssize_t) wcslen(L"-42wide string42.9"), true); EXPECT(wcscmp(wbuf, L"-42wide string42.9"), 0); /* test all-wide conversion */ res = our_snprintf_wide(wbuf, BUFFER_SIZE_ELEMENTS(wbuf), L"%S", "narrow string"); EXPECT(res == (ssize_t) wcslen(L"narrow string"), true); EXPECT(wcscmp(wbuf, L"narrow string"), 0); res = our_snprintf_wide(wbuf, BUFFER_SIZE_ELEMENTS(wbuf), L"%hs", "narrow string"); EXPECT(res == (ssize_t) wcslen(L"narrow string"), true); EXPECT(wcscmp(wbuf, L"narrow string"), 0); res = our_snprintf_wide(wbuf, BUFFER_SIZE_ELEMENTS(wbuf), L"%.3S", "narrow string"); EXPECT(res == (ssize_t) wcslen(L"nar"), true); EXPECT(wcscmp(wbuf, L"nar"), 0); res = our_snprintf_wide(wbuf, 6, L"%S", "narrow string"); EXPECT(res == -1, true); EXPECT(wbuf[6], L' '); /* ' ' from prior calls: no NULL written since hit max */ wbuf[6] = L'\0'; EXPECT(wcscmp(wbuf, L"narrow"), 0); #ifdef LINUX /* sscanf tests */ test_sscanf_maps_x86(); test_sscanf_maps_x64(); test_sscanf_all_specs(); /* memcpy tests */ test_our_memcpy(); our_memcpy_vs_libc(); /* memset tests */ test_our_memset(); #endif /* LINUX */ /* XXX: add more tests */ print_file(STDERR, "io all done\n"); }