|
@@ -26,6 +26,8 @@ import (
|
|
|
const (
|
|
const (
|
|
|
IO_FD_FDID_SYM_OFFSET = 129
|
|
IO_FD_FDID_SYM_OFFSET = 129
|
|
|
NET_SEND_SYM_OFFSET = 518
|
|
NET_SEND_SYM_OFFSET = 518
|
|
|
|
|
+ // 备份指令长度
|
|
|
|
|
+ ORIGIN_CODE_LEN = 12
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
type InstInfo struct {
|
|
type InstInfo struct {
|
|
@@ -46,6 +48,7 @@ type InnerSymbolInfo struct {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func (j *JvmInjector) findReleaseAddressInfoFromMem() error {
|
|
func (j *JvmInjector) findReleaseAddressInfoFromMem() error {
|
|
|
|
|
+ klog.Infof("findReleaseAddressInfoFromMem start.")
|
|
|
funcAbsAddress := j.ReleaseLibNetInfo.FuncSymbol.SymAddr
|
|
funcAbsAddress := j.ReleaseLibNetInfo.FuncSymbol.SymAddr
|
|
|
releaseFuncSym := InnerSymbolInfo{}
|
|
releaseFuncSym := InnerSymbolInfo{}
|
|
|
code, err := j.readMemory(funcAbsAddress, j.ReleaseLibNetInfo.FuncSymbol.SymSize)
|
|
code, err := j.readMemory(funcAbsAddress, j.ReleaseLibNetInfo.FuncSymbol.SymSize)
|
|
@@ -59,7 +62,7 @@ func (j *JvmInjector) findReleaseAddressInfoFromMem() error {
|
|
|
|
|
|
|
|
inst, err := x86asm.Decode(code[pc:], 64)
|
|
inst, err := x86asm.Decode(code[pc:], 64)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- fmt.Printf("Decode error at offset 0x%x: %v\n", pc, err)
|
|
|
|
|
|
|
+ klog.Errorf("Decode error at offset 0x%x: %v\n", pc, err)
|
|
|
pc++ // Skip this byte and try to decode again
|
|
pc++ // Skip this byte and try to decode again
|
|
|
continue
|
|
continue
|
|
|
}
|
|
}
|
|
@@ -125,8 +128,7 @@ func (j *JvmInjector) findReleaseAddressInfoFromMem() error {
|
|
|
releaseFuncSym.IO_fd_fdID = preContext
|
|
releaseFuncSym.IO_fd_fdID = preContext
|
|
|
releaseFuncSym.IO_fd_fdID.SymName = "<IO_fd_fdID>(Release)"
|
|
releaseFuncSym.IO_fd_fdID.SymName = "<IO_fd_fdID>(Release)"
|
|
|
preInst := preContext.Inst
|
|
preInst := preContext.Inst
|
|
|
- fmt.Println(preInst.Op)
|
|
|
|
|
- fmt.Println((preInst.Args))
|
|
|
|
|
|
|
+ klog.Infof("[findReleaseAddressInfoFromMem] preInst %v\n]", preInst)
|
|
|
// 计算目标地址
|
|
// 计算目标地址
|
|
|
if preInst.Op == x86asm.MOV &&
|
|
if preInst.Op == x86asm.MOV &&
|
|
|
len(preInst.Args) == 4 &&
|
|
len(preInst.Args) == 4 &&
|
|
@@ -136,31 +138,29 @@ func (j *JvmInjector) findReleaseAddressInfoFromMem() error {
|
|
|
if mem, ok := preInst.Args[1].(x86asm.Mem); ok && mem.Base == x86asm.RIP {
|
|
if mem, ok := preInst.Args[1].(x86asm.Mem); ok && mem.Base == x86asm.RIP {
|
|
|
relOffset := mem.Disp // 直接从Mem结构体中读取偏移
|
|
relOffset := mem.Disp // 直接从Mem结构体中读取偏移
|
|
|
targetAddress := preContext.SymAddr + uint64(preInst.Len) + uint64(relOffset)
|
|
targetAddress := preContext.SymAddr + uint64(preInst.Len) + uint64(relOffset)
|
|
|
- fmt.Printf("Target address: 0x%x\n", targetAddress)
|
|
|
|
|
|
|
+ klog.Infof("[findReleaseAddressInfoFromMem] target address 0x%x\n", targetAddress)
|
|
|
releaseFuncSym.IO_fd_fdID.TargetAddr = targetAddress
|
|
releaseFuncSym.IO_fd_fdID.TargetAddr = targetAddress
|
|
|
} else {
|
|
} else {
|
|
|
return fmt.Errorf("The instruction does not use RIP-relative addressing.")
|
|
return fmt.Errorf("The instruction does not use RIP-relative addressing.")
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- return fmt.Errorf("The decoded instruction is not a MOV to RDX.")
|
|
|
|
|
|
|
+ return fmt.Errorf("[findReleaseAddressInfoFromMem] The decoded instruction is not a MOV to RDX.")
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- //os.Exit(1)
|
|
|
|
|
}
|
|
}
|
|
|
callCount++
|
|
callCount++
|
|
|
if callCount == 4 {
|
|
if callCount == 4 {
|
|
|
releaseFuncSym.NET_Send = currentData
|
|
releaseFuncSym.NET_Send = currentData
|
|
|
- fmt.Printf("4 call Decoded instuction at 0x%x: %v\n", funcAbsAddress+pc, inst)
|
|
|
|
|
-
|
|
|
|
|
|
|
+ klog.Infof("4 call Decoded instuction at 0x%x: %v\n", funcAbsAddress+pc, inst)
|
|
|
relOffset, ok := inst.Args[0].(x86asm.Rel)
|
|
relOffset, ok := inst.Args[0].(x86asm.Rel)
|
|
|
if !ok {
|
|
if !ok {
|
|
|
return fmt.Errorf("The instruction does not use RIP-relative addressing.")
|
|
return fmt.Errorf("The instruction does not use RIP-relative addressing.")
|
|
|
}
|
|
}
|
|
|
targetAddress := currentData.SymAddr + uint64(inst.Len) + uint64(relOffset)
|
|
targetAddress := currentData.SymAddr + uint64(inst.Len) + uint64(relOffset)
|
|
|
releaseFuncSym.NET_Send.TargetAddr = targetAddress
|
|
releaseFuncSym.NET_Send.TargetAddr = targetAddress
|
|
|
- fmt.Println(releaseFuncSym.NET_Send)
|
|
|
|
|
|
|
+ klog.Infof("[findReleaseAddressInfoFromMem] target address 0x%x\n", releaseFuncSym.NET_Send)
|
|
|
releaseFuncSym.NET_Send.SymName = "<NET_Send>(Release)"
|
|
releaseFuncSym.NET_Send.SymName = "<NET_Send>(Release)"
|
|
|
- fmt.Printf("Target address: 0x%x\n", targetAddress)
|
|
|
|
|
|
|
+ klog.Infof("[findReleaseAddressInfoFromMem] target address 0x%x\n", targetAddress)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
preContext = InstInfo{
|
|
preContext = InstInfo{
|
|
@@ -171,11 +171,12 @@ func (j *JvmInjector) findReleaseAddressInfoFromMem() error {
|
|
|
pc += uint64(inst.Len)
|
|
pc += uint64(inst.Len)
|
|
|
}
|
|
}
|
|
|
j.ReleaseLibNetInfo.InnerSymbol = releaseFuncSym
|
|
j.ReleaseLibNetInfo.InnerSymbol = releaseFuncSym
|
|
|
- j.ReleaseLibNetInfo.FuncSymbol.OriginCode = code[0:12]
|
|
|
|
|
|
|
+ j.ReleaseLibNetInfo.FuncSymbol.OriginCode = code[0:ORIGIN_CODE_LEN]
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
|
|
func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
|
|
|
|
|
+ klog.Infof("[findDebugAddressInfoFromMem] Looking for debug address info from Mem")
|
|
|
funcAbsAddress := j.DebugLibNetInfo.FuncSymbol.SymAddr
|
|
funcAbsAddress := j.DebugLibNetInfo.FuncSymbol.SymAddr
|
|
|
debugFuncSym := InnerSymbolInfo{}
|
|
debugFuncSym := InnerSymbolInfo{}
|
|
|
//debugFuncSym.FuncSymbol.SymAddr = funcAbsAddress
|
|
//debugFuncSym.FuncSymbol.SymAddr = funcAbsAddress
|
|
@@ -193,7 +194,7 @@ func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
|
|
|
for pc < uint64(len(code)) {
|
|
for pc < uint64(len(code)) {
|
|
|
inst, err := x86asm.Decode(code[pc:], 64)
|
|
inst, err := x86asm.Decode(code[pc:], 64)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- fmt.Printf("Decode error at offset 0x%x: %v\n", pc, err)
|
|
|
|
|
|
|
+ klog.Errorf("Decode error at offset 0x%x: %v\n", pc, err)
|
|
|
pc++ // Skip this byte and try to decode again
|
|
pc++ // Skip this byte and try to decode again
|
|
|
continue
|
|
continue
|
|
|
}
|
|
}
|
|
@@ -211,7 +212,7 @@ func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
|
|
|
j.DebugLibNetInfo.FuncSymbol.OriginInst = currentData.Inst
|
|
j.DebugLibNetInfo.FuncSymbol.OriginInst = currentData.Inst
|
|
|
}
|
|
}
|
|
|
if pc == IO_FD_FDID_SYM_OFFSET {
|
|
if pc == IO_FD_FDID_SYM_OFFSET {
|
|
|
- fmt.Printf("Instuction at 0x%x: %v\n", preContext.PC, preContext.Inst)
|
|
|
|
|
|
|
+ klog.Infof("Instuction at 0x%x: %v\n", preContext.PC, preContext.Inst)
|
|
|
debugFuncSym.IO_fd_fdID = currentData
|
|
debugFuncSym.IO_fd_fdID = currentData
|
|
|
debugFuncSym.IO_fd_fdID.SymName = "<IO_fd_fdID>(Debug)"
|
|
debugFuncSym.IO_fd_fdID.SymName = "<IO_fd_fdID>(Debug)"
|
|
|
// 计算目标地址
|
|
// 计算目标地址
|
|
@@ -224,7 +225,7 @@ func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
|
|
|
// 直接从Mem结构体中读取偏移
|
|
// 直接从Mem结构体中读取偏移
|
|
|
relOffset := mem.Disp
|
|
relOffset := mem.Disp
|
|
|
targetAddress := currentData.SymAddr + uint64(currentData.Inst.Len) + uint64(relOffset)
|
|
targetAddress := currentData.SymAddr + uint64(currentData.Inst.Len) + uint64(relOffset)
|
|
|
- fmt.Printf("Find %s Target address: 0x%x\n", debugFuncSym.IO_fd_fdID.SymName, targetAddress)
|
|
|
|
|
|
|
+ klog.Infof("Find %s Target address: 0x%x\n", debugFuncSym.IO_fd_fdID.SymName, targetAddress)
|
|
|
debugFuncSym.IO_fd_fdID.TargetAddr = targetAddress
|
|
debugFuncSym.IO_fd_fdID.TargetAddr = targetAddress
|
|
|
// 保存原始数据
|
|
// 保存原始数据
|
|
|
debugFuncSym.IO_fd_fdID.OriginTargetAddr = targetAddress
|
|
debugFuncSym.IO_fd_fdID.OriginTargetAddr = targetAddress
|
|
@@ -234,12 +235,12 @@ func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
|
|
|
return 0, fmt.Errorf("The instruction does not use RIP-relative addressing.")
|
|
return 0, fmt.Errorf("The instruction does not use RIP-relative addressing.")
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- return 0, fmt.Errorf("The decoded instruction is not a MOV to RDX.")
|
|
|
|
|
|
|
+ return 0, fmt.Errorf("[findDebugAddressInfoFromMem] The decoded instruction is not a MOV to RDX.")
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
if pc == NET_SEND_SYM_OFFSET {
|
|
if pc == NET_SEND_SYM_OFFSET {
|
|
|
debugFuncSym.NET_Send = currentData
|
|
debugFuncSym.NET_Send = currentData
|
|
|
- fmt.Printf("4 call Decoded instuction at 0x%x: %v\n", funcAbsAddress+pc, inst)
|
|
|
|
|
|
|
+ klog.Infof("4 call Decoded instuction at 0x%x: %v\n", funcAbsAddress+pc, inst)
|
|
|
relOffset, ok := (inst.Args[0].(x86asm.Rel))
|
|
relOffset, ok := (inst.Args[0].(x86asm.Rel))
|
|
|
if !ok {
|
|
if !ok {
|
|
|
return 0, fmt.Errorf("The decoded instruction is not a Rel.")
|
|
return 0, fmt.Errorf("The decoded instruction is not a Rel.")
|
|
@@ -247,7 +248,7 @@ func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
|
|
|
targetAddress := currentData.SymAddr + uint64(inst.Len) + uint64(relOffset)
|
|
targetAddress := currentData.SymAddr + uint64(inst.Len) + uint64(relOffset)
|
|
|
debugFuncSym.NET_Send.TargetAddr = targetAddress
|
|
debugFuncSym.NET_Send.TargetAddr = targetAddress
|
|
|
debugFuncSym.NET_Send.SymName = "<NET_Send>(Debug)"
|
|
debugFuncSym.NET_Send.SymName = "<NET_Send>(Debug)"
|
|
|
- fmt.Printf("Find %s Target address: 0x%x\n", debugFuncSym.NET_Send.SymName, targetAddress)
|
|
|
|
|
|
|
+ klog.Infof("Find %s Target address: 0x%x\n", debugFuncSym.NET_Send.SymName, targetAddress)
|
|
|
|
|
|
|
|
// 保存原始数据
|
|
// 保存原始数据
|
|
|
debugFuncSym.NET_Send.OriginTargetAddr = targetAddress
|
|
debugFuncSym.NET_Send.OriginTargetAddr = targetAddress
|
|
@@ -268,6 +269,7 @@ func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func (j *JvmInjector) checkDebugFuncSymAfterChange() (uint64, error) {
|
|
func (j *JvmInjector) checkDebugFuncSymAfterChange() (uint64, error) {
|
|
|
|
|
+ klog.Infof("Checking debug function symbol after injection")
|
|
|
funcAbsAddress := j.DebugLibNetInfo.FuncSymbol.SymAddr
|
|
funcAbsAddress := j.DebugLibNetInfo.FuncSymbol.SymAddr
|
|
|
debugFuncSym := InnerSymbolInfo{}
|
|
debugFuncSym := InnerSymbolInfo{}
|
|
|
code, err := j.readMemory(funcAbsAddress, j.DebugLibNetInfo.FuncSymbol.SymSize)
|
|
code, err := j.readMemory(funcAbsAddress, j.DebugLibNetInfo.FuncSymbol.SymSize)
|
|
@@ -281,7 +283,7 @@ func (j *JvmInjector) checkDebugFuncSymAfterChange() (uint64, error) {
|
|
|
for pc < uint64(len(code)) {
|
|
for pc < uint64(len(code)) {
|
|
|
inst, err := x86asm.Decode(code[pc:], 64)
|
|
inst, err := x86asm.Decode(code[pc:], 64)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- fmt.Printf("Decode error at offset 0x%x: %v\n", pc, err)
|
|
|
|
|
|
|
+ klog.Infof("Decode error at offset 0x%x: %v\n", pc, err)
|
|
|
pc++ // Skip this byte and try to decode again
|
|
pc++ // Skip this byte and try to decode again
|
|
|
continue
|
|
continue
|
|
|
}
|
|
}
|
|
@@ -294,7 +296,7 @@ func (j *JvmInjector) checkDebugFuncSymAfterChange() (uint64, error) {
|
|
|
Inst: inst,
|
|
Inst: inst,
|
|
|
}
|
|
}
|
|
|
if pc == NET_SEND_SYM_OFFSET {
|
|
if pc == NET_SEND_SYM_OFFSET {
|
|
|
- fmt.Printf("Instuction at 0x%x: %v\n", preContext.PC, preContext.Inst)
|
|
|
|
|
|
|
+ klog.Infof("Instuction at 0x%x: %v\n", preContext.PC, preContext.Inst)
|
|
|
debugFuncSym.IO_fd_fdID = currentData
|
|
debugFuncSym.IO_fd_fdID = currentData
|
|
|
debugFuncSym.IO_fd_fdID.SymName = "<IO_fd_fdID>(Debug)"
|
|
debugFuncSym.IO_fd_fdID.SymName = "<IO_fd_fdID>(Debug)"
|
|
|
// 计算目标地址
|
|
// 计算目标地址
|
|
@@ -307,7 +309,7 @@ func (j *JvmInjector) checkDebugFuncSymAfterChange() (uint64, error) {
|
|
|
// 直接从Mem结构体中读取偏移
|
|
// 直接从Mem结构体中读取偏移
|
|
|
relOffset := mem.Disp
|
|
relOffset := mem.Disp
|
|
|
targetAddress := currentData.SymAddr + uint64(currentData.Inst.Len) + uint64(relOffset)
|
|
targetAddress := currentData.SymAddr + uint64(currentData.Inst.Len) + uint64(relOffset)
|
|
|
- fmt.Printf("Find %s Target address: 0x%x\n", debugFuncSym.IO_fd_fdID.SymName, targetAddress)
|
|
|
|
|
|
|
+ klog.Infof("Find %s Target address: 0x%x\n", debugFuncSym.IO_fd_fdID.SymName, targetAddress)
|
|
|
debugFuncSym.IO_fd_fdID.TargetAddr = targetAddress
|
|
debugFuncSym.IO_fd_fdID.TargetAddr = targetAddress
|
|
|
//j.PreCheck.IoFdCheck = true
|
|
//j.PreCheck.IoFdCheck = true
|
|
|
|
|
|
|
@@ -315,19 +317,19 @@ func (j *JvmInjector) checkDebugFuncSymAfterChange() (uint64, error) {
|
|
|
j.DebugLibNetInfo.InnerSymbol.IO_fd_fdID.TargetAddr = targetAddress
|
|
j.DebugLibNetInfo.InnerSymbol.IO_fd_fdID.TargetAddr = targetAddress
|
|
|
j.DebugLibNetInfo.InnerSymbol.IO_fd_fdID.Inst = currentData.Inst
|
|
j.DebugLibNetInfo.InnerSymbol.IO_fd_fdID.Inst = currentData.Inst
|
|
|
j.AfterCheck.IoFdCheck = true
|
|
j.AfterCheck.IoFdCheck = true
|
|
|
- fmt.Println("ok")
|
|
|
|
|
|
|
+ klog.Infoln("ok")
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
return 0, fmt.Errorf("The instruction does not use RIP-relative addressing.")
|
|
return 0, fmt.Errorf("The instruction does not use RIP-relative addressing.")
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- return 0, fmt.Errorf("The decoded instruction is not a MOV to RDX.")
|
|
|
|
|
|
|
+ return 0, fmt.Errorf("[checkDebugFuncSymAfterChange] The decoded instruction is not a MOV to RDX.")
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
if pc == NET_SEND_SYM_OFFSET {
|
|
if pc == NET_SEND_SYM_OFFSET {
|
|
|
debugFuncSym.NET_Send = currentData
|
|
debugFuncSym.NET_Send = currentData
|
|
|
//fmt.Println(currentData.IntelInst)
|
|
//fmt.Println(currentData.IntelInst)
|
|
|
- //fmt.Printf("4 call Decoded instuction at 0x%x: %v\n", funcAbsAddress+pc, inst)
|
|
|
|
|
|
|
+ //klog.Infof("4 call Decoded instuction at 0x%x: %v\n", funcAbsAddress+pc, inst)
|
|
|
relOffset, ok := (inst.Args[0].(x86asm.Rel))
|
|
relOffset, ok := (inst.Args[0].(x86asm.Rel))
|
|
|
if !ok {
|
|
if !ok {
|
|
|
return 0, fmt.Errorf("The decoded instruction is not a Rel.")
|
|
return 0, fmt.Errorf("The decoded instruction is not a Rel.")
|
|
@@ -335,7 +337,7 @@ func (j *JvmInjector) checkDebugFuncSymAfterChange() (uint64, error) {
|
|
|
targetAddress := currentData.SymAddr + uint64(inst.Len) + uint64(relOffset)
|
|
targetAddress := currentData.SymAddr + uint64(inst.Len) + uint64(relOffset)
|
|
|
debugFuncSym.NET_Send.TargetAddr = targetAddress
|
|
debugFuncSym.NET_Send.TargetAddr = targetAddress
|
|
|
debugFuncSym.NET_Send.SymName = "<NET_Send>(Debug)"
|
|
debugFuncSym.NET_Send.SymName = "<NET_Send>(Debug)"
|
|
|
- fmt.Printf("Find %s Target address: 0x%x\n", debugFuncSym.NET_Send.SymName, targetAddress)
|
|
|
|
|
|
|
+ klog.Infof("Find %s Target address: 0x%x\n", debugFuncSym.NET_Send.SymName, targetAddress)
|
|
|
|
|
|
|
|
if targetAddress == j.ReleaseLibNetInfo.InnerSymbol.NET_Send.TargetAddr {
|
|
if targetAddress == j.ReleaseLibNetInfo.InnerSymbol.NET_Send.TargetAddr {
|
|
|
j.DebugLibNetInfo.InnerSymbol.NET_Send.TargetAddr = targetAddress
|
|
j.DebugLibNetInfo.InnerSymbol.NET_Send.TargetAddr = targetAddress
|
|
@@ -360,7 +362,7 @@ func (j *JvmInjector) checkReleaseFuncSymAfterChange() error {
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return fmt.Errorf("readMemory error in checkReleaseFuncSymAfterChange <%v>", err)
|
|
return fmt.Errorf("readMemory error in checkReleaseFuncSymAfterChange <%v>", err)
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 原函数内容注释掉
|
|
// 原函数内容注释掉
|
|
|
// inst, err := x86asm.Decode(code[0:], 64)
|
|
// inst, err := x86asm.Decode(code[0:], 64)
|
|
|
// if err != nil {
|
|
// if err != nil {
|
|
@@ -378,35 +380,35 @@ func (j *JvmInjector) checkReleaseFuncSymAfterChange() error {
|
|
|
// if targetAddress != j.DebugLibNetInfo.FuncSymbol.SymAddr {
|
|
// if targetAddress != j.DebugLibNetInfo.FuncSymbol.SymAddr {
|
|
|
// return fmt.Errorf("Function entry jmp address does not match expectations.")
|
|
// return fmt.Errorf("Function entry jmp address does not match expectations.")
|
|
|
// }
|
|
// }
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 新的验证逻辑:验证指令序列:movabs $imm64,%rax 和 jmp *%rax
|
|
// 新的验证逻辑:验证指令序列:movabs $imm64,%rax 和 jmp *%rax
|
|
|
if len(code) < 13 { // movabs(10字节) + jmp(3字节) = 13字节
|
|
if len(code) < 13 { // movabs(10字节) + jmp(3字节) = 13字节
|
|
|
return fmt.Errorf("Instruction sequence too short, expected at least 13 bytes, got %d", len(code))
|
|
return fmt.Errorf("Instruction sequence too short, expected at least 13 bytes, got %d", len(code))
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 验证第一个指令:movabs $imm64,%rax
|
|
// 验证第一个指令:movabs $imm64,%rax
|
|
|
// movabs 指令格式:48 B8 + 8字节立即数 (RAX寄存器)
|
|
// movabs 指令格式:48 B8 + 8字节立即数 (RAX寄存器)
|
|
|
// 48 B8 = movabs rax, imm64
|
|
// 48 B8 = movabs rax, imm64
|
|
|
if code[0] != 0x48 || code[1] != 0xB8 {
|
|
if code[0] != 0x48 || code[1] != 0xB8 {
|
|
|
return fmt.Errorf("First instruction is not movabs rax, imm64. Got: 0x%02x 0x%02x", code[0], code[1])
|
|
return fmt.Errorf("First instruction is not movabs rax, imm64. Got: 0x%02x 0x%02x", code[0], code[1])
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 提取立即数值 (小端序)
|
|
// 提取立即数值 (小端序)
|
|
|
imm64 := uint64(code[2]) | uint64(code[3])<<8 | uint64(code[4])<<16 | uint64(code[5])<<24 |
|
|
imm64 := uint64(code[2]) | uint64(code[3])<<8 | uint64(code[4])<<16 | uint64(code[5])<<24 |
|
|
|
- uint64(code[6])<<32 | uint64(code[7])<<40 | uint64(code[8])<<48 | uint64(code[9])<<56
|
|
|
|
|
-
|
|
|
|
|
|
|
+ uint64(code[6])<<32 | uint64(code[7])<<40 | uint64(code[8])<<48 | uint64(code[9])<<56
|
|
|
|
|
+
|
|
|
// 验证立即数是否与 Debug 函数地址一致
|
|
// 验证立即数是否与 Debug 函数地址一致
|
|
|
expectedAddr := j.DebugLibNetInfo.FuncSymbol.SymAddr
|
|
expectedAddr := j.DebugLibNetInfo.FuncSymbol.SymAddr
|
|
|
if imm64 != expectedAddr {
|
|
if imm64 != expectedAddr {
|
|
|
return fmt.Errorf("movabs immediate value mismatch. Expected: 0x%x (Debug function addr), Got: 0x%x", expectedAddr, imm64)
|
|
return fmt.Errorf("movabs immediate value mismatch. Expected: 0x%x (Debug function addr), Got: 0x%x", expectedAddr, imm64)
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 验证第二个指令:jmp *%rax
|
|
// 验证第二个指令:jmp *%rax
|
|
|
// jmp *%rax 指令格式:FF E0
|
|
// jmp *%rax 指令格式:FF E0
|
|
|
if code[10] != 0xFF || code[11] != 0xE0 {
|
|
if code[10] != 0xFF || code[11] != 0xE0 {
|
|
|
return fmt.Errorf("Second instruction is not jmp *%%rax. Got: 0x%02x 0x%02x", code[10], code[11])
|
|
return fmt.Errorf("Second instruction is not jmp *%%rax. Got: 0x%02x 0x%02x", code[10], code[11])
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
klog.Infof("[checkReleaseFuncSymAfterChange] Successfully verified instruction sequence: movabs $0x%x,%%rax; jmp *%%rax", imm64)
|
|
klog.Infof("[checkReleaseFuncSymAfterChange] Successfully verified instruction sequence: movabs $0x%x,%%rax; jmp *%%rax", imm64)
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
@@ -666,27 +668,27 @@ func (j *JvmInjector) findDebugFuncContextFromLibPath() error {
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return fmt.Errorf("Error finding first CALL instuction: %v", err)
|
|
return fmt.Errorf("Error finding first CALL instuction: %v", err)
|
|
|
}
|
|
}
|
|
|
- fmt.Printf("First CALL instuction o1f %s at base 0x%x\n", functionName, baseAddress)
|
|
|
|
|
|
|
+ klog.Infof("First CALL instuction o1f %s at base 0x%x\n", functionName, baseAddress)
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func printCodeData(data LibNetInfo) {
|
|
func printCodeData(data LibNetInfo) {
|
|
|
- fmt.Printf("========FuncEnter <0x%x> \n", data.FuncSymbol.SymAddr)
|
|
|
|
|
- fmt.Printf("Name %s | CurrentAddr:<0x%x>\nOrigin-TargetAddr:<0x%x> | TargetAddr:<0x%x> \nOrigin-Inst:<%s> | Inst:<%s> \n",
|
|
|
|
|
|
|
+ klog.Infof("========FuncEnter <0x%x> \n", data.FuncSymbol.SymAddr)
|
|
|
|
|
+ klog.Infof("Name %s | CurrentAddr:<0x%x>\nOrigin-TargetAddr:<0x%x> | TargetAddr:<0x%x> \nOrigin-Inst:<%s> | Inst:<%s> \n",
|
|
|
data.InnerSymbol.IO_fd_fdID.SymName,
|
|
data.InnerSymbol.IO_fd_fdID.SymName,
|
|
|
data.InnerSymbol.IO_fd_fdID.SymAddr,
|
|
data.InnerSymbol.IO_fd_fdID.SymAddr,
|
|
|
data.InnerSymbol.IO_fd_fdID.OriginTargetAddr,
|
|
data.InnerSymbol.IO_fd_fdID.OriginTargetAddr,
|
|
|
data.InnerSymbol.IO_fd_fdID.TargetAddr,
|
|
data.InnerSymbol.IO_fd_fdID.TargetAddr,
|
|
|
x86asm.IntelSyntax(data.InnerSymbol.IO_fd_fdID.OriginInst, 0, nil),
|
|
x86asm.IntelSyntax(data.InnerSymbol.IO_fd_fdID.OriginInst, 0, nil),
|
|
|
x86asm.IntelSyntax(data.InnerSymbol.IO_fd_fdID.Inst, 0, nil))
|
|
x86asm.IntelSyntax(data.InnerSymbol.IO_fd_fdID.Inst, 0, nil))
|
|
|
- fmt.Printf("\nName %s | CurrentAddr:<0x%x>\nOrigin-TargetAddr:<0x%x> | TargetAddr:<0x%x>\nOrigin-Inst:<%s> | Inst:<%s> \n",
|
|
|
|
|
|
|
+ klog.Infof("\nName %s | CurrentAddr:<0x%x>\nOrigin-TargetAddr:<0x%x> | TargetAddr:<0x%x>\nOrigin-Inst:<%s> | Inst:<%s> \n",
|
|
|
data.InnerSymbol.NET_Send.SymName,
|
|
data.InnerSymbol.NET_Send.SymName,
|
|
|
data.InnerSymbol.NET_Send.SymAddr,
|
|
data.InnerSymbol.NET_Send.SymAddr,
|
|
|
data.InnerSymbol.NET_Send.OriginTargetAddr,
|
|
data.InnerSymbol.NET_Send.OriginTargetAddr,
|
|
|
data.InnerSymbol.NET_Send.TargetAddr,
|
|
data.InnerSymbol.NET_Send.TargetAddr,
|
|
|
x86asm.IntelSyntax(data.InnerSymbol.NET_Send.OriginInst, 0, nil),
|
|
x86asm.IntelSyntax(data.InnerSymbol.NET_Send.OriginInst, 0, nil),
|
|
|
x86asm.IntelSyntax(data.InnerSymbol.NET_Send.Inst, 0, nil))
|
|
x86asm.IntelSyntax(data.InnerSymbol.NET_Send.Inst, 0, nil))
|
|
|
- fmt.Println("========")
|
|
|
|
|
|
|
+ klog.Infoln("========")
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func (j *JvmInjector) jvmInjectLib() int {
|
|
func (j *JvmInjector) jvmInjectLib() int {
|
|
@@ -694,7 +696,7 @@ func (j *JvmInjector) jvmInjectLib() int {
|
|
|
rootfs := C.CString(j.Rootfs)
|
|
rootfs := C.CString(j.Rootfs)
|
|
|
defer C.free(unsafe.Pointer(dll))
|
|
defer C.free(unsafe.Pointer(dll))
|
|
|
result := C.cw_inject_library(C.int(j.Pid), C.int(1), dll, rootfs)
|
|
result := C.cw_inject_library(C.int(j.Pid), C.int(1), dll, rootfs)
|
|
|
- fmt.Printf("Result: %d\n", result)
|
|
|
|
|
|
|
+ klog.Infof("Result: %d\n", result)
|
|
|
return int(result)
|
|
return int(result)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -755,8 +757,7 @@ func modifyIoFdTargetAddr(pid int, insertAddr, distAddr, getTTLFunctionAddr uint
|
|
|
|
|
|
|
|
getTTLOffset := getTTLFunctionAddr - insertAddr - 5
|
|
getTTLOffset := getTTLFunctionAddr - insertAddr - 5
|
|
|
|
|
|
|
|
-
|
|
|
|
|
- // 读取原始数据
|
|
|
|
|
|
|
+ // 读取原始数据
|
|
|
// alignedAddr := insertAddr & ^(uintptr(unsafe.Sizeof(uintptr(0))) - 1)
|
|
// alignedAddr := insertAddr & ^(uintptr(unsafe.Sizeof(uintptr(0))) - 1)
|
|
|
originalData, err := readDataBytes(pid, insertAddr, 7)
|
|
originalData, err := readDataBytes(pid, insertAddr, 7)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -768,13 +769,13 @@ func modifyIoFdTargetAddr(pid int, insertAddr, distAddr, getTTLFunctionAddr uint
|
|
|
|
|
|
|
|
// 写入AMD64的绝对跳转指令: mov rax, addr; jmp rax
|
|
// 写入AMD64的绝对跳转指令: mov rax, addr; jmp rax
|
|
|
var getTTLOffset32 uint32 = uint32(getTTLOffset)
|
|
var getTTLOffset32 uint32 = uint32(getTTLOffset)
|
|
|
- originalData[offset] = 0xE8 // call
|
|
|
|
|
|
|
+ originalData[offset] = 0xE8 // call
|
|
|
originalData[offset+1] = byte(getTTLOffset32)
|
|
originalData[offset+1] = byte(getTTLOffset32)
|
|
|
originalData[offset+2] = byte(getTTLOffset32 >> 8)
|
|
originalData[offset+2] = byte(getTTLOffset32 >> 8)
|
|
|
originalData[offset+3] = byte(getTTLOffset32 >> 16)
|
|
originalData[offset+3] = byte(getTTLOffset32 >> 16)
|
|
|
originalData[offset+4] = byte(getTTLOffset32 >> 24)
|
|
originalData[offset+4] = byte(getTTLOffset32 >> 24)
|
|
|
- originalData[offset+5] = 0x90 //nop
|
|
|
|
|
- originalData[offset+6] = 0x90 //nop
|
|
|
|
|
|
|
+ originalData[offset+5] = 0x90 //nop
|
|
|
|
|
+ originalData[offset+6] = 0x90 //nop
|
|
|
|
|
|
|
|
err = writeDataBytes(pid, insertAddr, originalData)
|
|
err = writeDataBytes(pid, insertAddr, originalData)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -803,8 +804,8 @@ func modifyIoFdTargetAddr(pid int, insertAddr, distAddr, getTTLFunctionAddr uint
|
|
|
TTLOriginalData[offset+11] = 0x48
|
|
TTLOriginalData[offset+11] = 0x48
|
|
|
TTLOriginalData[offset+12] = 0x8b
|
|
TTLOriginalData[offset+12] = 0x8b
|
|
|
TTLOriginalData[offset+13] = 0x10
|
|
TTLOriginalData[offset+13] = 0x10
|
|
|
- TTLOriginalData[offset+14] = 0x58 //pop rax
|
|
|
|
|
- TTLOriginalData[offset+15] = 0xc3 //ret
|
|
|
|
|
|
|
+ TTLOriginalData[offset+14] = 0x58 //pop rax
|
|
|
|
|
+ TTLOriginalData[offset+15] = 0xc3 //ret
|
|
|
|
|
|
|
|
err = writeDataBytes(pid, getTTLFunctionAddr, TTLOriginalData)
|
|
err = writeDataBytes(pid, getTTLFunctionAddr, TTLOriginalData)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -835,8 +836,7 @@ func modifyNetSetTargetAddr(pid int, sendDebugAddr, sendReleaseAddr, convert0Fun
|
|
|
|
|
|
|
|
convert0Offset := convert0FunctionAddr - sendDebugAddr - 5
|
|
convert0Offset := convert0FunctionAddr - sendDebugAddr - 5
|
|
|
|
|
|
|
|
-
|
|
|
|
|
- // 读取原始数据
|
|
|
|
|
|
|
+ // 读取原始数据
|
|
|
// alignedAddr := insertAddr & ^(uintptr(unsafe.Sizeof(uintptr(0))) - 1)
|
|
// alignedAddr := insertAddr & ^(uintptr(unsafe.Sizeof(uintptr(0))) - 1)
|
|
|
originalData, err := readDataBytes(pid, sendDebugAddr, 5)
|
|
originalData, err := readDataBytes(pid, sendDebugAddr, 5)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -848,7 +848,7 @@ func modifyNetSetTargetAddr(pid int, sendDebugAddr, sendReleaseAddr, convert0Fun
|
|
|
|
|
|
|
|
// 写入AMD64的绝对跳转指令: mov rax, addr; jmp rax
|
|
// 写入AMD64的绝对跳转指令: mov rax, addr; jmp rax
|
|
|
var convert0Offset32 uint32 = uint32(convert0Offset)
|
|
var convert0Offset32 uint32 = uint32(convert0Offset)
|
|
|
- originalData[offset] = 0xE8 // call
|
|
|
|
|
|
|
+ originalData[offset] = 0xE8 // call
|
|
|
originalData[offset+1] = byte(convert0Offset32)
|
|
originalData[offset+1] = byte(convert0Offset32)
|
|
|
originalData[offset+2] = byte(convert0Offset32 >> 8)
|
|
originalData[offset+2] = byte(convert0Offset32 >> 8)
|
|
|
originalData[offset+3] = byte(convert0Offset32 >> 16)
|
|
originalData[offset+3] = byte(convert0Offset32 >> 16)
|
|
@@ -859,7 +859,6 @@ func modifyNetSetTargetAddr(pid int, sendDebugAddr, sendReleaseAddr, convert0Fun
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
convert0OriginalData, err := readDataBytes(pid, convert0FunctionAddr, 13)
|
|
convert0OriginalData, err := readDataBytes(pid, convert0FunctionAddr, 13)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
@@ -916,10 +915,10 @@ func modifyReleaseFuncEnter(pid int, originEnterAddr, debugEnterAddr uintptr) er
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
offset := originEnterAddr % uintptr(unsafe.Sizeof(uintptr(0)))
|
|
offset := originEnterAddr % uintptr(unsafe.Sizeof(uintptr(0)))
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 写入AMD64的绝对跳转指令: mov rax, addr; jmp rax
|
|
// 写入AMD64的绝对跳转指令: mov rax, addr; jmp rax
|
|
|
- originalData[offset] = 0x48 // REX.W prefix
|
|
|
|
|
- originalData[offset+1] = 0xb8 // mov rax, imm64
|
|
|
|
|
|
|
+ originalData[offset] = 0x48 // REX.W prefix
|
|
|
|
|
+ originalData[offset+1] = 0xb8 // mov rax, imm64
|
|
|
// 按小端序写入64位地址
|
|
// 按小端序写入64位地址
|
|
|
originalData[offset+2] = byte(debugEnterAddr)
|
|
originalData[offset+2] = byte(debugEnterAddr)
|
|
|
originalData[offset+3] = byte(debugEnterAddr >> 8)
|
|
originalData[offset+3] = byte(debugEnterAddr >> 8)
|
|
@@ -929,7 +928,7 @@ func modifyReleaseFuncEnter(pid int, originEnterAddr, debugEnterAddr uintptr) er
|
|
|
originalData[offset+7] = byte(debugEnterAddr >> 40)
|
|
originalData[offset+7] = byte(debugEnterAddr >> 40)
|
|
|
originalData[offset+8] = byte(debugEnterAddr >> 48)
|
|
originalData[offset+8] = byte(debugEnterAddr >> 48)
|
|
|
originalData[offset+9] = byte(debugEnterAddr >> 56)
|
|
originalData[offset+9] = byte(debugEnterAddr >> 56)
|
|
|
- originalData[offset+10] = 0xff // jmp rax
|
|
|
|
|
|
|
+ originalData[offset+10] = 0xff // jmp rax
|
|
|
originalData[offset+11] = 0xe0
|
|
originalData[offset+11] = 0xe0
|
|
|
|
|
|
|
|
err = writeDataBytes(pid, alignedAddr, originalData)
|
|
err = writeDataBytes(pid, alignedAddr, originalData)
|
|
@@ -1075,24 +1074,23 @@ func JvmInject(jvmInjector *JvmInjector) error {
|
|
|
ioFdReleaseTargetAddr := uintptr(jvmInjector.ReleaseLibNetInfo.InnerSymbol.IO_fd_fdID.TargetAddr)
|
|
ioFdReleaseTargetAddr := uintptr(jvmInjector.ReleaseLibNetInfo.InnerSymbol.IO_fd_fdID.TargetAddr)
|
|
|
netSendReleaseTargetAddr := uintptr(jvmInjector.ReleaseLibNetInfo.InnerSymbol.NET_Send.TargetAddr)
|
|
netSendReleaseTargetAddr := uintptr(jvmInjector.ReleaseLibNetInfo.InnerSymbol.NET_Send.TargetAddr)
|
|
|
|
|
|
|
|
- fmt.Printf("<0x%x> -> <0x%x>\n", originFuncEnterAddr, debugFuncEnterAddr)
|
|
|
|
|
- fmt.Printf("<0x%x> -> <0x%x>\n", debugIoFdAddr, ioFdReleaseTargetAddr)
|
|
|
|
|
- fmt.Printf("<0x%x> -> <0x%x>\n", debugNetSendAddr, netSendReleaseTargetAddr)
|
|
|
|
|
- fmt.Printf("conver0 -> <0x%x>\n", debugFuncConvert0EnterAddr)
|
|
|
|
|
- fmt.Printf("getttl -> <0x%x>\n", debugFuncGetTTLEnterAddr)
|
|
|
|
|
-
|
|
|
|
|
|
|
+ klog.Infof("<0x%x> -> <0x%x>\n", originFuncEnterAddr, debugFuncEnterAddr)
|
|
|
|
|
+ klog.Infof("<0x%x> -> <0x%x>\n", debugIoFdAddr, ioFdReleaseTargetAddr)
|
|
|
|
|
+ klog.Infof("<0x%x> -> <0x%x>\n", debugNetSendAddr, netSendReleaseTargetAddr)
|
|
|
|
|
+ klog.Infof("conver0 -> <0x%x>\n", debugFuncConvert0EnterAddr)
|
|
|
|
|
+ klog.Infof("getttl -> <0x%x>\n", debugFuncGetTTLEnterAddr)
|
|
|
|
|
|
|
|
// 附加到目标进程
|
|
// 附加到目标进程
|
|
|
klog.Infof("attach")
|
|
klog.Infof("attach")
|
|
|
err = syscall.PtraceAttach(pid)
|
|
err = syscall.PtraceAttach(pid)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- fmt.Printf("ptrace ATTACH: %v", err)
|
|
|
|
|
|
|
+ klog.Errorf("ptrace ATTACH: %v", err)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 等待目标进程停止
|
|
// 等待目标进程停止
|
|
|
klog.Infof("attach Wait")
|
|
klog.Infof("attach Wait")
|
|
|
if _, err := syscall.Wait4(pid, nil, 0, nil); err != nil {
|
|
if _, err := syscall.Wait4(pid, nil, 0, nil); err != nil {
|
|
|
- fmt.Printf("wait4: %v", err)
|
|
|
|
|
|
|
+ klog.Errorf("wait4: %v", err)
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
//time.Now().UnixNano()
|
|
//time.Now().UnixNano()
|
|
@@ -1125,6 +1123,16 @@ func JvmInject(jvmInjector *JvmInjector) error {
|
|
|
}
|
|
}
|
|
|
// 更新函数入口
|
|
// 更新函数入口
|
|
|
klog.Infof("modifyReleaseFuncEnter")
|
|
klog.Infof("modifyReleaseFuncEnter")
|
|
|
|
|
+ // 计算地址差
|
|
|
|
|
+ diff := originFuncEnterAddr - debugFuncEnterAddr
|
|
|
|
|
+ if diff < 0 {
|
|
|
|
|
+ diff = -diff
|
|
|
|
|
+ }
|
|
|
|
|
+ // 检查是否超过 2GB
|
|
|
|
|
+ if diff > (1 << 31) {
|
|
|
|
|
+ klog.Infof("[inject] originFuncEnterAddr(0x%x) and debugFuncEnterAddr(0x%x) distance > 2GB",
|
|
|
|
|
+ originFuncEnterAddr, debugFuncEnterAddr)
|
|
|
|
|
+ }
|
|
|
err = modifyReleaseFuncEnter(pid, originFuncEnterAddr, debugFuncEnterAddr)
|
|
err = modifyReleaseFuncEnter(pid, originFuncEnterAddr, debugFuncEnterAddr)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
klog.WithError(err).Errorf("[inject] failed modifyReleaseFuncEnter")
|
|
klog.WithError(err).Errorf("[inject] failed modifyReleaseFuncEnter")
|
|
@@ -1137,7 +1145,7 @@ func JvmInject(jvmInjector *JvmInjector) error {
|
|
|
if errReleaseFuncSymAfterChange != nil {
|
|
if errReleaseFuncSymAfterChange != nil {
|
|
|
klog.WithError(errReleaseFuncSymAfterChange).Errorf("[inject] failed checkReleaseFuncSymAfterChange")
|
|
klog.WithError(errReleaseFuncSymAfterChange).Errorf("[inject] failed checkReleaseFuncSymAfterChange")
|
|
|
// 回滚
|
|
// 回滚
|
|
|
- if len(jvmInjector.ReleaseLibNetInfo.FuncSymbol.OriginCode) == 12 {
|
|
|
|
|
|
|
+ if len(jvmInjector.ReleaseLibNetInfo.FuncSymbol.OriginCode) == ORIGIN_CODE_LEN {
|
|
|
err = restoreOriginalInstructions(pid, originFuncEnterAddr, jvmInjector.ReleaseLibNetInfo.FuncSymbol.OriginCode)
|
|
err = restoreOriginalInstructions(pid, originFuncEnterAddr, jvmInjector.ReleaseLibNetInfo.FuncSymbol.OriginCode)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
klog.WithError(err).Errorf("[inject] failed restoreOriginalInstructions")
|
|
klog.WithError(err).Errorf("[inject] failed restoreOriginalInstructions")
|