unit stacktrace2; {$MODE Delphi} interface uses LCLIntf, sysutils, classes, symbolhandler, CEFuncProc, NewKernelHandler, byteinterpreter, commonTypeDefs; procedure seperatestacktraceline(s: string; var address: string; var bytes: string; var details: string); procedure ce_stacktrace(esp: ptrUint; ebp: ptrUint; eip: ptrUint; stack: Pbytearray; sizeinbytes: integer; trace: tstrings; force4byteblocks: boolean=true; showmodulesonly: boolean=false; nosystemmodules:boolean=false; maxdepth:integer=0; ShowEBPinsteadOfESP: boolean=false); implementation uses StrUtils, ProcessHandlerUnit; procedure seperatestacktraceline(s: string; var address: string; var bytes: string; var details: string); var i,j: integer; begin //has 2 ' - ' occurances i:=pos(' - ',s); address:=copy(s,1,i-1); j:=posex(' - ',s,i+3); bytes:=copy(s,i+3,j-(i+3)); details:=copy(s,j+3,length(s)); //leftover end; procedure ce_stacktrace(esp: ptrUint; ebp: ptrUint; eip: ptrUint; stack: Pbytearray; sizeinbytes: integer; trace: tstrings; force4byteblocks: boolean=true; showmodulesonly: boolean=false; nosystemmodules:boolean=false; maxdepth:integer=0; ShowEBPinsteadOfESP: boolean=false); { ce_stacktrace will walk the provided stack trying to figure out functionnames ,passed strings and optional other data esp must be aligned on a 4 byte boundary the first entry alignment but other entries will try to be forced to 4 byte alignment unless otherwise needed (double, string,...) if eip is in a known function location this can help with the parameter naming (for the location of ebp) esp is the first 4 byte of stack nosystemmodules is only in effect when show moduleso only is enabled } var alignedstack: pbytearray; alignedstack32: PDwordArray absolute alignedstack; alignedstack64: Puint64Array absolute alignedstack; i: integer; Entries: integer; currentStackpos: ptruint; currentStackValue: ptruint; address: string; value: string; secondary: string; v: TVariableType; oldi: integer; originalesp: ptruint; offset: ptrint; offsetstring: string; pref: char; begin if processhandler.is64bit then pref:='r' else pref:='e'; originalesp:=esp; i:=esp mod processhandler.pointersize; if i>0 then begin //unalligned alignedstack:=stack+(processhandler.pointersize-i); dec(sizeinbytes,processhandler.pointersize-i); inc(esp,i); end else alignedstack:=stack; dec(sizeinbytes,sizeinbytes mod processhandler.pointersize); //so it's a full boundary Entries:=sizeinbytes div processhandler.pointersize; i:=0; while i0) and (trace.Count>=maxdepth) then exit; inc(esp, (i-oldi)*processhandler.pointersize); end; end; end.