def ReadBytes(self, address, num_bytes):
    """Reads at most num_bytes starting from offset <address>."""
    pdata = ctypes.c_void_p(0)
    data_cnt = ctypes.c_uint32(0)

    ret = libc.mach_vm_read(self.task, ctypes.c_ulonglong(address),
                            ctypes.c_longlong(num_bytes), ctypes.pointer(pdata),
                            ctypes.pointer(data_cnt))
    if ret:
      raise process_error.ProcessError("Error in mach_vm_read, ret=%s" % ret)
    buf = ctypes.string_at(pdata.value, data_cnt.value)
    libc.vm_deallocate(self.mytask, pdata, data_cnt)
    return buf