static kern_return_t write_user_mem(vm_map_t task_port, mach_vm_address_t target_addr, void* buf, uint32_t buf_len) { vm_prot_t orig_protection = get_protection(task_port, target_addr); /* * read current protection so we can restore it */ if (_mach_vm_protect(task_port, target_addr, buf_len, FALSE, VM_PROT_WRITE | VM_PROT_READ)) { LOG_ERROR("vm_protect to write injected library failed!"); return KERN_FAILURE; } /* write the modified header to process */ if (_vm_map_write_user(task_port, buf, target_addr, buf_len)) { LOG_ERROR("write of modified header failed!"); /* we want to try to protect again the memory segment else it will end real bad! */ } /* restore original protection */ if (_mach_vm_protect(task_port, target_addr, buf_len, FALSE, orig_protection)) { /* XXX: this will leave application in a bad state. what to do here? */ LOG_ERROR("vm_protect to original prot failed!"); return KERN_FAILURE; } return KERN_SUCCESS; }
inline osmium::util::MemoryMapping::MemoryMapping(size_t size, mapping_mode mode, int fd, off_t offset) : m_size(check_size(size)), m_offset(offset), m_fd(resize_fd(fd)), m_mapping_mode(mode), m_addr(::mmap(nullptr, m_size, get_protection(), get_flags(), m_fd, m_offset)) { assert(!(fd == -1 && mode == mapping_mode::readonly)); if (!is_valid()) { throw std::system_error(errno, std::system_category(), "mmap failed"); } }
inline void osmium::util::MemoryMapping::resize(size_t new_size) { assert(new_size > 0 && "can not resize to zero size"); if (m_fd == -1) { // anonymous mapping #ifdef __linux__ m_addr = ::mremap(m_addr, m_size, new_size, MREMAP_MAYMOVE); if (!is_valid()) { throw std::system_error(errno, std::system_category(), "mremap failed"); } m_size = new_size; #else assert(false && "can't resize anonymous mappings on non-linux systems"); #endif } else { // file-based mapping unmap(); m_size = new_size; resize_fd(m_fd); m_addr = ::mmap(nullptr, new_size, get_protection(), get_flags(), m_fd, m_offset); if (!is_valid()) { throw std::system_error(errno, std::system_category(), "mmap (remap) failed"); } } }
int main(int argc, char **argv) { pid_t pid; int i = 0; int j = 0; int regions = 1; int state = 0; char *mem; mach_vm_address_t base; mach_vm_address_t past = 0; mach_vm_address_t addr; vm_region_t **vm_region_list; mach_port_t task; if (geteuid() != 0) { fprintf(stderr, "[-] are you root?\n"); exit(1); } set_signal_handler(); printf("[+] Looking for Self Service\n"); pid = get_pid(); if (!pid) { fprintf(stderr, "[-] Not found. exiting\n"); exit(2); } printf("[+] Self Service found: %d\n", pid); task = attach(pid); printf("[+] ATTACHED TO PROCESS %d WITH TASK %d\n", pid, task); base = get_base_address(task); addr = base; while (regions) { vm_region_list = get_memory_map(task, addr, ®ions); printf("[+] Found %d regions\n", regions); for (i = 0; i < regions; ++i) { if (past > vm_region_list[i]->address_start) { printf("\n[!] Looped around somehow, exiting gracefully\n\n"); exit(256); } printf("[+] Region %d:%d;\n[+]\tType:\t%s\n[+]\tBase Address:\t%016llx\n[+]\tEnd Address:\t%016llx\n[+]\tSize:\t0x%llx (%lld bytes)\n[+]\tPermissions:\t%s \n", j, i, user_tag_to_string(vm_region_list[i]->region_type), vm_region_list[i]->address_start, vm_region_list[i]->address_start + vm_region_list[i]->size, vm_region_list[i]->size, vm_region_list[i]->size, get_protection(vm_region_list[i]->protection)); if ((vm_region_list[i]->protection) & 1) { printf("[+]\tMaking Local Copy of Memory\n"); mem = (char *)read_memory_allocate(task, vm_region_list[i]->address_start, vm_region_list[i]->size); } else { printf("[+]\t\tChanging memory permissions\n"); state = vm_region_list[i]->protection; change_page_protection(task, vm_region_list[i]->address_start, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE); printf("[+]\t\tMaking Local Copy of Memory\n"); mem = (char *)read_memory_allocate(task, vm_region_list[i]->address_start, vm_region_list[i]->size); printf("[+]\t\tChanging memory permissions back\n"); change_page_protection(task, vm_region_list[i]->address_start, state); } printf("[+]\tSearching local copy for username and password string\n"); checkit(mem, vm_region_list[i]->size); free(mem); } printf("[+] Completed searching %d regions\n", i); past = addr; addr += base; if (setjmp(buf)) { fprintf(stderr, "\n[!] Segfault at 0x%llX\n\n", addr); past = addr; addr = vm_region_list[i]->address_start + vm_region_list[i]->size; } j++; } printf("\n[+] Completed searching through allocated memory\n"); return 0; }
inline HANDLE osmium::util::MemoryMapping::create_file_mapping() const noexcept { if (m_fd != -1) { _setmode(m_fd, _O_BINARY); } return CreateFileMapping(get_handle(), nullptr, get_protection(), osmium::util::dword_hi(static_cast<uint64_t>(m_size) + m_offset), osmium::util::dword_lo(static_cast<uint64_t>(m_size) + m_offset), nullptr); }
int main(int argc, char ** argv) { // required structure for long options static struct option long_options[]={ { "pid", required_argument, NULL, 'p' }, { "address", required_argument, NULL, 'a' }, { "size", required_argument, NULL, 's' }, { "out", required_argument, NULL, 'o' }, { "full", no_argument, NULL, 'f' }, { NULL, 0, NULL, 0 } }; int option_index = 0; int c = 0; char *outputname = NULL; uint32_t size = 0; pid_t pid = 0; uint8_t fulldump = 0; #if defined (__arm__) uint32_t address = 0; #else uint64_t address = 0; #endif // process command line options while ((c = getopt_long (argc, argv, "a:s:o:p:f", long_options, &option_index)) != -1) { switch (c) { case ':': usage(); exit(1); break; case '?': usage(); exit(1); break; case 'o': outputname = optarg; break; case 'p': pid = (pid_t)strtoul(optarg, NULL, 0); break; case 'a': address = strtoul(optarg, NULL, 0); break; case 's': size = (uint32_t)strtoul(optarg, NULL, 0); break; case 'f': fulldump = 1; break; default: usage(); exit(1); } } header(); if (argc < 7) { usage(); } if (size > MAX_SIZE || (size == 0 && fulldump == 0)) { printf("[ERROR] Invalid size (higher than maximum or zero!)\n"); exit(1); } uint8_t *readbuffer = NULL; if (fulldump == 0) { readbuffer = malloc(size*sizeof(uint8_t)); if (readbuffer == NULL) { printf("[ERROR] Memory allocation failed!\n"); exit(1); } } FILE *outputfile; if (outputname != NULL) { if ( (outputfile = fopen(outputname, "wb")) == NULL) { fprintf(stderr,"[ERROR] Cannot open %s for output!\n", outputname); exit(1); } } if (outputname == NULL && fulldump == 1) { printf("[ERROR] Full dump requires output filename!\n"); exit(1); } vm_region_basic_info_data_64_t region_info; // read memory // if it's a full image dump, we need to read its header and find the LINKEDIT segment if (fulldump) { // first we need to find the file size because memory alignment slack spaces mach_vm_address_t imagesize = 0; imagesize = get_image_size(address, pid); // reallocate the buffer since size argument is not used readbuffer = malloc((long)imagesize * sizeof(uint8_t)); // and finally read the sections and dump their contents to the buffer dump_binary(address, pid, (void*)readbuffer); // dump buffer contents to file if (outputname != NULL) { if (fwrite(readbuffer, (long)imagesize, 1, outputfile) < 1) { fprintf(stderr,"[ERROR] Write error at %s occurred!\n", outputname); exit(1); } printf("\n[OK] Full binary dumped to %s!\n\n", outputname); } } // we just want to read bits'n'pieces! else { readmem((mach_vm_offset_t*)readbuffer, address, size, pid, ®ion_info); // dump to file if (outputname != NULL) { if (fwrite(readbuffer, size, 1, outputfile) < 1) { fprintf(stderr,"[ERROR] Write error at %s occurred!\n", outputname); exit(1); } printf("\n[OK] Memory dumped to %s!\n\n", outputname); } // dump to stdout else { int i = 0; int x = 0; int z = 0; int linelength = 0; // retrieve memory protection for the region of the starting address // CAVEAT: it will be incorrect if dumping size includes more than one region // but we can't get protection per page char current_protection[4]; char maximum_protection[4]; get_protection(region_info.protection, current_protection); get_protection(region_info.max_protection, maximum_protection); printf("Memory protection: %s/%s\n\n", current_protection, maximum_protection); // 16 columns while (i < size) { linelength = (size - i) <= 16 ? (size - i) : 16; printf("%p ",(void*)address); z = i; // hex dump for (x = 0; x < linelength; x++) { printf("%02x ", readbuffer[z++]); } // make it always 16 columns, this could be prettier :P for (x = linelength; x < 16; x++) printf(" "); z = i; // try to print ascii for (x = 0; x < linelength; x++) { printf("%c", isascii(readbuffer[z]) && isprint(readbuffer[z]) ? readbuffer[z] : '.'); z++; } i += 16; printf("\n"); address += 16; } printf("\n"); } } free(readbuffer); return 0; }
bool Player::get_damage(unsigned int dmg) { if(dmg - get_protection() > 0){ l_hp -=(dmg - get_protection()); } return is_alive(); }