static void log_buffer_notrunc(const uint8_t *buf, uintptr_t length) { if(buf == NULL || length == 0) { return; } bson b; bson_init(&b); bson_append_string(&b, "type", "buffer"); if(range_is_readable(buf, length) != 0) { bson_append_binary(&b, "buffer", BSON_BIN_BINARY, (const char *) buf, length); char checksum[64]; sha1(buf, length, checksum); bson_append_string(&b, "checksum", checksum); } else { bson_append_string(&b, "buffer", "<INVALID POINTER>"); bson_append_string(&b, "checksum", "???"); } bson_finish(&b); log_raw(bson_data(&b), bson_size(&b)); bson_destroy(&b); }
static int _eat_pointers_for_module(const uint8_t *mod, uint32_t **function_addresses, uint32_t **names_addresses, uint16_t **ordinals, uint32_t *number_of_names) { IMAGE_DOS_HEADER *image_dos_header = (IMAGE_DOS_HEADER *) mod; IMAGE_NT_HEADERS_CROSS *image_nt_headers = (IMAGE_NT_HEADERS_CROSS *)(mod + image_dos_header->e_lfanew); // Check whether this module is the Monitor DLL. As the monitor destroys // its own PE header we cache the related pointers. Fetch them now. if(mod == g_monitor_base_address) { *function_addresses = g_monitor_function_addresses; *names_addresses = g_monitor_names_addresses; *ordinals = g_monitor_ordinals; *number_of_names = g_monitor_number_of_names; return 0; } IMAGE_DATA_DIRECTORY *data_directories = image_nt_headers->OptionalHeader.DataDirectory; if(image_nt_headers->OptionalHeader.NumberOfRvaAndSizes < IMAGE_DIRECTORY_ENTRY_EXPORT + 1) { return -1; } IMAGE_DATA_DIRECTORY *export_data_directory = &data_directories[IMAGE_DIRECTORY_ENTRY_EXPORT]; if(export_data_directory->VirtualAddress == 0 || export_data_directory->Size == 0) { return -1; } IMAGE_EXPORT_DIRECTORY *export_directory = (IMAGE_EXPORT_DIRECTORY *)( mod + export_data_directory->VirtualAddress); // Due to corrupted PE files or incorrect loading of the PE file by us // the export directory may point to invalid memory. If so, don't crash. if(range_is_readable(export_directory, sizeof(IMAGE_EXPORT_DIRECTORY)) == 0) { return -1; } *number_of_names = export_directory->NumberOfNames; *function_addresses = (uint32_t *)( mod + export_directory->AddressOfFunctions); *names_addresses = (uint32_t *)(mod + export_directory->AddressOfNames); *ordinals = (uint16_t *)(mod + export_directory->AddressOfNameOrdinals); return 0; }
static void log_buffer(bson *b, const char *idx, const uint8_t *buf, uintptr_t length) { uintptr_t trunclength = length < BUFFER_LOG_MAX ? length : BUFFER_LOG_MAX; if(buf == NULL) { trunclength = 0; } if(range_is_readable(buf, length) != 0) { bson_append_binary(b, idx, BSON_BIN_BINARY, (const char *) buf, trunclength); } else { bson_append_binary(b, idx, BSON_BIN_BINARY, "<INVALID POINTER>", 17); } }
const uint8_t *module_from_address(const uint8_t *addr) { MEMORY_BASIC_INFORMATION_CROSS mbi; if(virtual_query(addr, &mbi) == FALSE || range_is_readable((const uint8_t *) mbi.AllocationBase, 2) == 0) { return NULL; } addr = (const uint8_t *) mbi.AllocationBase; // We're looking for either an MZ header or the image base address // of our monitor. if(our_memcmp(addr, "MZ", 2) == 0 || addr == g_monitor_base_address) { return addr; } return NULL; }
void log_wstring(bson *b, const char *idx, const wchar_t *str, int length) { if(str == NULL) { bson_append_string_n(b, idx, "", 0); return; } if(range_is_readable(str, length) != 0) { int ret, utf8len; char *utf8s = utf8_wstring(str, length); utf8len = *(int *) utf8s; ret = bson_append_binary(b, idx, BSON_BIN_BINARY, utf8s+4, utf8len); if(ret == BSON_ERROR) { pipe("CRITICAL:Error creating bson wstring, error %x, utf8len %d.", b->err, utf8len); } mem_free(utf8s); } else { bson_append_binary(b, idx, BSON_BIN_BINARY, "<INVALID POINTER>", 17); } }