unit x86_index_instr; {$mode ObjFPC}{$H+} {$CALLING SysV_ABI_CDecl} interface const //instruction reg RAX= 0; RCX= 1; RDX= 2; RBX= 3; RSP= 4; RBP= 5; RSI= 6; RDI= 7; R8 = 8; R9 = 9; R10=10; R11=11; R12=12; R13=13; R14=14; R15=15; //instruction segment base FSBASE=16; GSBASE=17; //instruction id I_MOV_BASE32=0; I_MOV_BASE64=1; I_SYSCALL =2; type p_instr_index_info=^t_instr_index_info; t_instr_index_info=record inlen:Byte; //instruction len instr:Byte; //instruction id inreg:Byte; //instruction reg sbase:Byte; //instruction segment base osize:Byte; //instruction data offset size offst:Int64; //instruction data offset end; function IndexInstr(var pbuf:Pointer;pend:Pointer;var info:t_instr_index_info):Boolean; implementation function IndexInstr(var pbuf:Pointer;pend:Pointer;var info:t_instr_index_info):Boolean; var psrc:Pointer; W:DWORD; i:Integer; offset:Int64; begin Result:=False; i:=-1; psrc:=pbuf; while (psrc$25) then begin Inc(psrc,4); Continue; end; offset:=PInteger(@PBYTE(psrc)[5])^; if (offset>+65536) or (offset<-65536) then begin Inc(psrc,4); Continue; end; info.inlen:=9; info.instr:=I_MOV_BASE32; case i of 0..15:info.inreg:=i; 17..32:info.inreg:=i-17; else; end; case i of 0..15:info.sbase:=FSBASE; 17..32:info.sbase:=GSBASE; else; end; info.osize:=4; info.offst:=offset; end; 16, 33: begin offset:=PInt64(@PBYTE(psrc)[3])^; if (offset>+65536) or (offset<-65536) then begin Inc(psrc,4); Continue; end; info.inlen:=12; info.instr:=I_MOV_BASE64; info.inreg:=RAX; case i of 16:info.sbase:=FSBASE; 33:info.sbase:=GSBASE; else; end; info.osize:=8; info.offst:=offset; end; 34: begin if (PDWORD(@PBYTE(psrc)[4])^<>$050FCA89) then begin Inc(psrc,4); Continue; end; Case PBYTE(psrc)[8] of $41, $48, $5f, $72, $c3:; else begin Inc(psrc,4); Continue; end; end; Inc(psrc,3); info.inlen:=5; info.instr:=I_SYSCALL; info.sbase:=0; info.osize:=0; info.offst:=0; end; else; end; if (i<>-1) then begin pbuf:=psrc; Exit(True); end; Inc(psrc); end; //while end; end.