Skip to content

Commit 608c12d

Browse files
authored
Code style and refactoring changes (#7)
* Code style and refactoring changes * fmt changes * add go1.10 in the test suite * adding go1.9 in the test matrix * adding go1.8 in the test matrix * test matrix changes * adding go1.7 in the test matrix * try to add macos to the test matrix * go1.6 in test matrix * remove go1.6 from the test matrix due an error in go get for macos
1 parent bfd2e1d commit 608c12d

File tree

8 files changed

+66
-37
lines changed

8 files changed

+66
-37
lines changed

.github/workflows/go.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ jobs:
55
name: Test
66
strategy:
77
matrix:
8-
go_version: [1.11, 1.12, 1.13, 1.14]
9-
os: [ubuntu-latest, windows-latest]
8+
go_version: [1.7, 1.8, 1.9, "1.10", 1.11, 1.12, 1.13, 1.14, 1.15]
9+
os: [ubuntu-latest, windows-latest, macos-latest]
1010
runs-on: ${{ matrix.os }}
1111
steps:
1212
- name: Set up Go ${{ matrix.go_version }}

patcher.go

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,11 @@ var (
3434
func PatchMethod(target, redirection interface{}) (*Patch, error) {
3535
tValue := getValueFrom(target)
3636
rValue := getValueFrom(redirection)
37-
err := isPatchable(&tValue, &rValue)
38-
if err != nil {
37+
if err := isPatchable(&tValue, &rValue); err != nil {
3938
return nil, err
4039
}
4140
patch := &Patch{target: &tValue, redirection: &rValue}
42-
err = applyPatch(patch)
43-
if err != nil {
41+
if err := applyPatch(patch); err != nil {
4442
return nil, err
4543
}
4644
return patch, nil
@@ -54,37 +52,32 @@ func PatchInstanceMethodByName(target reflect.Type, methodName string, redirecti
5452
if !ok {
5553
return nil, errors.New(fmt.Sprintf("Method '%v' not found", methodName))
5654
}
57-
return PatchMethodByReflect(method, redirection)
55+
return PatchMethodByReflect(method.Func, redirection)
5856
}
59-
func PatchMethodByReflect(target reflect.Method, redirection interface{}) (*Patch, error) {
60-
tValue := &target.Func
57+
func PatchMethodByReflect(target reflect.Value, redirection interface{}) (*Patch, error) {
58+
tValue := &target
6159
rValue := getValueFrom(redirection)
62-
err := isPatchable(tValue, &rValue)
63-
if err != nil {
60+
if err := isPatchable(tValue, &rValue); err != nil {
6461
return nil, err
6562
}
6663
patch := &Patch{target: tValue, redirection: &rValue}
67-
err = applyPatch(patch)
68-
if err != nil {
64+
if err := applyPatch(patch); err != nil {
6965
return nil, err
7066
}
7167
return patch, nil
7268
}
73-
func PatchMethodWithMakeFunc(target reflect.Method, fn func(args []reflect.Value) (results []reflect.Value)) (*Patch, error) {
74-
rValue := reflect.MakeFunc(target.Type, fn)
75-
return PatchMethodByReflect(target, rValue)
69+
func PatchMethodWithMakeFunc(target reflect.Value, fn func(args []reflect.Value) (results []reflect.Value)) (*Patch, error) {
70+
return PatchMethodByReflect(target, reflect.MakeFunc(target.Type(), fn))
7671
}
7772

7873
func (p *Patch) Patch() error {
7974
if p == nil {
8075
return errors.New("patch is nil")
8176
}
82-
err := isPatchable(p.target, p.redirection)
83-
if err != nil {
77+
if err := isPatchable(p.target, p.redirection); err != nil {
8478
return err
8579
}
86-
err = applyPatch(p)
87-
if err != nil {
80+
if err := applyPatch(p); err != nil {
8881
return err
8982
}
9083
return nil
@@ -103,7 +96,7 @@ func isPatchable(target, redirection *reflect.Value) error {
10396
if target.Type() != redirection.Type() {
10497
return errors.New(fmt.Sprintf("the target and/or redirection doesn't have the same type: %s != %s", target.Type(), redirection.Type()))
10598
}
106-
if _, ok := patches[getSafePointer(target)]; ok {
99+
if _, ok := patches[getSafeCodePointer(target)]; ok {
107100
return errors.New("the target is already patched")
108101
}
109102
return nil
@@ -112,7 +105,7 @@ func isPatchable(target, redirection *reflect.Value) error {
112105
func applyPatch(patch *Patch) error {
113106
patchLock.Lock()
114107
defer patchLock.Unlock()
115-
tPointer := getSafePointer(patch.target)
108+
tPointer := getSafeCodePointer(patch.target)
116109
rPointer := getInternalPtrFromValue(patch.redirection)
117110
rPointerJumpBytes, err := getJumpFuncBytes(rPointer)
118111
if err != nil {
@@ -121,8 +114,7 @@ func applyPatch(patch *Patch) error {
121114
tPointerBytes := getMemorySliceFromPointer(tPointer, len(rPointerJumpBytes))
122115
targetBytes := make([]byte, len(tPointerBytes))
123116
copy(targetBytes, tPointerBytes)
124-
err = copyDataToPtr(tPointer, rPointerJumpBytes)
125-
if err != nil {
117+
if err := copyDataToPtr(tPointer, rPointerJumpBytes); err != nil {
126118
return err
127119
}
128120
patch.targetBytes = targetBytes
@@ -136,7 +128,7 @@ func applyUnpatch(patch *Patch) error {
136128
if patch.targetBytes == nil || len(patch.targetBytes) == 0 {
137129
return errors.New("the target is not patched")
138130
}
139-
tPointer := getSafePointer(patch.target)
131+
tPointer := getSafeCodePointer(patch.target)
140132
if _, ok := patches[tPointer]; !ok {
141133
return errors.New("the target is not patched")
142134
}
@@ -164,7 +156,7 @@ func getMemorySliceFromPointer(p unsafe.Pointer, length int) []byte {
164156
}))
165157
}
166158

167-
func getSafePointer(value *reflect.Value) unsafe.Pointer {
159+
func getSafeCodePointer(value *reflect.Value) unsafe.Pointer {
168160
p := getInternalPtrFromValue(value)
169161
if p != nil {
170162
p = *(*unsafe.Pointer)(p)

patcher_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,44 @@ func TestPatcher(t *testing.T) {
4444
}
4545
}
4646

47+
func TestPatcherUsingReflect(t *testing.T) {
48+
patch, err := PatchMethodByReflect(reflect.ValueOf(methodA), methodB)
49+
if err != nil {
50+
t.Fatal(err)
51+
}
52+
if methodA() != 2 {
53+
t.Fatal("The patch did not work")
54+
}
55+
56+
err = patch.Unpatch()
57+
if err != nil {
58+
t.Fatal(err)
59+
}
60+
if methodA() != 1 {
61+
t.Fatal("The unpatch did not work")
62+
}
63+
}
64+
65+
func TestPatcherUsingMakeFunc(t *testing.T) {
66+
patch, err := PatchMethodWithMakeFunc(reflect.ValueOf(methodA), func(args []reflect.Value) (results []reflect.Value) {
67+
return []reflect.Value{reflect.ValueOf(42)}
68+
})
69+
if err != nil {
70+
t.Fatal(err)
71+
}
72+
if methodA() != 42 {
73+
t.Fatal("The patch did not work")
74+
}
75+
76+
err = patch.Unpatch()
77+
if err != nil {
78+
t.Fatal(err)
79+
}
80+
if methodA() != 1 {
81+
t.Fatal("The unpatch did not work")
82+
}
83+
}
84+
4785
func TestInstancePatcher(t *testing.T) {
4886
mStruct := myStruct{}
4987

patcher_unix.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ func getMemorySliceFromUintptr(p uintptr, length int) []byte {
2424
func callMProtect(addr unsafe.Pointer, length int, prot int) error {
2525
for p := uintptr(addr) & ^(uintptr(pageSize - 1)); p < uintptr(addr)+uintptr(length); p += uintptr(pageSize) {
2626
page := getMemorySliceFromUintptr(p, pageSize)
27-
err := syscall.Mprotect(page, prot)
28-
if err != nil {
27+
if err := syscall.Mprotect(page, prot); err != nil {
2928
return err
3029
}
3130
}
@@ -35,13 +34,11 @@ func callMProtect(addr unsafe.Pointer, length int, prot int) error {
3534
func copyDataToPtr(ptr unsafe.Pointer, data []byte) error {
3635
dataLength := len(data)
3736
ptrByteSlice := getMemorySliceFromPointer(ptr, len(data))
38-
err := callMProtect(ptr, dataLength, writeAccess)
39-
if err != nil {
37+
if err := callMProtect(ptr, dataLength, writeAccess); err != nil {
4038
return err
4139
}
4240
copy(ptrByteSlice, data[:])
43-
err = callMProtect(ptr, dataLength, readAccess)
44-
if err != nil {
41+
if err := callMProtect(ptr, dataLength, readAccess); err != nil {
4542
return err
4643
}
4744
return nil

patcher_unsupported.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ import (
1313
// Gets the jump function rewrite bytes
1414
//go:nosplit
1515
func getJumpFuncBytes(to unsafe.Pointer) ([]byte, error) {
16-
return nil, errors.New(fmt.Sprintf("Unsupported architecture: %s", runtime.GOARCH))
16+
return nil, errors.New(fmt.Sprintf("unsupported architecture: %s", runtime.GOARCH))
1717
}

patcher_windows.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,11 @@ func copyDataToPtr(ptr unsafe.Pointer, data []byte) error {
2323
var oldPerms, tmp uint32
2424
dataLength := len(data)
2525
ptrByteSlice := getMemorySliceFromPointer(ptr, len(data))
26-
err := callVirtualProtect(ptr, dataLength, pageExecuteReadAndWrite, unsafe.Pointer(&oldPerms))
27-
if err != nil {
26+
if err := callVirtualProtect(ptr, dataLength, pageExecuteReadAndWrite, unsafe.Pointer(&oldPerms)); err != nil {
2827
return err
2928
}
3029
copy(ptrByteSlice, data[:])
31-
err = callVirtualProtect(ptr, dataLength, oldPerms, unsafe.Pointer(&tmp))
32-
if err != nil {
30+
if err := callVirtualProtect(ptr, dataLength, oldPerms, unsafe.Pointer(&tmp)); err != nil {
3331
return err
3432
}
3533
return nil

patcher_x32.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ package mpatch
44

55
import "unsafe"
66

7+
const jumpLength = 7
8+
79
// Gets the jump function rewrite bytes
810
//go:nosplit
911
func getJumpFuncBytes(to unsafe.Pointer) ([]byte, error) {

patcher_x64.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ package mpatch
44

55
import "unsafe"
66

7+
const jumpLength = 12
8+
79
// Gets the jump function rewrite bytes
810
//go:nosplit
911
func getJumpFuncBytes(to unsafe.Pointer) ([]byte, error) {

0 commit comments

Comments
 (0)