Beispiel #1
0
static int fpm_mach_vm_read_page(vm_offset_t page) /* {{{ */
{
	kern_return_t kr;

	kr = mach_vm_read(target, page, fpm_pagesize, &local_page, &local_size);
	if (kr != KERN_SUCCESS) {
		zlog(ZLOG_ERROR, "failed to read vm page: mach_vm_read(): %s (%d)", mach_error_string(kr), kr);
		return -1;
	}
	return 0;
}
Beispiel #2
0
bool ZGReadBytes(ZGMemoryMap processTask, ZGMemoryAddress address, void **bytes, ZGMemorySize *size)
{
	ZGMemorySize originalSize = *size;
	vm_offset_t dataPointer = 0;
	mach_msg_type_number_t dataSize = 0;
	bool success = false;
	if (mach_vm_read(processTask, address, originalSize, &dataPointer, &dataSize) == KERN_SUCCESS)
	{
		success = true;
		*bytes = (void *)dataPointer;
		*size = dataSize;
	}
	
	return success;
}
Beispiel #3
0
int main(int ac, char **av)
{
	kern_return_t kr; 
	task_t mytask;
	uint32_t sz;
	unsigned long startaddr,endaddr,i=0,numpages=0;
	unsigned char **outbuff;
	
	FILE *fp;

	if(ac != 5) {
		printf("usage: %s <pid> <output file> <start address> <end address>\n",av[0]);
		exit(1);
	}

	if(task_for_pid(mach_task_self(),atoi(av[1]),&mytask)) {
		printf("[!] error: could not attach to pid.\n");
		exit(1);
	}

	if(task_suspend(mytask) != KERN_SUCCESS) {
		printf("[!] Failed suspending task, trying again.\n");
		exit(1);
	}

	sscanf(av[3],"%lx",&startaddr);
	sscanf(av[4],"%lx",&endaddr);

	numpages = ((endaddr - startaddr) / PAGESIZE);

	fp = fopen(av[2],"w+");
	if(fp == NULL){
		printf("[!] error: opening output file.\n");
		exit(1);
	}

	for(i=0; i<=numpages; i++) {
/*
kern_return_t   vm_read
                (vm_task_t                          target_task,
                 vm_address_t                           address,
                 vm_size_t                                 size,
                 size                                  data_out,
                 target_task                         data_count);
*/
		sz = 4;
		//printf("[+] reading from 0xx%lx\n",startaddr);
		if(mach_vm_read(mytask,(unsigned long)startaddr,PAGESIZE,&outbuff,&sz) != KERN_SUCCESS) {
			printf("error: reading from process\n");
			exit(1);
		}
	
		if(fwrite(outbuff,PAGESIZE,1,fp) != 1) {
			printf("error: writing to file\n");
			exit(1);
		}
		startaddr+=PAGESIZE;
	}

	fclose(fp);

	if(task_resume(mytask) != KERN_SUCCESS) {
		printf("[!] Failed resuming task, trying again.\n");
		exit(1);
	}

	return 0;
}
Beispiel #4
0
static int
mach_xfer_memory_block (CORE_ADDR memaddr, char *myaddr,
                        int len, int write, task_t task)
{
  vm_size_t pagesize = child_get_pagesize ();

  vm_offset_t mempointer;       /* local copy of inferior's memory */
  mach_msg_type_number_t memcopied;     /* for vm_read to use */

  kern_return_t kret;

  CHECK_FATAL ((memaddr % pagesize) == 0);
  CHECK_FATAL ((len % pagesize) == 0);

  if (!write)
    {
      kret =
        mach_vm_read (task, memaddr, len, &mempointer,
                      &memcopied);
      if (kret != KERN_SUCCESS)
        {
#ifdef DEBUG_MACOSX_MUTILS
          mutils_debug
            ("Unable to read region at 0x%8.8llx with length %lu from inferior: %s (0x%lx)\n",
             (uint64_t) memaddr, (unsigned long) len,
             MACH_ERROR_STRING (kret), kret);
#endif
          return 0;
        }
      if (memcopied != len)
        {
          kret = vm_deallocate (mach_task_self (), mempointer, memcopied);
          if (kret != KERN_SUCCESS)
            {
              warning
                ("Unable to deallocate memory used by failed read from inferior: %s (0x%ux)",
                 MACH_ERROR_STRING (kret), kret);
            }
#ifdef DEBUG_MACOSX_MUTILS
          mutils_debug
            ("Unable to read region at 0x%8.8llx with length %lu from inferior: "
             "vm_read returned %lu bytes instead of %lu\n",
             (uint64_t) memaddr, (unsigned long) len,
             (unsigned long) memcopied, (unsigned long) len);
#endif
          return 0;
        }
      memcpy (myaddr, ((unsigned char *) 0) + mempointer, len);
      kret = vm_deallocate (mach_task_self (), mempointer, memcopied);
      if (kret != KERN_SUCCESS)
        {
          warning
            ("Unable to deallocate memory used by read from inferior: %s (0x%ulx)",
             MACH_ERROR_STRING (kret), kret);
          return 0;
        }
    }
  else
    {
      kret =
        mach_vm_write (task, memaddr, (pointer_t) myaddr, len);
      if (kret != KERN_SUCCESS)
        {
#ifdef DEBUG_MACOSX_MUTILS
          mutils_debug
            ("Unable to write region at 0x%8.8llx with length %lu from inferior: %s (0x%lx)\n",
             (uint64_t) memaddr, (unsigned long) len,
             MACH_ERROR_STRING (kret), kret);
#endif
          return 0;
        }
    }

  return len;
}
Beispiel #5
0
static int
mach_xfer_memory_remainder (CORE_ADDR memaddr, char *myaddr,
                            int len, int write,
                            task_t task)
{
  vm_size_t pagesize = child_get_pagesize ();

  vm_offset_t mempointer;       /* local copy of inferior's memory */
  mach_msg_type_number_t memcopied;     /* for vm_read to use */

  CORE_ADDR pageaddr = memaddr - (memaddr % pagesize);

  kern_return_t kret;

  CHECK_FATAL (((memaddr + len - 1) - ((memaddr + len - 1) % pagesize))
               == pageaddr);

  if (!write)
    {
      kret = mach_vm_read (task, pageaddr, pagesize, &mempointer, &memcopied);
      
      if (kret != KERN_SUCCESS)
	{
#ifdef DEBUG_MACOSX_MUTILS
	  mutils_debug
	    ("Unable to read page for region at 0x%8.8llx with length %lu from inferior: %s (0x%lx)\n",
	     (uint64_t) pageaddr, (unsigned long) len,
	     MACH_ERROR_STRING (kret), kret);
#endif
	  return 0;
	}
      if (memcopied != pagesize)
	{
	  kret = vm_deallocate (mach_task_self (), mempointer, memcopied);
	  if (kret != KERN_SUCCESS)
	    {
	      warning
		("Unable to deallocate memory used by failed read from inferior: %s (0x%lx)",
		 MACH_ERROR_STRING (kret), (unsigned long) kret);
	    }
#ifdef DEBUG_MACOSX_MUTILS
	  mutils_debug
	    ("Unable to read region at 0x%8.8llx with length %lu from inferior: "
	     "vm_read returned %lu bytes instead of %lu\n",
	     (uint64_t) pageaddr, (unsigned long) pagesize,
	     (unsigned long) memcopied, (unsigned long) pagesize);
#endif
	  return 0;
	}
      
      memcpy (myaddr, ((unsigned char *) 0) + mempointer
              + (memaddr - pageaddr), len);
      kret = vm_deallocate (mach_task_self (), mempointer, memcopied);
      if (kret != KERN_SUCCESS)
	{
	  warning
	    ("Unable to deallocate memory used to read from inferior: %s (0x%ulx)",
	     MACH_ERROR_STRING (kret), kret);
	  return 0;
	}
    }
  else
    {
      /* We used to read in a whole page, then modify the page
	 contents, then write that page back out.  I bet we did that
	 so we didn't break up page maps or something like that.
	 However, in Leopard there's a bug in the shared cache
	 implementation, such that if we write into it with whole
	 pages the maximum page protections don't get set properly and
	 we can no longer reset the execute bit.  In 64 bit Leopard
	 apps, the execute bit has to be set or we can't run code from
	 there.

	 If we figure out that not writing whole pages causes problems
	 of it's own, then we will have to revisit this.  */

#if defined (TARGET_POWERPC)
      vm_machine_attribute_val_t flush = MATTR_VAL_CACHE_FLUSH;
      /* This vm_machine_attribute only works on PPC, so no reason
	 to keep failing on x86... */

      kret = vm_machine_attribute (mach_task_self (), mempointer,
                                   pagesize, MATTR_CACHE, &flush);
#ifdef DEBUG_MACOSX_MUTILS
      if (kret != KERN_SUCCESS)
        {
          mutils_debug
            ("Unable to flush GDB's address space after memcpy prior to vm_write: %s (0x%lx)\n",
             MACH_ERROR_STRING (kret), kret);
        }
#endif
#endif
      kret =
        mach_vm_write (task, memaddr, (pointer_t) myaddr, len);
      if (kret != KERN_SUCCESS)
        {
#ifdef DEBUG_MACOSX_MUTILS
          mutils_debug
            ("Unable to write region at 0x%8.8llx with length %lu to inferior: %s (0x%lx)\n",
             (uint64_t) memaddr, (unsigned long) len,
             MACH_ERROR_STRING (kret), kret);
#endif
          return 0;
        }
    }

  return len;
}