[Golang] 纯文本查看 复制代码
package main
import (
	"encoding/hex"
	"fmt"
	"os"
	"strings"
)
func main() {
	exe := "test.exe"
	exeOriginBytes := []string{"8B 7B 08 8B 73 10 8B C7 83 E8 01"}
	exeNewbytes := []string{"FF 43 08 FF 43 10 B0 01 33 C0 90"}
	dll := "test.dll"
	dllOriginBytes := []string{"7F ?? 7C ?? 39 75 F4 77 ?? 39 45 FC 7F ?? 7C ?? 3B F1 77 ?? 80 7D 08 00 75 ?? 8B 37"}
	dllNewBytes := []string{"7F 00 7C 00 39 75 F4 77 00 39 45 FC 7F 00 7C 00 3B F1 77 00 80 7D 08 00 EB ?? 8B 37"}
	patch(exe, exeOriginBytes, exeNewbytes, false)
	patch(dll, dllOriginBytes, dllNewBytes, false)
}
func patch(filename string, originBytes []string, newBytes []string, patchOnce bool) {
	origin, err := os.ReadFile(filename)
	if err != nil {
		fmt.Println("patch失败,未找到指定文件: " + filename)
		return
	}
	patchlist := make(map[int][]byte)
	for i := range originBytes {
		oldstr, keys := str2bytes(originBytes[i])
		patchstr, patchkeys := str2bytes(newBytes[i])
		patchlens := len(patchstr)
		locs := fuzzsearch(origin, oldstr, keys, patchOnce)
		if len(locs) > 0 {
			for i, v := range locs {
				fmt.Printf("找到patch点: %d\n", i+1)
				tmpstr := origin[v : v+patchlens]
				tmpdata := fuzzreplace(tmpstr, patchstr, patchkeys)
				patchlist[v] = tmpdata
			}
		} else {
			fmt.Printf("未找到patch点: %d\n", i+1)
			return
		}
	}
	newFile := replace(origin, patchlist)
	err = os.WriteFile(filename, newFile, os.ModePerm)
	if err == nil {
		fmt.Println(filename + " Patch成功")
	} else {
		fmt.Println(filename + " Patch失败")
	}
}
func fuzzsearch(src []byte, hexsub []byte, fuzzkeys []int, patchonce bool) []int {
	offsets := []int{}
	dwsublen := len(hexsub)
	dwsrclen := len(src)
	p := make([]int, 256)
	for i := 0; i < 256; i++ {
		p[i] = -1
	}
	wildaddr := 0
	if len(fuzzkeys) > 0 {
		wildaddr = fuzzkeys[len(fuzzkeys)-1]
	}
	for i := wildaddr + 1; i < dwsublen; i++ {
		p[hexsub[i]] = dwsublen - i
	}
	for i := 0; i < 256; i++ {
		if p[i] == -1 {
			p[i] = dwsublen - wildaddr
		}
	}
	j, k := 0, 0
	j = dwsublen - 1
	found := true
	for {
		found = true
		for k = 0; k < dwsublen; k++ {
			if !isfound(fuzzkeys, dwsublen-k-1) && src[j-k] != hexsub[dwsublen-k-1] {
				found = false
				break
			}
		}
		if found {
			if j < dwsrclen {
				offsets = append(offsets, j-dwsublen+1)
				if patchonce {
					break
				}
			}
		}
		if j < dwsrclen-dwsublen-1 {
			j += p[src[j+1]]
		} else {
			j++
		}
		if j > dwsrclen-dwsublen {
			break
		}
	}
	return offsets
}
func isfound(source []int, ptr int) bool {
	for _, i := range source {
		if i == ptr {
			return true
		}
	}
	return false
}
func fuzzreplace(oldstr []byte, patchstr []byte, patchkeys []int) []byte {
	tmplist := make([]byte, len(patchstr))
	copy(tmplist, patchstr)
	for i := range tmplist {
		if isfound(patchkeys, i) {
			tmplist[i] = oldstr[i]
		}
	}
	return tmplist
}
func replace(origin []byte, patchlist map[int][]byte) []byte {
	tmpdata := origin
	for index, new := range patchlist {
		copy(tmpdata[index:index+len(new)], new)
	}
	return tmpdata
}
func str2bytes(binstr string) ([]byte, []int) {
	var fuzzkeys []int
	tmpstr := strings.Replace(binstr, " ", "", -1)
	hexlens := len(tmpstr) / 2
	for i := 0; i < hexlens; i++ {
		tmphex := tmpstr[i*2 : i*2+2]
		if tmphex == "??" {
			fuzzkeys = append(fuzzkeys, i)
		}
	}
	tmpstr = strings.Replace(tmpstr, "??", "00", -1)
	binlist, _ := hex.DecodeString(tmpstr)
	return binlist, fuzzkeys
}