|
@@ -11,11 +11,11 @@ import "C"
|
|
|
|
|
|
|
|
import (
|
|
import (
|
|
|
"bufio"
|
|
"bufio"
|
|
|
|
|
+ "bytes"
|
|
|
"debug/elf"
|
|
"debug/elf"
|
|
|
"fmt"
|
|
"fmt"
|
|
|
"golang.org/x/arch/arm64/arm64asm"
|
|
"golang.org/x/arch/arm64/arm64asm"
|
|
|
"golang.org/x/arch/x86/x86asm"
|
|
"golang.org/x/arch/x86/x86asm"
|
|
|
- "log"
|
|
|
|
|
"os"
|
|
"os"
|
|
|
"strings"
|
|
"strings"
|
|
|
"syscall"
|
|
"syscall"
|
|
@@ -64,10 +64,17 @@ type LibNetInfo struct {
|
|
|
InnerSymbol InnerSymbolInfo
|
|
InnerSymbol InnerSymbolInfo
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+type UprobeData struct {
|
|
|
|
|
+ Offset int
|
|
|
|
|
+ Func string
|
|
|
|
|
+ ELFPath string
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
type JvmInjector struct {
|
|
type JvmInjector struct {
|
|
|
Pid int
|
|
Pid int
|
|
|
ReleaseLibNetInfo LibNetInfo
|
|
ReleaseLibNetInfo LibNetInfo
|
|
|
DebugLibNetInfo LibNetInfo
|
|
DebugLibNetInfo LibNetInfo
|
|
|
|
|
+ RecodeInfo LibNetInfo
|
|
|
// 原方法首个指令不为jmp | ReleaseLibNetInfo 读取无异常
|
|
// 原方法首个指令不为jmp | ReleaseLibNetInfo 读取无异常
|
|
|
PreCheck struct {
|
|
PreCheck struct {
|
|
|
NeedInjectionCheck bool // 原指令校验 true表示可以继续执行注入
|
|
NeedInjectionCheck bool // 原指令校验 true表示可以继续执行注入
|
|
@@ -80,6 +87,7 @@ type JvmInjector struct {
|
|
|
IoFdCheck bool
|
|
IoFdCheck bool
|
|
|
NetSendFuncCheck bool
|
|
NetSendFuncCheck bool
|
|
|
}
|
|
}
|
|
|
|
|
+ Uprobe UprobeData
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func (j *JvmInjector) checkEnc(code []byte, start, len uint64, enc uint32) error {
|
|
func (j *JvmInjector) checkEnc(code []byte, start, len uint64, enc uint32) error {
|
|
@@ -102,12 +110,31 @@ func (j *JvmInjector) findReleaseAddressInfoFromMem() error {
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
- //pc := uint64(0)
|
|
|
|
|
- //add := 0
|
|
|
|
|
- //bl := 0
|
|
|
|
|
- //callCount := 0
|
|
|
|
|
- //preContext := InstInfo{}
|
|
|
|
|
fmt.Println(j.ReleaseLibNetInfo.FuncSymbol.SymSize)
|
|
fmt.Println(j.ReleaseLibNetInfo.FuncSymbol.SymSize)
|
|
|
|
|
+ // cwso是否载入,载入则从recode判断指令
|
|
|
|
|
+ baseAddress, libPath, err := j.findLibBaseFromProcMaps(j.DebugLibNetInfo.LibName)
|
|
|
|
|
+ if err == nil {
|
|
|
|
|
+ j.PreCheck.LoadingCheck = true
|
|
|
|
|
+ fmt.Println("so already loaded check enc...")
|
|
|
|
|
+ // 获取recode地址
|
|
|
|
|
+ fmt.Println(baseAddress)
|
|
|
|
|
+
|
|
|
|
|
+ recodeFunctionSym, err := j.getFunctionOffset(libPath, j.RecodeInfo.FuncSymbol.SymName)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ j.RecodeInfo.FuncSymbol.SymAddr = baseAddress + recodeFunctionSym.Value
|
|
|
|
|
+ recode, err := j.readMemory(j.RecodeInfo.FuncSymbol.SymAddr, 20)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ if bytes.Equal(recode, code[56:56+20]) {
|
|
|
|
|
+ j.PreCheck.EbpfCanInjection = true
|
|
|
|
|
+ fmt.Println("successful...")
|
|
|
|
|
+ return nil
|
|
|
|
|
+ }
|
|
|
|
|
+ fmt.Println("so already loaded. check failed.")
|
|
|
|
|
+ }
|
|
|
/*
|
|
/*
|
|
|
0x0000fffbdc0ef24c <+56>: str x2, [x6,#120]
|
|
0x0000fffbdc0ef24c <+56>: str x2, [x6,#120]
|
|
|
0x0000fffbdc0ef250 <+60>: str x3, [x29,#96]
|
|
0x0000fffbdc0ef250 <+60>: str x3, [x29,#96]
|
|
@@ -136,113 +163,6 @@ func (j *JvmInjector) findReleaseAddressInfoFromMem() error {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /* for pc < j.ReleaseLibNetInfo.FuncSymbol.SymSize {
|
|
|
|
|
-
|
|
|
|
|
- inst, err := arm64asm.Decode(code[pc:])
|
|
|
|
|
- if err != nil {
|
|
|
|
|
- fmt.Printf("Decode error at offset 0x%x: %v\n", pc, err)
|
|
|
|
|
- pc++ // Skip this byte and try to decode again
|
|
|
|
|
- continue
|
|
|
|
|
- }
|
|
|
|
|
- fmt.Printf("Decoded instuction at 0x%x: %v\n", funcAbsAddress+pc, inst)
|
|
|
|
|
- //fmt.Printf("Decoded x86 instuction at 0x%x: %v\n", funcAbsAddress+pc, x86asm.IntelSyntax(inst, 0, nil))
|
|
|
|
|
- //fmt.Printf("Decoded GNU instuction at 0x%x: %v\n", funcAbsAddress+pc, x86asm.GNUSyntax(Inst, 0, nil))
|
|
|
|
|
- currentData := InstInfo{
|
|
|
|
|
- PC: pc,
|
|
|
|
|
- SymAddr: funcAbsAddress + pc,
|
|
|
|
|
- Inst: inst,
|
|
|
|
|
- //IntelInst: x86asm.IntelSyntax(inst, 0, nil),
|
|
|
|
|
- }
|
|
|
|
|
- if pc == 0 && (inst.Op == arm64asm.B || inst.Op == arm64asm.BL) {
|
|
|
|
|
- // 已经被修改过的首指令
|
|
|
|
|
- return fmt.Errorf("Inst already modified. <%s>", arm64asm.GNUSyntax(inst))
|
|
|
|
|
- }
|
|
|
|
|
- if pc == 0 {
|
|
|
|
|
- j.ReleaseLibNetInfo.FuncSymbol.PC = currentData.PC
|
|
|
|
|
- j.ReleaseLibNetInfo.FuncSymbol.Inst = currentData.Inst
|
|
|
|
|
- j.ReleaseLibNetInfo.FuncSymbol.OriginInst = currentData.Inst
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if pc == 88 && inst.Op == arm64asm.STR {
|
|
|
|
|
- fmt.Println(inst.Args[0])
|
|
|
|
|
- fmt.Println(inst.Args[1], inst.Args[1].(arm64asm.MemImmediate).Base, inst.Args[1].(arm64asm.MemImmediate).Mode)
|
|
|
|
|
- fmt.Println("inst.Args[0]", inst.Args[0])
|
|
|
|
|
- fmt.Println("arm64asm.W5", arm64asm.W5)
|
|
|
|
|
- fmt.Println(inst.Args[0] == arm64asm.W5)
|
|
|
|
|
- if inst.Args[0].String() == arm64asm.W5.String() {
|
|
|
|
|
- if src, okSrc := inst.Args[1].(arm64asm.MemImmediate); okSrc {
|
|
|
|
|
- base := arm64asm.Reg(src.Base)
|
|
|
|
|
- if base == arm64asm.X0 {
|
|
|
|
|
- j.PreCheck.EbpfCanInjection = true
|
|
|
|
|
- return nil
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // IO_fd_fdID
|
|
|
|
|
- if inst.Op == arm64asm.ADD {
|
|
|
|
|
- if add == 1 && preContext.Inst.Op == arm64asm.ADRP && inst.Args[0].String() == arm64asm.X2.String() {
|
|
|
|
|
- fmt.Println("inst.Args[0]", inst.Args[0])
|
|
|
|
|
- fmt.Println("arm64asm.X2", arm64asm.X2)
|
|
|
|
|
-
|
|
|
|
|
- if pcRelAddr, okAddr := preContext.Inst.Args[1].(arm64asm.PCRel); okAddr {
|
|
|
|
|
-
|
|
|
|
|
- fmt.Println("preContext.Inst", preContext.Inst)
|
|
|
|
|
- fmt.Println("preContext.Inst.args", preContext.Inst.Args)
|
|
|
|
|
- // 掩码:高位全1,低12位为0
|
|
|
|
|
- clearedAddress := preContext.SymAddr & 0xFFFFFFFFFFFFF000
|
|
|
|
|
-
|
|
|
|
|
- fmt.Printf("preContext.Inst.args %d \n", clearedAddress+uint64(pcRelAddr))
|
|
|
|
|
- fmt.Println("inst", inst)
|
|
|
|
|
- fmt.Println("inst.Args", inst.Args[2].(arm64asm.ImmShift))
|
|
|
|
|
-
|
|
|
|
|
- // 去掉前缀 "#",并提取十六进制部分
|
|
|
|
|
- hexStr := strings.TrimPrefix(inst.Args[2].(arm64asm.ImmShift).String(), "#0x")
|
|
|
|
|
- // 将十六进制字符串转换为整数
|
|
|
|
|
- decimalValue, err := strconv.ParseUint(hexStr, 16, 32)
|
|
|
|
|
- if err != nil {
|
|
|
|
|
- return fmt.Errorf("Error parsing hex string: %v\n", err)
|
|
|
|
|
- }
|
|
|
|
|
- // 打印十进制值
|
|
|
|
|
- fmt.Printf("Decimal value: %d\n", decimalValue)
|
|
|
|
|
- fmt.Printf("preContext.Inst.args %d \n", clearedAddress+uint64(pcRelAddr)+decimalValue)
|
|
|
|
|
- targetAddress := clearedAddress + uint64(pcRelAddr) + decimalValue
|
|
|
|
|
- releaseFuncSym.IO_fd_fdID_ADRP = preContext
|
|
|
|
|
- releaseFuncSym.IO_fd_fdID_ADRP.SymName = "<IO_fd_fdID ADRP>(Release)"
|
|
|
|
|
- releaseFuncSym.IO_fd_fdID_ADRP.TargetAddr = targetAddress
|
|
|
|
|
-
|
|
|
|
|
- releaseFuncSym.IO_fd_fdID_ADD = currentData
|
|
|
|
|
- releaseFuncSym.IO_fd_fdID_ADD.SymName = "<IO_fd_fdID ADD>(Release)"
|
|
|
|
|
- releaseFuncSym.IO_fd_fdID_ADD.TargetEnc = currentData.Inst.Enc
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- add++
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if inst.Op == arm64asm.BL {
|
|
|
|
|
-
|
|
|
|
|
- //offset = ( target- pc ) / 4
|
|
|
|
|
- // enc = offset +0x94000000
|
|
|
|
|
-
|
|
|
|
|
- if bl == 0 {
|
|
|
|
|
- if pcRelAddr, okAddr := inst.Args[0].(arm64asm.PCRel); okAddr {
|
|
|
|
|
- releaseFuncSym.NET_Send = currentData
|
|
|
|
|
- releaseFuncSym.NET_Send.SymName = "<NET_Send>(Release)"
|
|
|
|
|
- targetAddress := currentData.SymAddr + uint64(pcRelAddr)
|
|
|
|
|
- releaseFuncSym.NET_Send.TargetAddr = targetAddress
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- bl++
|
|
|
|
|
- }
|
|
|
|
|
- preContext = InstInfo{
|
|
|
|
|
- PC: pc,
|
|
|
|
|
- SymAddr: funcAbsAddress + pc,
|
|
|
|
|
- Inst: inst,
|
|
|
|
|
- }
|
|
|
|
|
- pc += 4
|
|
|
|
|
- }
|
|
|
|
|
- */
|
|
|
|
|
j.ReleaseLibNetInfo.InnerSymbol = releaseFuncSym
|
|
j.ReleaseLibNetInfo.InnerSymbol = releaseFuncSym
|
|
|
j.ReleaseLibNetInfo.FuncSymbol.OriginCode = code[0:4]
|
|
j.ReleaseLibNetInfo.FuncSymbol.OriginCode = code[0:4]
|
|
|
return nil
|
|
return nil
|
|
@@ -550,7 +470,6 @@ func (j *JvmInjector) getFunctionOffset(libPath, functionName string) (elf.Symbo
|
|
|
|
|
|
|
|
for _, sym := range symbols {
|
|
for _, sym := range symbols {
|
|
|
if sym.Name == functionName {
|
|
if sym.Name == functionName {
|
|
|
- fmt.Println("size:", sym.Size)
|
|
|
|
|
return sym, nil
|
|
return sym, nil
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -579,8 +498,7 @@ func (j *JvmInjector) findReleaseFuncContextFromLibPath() error {
|
|
|
j.ReleaseLibNetInfo.LibPath = libPath
|
|
j.ReleaseLibNetInfo.LibPath = libPath
|
|
|
libName := j.ReleaseLibNetInfo.LibName
|
|
libName := j.ReleaseLibNetInfo.LibName
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.Fatalf("Error finding base addresses: %v", err)
|
|
|
|
|
- return err
|
|
|
|
|
|
|
+ return fmt.Errorf("Error finding base addresses: %v", err)
|
|
|
}
|
|
}
|
|
|
fmt.Printf("Base address of (%s)%s: %x\n", "", libName, baseAddress)
|
|
fmt.Printf("Base address of (%s)%s: %x\n", "", libName, baseAddress)
|
|
|
|
|
|
|
@@ -591,8 +509,7 @@ func (j *JvmInjector) findReleaseFuncContextFromLibPath() error {
|
|
|
j.ReleaseLibNetInfo.FuncSymbol.SymAddr = baseAddress + functionSym.Value
|
|
j.ReleaseLibNetInfo.FuncSymbol.SymAddr = baseAddress + functionSym.Value
|
|
|
j.ReleaseLibNetInfo.FuncSymbol.SymSize = functionSym.Size
|
|
j.ReleaseLibNetInfo.FuncSymbol.SymSize = functionSym.Size
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.Fatalf("Error getting function offset: %v", err)
|
|
|
|
|
- return err
|
|
|
|
|
|
|
+ return fmt.Errorf("Error getting function offset: %v", err)
|
|
|
}
|
|
}
|
|
|
fmt.Printf("Actual memory address of %s at base 0x%x: 0x%x\n", functionName, baseAddress, j.ReleaseLibNetInfo.FuncSymbol.SymAddr)
|
|
fmt.Printf("Actual memory address of %s at base 0x%x: 0x%x\n", functionName, baseAddress, j.ReleaseLibNetInfo.FuncSymbol.SymAddr)
|
|
|
err = j.findReleaseAddressInfoFromMem()
|
|
err = j.findReleaseAddressInfoFromMem()
|
|
@@ -615,8 +532,7 @@ func (j *JvmInjector) findDebugFuncContextFromLibPath() error {
|
|
|
functionName := j.DebugLibNetInfo.FuncSymbol.SymName
|
|
functionName := j.DebugLibNetInfo.FuncSymbol.SymName
|
|
|
j.DebugLibNetInfo.LibPath = libPath
|
|
j.DebugLibNetInfo.LibPath = libPath
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.Fatalf("Error finding base addresses: %v", err)
|
|
|
|
|
- return err
|
|
|
|
|
|
|
+ return fmt.Errorf("Error finding base addresses: %v", err)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 获取函数的偏移量
|
|
// 获取函数的偏移量
|
|
@@ -626,17 +542,22 @@ func (j *JvmInjector) findDebugFuncContextFromLibPath() error {
|
|
|
j.DebugLibNetInfo.FuncSymbol.SymSize = functionSym.Size
|
|
j.DebugLibNetInfo.FuncSymbol.SymSize = functionSym.Size
|
|
|
|
|
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.Fatalf("Error getting function offset: %v", err)
|
|
|
|
|
- return err
|
|
|
|
|
|
|
+ return fmt.Errorf("Error getting function offset: %v", err)
|
|
|
}
|
|
}
|
|
|
- fmt.Printf("Actual memory address of %s at base 0x%x: 0x%x\n", functionName, baseAddress, j.DebugLibNetInfo.FuncSymbol.SymAddr)
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 计算recode内存地址
|
|
|
|
|
+ recodeFunctionSym, err := j.getFunctionOffset(libPath, j.RecodeInfo.FuncSymbol.SymName)
|
|
|
|
|
+ j.RecodeInfo.FuncSymbol.SymAddr = baseAddress + recodeFunctionSym.Value
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return fmt.Errorf("Error getting function offset: %v", err)
|
|
|
|
|
+ }
|
|
|
|
|
+ fmt.Printf("DEBUG Actual memory address of %s at base 0x%x: 0x%x\n", functionName, baseAddress, j.DebugLibNetInfo.FuncSymbol.SymAddr)
|
|
|
|
|
+ fmt.Printf("DEBUG Actual memory address of %s at base 0x%x: 0x%x\n", j.RecodeInfo.FuncSymbol.SymName, baseAddress, j.RecodeInfo.FuncSymbol.SymAddr)
|
|
|
|
|
|
|
|
_, err = j.findDebugAddressInfoFromMem()
|
|
_, err = j.findDebugAddressInfoFromMem()
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- //log.Printf("Error finding first CALL instuction: %v", err)
|
|
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
- //fmt.Printf("First CALL instuction o1f %s at base 0x%x: 0x%x\n", functionName, baseAddress, callAddress)
|
|
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -798,14 +719,14 @@ func buildNopEnc(pid int, nopAddr, originAddr uintptr) error {
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func setEncByAddr(pid int, soAddr, originAddr uintptr) error {
|
|
|
|
|
|
|
+func setEncByAddr(pid int, currentAddr, targetAddr uintptr) error {
|
|
|
// 获取目标地址处的数据
|
|
// 获取目标地址处的数据
|
|
|
- originalData, err := readData(pid, originAddr)
|
|
|
|
|
|
|
+ originalData, err := readData(pid, targetAddr)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
// 更新数据中的目标偏移
|
|
// 更新数据中的目标偏移
|
|
|
- err = writeData(pid, soAddr, originalData)
|
|
|
|
|
|
|
+ err = writeData(pid, currentAddr, originalData)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
@@ -829,17 +750,19 @@ set *(unsigned int*)($origin+68) = 0xf2e00012
|
|
|
# blr x18
|
|
# blr x18
|
|
|
set *(unsigned int*)($origin+72) = 0xd63f0240
|
|
set *(unsigned int*)($origin+72) = 0xd63f0240
|
|
|
*/
|
|
*/
|
|
|
-func modifyOriginEnc(pid int, nopAddr uint64, origin uintptr) error {
|
|
|
|
|
|
|
+func modifyOriginEnc(pid int, nopAddr uint64, origin uintptr, recode uintptr) error {
|
|
|
|
|
+ var err error
|
|
|
|
|
+
|
|
|
// Original 64-bit address
|
|
// Original 64-bit address
|
|
|
blrAddr := nopAddr
|
|
blrAddr := nopAddr
|
|
|
- // 拆分四段地址
|
|
|
|
|
|
|
+ // 拆分四段16位地址
|
|
|
// Extract the 16-bit chunks
|
|
// Extract the 16-bit chunks
|
|
|
part1 := blrAddr & 0xFFFF // Lower 16 bits
|
|
part1 := blrAddr & 0xFFFF // Lower 16 bits
|
|
|
part2 := (blrAddr >> 16) & 0xFFFF // Next 16 bits
|
|
part2 := (blrAddr >> 16) & 0xFFFF // Next 16 bits
|
|
|
part3 := (blrAddr >> 32) & 0xFFFF // Upper 16 bits
|
|
part3 := (blrAddr >> 32) & 0xFFFF // Upper 16 bits
|
|
|
part4 := (blrAddr >> 48) & 0xFFFF // MAXUpper 16 bits
|
|
part4 := (blrAddr >> 48) & 0xFFFF // MAXUpper 16 bits
|
|
|
|
|
|
|
|
- err := setEnc(pid, origin+56, buildArm64Enc(part1, OFFSET_0))
|
|
|
|
|
|
|
+ err = setEnc(pid, origin+56, buildArm64Enc(part1, OFFSET_0))
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
@@ -860,6 +783,29 @@ func modifyOriginEnc(pid int, nopAddr uint64, origin uintptr) error {
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ // save change
|
|
|
|
|
+ err = setEncByAddr(pid, recode, origin+56)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ err = setEncByAddr(pid, recode+4, origin+60)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ err = setEncByAddr(pid, recode+8, origin+64)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ err = setEncByAddr(pid, recode+12, origin+68)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ err = setEncByAddr(pid, recode+16, origin+72)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
fmt.Printf("# blr x18 \nset *(unsigned int*)($origin+%d) = 0x%08x\n", PC_START+4*4, 0xD63F0240)
|
|
fmt.Printf("# blr x18 \nset *(unsigned int*)($origin+%d) = 0x%08x\n", PC_START+4*4, 0xD63F0240)
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
@@ -973,13 +919,14 @@ func restoreOriginalInstructions(pid int, addr uintptr, instructions []byte) err
|
|
|
func JvmInject(jvmInjector *JvmInjector) error {
|
|
func JvmInject(jvmInjector *JvmInjector) error {
|
|
|
jvmInjector.DebugLibNetInfo.FuncSymbol.SymName = "CW_Java_java_net_SocketOutputStream_socketWrite0"
|
|
jvmInjector.DebugLibNetInfo.FuncSymbol.SymName = "CW_Java_java_net_SocketOutputStream_socketWrite0"
|
|
|
pid := jvmInjector.Pid
|
|
pid := jvmInjector.Pid
|
|
|
|
|
+
|
|
|
var err error
|
|
var err error
|
|
|
err = jvmInjector.findReleaseFuncContextFromLibPath()
|
|
err = jvmInjector.findReleaseFuncContextFromLibPath()
|
|
|
|
|
|
|
|
fmt.Println(err)
|
|
fmt.Println(err)
|
|
|
- // Debug版本无需修改寄存器 TODO 直接使用原函数 需要在ebpf层适配
|
|
|
|
|
|
|
+ // Debug版本无需修改寄存器 TODO 直接使用原函数 需要在ebpf层适配
|
|
|
|
|
+ // 已经加载so并指令修改正确的
|
|
|
if jvmInjector.PreCheck.EbpfCanInjection {
|
|
if jvmInjector.PreCheck.EbpfCanInjection {
|
|
|
- fmt.Println("Debug version loaded.")
|
|
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -991,7 +938,9 @@ func JvmInject(jvmInjector *JvmInjector) error {
|
|
|
if !jvmInjector.PreCheck.NeedInjectionCheck {
|
|
if !jvmInjector.PreCheck.NeedInjectionCheck {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
printCodeData(jvmInjector.ReleaseLibNetInfo)
|
|
printCodeData(jvmInjector.ReleaseLibNetInfo)
|
|
|
|
|
+
|
|
|
_type, _, err := jvmInjector.findLibBaseFromProcMaps(jvmInjector.DebugLibNetInfo.LibName)
|
|
_type, _, err := jvmInjector.findLibBaseFromProcMaps(jvmInjector.DebugLibNetInfo.LibName)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
// load so
|
|
// load so
|
|
@@ -1004,36 +953,31 @@ func JvmInject(jvmInjector *JvmInjector) error {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- jvmInjector.PreCheck.LoadingCheck = true
|
|
|
|
|
- fmt.Println(err, "So already loaded.")
|
|
|
|
|
- // TODO 指令校验成功后 return nil
|
|
|
|
|
- return fmt.Errorf("So already loaded.")
|
|
|
|
|
|
|
+ if jvmInjector.jvmInjectLib() == 0 {
|
|
|
|
|
+ jvmInjector.PreCheck.LoadingCheck = true
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ //jvmInjector.PreCheck.LoadingCheck = true
|
|
|
|
|
+ //fmt.Println(err, "So already loaded.")
|
|
|
|
|
+ //TODO 指令校验成功后 return nil
|
|
|
|
|
+ //return fmt.Errorf("So already loaded.")
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if !jvmInjector.PreCheck.LoadingCheck {
|
|
if !jvmInjector.PreCheck.LoadingCheck {
|
|
|
- fmt.Println("Failed load so")
|
|
|
|
|
- return err
|
|
|
|
|
|
|
+ return fmt.Errorf("Failed load so")
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
err = jvmInjector.findDebugFuncContextFromLibPath()
|
|
err = jvmInjector.findDebugFuncContextFromLibPath()
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.Fatalf("Failed to find debug Context: %v", err)
|
|
|
|
|
|
|
+ return fmt.Errorf("Failed to find debug Context: %v", err)
|
|
|
}
|
|
}
|
|
|
printCodeData(jvmInjector.DebugLibNetInfo)
|
|
printCodeData(jvmInjector.DebugLibNetInfo)
|
|
|
|
|
|
|
|
- //if !jvmInjector.validateAllPreCheck() {
|
|
|
|
|
- // fmt.Println("failed validateAllPreCheck ")
|
|
|
|
|
- // return err
|
|
|
|
|
- //}
|
|
|
|
|
//// 修改
|
|
//// 修改
|
|
|
debugFuncEnterAddr := uintptr(jvmInjector.DebugLibNetInfo.FuncSymbol.SymAddr)
|
|
debugFuncEnterAddr := uintptr(jvmInjector.DebugLibNetInfo.FuncSymbol.SymAddr)
|
|
|
- //debugIoFdAddr := uintptr(jvmInjector.DebugLibNetInfo.InnerSymbol.IO_fd_fdID.SymAddr)
|
|
|
|
|
- //debugNetSendAddr := uintptr(jvmInjector.DebugLibNetInfo.InnerSymbol.NET_Send.SymAddr)
|
|
|
|
|
- //
|
|
|
|
|
originFuncEnterAddr := uintptr(jvmInjector.ReleaseLibNetInfo.FuncSymbol.SymAddr)
|
|
originFuncEnterAddr := uintptr(jvmInjector.ReleaseLibNetInfo.FuncSymbol.SymAddr)
|
|
|
- //ioFdReleaseTargetAddr := uintptr(jvmInjector.ReleaseLibNetInfo.InnerSymbol.IO_fd_fdID.TargetAddr)
|
|
|
|
|
- //netSendReleaseTargetAddr := uintptr(jvmInjector.ReleaseLibNetInfo.InnerSymbol.NET_Send.TargetAddr)
|
|
|
|
|
- //
|
|
|
|
|
|
|
+ recodeFuncEnterAddr := uintptr(jvmInjector.RecodeInfo.FuncSymbol.SymAddr)
|
|
|
//fmt.Printf("<0x%x> -> <0x%x>\n", originFuncEnterAddr, debugFuncEnterAddr)
|
|
//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", debugIoFdAddr, ioFdReleaseTargetAddr)
|
|
|
//fmt.Printf("<0x%x> -> <0x%x>\n", debugNetSendAddr, netSendReleaseTargetAddr)
|
|
//fmt.Printf("<0x%x> -> <0x%x>\n", debugNetSendAddr, netSendReleaseTargetAddr)
|
|
@@ -1049,7 +993,7 @@ func JvmInject(jvmInjector *JvmInjector) error {
|
|
|
fmt.Printf("wait4: %v", err)
|
|
fmt.Printf("wait4: %v", err)
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
- // 保存原始指令到并扩充新指令
|
|
|
|
|
|
|
+ // 保存原始指令并扩充新指令
|
|
|
err = buildNopEnc(pid, debugFuncEnterAddr, originFuncEnterAddr)
|
|
err = buildNopEnc(pid, debugFuncEnterAddr, originFuncEnterAddr)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
fmt.Println(err)
|
|
fmt.Println(err)
|
|
@@ -1073,8 +1017,8 @@ func JvmInject(jvmInjector *JvmInjector) error {
|
|
|
// return err
|
|
// return err
|
|
|
//}
|
|
//}
|
|
|
|
|
|
|
|
- //变更原指令 长跳转到新地址
|
|
|
|
|
- err = modifyOriginEnc(pid, uint64(debugFuncEnterAddr), originFuncEnterAddr)
|
|
|
|
|
|
|
+ //变更原指令 长跳转到新地址 保存到recode
|
|
|
|
|
+ err = modifyOriginEnc(pid, uint64(debugFuncEnterAddr), originFuncEnterAddr, recodeFuncEnterAddr)
|
|
|
|
|
|
|
|
//// 更新函数入口
|
|
//// 更新函数入口
|
|
|
//err = modifyReleaseFuncEnter(pid, originFuncEnterAddr, debugFuncEnterAddr)
|
|
//err = modifyReleaseFuncEnter(pid, originFuncEnterAddr, debugFuncEnterAddr)
|