unit libipt; {$mode DELPHI} interface uses Windows, Classes, SysUtils; const pt_asid_no_cr3 = QWORD($ffffffffffffffff); pt_asid_no_vmcs = QWORD($ffffffffffffffff); pt_max_insn_size= 15; type pt_error_code = (pte_ok,pte_internal,pte_invalid,pte_nosync, pte_bad_opc,pte_bad_packet,pte_bad_context, pte_eos,pte_bad_query,pte_nomem,pte_bad_config, pte_noip,pte_ip_suppressed,pte_nomap, pte_bad_insn,pte_no_time,pte_no_cbr, pte_bad_image,pte_bad_lock,pte_not_supported, pte_retstack_empty,pte_bad_retcomp, pte_bad_status_update,pte_no_enable, pte_event_ignored); {$PACKENUM 4} pt_insn_class = (ptic_error,ptic_other,ptic_call,ptic_return, ptic_jump,ptic_cond_jump,ptic_far_call, ptic_far_return,ptic_far_jump); {$PACKENUM DEFAULT} pt_exec_mode = (ptem_unknown,ptem_16bit,ptem_32bit,ptem_64bit); PPT_Image=pointer; Ppt_encoder = pointer; Ppt_packet_decoder = pointer; Ppt_query_decoder = pointer; Ppt_insn_decoder = pointer; Ppt_packet_unknown = pointer; TPT_ASID=record size: SIZE_T; cr3: uint64; vmcs: uint64; end; PPT_ASID=^TPT_ASID; Ppt_insn = ^pt_insn; pt_insn = record ip : uint64; iclass : pt_insn_class; mode : pt_exec_mode; raw : array[0..(pt_max_insn_size)-1] of uint8; size : uint8; flag0 : word; { flag0 bit: 0: speculative - the instruction was executed speculatively. 1: aborted - speculative execution was aborted after this instruction 2: committed - speculative execution was committed after this instruction 3: disabled - tracing was disabled after this instruction. 4: enabled - tracing was enabled at this instruction 5: resumed - tracing was resumed at this instruction. In addition to tracing being enabled, it continues from the IP at which tracing had been disabled before. 6: interrupted - normal execution flow was interrupted after this instruction. 7: resynced - tracing resumed at this instruction after an overflow. 8: stopped - tracing was stopped after this instruction } end; pt_cpu_vendor = (pcv_unknown,pcv_intel); Ppt_cpu = ^pt_cpu; pt_cpu = record vendor : pt_cpu_vendor; family : uint16; model : uint8; stepping : uint8; end; ppt_errata = ^pt_errata; pt_errata = record flag0 : word; reserved : array[0..14] of uint32; end; Ppt_config = ^pt_config; pt_config = record size : size_t; beginaddress : pointer; endaddress : pointer; decode : record callback : function (unknown:Ppt_packet_unknown; config:Ppt_config; pos:Puint8; context:pointer):integer;cdecl; context : pointer; end; cpu : pt_cpu; errata : pt_errata; cpuid_0x15_eax : uint32; cpuid_0x15_ebx : uint32; mtc_freq : uint8; nom_freq : uint8; end; Tread_memory_callback=function(buffer: PByteArray; size: SIZE_T; asid: PPT_ASID; ip: uint64; context: pointer): integer; cdecl; pt_event_type = (ptev_enabled,ptev_disabled,ptev_async_disabled, ptev_async_branch,ptev_paging,ptev_async_paging, ptev_overflow,ptev_exec_mode,ptev_tsx, ptev_stop,ptev_vmcs,ptev_async_vmcs ); Ppt_event = ^pt_event; pt_event = record _type : pt_event_type; flag0 : word; tsc : uint64; lost_mtc : uint32; lost_cyc : uint32; reserved : array[0..1] of uint64; variant : record case longint of 0 : ( enabled : record ip : uint64; end ); 1 : ( disabled : record ip : uint64; end ); 2 : ( async_disabled : record at : uint64; ip : uint64; end ); 3 : ( async_branch : record froma : uint64; toa : uint64; end ); 4 : ( paging : record cr3 : uint64; flag0 : word; end ); 5 : ( async_paging : record cr3 : uint64; flag0 : word; ip : uint64; end ); 6 : ( overflow : record ip : uint64; end ); 7 : ( exec_mode : record mode : pt_exec_mode; ip : uint64; end ); 8 : ( tsx : record ip : uint64; flag0 : word; end ); 9 : ( vmcs : record base : uint64; end ); 10 : ( async_vmcs : record base : uint64; ip : uint64; end ); end; end; var pt_image_alloc:function(name: pchar): PPT_Image; cdecl; pt_image_free:procedure(img: PPT_Image); cdecl; pt_image_set_callback: function(img: PPT_Image; callback: Tread_memory_callback; context: pointer): integer; cdecl; pt_cpu_read:function (cpu: ppt_cpu): integer; cdecl; pt_cpu_errata: function(errata: ppt_errata; cpu: ppt_cpu): integer; cdecl; pt_insn_alloc_decoder:function(config: ppt_config): ppt_insn_decoder; cdecl; pt_insn_free_decoder:procedure(decoder: ppt_insn_decoder); cdecl; pt_insn_set_image:function(decoder: ppt_insn_decoder; image: PPT_Image): integer; cdecl; pt_insn_sync_forward:function(decoder: ppt_insn_decoder): integer; cdecl; pt_insn_next: function(decoder: ppt_insn_decoder; insn: Ppt_insn; size: size_t): integer; cdecl; pt_insn_get_offset:function(decoder: Ppt_insn_decoder; offset: PQWord): integer; cdecl; pt_qry_alloc_decoder:function(config: ppt_config): ppt_query_decoder; cdecl; pt_qry_free_decoder:procedure(decoder: ppt_query_decoder); cdecl; pt_qry_sync_forward: function(decoder: ppt_query_decoder; ip: pqword): integer; cdecl; pt_qry_get_offset: function(decoder: ppt_query_decoder; offset: pqword): integer; cdecl; pt_qry_indirect_branch: function(decoder: ppt_query_decoder; ip: pqword): integer; cdecl; pt_qry_event:function(decoder: ppt_query_decoder; event: Ppt_event; size: size_t): integer; cdecl; pt_qry_cond_branch: function(decoder: Ppt_query_decoder; taken: pinteger): integer; cdecl; procedure pt_asid_init(asid: PPT_ASID); inline; procedure pt_config_init(config: ppt_config); inline; function libIptInit: boolean; implementation var hLibIPT: HModule=0; procedure pt_asid_init(asid: PPT_ASID); inline; begin asid^.size:=sizeof(TPT_ASID); asid^.cr3:=pt_asid_no_cr3; asid^.vmcs:=pt_asid_no_vmcs; end; procedure pt_config_init(config: ppt_config); inline; begin zeromemory(config, sizeof(pt_config)); config^.size:=sizeof(pt_config); end; function libIptInit: boolean; begin if hLibIPT=0 then begin hLibIPT:=LoadLibrary('libipt-64.dll'); if hLibIPT=0 then hLibIPT:=LoadLibrary('D:\svn\Cheat Engine\bin\libipt-64.dll'); //during debug if hLibIPT<>0 then begin pt_image_alloc:=GetProcAddress(hLibIPT, 'pt_image_alloc'); pt_image_free:=GetProcAddress(hLibIPT, 'pt_image_free'); pt_image_set_callback:=GetProcAddress(hLibIPT, 'pt_image_set_callback'); pt_cpu_read:=GetProcAddress(hLibIPT, 'pt_cpu_read'); pt_cpu_errata:=GetProcAddress(hLibIPT, 'pt_cpu_errata'); pt_insn_alloc_decoder:=GetProcAddress(hLibIPT, 'pt_insn_alloc_decoder'); pt_insn_free_decoder:=GetProcAddress(hLibIPT, 'pt_insn_free_decoder'); pt_insn_set_image:=GetProcAddress(hLibIPT, 'pt_insn_set_image'); pt_insn_sync_forward:=GetProcAddress(hLibIPT, 'pt_insn_sync_forward'); pt_insn_next:=GetProcAddress(hLibIPT, 'pt_insn_next'); pt_insn_get_offset:=GetProcAddress(hLibIPT, 'pt_insn_get_offset'); pt_qry_alloc_decoder:=GetProcAddress(hLibIPT, 'pt_qry_alloc_decoder'); pt_qry_free_decoder:=GetProcAddress(hLibIPT, 'pt_qry_free_decoder'); pt_qry_sync_forward:=GetProcAddress(hLibIPT, 'pt_qry_sync_forward'); pt_qry_indirect_branch:=GetProcAddress(hLibIPT, 'pt_qry_indirect_branch'); pt_qry_get_offset:=GetProcAddress(hLibIPT, 'pt_qry_get_offset'); pt_qry_event:=GetProcAddress(hLibIPT, 'pt_qry_event'); pt_qry_cond_branch:=GetProcAddress(hLibIPT, 'pt_qry_event'); end; end; result:=hLibIPT<>0; end; end.