Пример #1
0
func DetachNotifyHandler(hwnd uint32) {
	key := uintptr(hwnd)
	if _, exists := notifyHandlers[key]; exists {
		C.HTMLayoutSetCallback(C.HWND(C.HANDLE(key)), nil, nil)
		delete(notifyHandlers, key)
	}
}
Пример #2
0
func RootElement(hwnd uint32) *Element {
	var handle HELEMENT = BAD_HELEMENT
	if ret := C.HTMLayoutGetRootElement(C.HWND(C.HANDLE(uintptr(hwnd))), (*C.HELEMENT)(&handle)); ret != HLDOM_OK {
		domPanic(ret, "Failed to get root element")
	}
	return NewElementFromHandle(handle)
}
Пример #3
0
func (dbp *Process) requestManualStop() error {
	res := C.DebugBreakProcess(C.HANDLE(dbp.os.hProcess))
	if res == C.FALSE {
		return fmt.Errorf("failed to break process %d", dbp.Pid)
	}
	return nil
}
Пример #4
0
// Load html contents into window
func LoadHtml(hwnd uint32, data []byte, baseUrl string) error {
	if len(data) > 0 {
		if ok := C.HTMLayoutLoadHtmlEx(C.HWND(C.HANDLE(uintptr(hwnd))), (*C.BYTE)(&data[0]),
			C.UINT(len(data)), (*C.WCHAR)(stringToUtf16Ptr(baseUrl))); ok == 0 {
			return errors.New("HTMLayoutLoadHtmlEx failed")
		}
	}
	return nil
}
Пример #5
0
// SetPC sets the RIP register to the value specified by `pc`.
func (r *Regs) SetPC(thread *Thread, pc uint64) error {
	var context C.CONTEXT
	context.ContextFlags = C.CONTEXT_ALL

	res := C.GetThreadContext(C.HANDLE(thread.os.hThread), &context)
	if res == C.FALSE {
		return fmt.Errorf("could not GetThreadContext")
	}

	context.Rip = C.DWORD64(pc)

	res = C.SetThreadContext(C.HANDLE(thread.os.hThread), &context)
	if res == C.FALSE {
		return fmt.Errorf("could not SetThreadContext")
	}

	return nil
}
Пример #6
0
func FocusedElement(hwnd uint32) *Element {
	var handle HELEMENT = BAD_HELEMENT
	if ret := C.HTMLayoutGetFocusElement(C.HWND(C.HANDLE(uintptr(hwnd))), (*C.HELEMENT)(&handle)); ret != HLDOM_OK {
		domPanic(ret, "Failed to get focus element")
	}
	if handle != BAD_HELEMENT {
		return NewElementFromHandle(handle)
	}
	return nil
}
Пример #7
0
func DetachWindowEventHandler(hwnd uint32) {
	key := uintptr(hwnd)
	if handler, exists := windowEventHandlers[hwnd]; exists {
		tag := uintptr(unsafe.Pointer(handler))
		if ret := C.HTMLayoutWindowDetachEventHandler(C.HWND(C.HANDLE(key)), (*[0]byte)(unsafe.Pointer(goElementProc)), C.LPVOID(tag)); ret != HLDOM_OK {
			domPanic(ret, "Failed to detach event handler from window")
		}
		delete(windowEventHandlers, hwnd)
	}
}
Пример #8
0
func newHandle(c *Config) (handle syscall.Handle, err error) {
	handle, err = syscall.CreateFile(
		syscall.StringToUTF16Ptr(c.Address),
		syscall.GENERIC_READ|syscall.GENERIC_WRITE,
		0,   // mode
		nil, // security
		syscall.OPEN_EXISTING, // create mode
		0, // attributes
		0) // templates
	if err != nil {
		return
	}
	defer func() {
		if err != nil {
			syscall.CloseHandle(handle)
		}
	}()
	var dcb C.DCB
	dcb.BaudRate = C.DWORD(c.BaudRate)
	// Data bits
	if c.DataBits == 0 {
		dcb.ByteSize = 8
	} else {
		dcb.ByteSize = C.BYTE(c.DataBits)
	}
	// Stop bits
	switch c.StopBits {
	case 0, 1:
		// Default is one stop bit.
		dcb.StopBits = C.ONESTOPBIT
	case 2:
		dcb.StopBits = C.TWOSTOPBITS
	default:
		err = fmt.Errorf("serial: unsupported stop bits %v", c.StopBits)
		return
	}
	// Parity
	switch c.Parity {
	case "", "E":
		// Default parity mode is Even.
		dcb.Parity = C.EVENPARITY
	case "O":
		dcb.Parity = C.ODDPARITY
	case "N":
		dcb.Parity = C.NOPARITY
	default:
		err = fmt.Errorf("serial: unsupported parity %v", c.Parity)
		return
	}
	if C.SetCommState(C.HANDLE(handle), &dcb) == 0 {
		err = fmt.Errorf("serial: could not set device state: %v", syscall.GetLastError())
		return
	}
	return
}
Пример #9
0
func registers(thread *Thread) (Registers, error) {
	var context C.CONTEXT

	context.ContextFlags = C.CONTEXT_ALL
	res := C.GetThreadContext(C.HANDLE(thread.os.hThread), &context)
	if res == C.FALSE {
		return nil, fmt.Errorf("failed to read ThreadContext")
	}

	var threadInfo C.THREAD_BASIC_INFORMATION
	res = C.thread_basic_information(C.HANDLE(thread.os.hThread), &threadInfo)
	if res == C.FALSE {
		return nil, fmt.Errorf("failed to get thread_basic_information")
	}
	tls := uintptr(threadInfo.TebBaseAddress)

	regs := &Regs{
		rax:    uint64(context.Rax),
		rbx:    uint64(context.Rbx),
		rcx:    uint64(context.Rcx),
		rdx:    uint64(context.Rdx),
		rdi:    uint64(context.Rdi),
		rsi:    uint64(context.Rsi),
		rbp:    uint64(context.Rbp),
		rsp:    uint64(context.Rsp),
		r8:     uint64(context.R8),
		r9:     uint64(context.R9),
		r10:    uint64(context.R10),
		r11:    uint64(context.R11),
		r12:    uint64(context.R12),
		r13:    uint64(context.R13),
		r14:    uint64(context.R14),
		r15:    uint64(context.R15),
		rip:    uint64(context.Rip),
		eflags: uint64(context.EFlags),
		cs:     uint64(context.SegCs),
		fs:     uint64(context.SegFs),
		gs:     uint64(context.SegGs),
		tls:    uint64(tls),
	}
	return regs, nil
}
Пример #10
0
func AttachWindowEventHandler(hwnd uint32, handler *EventHandler) {
	key := uintptr(hwnd)
	tag := uintptr(unsafe.Pointer(handler))

	if _, exists := windowEventHandlers[hwnd]; exists {
		if ret := C.HTMLayoutWindowDetachEventHandler(C.HWND(C.HANDLE(key)), (*[0]byte)(unsafe.Pointer(goElementProc)), C.LPVOID(tag)); ret != HLDOM_OK {
			domPanic(ret, "Failed to detach event handler from window before adding the new one")
		}
	}

	// Overwrite if it exists
	windowEventHandlers[hwnd] = handler

	// Don't let the caller disable ATTACH/DETACH events, otherwise we
	// won't know when to throw out our event handler object
	subscription := handler.Subscription()
	subscription &= ^uint32(DISABLE_INITIALIZATION & 0xffffffff)

	if ret := C.HTMLayoutWindowAttachEventHandler(C.HWND(C.HANDLE(key)), (*[0]byte)(unsafe.Pointer(goElementProc)), C.LPVOID(tag), C.UINT(subscription)); ret != HLDOM_OK {
		domPanic(ret, "Failed to attach event handler to window")
	}
}
Пример #11
0
func (t *Thread) writeMemory(addr uintptr, data []byte) (int, error) {
	var (
		vmData = C.LPCVOID(unsafe.Pointer(&data[0]))
		vmAddr = C.LPVOID(addr)
		length = C.SIZE_T(len(data))
		count  C.SIZE_T
	)
	ret := C.WriteProcessMemory(C.HANDLE(t.dbp.os.hProcess), vmAddr, vmData, length, &count)
	if ret == C.FALSE {
		return int(count), fmt.Errorf("could not write memory")
	}
	return int(count), nil
}
Пример #12
0
// Kill kills the process.
func (dbp *Process) Kill() error {
	if dbp.exited {
		return nil
	}
	if !dbp.Threads[dbp.Pid].Stopped() {
		return errors.New("process must be stopped in order to kill it")
	}
	// TODO: Should not have to ignore failures here,
	// but some tests appear to Kill twice causing
	// this to fail on second attempt.
	_ = C.TerminateProcess(C.HANDLE(dbp.os.hProcess), 1)
	dbp.exited = true
	return nil
}
Пример #13
0
func (t *Thread) readMemory(addr uintptr, size int) ([]byte, error) {
	if size == 0 {
		return nil, nil
	}
	var (
		buf    = make([]byte, size)
		vmData = C.LPVOID(unsafe.Pointer(&buf[0]))
		vmAddr = C.LPCVOID(addr)
		length = C.SIZE_T(size)
		count  C.SIZE_T
	)
	ret := C.ReadProcessMemory(C.HANDLE(t.dbp.os.hProcess), vmAddr, vmData, length, &count)
	if ret == C.FALSE {
		return nil, fmt.Errorf("could not read memory")
	}
	return buf, nil
}
Пример #14
0
func registers(thread *Thread) (Registers, error) {
	var context C.CONTEXT

	context.ContextFlags = C.CONTEXT_ALL
	res := C.GetThreadContext(C.HANDLE(thread.os.hThread), &context)
	if res == C.FALSE {
		return nil, fmt.Errorf("failed to read ThreadContext")
	}

	var threadInfo _THREAD_BASIC_INFORMATION
	status := _NtQueryInformationThread(syscall.Handle(thread.os.hThread), _ThreadBasicInformation, uintptr(unsafe.Pointer(&threadInfo)), uint32(unsafe.Sizeof(threadInfo)), nil)
	if !_NT_SUCCESS(status) {
		return nil, fmt.Errorf("failed to get thread_basic_information")
	}

	regs := &Regs{
		rax:    uint64(context.Rax),
		rbx:    uint64(context.Rbx),
		rcx:    uint64(context.Rcx),
		rdx:    uint64(context.Rdx),
		rdi:    uint64(context.Rdi),
		rsi:    uint64(context.Rsi),
		rbp:    uint64(context.Rbp),
		rsp:    uint64(context.Rsp),
		r8:     uint64(context.R8),
		r9:     uint64(context.R9),
		r10:    uint64(context.R10),
		r11:    uint64(context.R11),
		r12:    uint64(context.R12),
		r13:    uint64(context.R13),
		r14:    uint64(context.R14),
		r15:    uint64(context.R15),
		rip:    uint64(context.Rip),
		eflags: uint64(context.EFlags),
		cs:     uint64(context.SegCs),
		fs:     uint64(context.SegFs),
		gs:     uint64(context.SegGs),
		tls:    uint64(threadInfo.TebBaseAddress),
	}
	return regs, nil
}
Пример #15
0
// Open connects to the given serial port.
func (p *port) Open(c *Config) (err error) {
	handle, err := newHandle(c)
	if err != nil {
		return
	}
	// Read and write timeout
	if c.Timeout > 0 {
		timeout := C.DWORD(c.Timeout.Nanoseconds() / 1E6)
		var timeouts C.COMMTIMEOUTS
		// wait until a byte arrived or time out
		timeouts.ReadIntervalTimeout = C.MAXDWORD
		timeouts.ReadTotalTimeoutMultiplier = C.MAXDWORD
		timeouts.ReadTotalTimeoutConstant = timeout
		timeouts.WriteTotalTimeoutMultiplier = 0
		timeouts.WriteTotalTimeoutConstant = timeout
		if C.SetCommTimeouts(C.HANDLE(handle), &timeouts) == 0 {
			err = fmt.Errorf("serial: could not set timeout: %v", syscall.GetLastError())
			syscall.CloseHandle(handle)
			return
		}
	}
	p.handle = handle
	return
}
Пример #16
0
func (dbp *Process) waitForDebugEvent() (threadID, exitCode int, err error) {
	var debugEvent C.DEBUG_EVENT
	for {
		// Wait for a debug event...
		res := C.WaitForDebugEvent(&debugEvent, C.INFINITE)
		if res == C.FALSE {
			return 0, 0, fmt.Errorf("could not WaitForDebugEvent")
		}

		// ... handle each event kind ...
		unionPtr := unsafe.Pointer(&debugEvent.u[0])
		switch debugEvent.dwDebugEventCode {
		case C.CREATE_PROCESS_DEBUG_EVENT:
			debugInfo := (*C.CREATE_PROCESS_DEBUG_INFO)(unionPtr)
			hFile := debugInfo.hFile
			if hFile != C.HANDLE(uintptr(0)) /* NULL */ && hFile != C.HANDLE(uintptr(0xFFFFFFFFFFFFFFFF)) /* INVALID_HANDLE_VALUE */ {
				res = C.CloseHandle(hFile)
				if res == C.FALSE {
					return 0, 0, fmt.Errorf("could not close create process file handle")
				}
			}
			dbp.os.hProcess = sys.Handle(debugInfo.hProcess)
			_, err = dbp.addThread(sys.Handle(debugInfo.hThread), int(debugEvent.dwThreadId), false)
			if err != nil {
				return 0, 0, err
			}
			break
		case C.CREATE_THREAD_DEBUG_EVENT:
			debugInfo := (*C.CREATE_THREAD_DEBUG_INFO)(unionPtr)
			_, err = dbp.addThread(sys.Handle(debugInfo.hThread), int(debugEvent.dwThreadId), false)
			if err != nil {
				return 0, 0, err
			}
			break
		case C.EXIT_THREAD_DEBUG_EVENT:
			delete(dbp.Threads, int(debugEvent.dwThreadId))
			break
		case C.OUTPUT_DEBUG_STRING_EVENT:
			//TODO: Handle debug output strings
			break
		case C.LOAD_DLL_DEBUG_EVENT:
			debugInfo := (*C.LOAD_DLL_DEBUG_INFO)(unionPtr)
			hFile := debugInfo.hFile
			if hFile != C.HANDLE(uintptr(0)) /* NULL */ && hFile != C.HANDLE(uintptr(0xFFFFFFFFFFFFFFFF)) /* INVALID_HANDLE_VALUE */ {
				res = C.CloseHandle(hFile)
				if res == C.FALSE {
					return 0, 0, fmt.Errorf("could not close DLL load file handle")
				}
			}
			break
		case C.UNLOAD_DLL_DEBUG_EVENT:
			break
		case C.RIP_EVENT:
			break
		case C.EXCEPTION_DEBUG_EVENT:
			tid := int(debugEvent.dwThreadId)
			dbp.os.breakThread = tid
			return tid, 0, nil
		case C.EXIT_PROCESS_DEBUG_EVENT:
			debugInfo := (*C.EXIT_PROCESS_DEBUG_INFO)(unionPtr)
			return 0, int(debugInfo.dwExitCode), nil
		default:
			return 0, 0, fmt.Errorf("unknown debug event code: %d", debugEvent.dwDebugEventCode)
		}

		// .. and then continue unless we received an event that indicated we should break into debugger.
		res = C.ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, C.DBG_CONTINUE)
		if res == C.WINBOOL(0) {
			return 0, 0, fmt.Errorf("could not ContinueDebugEvent")
		}
	}
}
Пример #17
0
func (t *Thread) singleStep() error {
	var context C.CONTEXT
	context.ContextFlags = C.CONTEXT_ALL

	// Set the processor TRAP flag
	res := C.GetThreadContext(C.HANDLE(t.os.hThread), &context)
	if res == C.FALSE {
		return fmt.Errorf("could not GetThreadContext")
	}

	context.EFlags |= 0x100

	res = C.SetThreadContext(C.HANDLE(t.os.hThread), &context)
	if res == C.FALSE {
		return fmt.Errorf("could not SetThreadContext")
	}

	// Suspend all threads except this one
	for _, thread := range t.dbp.Threads {
		if thread.ID == t.ID {
			continue
		}
		res := C.SuspendThread(C.HANDLE(thread.os.hThread))
		if res == C.DWORD(0xFFFFFFFF) {
			return fmt.Errorf("could not suspend thread: %d", thread.ID)
		}
	}

	// Continue and wait for the step to complete
	t.dbp.execPtraceFunc(func() {
		res = C.ContinueDebugEvent(C.DWORD(t.dbp.Pid), C.DWORD(t.ID), C.DBG_CONTINUE)
	})
	if res == C.FALSE {
		return fmt.Errorf("could not ContinueDebugEvent.")
	}
	_, err := t.dbp.trapWait(0)
	if err != nil {
		return err
	}

	// Resume all threads except this one
	for _, thread := range t.dbp.Threads {
		if thread.ID == t.ID {
			continue
		}
		res := C.ResumeThread(C.HANDLE(thread.os.hThread))
		if res == C.DWORD(0xFFFFFFFF) {
			return fmt.Errorf("ould not resume thread: %d", thread.ID)
		}
	}

	// Unset the processor TRAP flag
	res = C.GetThreadContext(C.HANDLE(t.os.hThread), &context)
	if res == C.FALSE {
		return fmt.Errorf("could not GetThreadContext")
	}

	context.EFlags &= ^C.DWORD(0x100)

	res = C.SetThreadContext(C.HANDLE(t.os.hThread), &context)
	if res == C.FALSE {
		return fmt.Errorf("could not SetThreadContext")
	}

	return nil
}
Пример #18
0
func main() {
	handle, err := syscall.CreateFile(syscall.StringToUTF16Ptr(port),
		syscall.GENERIC_READ|syscall.GENERIC_WRITE,
		0,   // mode
		nil, // security
		syscall.OPEN_EXISTING, // no creating new
		0,
		0)
	if err != nil {
		fmt.Print(err)
		return
	}
	fmt.Printf("handle created %d\n", handle)
	defer syscall.CloseHandle(handle)

	var dcb C.DCB
	dcb.BaudRate = 9600
	dcb.ByteSize = 8
	dcb.StopBits = C.ONESTOPBIT
	dcb.Parity = C.NOPARITY
	if C.SetCommState(C.HANDLE(handle), &dcb) == 0 {
		fmt.Printf("set comm state error %v\n", syscall.GetLastError())
		return
	}
	fmt.Printf("set comm state succeed\n")

	var timeouts C.COMMTIMEOUTS
	// time-out between charactor for receiving (ms)
	timeouts.ReadIntervalTimeout = 1000
	timeouts.ReadTotalTimeoutMultiplier = 0
	timeouts.ReadTotalTimeoutConstant = 1000
	timeouts.WriteTotalTimeoutMultiplier = 0
	timeouts.WriteTotalTimeoutConstant = 1000
	if C.SetCommTimeouts(C.HANDLE(handle), &timeouts) == 0 {
		fmt.Printf("set comm timeouts error %v\n", syscall.GetLastError())
		return
	}
	fmt.Printf("set comm timeouts succeed\n")

	var n uint32
	data := []byte("abc")
	err = syscall.WriteFile(handle, data, &n, nil)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Printf("write file succeed\n")
	fmt.Printf("Press Enter when ready for reading...")
	reader := bufio.NewReader(os.Stdin)
	_, _ = reader.ReadString('\n')

	data = make([]byte, 512)
	err = syscall.ReadFile(handle, data, &n, nil)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Printf("received data %v:\n", n)
	fmt.Printf("%x\n", data[:n])
	fmt.Printf("closed\n")
}
Пример #19
0
// Main htmlayout wndproc
func ProcNoDefault(hwnd, msg uint32, wparam, lparam uintptr) (uintptr, bool) {
	var handled C.BOOL = 0
	var result C.LRESULT = C.HTMLayoutProcND(C.HWND(C.HANDLE(uintptr(hwnd))), C.UINT(msg),
		C.WPARAM(wparam), C.LPARAM(lparam), &handled)
	return uintptr(result), handled != 0
}
Пример #20
0
// Load resource (file or url) into window
func LoadResource(hwnd uint32, uri string) error {
	if ok := C.HTMLayoutLoadFile(C.HWND(C.HANDLE(uintptr(hwnd))), (*C.WCHAR)(stringToUtf16Ptr(uri))); ok == 0 {
		return errors.New("HTMLayoutLoadFile failed")
	}
	return nil
}
Пример #21
0
func AttachNotifyHandler(hwnd uint32, handler *NotifyHandler) {
	key := uintptr(hwnd)
	// Overwrite if it exists
	notifyHandlers[key] = handler
	C.HTMLayoutSetCallback(C.HWND(C.HANDLE(key)), (*[0]byte)(unsafe.Pointer(goNotifyProc)), C.LPVOID(key))
}
Пример #22
0
// Call this from your NotifyHandler.HandleLoadData method if you want htmlayout to
// process the data right away so you don't have to provide a buffer in the NmhlLoadData structure.
func DataReady(hwnd uint32, uri *uint16, data []byte) bool {
	return C.HTMLayoutDataReady(C.HWND(C.HANDLE(uintptr(hwnd))), (*C.WCHAR)(uri), (*C.BYTE)(&data[0]), C.DWORD(len(data))) != 0
}