//---------------------------------------------------------------------- // find_cstring_in_heap // // Finds a C string inside one or more currently valid malloc blocks. //---------------------------------------------------------------------- malloc_match * find_cstring_in_heap (const char *s, int check_vm_regions) { g_matches.clear(); if (s == NULL || s[0] == '\0') { printf ("error: invalid argument (empty cstring)\n"); return NULL; } // Setup "info" to look for a malloc block that contains data // that is the C string passed in aligned on a 1 byte boundary range_contains_data_callback_info_t data_info; data_info.type = eDataTypeContainsData; // Check each block for data data_info.data.buffer = (uint8_t *)s; // What data? The C string passed in data_info.data.size = strlen(s); // How many bytes? The length of the C string data_info.data.align = 1; // Data doesn't need to be aligned, so set the alignment to 1 data_info.match_count = 0; // Initialize the match count to zero data_info.done = false; // Set done to false so searching doesn't stop data_info.unique = false; // Set to true when iterating on the vm_regions range_callback_info_t info = { enumerate_range_in_zone, range_info_callback, &data_info, check_vm_regions }; foreach_zone_in_this_process (&info); g_matches.dump(); return g_matches.data(); }
void IExtractor::Extract() { MatchResults resultat; do { resultat.Clear(); resultat = Match(m_cadena); if (resultat.matched) { Parse(resultat); } } while(resultat.matched); }
//---------------------------------------------------------------------- // find_block_for_address // // Find the malloc block that whose address range contains "addr". //---------------------------------------------------------------------- malloc_match * find_block_for_address (const void *addr, int check_vm_regions) { g_matches.clear(); // Setup "info" to look for a malloc block that contains data // that is the C string passed in aligned on a 1 byte boundary range_contains_data_callback_info_t data_info; data_info.type = eDataTypeAddress; // Check each block to see if the block contains the address passed in data_info.addr = (uintptr_t)addr; // What data? The C string passed in data_info.match_count = 0; // Initialize the match count to zero data_info.done = false; // Set done to false so searching doesn't stop data_info.unique = false; // Set to true when iterating on the vm_regions range_callback_info_t info = { enumerate_range_in_zone, range_info_callback, &data_info, check_vm_regions }; foreach_zone_in_this_process (&info); return g_matches.data(); }
//---------------------------------------------------------------------- // find_pointer_in_memory // // Finds a pointer value inside one or more currently valid malloc // blocks. //---------------------------------------------------------------------- malloc_match * find_pointer_in_memory (uint64_t memory_addr, uint64_t memory_size, const void * addr) { g_matches.clear(); // Setup "info" to look for a malloc block that contains data // that is the pointer range_contains_data_callback_info_t data_info; data_info.type = eDataTypeContainsData; // Check each block for data data_info.data.buffer = (uint8_t *)&addr; // What data? The pointer value passed in data_info.data.size = sizeof(addr); // How many bytes? The byte size of a pointer data_info.data.align = sizeof(addr); // Align to a pointer byte size data_info.match_count = 0; // Initialize the match count to zero data_info.done = false; // Set done to false so searching doesn't stop data_info.unique = false; // Set to true when iterating on the vm_regions range_info_callback (mach_task_self(), &data_info, stack_logging_type_generic, memory_addr, memory_size); return g_matches.data(); }
//---------------------------------------------------------------------- // find_objc_objects_in_memory // // Find all instances of ObjC classes 'c', or all ObjC classes if 'c' is // NULL. If 'c' is non NULL, then also check objects to see if they // inherit from 'c' //---------------------------------------------------------------------- malloc_match * find_objc_objects_in_memory (void *isa, int check_vm_regions) { g_matches.clear(); if (g_objc_classes.Update()) { // Setup "info" to look for a malloc block that contains data // that is the pointer range_contains_data_callback_info_t data_info; data_info.type = eDataTypeObjC; // Check each block for data data_info.objc.match_isa = isa; data_info.objc.match_superclasses = true; data_info.match_count = 0; // Initialize the match count to zero data_info.done = false; // Set done to false so searching doesn't stop data_info.unique = false; // Set to true when iterating on the vm_regions range_callback_info_t info = { enumerate_range_in_zone, range_info_callback, &data_info, check_vm_regions }; foreach_zone_in_this_process (&info); } return g_matches.data(); }
//---------------------------------------------------------------------- // find_pointer_in_heap // // Finds a pointer value inside one or more currently valid malloc // blocks. //---------------------------------------------------------------------- malloc_match * find_pointer_in_heap (const void * addr, int check_vm_regions) { g_matches.clear(); // Setup "info" to look for a malloc block that contains data // that is the pointer if (addr) { range_contains_data_callback_info_t data_info; data_info.type = eDataTypeContainsData; // Check each block for data data_info.data.buffer = (uint8_t *)&addr; // What data? The pointer value passed in data_info.data.size = sizeof(addr); // How many bytes? The byte size of a pointer data_info.data.align = sizeof(addr); // Align to a pointer byte size data_info.match_count = 0; // Initialize the match count to zero data_info.done = false; // Set done to false so searching doesn't stop data_info.unique = false; // Set to true when iterating on the vm_regions range_callback_info_t info = { enumerate_range_in_zone, range_info_callback, &data_info, check_vm_regions }; foreach_zone_in_this_process (&info); } return g_matches.data(); }
static void range_info_callback (task_t task, void *baton, unsigned type, uint64_t ptr_addr, uint64_t ptr_size) { const uint64_t end_addr = ptr_addr + ptr_size; range_contains_data_callback_info_t *info = (range_contains_data_callback_info_t *)baton; switch (info->type) { case eDataTypeAddress: // Check if the current malloc block contains an address specified by "info->addr" if (ptr_addr <= info->addr && info->addr < end_addr) { ++info->match_count; malloc_match match = { (void *)ptr_addr, ptr_size, info->addr - ptr_addr, type }; g_matches.push_back(match, info->unique); } break; case eDataTypeContainsData: // Check if the current malloc block contains data specified in "info->data" { const uint32_t size = info->data.size; if (size < ptr_size) // Make sure this block can contain this data { uint8_t *ptr_data = NULL; if (task_peek (task, ptr_addr, ptr_size, (void **)&ptr_data) == KERN_SUCCESS) { const void *buffer = info->data.buffer; assert (ptr_data); const uint32_t align = info->data.align; for (uint64_t addr = ptr_addr; addr < end_addr && ((end_addr - addr) >= size); addr += align, ptr_data += align) { if (memcmp (buffer, ptr_data, size) == 0) { ++info->match_count; malloc_match match = { (void *)ptr_addr, ptr_size, addr - ptr_addr, type }; g_matches.push_back(match, info->unique); } } } else { printf ("0x%llx: error: couldn't read %llu bytes\n", ptr_addr, ptr_size); } } } break; case eDataTypeObjC: // Check if the current malloc block contains an objective C object // of any sort where the first pointer in the object is an OBJC class // pointer (an isa) { malloc_block_contents *block_contents = NULL; if (task_peek (task, ptr_addr, sizeof(void *), (void **)&block_contents) == KERN_SUCCESS) { // We assume that g_objc_classes is up to date // that the class list was verified to have some classes in it // before calling this function const uint32_t objc_class_idx = g_objc_classes.FindClassIndex (block_contents->isa); if (objc_class_idx != UINT32_MAX) { bool match = false; if (info->objc.match_isa == 0) { // Match any objective C object match = true; } else { // Only match exact isa values in the current class or // optionally in the super classes if (info->objc.match_isa == block_contents->isa) match = true; else if (info->objc.match_superclasses) { Class super = class_getSuperclass(block_contents->isa); while (super) { match = super == info->objc.match_isa; if (match) break; super = class_getSuperclass(super); } } } if (match) { //printf (" success\n"); ++info->match_count; malloc_match match = { (void *)ptr_addr, ptr_size, 0, type }; g_matches.push_back(match, info->unique); } else { //printf (" error: wrong class: %s\n", dl_info.dli_sname); } } else { //printf ("\terror: symbol not objc class: %s\n", dl_info.dli_sname); return; } } } break; case eDataTypeHeapInfo: // Check if the current malloc block contains an objective C object // of any sort where the first pointer in the object is an OBJC class // pointer (an isa) { malloc_block_contents *block_contents = NULL; if (task_peek (task, ptr_addr, sizeof(void *), (void **)&block_contents) == KERN_SUCCESS) { // We assume that g_objc_classes is up to date // that the class list was verified to have some classes in it // before calling this function const uint32_t objc_class_idx = g_objc_classes.FindClassIndex (block_contents->isa); if (objc_class_idx != UINT32_MAX) { // This is an objective C object g_objc_class_snapshot.AddInstance (objc_class_idx, ptr_size); } else { // Classify other heap info } } } break; } }