github.com/tencent/goom@v1.0.1/internal/patch/guard.go (about) 1 // Package patch 生成指令跳转(到代理函数)并替换.text 区内存 2 package patch 3 4 import ( 5 "fmt" 6 7 "github.com/tencent/goom/internal/bytecode" 8 "github.com/tencent/goom/internal/bytecode/memory" 9 "github.com/tencent/goom/internal/logger" 10 ) 11 12 // Guard 代理执行控制句柄, 可通过此对象进行代理还原 13 type Guard struct { 14 origin uintptr // 被 patch 的函数 15 originBytes []byte // 原始字节码 16 jumpBytes []byte // 跳转指令字节 17 fixOriginPtr uintptr // 修复的函数指针 18 applied bool // 是否已经被应用 19 } 20 21 // Apply 执行 22 func (g *Guard) Apply() { 23 lock() 24 defer unlock() 25 26 g.applied = true 27 // 执行函数调用地址替换(延迟执行) 28 if err := memory.WriteTo(g.origin, g.jumpBytes); err != nil { 29 logger.Errorf("Apply to 0x%x error: %s", g.origin, err) 30 } 31 bytecode.PrintInst(fmt.Sprintf("apply copy to 0x%x", g.origin), g.origin, 30, logger.DebugLevel) 32 } 33 34 // Unpatch 取消代理,还原指令码 35 // 外部调用请使用 PatchGuard.UnpatchWithLock() 36 func (g *Guard) Unpatch() { 37 if g != nil && g.applied { 38 if err := memory.WriteTo(g.origin, g.originBytes); err != nil { 39 logger.Errorf("Unpatch to 0x%x error: %s", g.origin, err) 40 } 41 bytecode.PrintInst(fmt.Sprintf("unpatch copy to 0x%x", g.origin), g.origin, 20, logger.DebugLevel) 42 } 43 } 44 45 // UnpatchWithLock 外部调用需要加锁 46 func (g *Guard) UnpatchWithLock() { 47 lock() 48 defer unlock() 49 g.Unpatch() 50 } 51 52 // Restore 重新应用代理 53 func (g *Guard) Restore() { 54 lock() 55 defer unlock() 56 if g != nil && g.applied { 57 if err := memory.WriteTo(g.origin, g.jumpBytes); err != nil { 58 logger.Errorf("Restore to 0x%x error: %s", g.origin, err) 59 } 60 bytecode.PrintInst(fmt.Sprintf("unpatch copy to 0x%x", g.origin), g.origin, 20, logger.DebugLevel) 61 } 62 } 63 64 // FixOriginFunc 获取应用代理后的原函数地址(和代理前的原函数地址不一样) 65 func (g *Guard) FixOriginFunc() uintptr { 66 return g.fixOriginPtr 67 }