brahma-adshonor / gohook

a funny library to hook golang function at runtime

Home Page:https://www.cnblogs.com/catch/p/10973611.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Bug lead to instruction lost

sud0why opened this issue · comments

commented

Test code:

package main

import (
	"fmt"
	"net/http"
	"net/url"

	"github.com/brahma-adshonor/gohook"
)

func main() {
	http.HandleFunc("/urlHeaderCookie", URLHeaderCookie)
	http.ListenAndServe("0.0.0.0:8001", nil)
}

func URLHeaderCookie(w http.ResponseWriter, request *http.Request) {
	url := request.URL
	values := url.Query()
	_, _ = fmt.Fprintf(w, "You url is: %s\n", url)
	value := values.Get("id")
	_, _ = fmt.Fprintf(w, "You id is: %s\n", value)
}

func init() {
	var u *url.URL
	err := gohook.HookMethod(u, "Query", Query, QueryT)
	if err != nil {
		fmt.Printf("%s", err.Error())
	}
}

func Query(URL *url.URL) url.Values {

	values := QueryT(URL)

	return values
}

func QueryT(URL *url.URL) url.Values {
	return url.Values{}
}

Test on linux x64 Kernel Version 5.4.119, Go 1.19.4
Trigger this bug, can use: while true; do curl --connect-timeout 1 -X GET --location "http://127.0.0.1:8001/urlHeaderCookie?id=1" ;done

The Origin Disassamble Code is:
image

After Hook Disassamble Code is:
image

The instruction at 0x5c8f3d was be lost. It's lead to crash.

I think this bug is about "break" in function doFixTargetFuncCode, and "FuncEnd" in function adjustJmpOffset.

Thanks.

sorry for missing this, I will take a look at it.

It seems that I can't reproduce it, also wondering how you compile and run the code(also you should probably put a directive //go:noinline before QueryT() to disable inlining since this function is short and simple it may get inlined).

as for the disassembly you mentioned, after being hooked, the original instructions from the bottom part of the url.(*URL).Query is moved upward, leaving a few bytes unchanged(from 0x5c8f2e ~ 0x5c8f3d).

in a normal execution flow, it should never run to 0x5c8f3d, also notes that the origin url.(*URL).Query() ends at 0x5c8f2d, remaining byte codes are for other functions following.