飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 1413|回复: 9

[Go] 一个简单的支持模糊搜索patch的代码

[复制链接]
  • TA的每日心情
    开心
    2018-10-30 22:05
  • 签到天数: 6 天

    [LV.2]偶尔看看I

    发表于 2023-8-31 10:45:36 | 显示全部楼层 |阅读模式
    用go的优势就是支持全平台,一套代码我们可以给mac、linux、windows的程序做patch。
    代码核心函数为patch(filename string, originBytes []string, newBytes []string, patchOnce bool),4个参数分别意义为:
    1.filename 为需要patch的文件路径
    2.originBytes 为需要搜索的二进制字符串数组,支持??
    3.newBytes 为对应替换的二进制字符串数据,支持??
    4.patchOnce 为true时表示搜索替换所有结果,为false时只搜索到的第一个结果

    代码比较丑,希望各位大佬们可以优化分享。

    [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
    }
    
    

    评分

    参与人数 9威望 +12 飘云币 +13 收起 理由
    wgz001 + 1 + 1 PYG有你更精彩!
    飞天 + 1 + 1 感谢发布原创作品,PYG有你更精彩!
    dryzh + 2 + 2 先收藏,等以后有目标试试效果
    不破不立 + 2 + 2 感谢发布原创作品,PYG有你更精彩!
    HiPP + 2 + 2 PYG有你更精彩!
    哥又回来了 + 1
    yosen2001 + 2 热心分享 共同提升!
    3yu3 + 1 + 1 PYG有你更精彩!
    风轻云淡 + 2 + 2

    查看全部评分

    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    13 小时前
  • 签到天数: 1538 天

    [LV.Master]伴坛终老

    发表于 2023-8-31 10:49:48 | 显示全部楼层
    加个GUI就完美了
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    6 小时前
  • 签到天数: 528 天

    [LV.9]以坛为家II

    发表于 2023-8-31 11:04:33 | 显示全部楼层
    大佬,求个C#版本。。
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    昨天 11:08
  • 签到天数: 615 天

    [LV.9]以坛为家II

    发表于 2023-8-31 13:28:44 | 显示全部楼层
    @iamok
    但是代码看着很精干,不算很复杂。
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    难过
    6 天前
  • 签到天数: 11 天

    [LV.3]偶尔看看II

    发表于 2023-9-1 00:20:28 | 显示全部楼层
    Go一统江湖  浓浓的GPT味啊

    点评

    哈哈,飘总一眼就看出我这个代码的业余 不过这个还真不是gpt写的, 大概21年初的时候当时网上还是看了很多别人的代码,kmp和sunday这些都看了下 抄了匹配算法部分,支持??是按自己想法改写的,所以实现方式估计  详情 回复 发表于 2023-9-1 09:09
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-10-30 22:05
  • 签到天数: 6 天

    [LV.2]偶尔看看I

     楼主| 发表于 2023-9-1 09:09:58 | 显示全部楼层
    飘云 发表于 2023-9-1 00:20
    Go一统江湖  浓浓的GPT味啊&#128512;

    哈哈,飘总一眼就看出我这个代码的业余

    不过这个还真不是gpt写的,
    大概21年初的时候当时网上还是看了很多别人的代码,kmp和sunday这些都看了下
    抄了匹配算法部分,支持??是按自己想法改写的,所以实现方式估计很丑很业余,也不清楚现有的类似工具是用什么形式处理的。

    点评

    反正比我写得好~ 感谢分享~  详情 回复 发表于 2023-9-1 14:18
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    难过
    6 天前
  • 签到天数: 11 天

    [LV.3]偶尔看看II

    发表于 2023-9-1 14:18:49 | 显示全部楼层
    iamok 发表于 2023-9-1 09:09
    哈哈,飘总一眼就看出我这个代码的业余

    不过这个还真不是gpt写的,

    反正比我写得好~ 感谢分享~
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2016-1-13 12:25
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2023-9-1 16:48:55 | 显示全部楼层
    本帖最后由 small-q 于 2023-9-1 16:52 编辑

    谢谢大佬分享,收藏学习
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    3 小时前
  • 签到天数: 1407 天

    [LV.10]以坛为家III

    发表于 2023-9-1 21:20:17 | 显示全部楼层
    感谢分享好东西。
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表