Example #1
0
func (u *uc) HookAdd(htype int, cb interface{}, extra ...uint64) (Hook, error) {
	var callback unsafe.Pointer
	var iarg1 C.int
	var uarg1, uarg2 C.uint64_t
	rangeMode := false
	switch htype {
	case HOOK_BLOCK, HOOK_CODE:
		rangeMode = true
		callback = C.hookCode_cgo
	case HOOK_MEM_READ, HOOK_MEM_WRITE, HOOK_MEM_READ | HOOK_MEM_WRITE:
		rangeMode = true
		callback = C.hookMemAccess_cgo
	case HOOK_INTR:
		callback = C.hookInterrupt_cgo
	case HOOK_INSN:
		iarg1 = C.int(extra[0])
		switch iarg1 {
		case X86_INS_IN:
			callback = C.hookX86In_cgo
		case X86_INS_OUT:
			callback = C.hookX86Out_cgo
		case X86_INS_SYSCALL, X86_INS_SYSENTER:
			callback = C.hookX86Syscall_cgo
		default:
			return 0, errors.New("Unknown instruction type.")
		}
	default:
		// special case for mask
		if htype&(HOOK_MEM_READ_UNMAPPED|HOOK_MEM_WRITE_UNMAPPED|HOOK_MEM_FETCH_UNMAPPED|
			HOOK_MEM_READ_PROT|HOOK_MEM_WRITE_PROT|HOOK_MEM_FETCH_PROT) != 0 {
			rangeMode = true
			callback = C.hookMemInvalid_cgo
		} else {
			return 0, errors.New("Unknown hook type.")
		}
	}
	var h2 C.uc_hook
	data := &HookData{u, cb}
	uptr := uintptr(unsafe.Pointer(data))
	if rangeMode {
		if len(extra) == 2 {
			uarg1 = C.uint64_t(extra[0])
			uarg2 = C.uint64_t(extra[1])
		} else {
			uarg1, uarg2 = 1, 0
		}
		C.uc_hook_add_u2(u.handle, &h2, C.uc_hook_type(htype), callback, C.uintptr_t(uptr), uarg1, uarg2)
	} else {
		C.uc_hook_add_i1(u.handle, &h2, C.uc_hook_type(htype), callback, C.uintptr_t(uptr), iarg1)
	}
	hookDataMap[uptr] = data
	hookToUintptr[Hook(h2)] = uptr
	return Hook(h2), nil
}
Example #2
0
File: hook.go Project: 4577/unicorn
func (u *uc) HookAdd(htype int, cb interface{}, begin, end uint64, extra ...int) (Hook, error) {
	var callback unsafe.Pointer
	var insn C.int
	var insnMode bool
	switch htype {
	case HOOK_BLOCK, HOOK_CODE:
		callback = C.hookCode_cgo
	case HOOK_MEM_READ, HOOK_MEM_WRITE, HOOK_MEM_READ | HOOK_MEM_WRITE:
		callback = C.hookMemAccess_cgo
	case HOOK_INTR:
		callback = C.hookInterrupt_cgo
	case HOOK_INSN:
		insn = C.int(extra[0])
		insnMode = true
		switch insn {
		case X86_INS_IN:
			callback = C.hookX86In_cgo
		case X86_INS_OUT:
			callback = C.hookX86Out_cgo
		case X86_INS_SYSCALL, X86_INS_SYSENTER:
			callback = C.hookX86Syscall_cgo
		default:
			return 0, errors.New("Unknown instruction type.")
		}
	default:
		// special case for mask
		if htype&(HOOK_MEM_READ_UNMAPPED|HOOK_MEM_WRITE_UNMAPPED|HOOK_MEM_FETCH_UNMAPPED|
			HOOK_MEM_READ_PROT|HOOK_MEM_WRITE_PROT|HOOK_MEM_FETCH_PROT) != 0 {
			callback = C.hookMemInvalid_cgo
		} else {
			return 0, errors.New("Unknown hook type.")
		}
	}
	var h2 C.uc_hook
	data := &HookData{u, cb}
	uptr := uintptr(unsafe.Pointer(data))
	if insnMode {
		C.uc_hook_add_insn(u.handle, &h2, C.uc_hook_type(htype), callback, C.uintptr_t(uptr), C.uint64_t(begin), C.uint64_t(end), insn)
	} else {
		C.uc_hook_add_wrap(u.handle, &h2, C.uc_hook_type(htype), callback, C.uintptr_t(uptr), C.uint64_t(begin), C.uint64_t(end))
	}
	hookDataLock.Lock()
	hookDataMap[uptr] = data
	hookDataLock.Unlock()
	u.hooks[Hook(h2)] = uptr
	return Hook(h2), nil
}