-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy patharchamd64.go
48 lines (38 loc) · 1.07 KB
/
archamd64.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package hinako
import (
"encoding/binary"
"unsafe"
)
type ArchAMD64 struct{}
func (a *ArchAMD64) DisassembleMode() int {
return 64
}
func (a *ArchAMD64) NearJumpSize() uint {
return uint(1 + unsafe.Sizeof(uint32(0)))
}
func (a *ArchAMD64) FarJumpSize() uint {
return 14
}
func (a *ArchAMD64) NewNearJumpAsm(from, to uintptr) []byte {
asm := make([]byte, a.NearJumpSize())
asm[0] = _ASM_OP_NEAR_JMP
*(*int32)(unsafe.Pointer(&asm[1])) = int32(to) - int32(from) - int32(a.NearJumpSize())
return asm
}
func (a *ArchAMD64) NewFarJumpAsm(from, to uintptr) []byte {
asm := make([]byte, a.FarJumpSize())
// 3) This one was found on Nikolay Igotti’s blog.
// http://www.ragestorm.net/blogs/?p=107
asm[0] = _ASM_OP_PUSH
binary.LittleEndian.PutUint32(asm[1:], lowDword(uint64(to)))
binary.LittleEndian.PutUint32(asm[5:], _ASM_OP_MOV_RSP4)
binary.LittleEndian.PutUint32(asm[9:], highDword(uint64(to)))
asm[13] = _ASM_OP_RET
return asm
}
func lowDword(qword uint64) uint32 {
return uint32(qword & 0xffffffff)
}
func highDword(qword uint64) uint32 {
return uint32(qword >> 32)
}