Ejemplo n.º 1
0
// The idea of Dynamic Attach on Windows is to inject a thread into remote JVM
// that calls JVM_EnqueueOperation() function exported by HotSpot DLL
static int inject_thread(int pid, char* pipeName, int argc, char** argv) {
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
    if (hProcess == NULL && GetLastError() == ERROR_ACCESS_DENIED) {
        if (!enable_debug_privileges()) {
            print_error("Not enough privileges", GetLastError());
            return 0;
        }
        hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
    }
    if (hProcess == NULL) {
        print_error("Could not open process", GetLastError());
        return 0;
    }

    LPTHREAD_START_ROUTINE code = allocate_code(hProcess);
    LPVOID data = code != NULL ? allocate_data(hProcess, pipeName, argc, argv) : NULL;
    if (data == NULL) {
        print_error("Could not allocate memory in target process", GetLastError());
        CloseHandle(hProcess);
        return 0;
    }

    int success = 1;
    HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, code, data, 0, NULL);
    if (hThread == NULL) {
        print_error("Could not create remote thread", GetLastError());
        success = 0;
    } else {
        printf("Connected to remote process\n");
        WaitForSingleObject(hThread, INFINITE);
        DWORD exitCode;
        GetExitCodeThread(hThread, &exitCode);
        if (exitCode != 0) {
            print_error("Attach is not supported by the target process", exitCode);
            success = 0;
        }
        CloseHandle(hThread);
    }

    VirtualFreeEx(hProcess, code, 0, MEM_RELEASE);
    VirtualFreeEx(hProcess, data, 0, MEM_RELEASE);
    CloseHandle(hProcess);

    return success;
}
Ejemplo n.º 2
0
/**
 * mono_code_manager_reserve:
 * @cman: a code manager
 * @size: size of memory to allocate
 * @alignment: power of two alignment value
 *
 * Allocates at least @size bytes of memory inside the code manager @cman.
 *
 * Returns: the pointer to the allocated memory or #NULL on failure
 */
void*
mono_code_manager_reserve_align (MonoCodeManager *cman, int size, int alignment)
{
#if !defined(__native_client__) || !defined(__native_client_codegen__)
	CodeChunk *chunk, *prev;
	void *ptr;
	guint32 align_mask = alignment - 1;

	g_assert (!cman->read_only);

	/* eventually allow bigger alignments, but we need to fix the dynamic alloc code to
	 * handle this before
	 */
	g_assert (alignment <= MIN_ALIGN);

	if (cman->dynamic) {
		++dynamic_code_alloc_count;
		dynamic_code_bytes_count += size;
	}

	if (!cman->current) {
		cman->current = new_codechunk (cman->last, cman->dynamic, size);
		if (!cman->current)
			return NULL;
		cman->last = cman->current;
	}

	for (chunk = cman->current; chunk; chunk = chunk->next) {
		if (ALIGN_INT (chunk->pos, alignment) + size <= chunk->size) {
			chunk->pos = ALIGN_INT (chunk->pos, alignment);
			/* Align the chunk->data we add to chunk->pos */
			/* or we can't guarantee proper alignment     */
			ptr = (void*)((((uintptr_t)chunk->data + align_mask) & ~(uintptr_t)align_mask) + chunk->pos);
			chunk->pos = ((char*)ptr - chunk->data) + size;
			return ptr;
		}
	}
	/* 
	 * no room found, move one filled chunk to cman->full 
	 * to keep cman->current from growing too much
	 */
	prev = NULL;
	for (chunk = cman->current; chunk; prev = chunk, chunk = chunk->next) {
		if (chunk->pos + MIN_ALIGN * 4 <= chunk->size)
			continue;
		if (prev) {
			prev->next = chunk->next;
		} else {
			cman->current = chunk->next;
		}
		chunk->next = cman->full;
		cman->full = chunk;
		break;
	}
	chunk = new_codechunk (cman->last, cman->dynamic, size);
	if (!chunk)
		return NULL;
	chunk->next = cman->current;
	cman->current = chunk;
	cman->last = cman->current;
	chunk->pos = ALIGN_INT (chunk->pos, alignment);
	/* Align the chunk->data we add to chunk->pos */
	/* or we can't guarantee proper alignment     */
	ptr = (void*)((((uintptr_t)chunk->data + align_mask) & ~(uintptr_t)align_mask) + chunk->pos);
	chunk->pos = ((char*)ptr - chunk->data) + size;
	return ptr;
#else
	unsigned char *temp_ptr, *code_ptr;
	/* Round up size to next bundle */
	alignment = kNaClBundleSize;
	size = (size + kNaClBundleSize) & (~kNaClBundleMask);
	/* Allocate a temp buffer */
	temp_ptr = memalign (alignment, size);
	g_assert (((uintptr_t)temp_ptr & kNaClBundleMask) == 0);
	/* Allocate code space from the service runtime */
	code_ptr = allocate_code (size);
	/* Insert pointer to code space in hash, keyed by buffer ptr */
	g_hash_table_insert (cman->hash, temp_ptr, code_ptr);

#ifndef USE_JUMP_TABLES
	nacl_jit_check_init ();

	patch_current_depth++;
	patch_source_base[patch_current_depth] = temp_ptr;
	patch_dest_base[patch_current_depth] = code_ptr;
	patch_alloc_size[patch_current_depth] = size;
	g_assert (patch_current_depth < kMaxPatchDepth);
#endif

	return temp_ptr;
#endif
}