unit RipRelativeScanner; { This class will scan a given module and return the rip relative instructions } {$mode delphi} interface uses Windows, Classes, SysUtils, disassembler, symbolhandler, processhandlerunit, NewKernelHandler, CEFuncProc; type TRIPRelativeScanner=class private modulebase: ptruint; modulesize: dword; executablelist: array of record base: ptruint; size: dword; end; addresslist: array of ptruint; valuelist: array of ptruint; addresslistpos: integer; addresslistsize: integer; function getAddress(i: integer): ptruint; procedure scan(startaddress, stopaddress: ptruint; includeLongJumpsAndCalls: boolean; modulebase: ptruint=0; modulesize: ptruint=0); public constructor create(startaddress, stopaddress: ptruint; includeLongJumpsAndCalls: boolean); overload; constructor create(modulename: string; includeLongJumpsAndCalls: boolean); overload; property Address[i: integer]: ptruint read getAddress; published property Count: integer read addresslistpos; end; implementation function TRIPRelativeScanner.getAddress(i: integer): ptruint; begin result:=0; if (i<0) or (i>=addresslistpos) then exit; result:=addresslist[i]; end; procedure TRIPRelativeScanner.scan(startaddress, stopaddress: ptruint; includeLongJumpsAndCalls: boolean; modulebase: ptruint=0; modulesize: ptruint=0); var currentbase: ptruint; mbi: TMemoryBasicInformation; d: TDisassembler; a: ptruint; stop: ptruint; i: integer; desc: string; begin //querry the executable memory regions currentbase:=startaddress; zeromemory(@mbi, sizeof(mbi)); while (currentbase0 then begin setlength(executablelist, length(executablelist)+1); executablelist[length(executablelist)-1].base:=ptruint(mbi.BaseAddress); executablelist[length(executablelist)-1].size:=mbi.RegionSize; end; currentbase:=ptruint(mbi.BaseAddress)+mbi.RegionSize; end; setlength(addresslist, 512); addresslistsize:=512; addresslistpos:=0; d:=TDisassembler.Create; d.dataOnly:=true; d.MarkIPRelativeInstructions:=includeLongJumpsAndCalls; try for i:=0 to length(executablelist)-1 do begin a:=maxx(startaddress, executablelist[i].base); stop:=MinX(stopaddress, executablelist[i].base+executablelist[i].size); while a0) and ((modulebase=0) or InRangeX(d.LastDisassembleData.modrmValue, modulebase, modulebase+modulesize)) then begin //found one addresslist[addresslistpos]:=d.LastDisassembleData.address+d.LastDisassembleData.riprelative; inc(addresslistpos); if addresslistpos>=addresslistsize then begin addresslistsize:=addresslistsize*2; setlength(addresslist, addresslistsize); end; end; end else inc(a, 8-(a mod 8)); //this can cause an alignment issue end; end; finally d.free; end; end; constructor TRIPRelativeScanner.create(startaddress, stopaddress: ptruint; includeLongJumpsAndCalls: boolean); begin scan(startaddress, stopaddress, includeLongJumpsAndCalls); end; constructor TRIPRelativeScanner.create(modulename: string; includeLongJumpsAndCalls: boolean); var mi: TModuleInfo; begin if (includeLongJumpsAndCalls or processhandler.is64bit) and symhandler.getmodulebyname(modulename, mi) then begin modulebase:=mi.baseaddress; modulesize:=mi.basesize; scan(modulebase, modulebase+modulesize, includeLongJumpsAndCalls, modulebase, modulesize); end; end; end.