From f2051b2f230765a5596a4b59ccba60d169f8a838 Mon Sep 17 00:00:00 2001 From: pkujhd Date: Wed, 6 Sep 2023 09:09:24 +0800 Subject: [PATCH] fix #87 rewrite R_CALL and PCRELxCALL to avoid panic 'unexpected return pc 0x0' when switch stack on call instrunction --- asm_bytes.go | 4 ++++ relocate.go | 28 ++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/asm_bytes.go b/asm_bytes.go index 4c95d1f4..a5ca555c 100644 --- a/asm_bytes.go +++ b/asm_bytes.go @@ -26,6 +26,10 @@ var ( x86amd64NOPcode = []byte{0x90} // NOP x86amd64JMPLcode = []byte{0xff, 0x25, 0x00, 0x00, 0x00, 0x00} // JMPL *ADDRESS x86amd64JMPNcode = []byte{0xE9, 0x00, 0x00, 0x00, 0x00} // JMP (PCREL offset)+4 + x86amd64replaceCALLcode = []byte{ + 0xFF, 0x15, 0x00, 0x00, 0x00, 0x00, //CALL *(rel)rip + 0xE9, 0x00, 0x00, 0x00, 0x00, //JMP (PCREL offset)+4 + } x86amd64replaceCMPLcode = []byte{ 0x50, // PUSH RAX 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // MOVABS RAX x (64 bit) diff --git a/relocate.go b/relocate.go index 0bfacd82..dbe6806c 100644 --- a/relocate.go +++ b/relocate.go @@ -19,9 +19,9 @@ const ( maxExtraCodeSize_ARM64_PCREL_LDST = 24 maxExtraCodeSize_PCRELxMOV = 18 maxExtraCodeSize_PCRELxCMPL = 21 - maxExtraCodeSize_PCRELxCALL = 14 + maxExtraCodeSize_PCRELxCALL = 11 maxExtraCodeSize_PCRELxJMP = 14 - maxExtraCodeSize_CALL = 14 + maxExtraCodeSize_CALL = 11 ) func expandFunc(linker *Linker, objsym *obj.ObjSymbol, symbol *obj.Sym) { @@ -154,11 +154,17 @@ func (linker *Linker) relocateCALL(addr uintptr, loc obj.Reloc, segment *segment byteorder := linker.Arch.ByteOrder offset := int(addr) - (addrBase + loc.Offset + loc.Size) + loc.Add if offset > 0x7FFFFFFF || offset < -0x80000000 { + segment.dataOff = alignof(segment.dataOff, PtrSize) epilogueOffset := loc.Epilogue.Offset offset = (segment.codeBase + epilogueOffset) - (addrBase + loc.Offset + loc.Size) - copy(segment.codeByte[epilogueOffset:], x86amd64JMPLcode) - epilogueOffset += len(x86amd64JMPLcode) - putAddressAddOffset(byteorder, segment.codeByte, &epilogueOffset, uint64(addr)+uint64(loc.Add)) + relocByte[loc.Offset-1] = x86amd64JMPcode + copy(segment.codeByte[epilogueOffset:], x86amd64replaceCALLcode) + off := (segment.dataBase + segment.dataOff - segment.codeBase - epilogueOffset - 6) + byteorder.PutUint32(segment.codeByte[epilogueOffset+2:], uint32(off)) + putAddressAddOffset(byteorder, segment.dataByte, &segment.dataOff, uint64(addr)+uint64(loc.Add)) + epilogueOffset += len(x86amd64replaceCALLcode) + off = addrBase + loc.Offset + loc.Size - segment.codeBase - epilogueOffset + byteorder.PutUint32(segment.codeByte[epilogueOffset-4:], uint32(off)) } byteorder.PutUint32(relocByte[loc.Offset:], uint32(offset)) } @@ -202,9 +208,15 @@ func (linker *Linker) relocatePCREL(addr uintptr, loc obj.Reloc, segment *segmen putAddress(byteorder, segment.codeByte[epilogueOffset+2:], uint64(addr)+uint64(loc.Add)) epilogueOffset += len(x86amd64replaceMOVQcode) case x86amd64CALLcode: - copy(segment.codeByte[epilogueOffset:], x86amd64JMPLcode) - epilogueOffset += len(x86amd64JMPLcode) - putAddressAddOffset(byteorder, segment.codeByte, &epilogueOffset, uint64(addr)+uint64(loc.Add)) + segment.dataOff = alignof(segment.dataOff, PtrSize) + bytes[1] = x86amd64JMPcode + copy(segment.codeByte[epilogueOffset:], x86amd64replaceCALLcode) + off := (segment.dataBase + segment.dataOff - segment.codeBase - epilogueOffset - 6) + byteorder.PutUint32(segment.codeByte[epilogueOffset+2:], uint32(off)) + epilogueOffset += len(x86amd64replaceCALLcode) + putAddressAddOffset(byteorder, segment.dataByte, &segment.dataOff, uint64(addr)+uint64(loc.Add)) + off = addrBase + loc.Offset + loc.Size - segment.codeBase - epilogueOffset + byteorder.PutUint32(segment.codeByte[epilogueOffset-4:], uint32(off)) case x86amd64JMPcode: copy(segment.codeByte[epilogueOffset:], x86amd64JMPLcode) epilogueOffset += len(x86amd64JMPLcode)