pkg/proc: fix StepBreakpoint handling
StepBreakpoints are set on CALL instructions, when they are hit we disassemble the current instruction, figure out the destination address and set a breakpoint after the prologue of the called function. In order to disassemble the current instruction we disassemble the area of memory starting from PC and going to PC+15 (because 15 bytes is the maximum length of one instruction on AMD64). This means that we won't just disassemble one instruction but also a few instructions following it ending with one truncated instruction. This usually works fine but sometimes the disassembler will panic with an array out of bounds error when trying to disassemble a truncated instruction. To avoid this problem this commit changes the funciton disassemble to take one extra parameter, singleInstr, when singleInstr is set disassemble will quit after disassembling a single instruction.
This commit is contained in:
parent
5f0f77f414
commit
bc86c662a6
@ -27,7 +27,7 @@ func Disassemble(dbp Process, g *G, startPC, endPC uint64) ([]AsmInstruction, er
|
||||
if g == nil {
|
||||
ct := dbp.CurrentThread()
|
||||
regs, _ := ct.Registers(false)
|
||||
return disassemble(ct, regs, dbp.Breakpoints(), dbp.BinInfo(), startPC, endPC)
|
||||
return disassemble(ct, regs, dbp.Breakpoints(), dbp.BinInfo(), startPC, endPC, false)
|
||||
}
|
||||
|
||||
var regs Registers
|
||||
@ -37,10 +37,10 @@ func Disassemble(dbp Process, g *G, startPC, endPC uint64) ([]AsmInstruction, er
|
||||
regs, _ = g.Thread.Registers(false)
|
||||
}
|
||||
|
||||
return disassemble(mem, regs, dbp.Breakpoints(), dbp.BinInfo(), startPC, endPC)
|
||||
return disassemble(mem, regs, dbp.Breakpoints(), dbp.BinInfo(), startPC, endPC, false)
|
||||
}
|
||||
|
||||
func disassemble(memrw MemoryReadWriter, regs Registers, breakpoints *BreakpointMap, bi *BinaryInfo, startPC, endPC uint64) ([]AsmInstruction, error) {
|
||||
func disassemble(memrw MemoryReadWriter, regs Registers, breakpoints *BreakpointMap, bi *BinaryInfo, startPC, endPC uint64, singleInstr bool) ([]AsmInstruction, error) {
|
||||
mem := make([]byte, int(endPC-startPC))
|
||||
_, err := memrw.ReadMemory(mem, uintptr(startPC))
|
||||
if err != nil {
|
||||
@ -77,6 +77,9 @@ func disassemble(memrw MemoryReadWriter, regs Registers, breakpoints *Breakpoint
|
||||
pc++
|
||||
mem = mem[1:]
|
||||
}
|
||||
if singleInstr {
|
||||
break
|
||||
}
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ func FirstPCAfterPrologue(p Process, fn *Function, sameline bool) (uint64, error
|
||||
var mem MemoryReadWriter = p.CurrentThread()
|
||||
breakpoints := p.Breakpoints()
|
||||
bi := p.BinInfo()
|
||||
text, err := disassemble(mem, nil, breakpoints, bi, fn.Entry, fn.End)
|
||||
text, err := disassemble(mem, nil, breakpoints, bi, fn.Entry, fn.End, false)
|
||||
if err != nil {
|
||||
return fn.Entry, err
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ func Continue(dbp Process) error {
|
||||
return err
|
||||
}
|
||||
pc := regs.PC()
|
||||
text, err := disassemble(curthread, regs, dbp.Breakpoints(), dbp.BinInfo(), pc, pc+maxInstructionLength)
|
||||
text, err := disassemble(curthread, regs, dbp.Breakpoints(), dbp.BinInfo(), pc, pc+maxInstructionLength, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ func next(dbp Process, stepInto bool) error {
|
||||
}
|
||||
}
|
||||
|
||||
text, err := disassemble(thread, regs, dbp.Breakpoints(), dbp.BinInfo(), topframe.Current.Fn.Entry, topframe.Current.Fn.End)
|
||||
text, err := disassemble(thread, regs, dbp.Breakpoints(), dbp.BinInfo(), topframe.Current.Fn.Entry, topframe.Current.Fn.End, false)
|
||||
if err != nil && stepInto {
|
||||
return err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user