This commit is contained in:
Pavel 2023-07-28 17:13:41 +03:00
parent 8857e2aab9
commit 9dcba4f540
8 changed files with 568 additions and 237 deletions

260
rtl/x86_index_instr.pas Normal file
View File

@ -0,0 +1,260 @@
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<pend) do
begin
W:=PDWORD(psrc)^;
Case W of
$048B4864:i:= 0; //fs_rax
$0C8B4864:i:= 1; //fs_rcx
$148B4864:i:= 2; //fs_rdx
$1C8B4864:i:= 3; //fs_rbx
$248B4864:i:= 4; //fs_rsp
$2C8B4864:i:= 5; //fs_rbp
$348B4864:i:= 6; //fs_rsi
$3C8B4864:i:= 7; //fs_rdi
$048B4C64:i:= 8; //fs_r8
$0C8B4C64:i:= 9; //fs_r9
$148B4C64:i:=10; //fs_r10
$1C8B4C64:i:=11; //fs_r11
$248B4C64:i:=12; //fs_r12
$2C8B4C64:i:=13; //fs_r13
$348B4C64:i:=14; //fs_r14
$3C8B4C64:i:=15; //fs_r15
$00A14864:i:=16; //fs_rax64
$048B4865:i:=17; //gs_rax
$0C8B4865:i:=18; //gs_rcx
$148B4865:i:=19; //gs_rdx
$1C8B4865:i:=20; //gs_rbx
$248B4865:i:=21; //gs_rsp
$2C8B4865:i:=22; //gs_rbp
$348B4865:i:=23; //gs_rsi
$3C8B4865:i:=24; //gs_rdi
$048B4C65:i:=25; //gs_r8
$0C8B4C65:i:=26; //gs_r9
$148B4C65:i:=27; //gs_r10
$1C8B4C65:i:=28; //gs_r11
$248B4C65:i:=29; //gs_r12
$2C8B4C65:i:=30; //gs_r13
$348B4C65:i:=31; //gs_r14
$3C8B4C65:i:=32; //gs_r15
$00A14865:i:=33; //gs_rax64
$49000000,
$49000001,
$49000002:i:=34; //syscall
//shft 8
$8B486400..$8B4864FF, //fs
$8B4C6400..$8B4C64FF, //fs
$A1486400..$A14864FF, //fs
$8B486500..$8B4865FF, //gs
$8B4C6500..$8B4C65FF, //gs
$A1486500..$A14865FF, //gs
$00000000..$000002FF: //sv
begin
Inc(psrc,1);
Continue;
end;
//shft 16
$48640000..$4864FFFF, //fs
$4C640000..$4C64FFFF, //fs
$48650000..$4865FFFF, //gs
$4C650000..$4C65FFFF, //gs
$00000300..$0002FFFF: //sv
begin
Inc(psrc,2);
Continue;
end;
//shft 24
$64000000..$64FFFFFF, //fs
$65000000..$65FFFFFF, //gs
$00030000..$00A14863, //sv
$00A14866..$02FFFFFF: //sv
begin
Inc(psrc,3);
Continue;
end;
else
begin
Inc(psrc,4);
Continue;
end;
end;
Case i of
0..15,
17..32:
begin
if (PBYTE(psrc)[4]<>$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.

View File

@ -371,10 +371,11 @@ type
t_jmpq64_trampoline=packed record
lea:array[0..6] of Byte;
//
inst :Word; //FF 25
offset:DWORD; //00
addr :QWORD;
str :PChar;
inst :Word; //FF 25
offset :DWORD; //00
addr :QWORD;
str :PChar;
libname:PChar;
end;
const
@ -382,11 +383,11 @@ const
procedure _unresolve_symbol(data:p_jmpq64_trampoline);
begin
Writeln('_unresolve_symbol:',data^.str);
Writeln('_unresolve_symbol:',data^.str,':',data^.libname);
readln;
end;
function get_unresolve_ptr(str:PChar):Pointer;
function get_unresolve_ptr(str,libname:PChar):Pointer;
var
stub:p_stub_chunk;
begin
@ -395,6 +396,7 @@ begin
p_jmpq64_trampoline(@stub^.body)^:=c_jmpq64_trampoline;
p_jmpq64_trampoline(@stub^.body)^.addr:=QWORD(@_unresolve_symbol);
p_jmpq64_trampoline(@stub^.body)^.str:=str;
p_jmpq64_trampoline(@stub^.body)^.libname:=libname;
Result:=@stub^.body;
end;
@ -493,7 +495,7 @@ begin
begin
dynlibs_info.sym_nops.st_info :=(STB_GLOBAL shl 4) or STT_NOTYPE;
dynlibs_info.sym_nops.st_shndx:=SHN_UNDEF;
dynlibs_info.sym_nops.st_value:=-Int64(dynlibs_info.libprogram^.relocbase)+Int64(get_unresolve_ptr(str));
dynlibs_info.sym_nops.st_value:=-Int64(dynlibs_info.libprogram^.relocbase)+Int64(get_unresolve_ptr(str,req.libname));
def :=@dynlibs_info.sym_nops;
defobj:=dynlibs_info.libprogram;

View File

@ -844,6 +844,11 @@ begin
end;
end;
procedure null_init; assembler; nostackframe;
asm
//
end;
function dynlib_proc_initialize_step2(imgp:p_image_params):Integer;
var
obj,tail:p_lib_info;
@ -895,8 +900,8 @@ begin
tail,
dynlibs_info.init_proc_list);
obj^.init_proc_addr:=init_proc_addr;
obj^.fini_proc_addr:=fini_proc_addr;
obj^.init_proc_addr:=@null_init;//init_proc_addr;
obj^.fini_proc_addr:=@null_init;//fini_proc_addr;
///
end;

View File

@ -17,7 +17,8 @@ uses
kern_thr,
vm_pmap,
vm_patch_link,
trap;
trap,
x86_index_instr;
{
64 48 A1 [0000000000000000] mov rax,fs:[$0000000000000000] -> 65 48 A1 [0807000000000000] mov rax,gs:[$0000000000000708]
@ -39,6 +40,25 @@ uses
64 4C 8B 3C 25 [00000000] mov r15,fs:[$00000000] -> 65 4C 8B 3C 25 [08070000] mov r15,gs:[$00000708]
}
{
90488B80 [11111111] mov rax,[rax+$11111111]
90488B89 [11111111] mov rcx,[rcx+$11111111]
90488B92 [11111111] mov rdx,[rdx+$11111111]
90488B9B [11111111] mov rbx,[rbx+$11111111]
488BA424 [11111111] mov rsp,[rsp+$11111111]
90488BAD [11111111] mov rbp,[rbp+$11111111]
90488BB6 [11111111] mov rsi,[rsi+$11111111]
90488BBF [11111111] mov rdi,[rdi+$11111111]
904D8B80 [11111111] mov r8 ,[r8 +$11111111]
904D8B89 [11111111] mov r9 ,[r9 +$11111111]
904D8B92 [11111111] mov r10,[r10+$11111111]
904D8B9B [11111111] mov r11,[r11+$11111111]
4D8BA424 [11111111] mov r12,[r12+$11111111]
904D8BAD [11111111] mov r13,[r13+$11111111]
904D8BB6 [11111111] mov r14,[r14+$11111111]
904D8BBF [11111111] mov r15,[r15+$11111111]
}
{
[48 b8 | 10 01 00 00 00 00 00 00]:MOV RAX,0x110
@ -201,6 +221,7 @@ c3 RET
}
type
{
p_patch_base_long=^t_patch_base_long;
t_patch_base_long=packed record
len :Byte ; //12
@ -221,6 +242,7 @@ type
1:(B:t_patch_base_short);
2:(C:array[0..11] of Byte);
end;
}
p_jmpq64_trampoline=^t_jmpq64_trampoline;
t_jmpq64_trampoline=packed record
@ -235,8 +257,28 @@ type
addr:Integer;
end;
p_mov_rel_base32=^t_mov_rel_base32;
t_mov_rel_base32=packed record
inst:array[0..4] of Byte;
addr:Integer; //teb_tcb/teb_gsbase
end;
p_mov_rel32=^t_mov_rel32;
t_mov_rel32=packed record
inst:array[0..3] of Byte;
addr:Integer; //offset
end;
p_base_data_trampoline=^t_base_data_trampoline;
t_base_data_trampoline=packed record
bseg:t_mov_rel_base32;
data:t_mov_rel32;
bjmp:t_jmpq64_trampoline;
end;
const
patch_table:array[0..33] of t_patch_inst=(
{
patch_table:array[0..33] of t_patch_inst=(
(B:(len: 9;inst:($65,$48,$8B,$04,$25);addr:teb_tcb )),
(B:(len: 9;inst:($65,$48,$8B,$0C,$25);addr:teb_tcb )),
(B:(len: 9;inst:($65,$48,$8B,$14,$25);addr:teb_tcb )),
@ -273,196 +315,131 @@ const
(B:(len: 9;inst:($65,$4C,$8B,$3C,$25);addr:teb_gsbase)),
(A:(len:12;inst:($65,$48,$A1 );addr:teb_gsbase))
);
}
patch_fs_table:array[0..15] of t_mov_rel_base32=(
(inst:($65,$48,$8B,$04,$25);addr:teb_tcb),
(inst:($65,$48,$8B,$0C,$25);addr:teb_tcb),
(inst:($65,$48,$8B,$14,$25);addr:teb_tcb),
(inst:($65,$48,$8B,$1C,$25);addr:teb_tcb),
(inst:($65,$48,$8B,$24,$25);addr:teb_tcb),
(inst:($65,$48,$8B,$2C,$25);addr:teb_tcb),
(inst:($65,$48,$8B,$34,$25);addr:teb_tcb),
(inst:($65,$48,$8B,$3C,$25);addr:teb_tcb),
(inst:($65,$4C,$8B,$04,$25);addr:teb_tcb),
(inst:($65,$4C,$8B,$0C,$25);addr:teb_tcb),
(inst:($65,$4C,$8B,$14,$25);addr:teb_tcb),
(inst:($65,$4C,$8B,$1C,$25);addr:teb_tcb),
(inst:($65,$4C,$8B,$24,$25);addr:teb_tcb),
(inst:($65,$4C,$8B,$2C,$25);addr:teb_tcb),
(inst:($65,$4C,$8B,$34,$25);addr:teb_tcb),
(inst:($65,$4C,$8B,$3C,$25);addr:teb_tcb)
);
patch_gs_table:array[0..15] of t_mov_rel_base32=(
(inst:($65,$48,$8B,$04,$25);addr:teb_gsbase),
(inst:($65,$48,$8B,$0C,$25);addr:teb_gsbase),
(inst:($65,$48,$8B,$14,$25);addr:teb_gsbase),
(inst:($65,$48,$8B,$1C,$25);addr:teb_gsbase),
(inst:($65,$48,$8B,$24,$25);addr:teb_gsbase),
(inst:($65,$48,$8B,$2C,$25);addr:teb_gsbase),
(inst:($65,$48,$8B,$34,$25);addr:teb_gsbase),
(inst:($65,$48,$8B,$3C,$25);addr:teb_gsbase),
(inst:($65,$4C,$8B,$04,$25);addr:teb_gsbase),
(inst:($65,$4C,$8B,$0C,$25);addr:teb_gsbase),
(inst:($65,$4C,$8B,$14,$25);addr:teb_gsbase),
(inst:($65,$4C,$8B,$1C,$25);addr:teb_gsbase),
(inst:($65,$4C,$8B,$24,$25);addr:teb_gsbase),
(inst:($65,$4C,$8B,$2C,$25);addr:teb_gsbase),
(inst:($65,$4C,$8B,$34,$25);addr:teb_gsbase),
(inst:($65,$4C,$8B,$3C,$25);addr:teb_gsbase)
);
patch_mov_rel_table:array[0..15] of t_mov_rel32=(
(inst:($90,$48,$8B,$80);addr:0),
(inst:($90,$48,$8B,$89);addr:0),
(inst:($90,$48,$8B,$92);addr:0),
(inst:($90,$48,$8B,$9B);addr:0),
(inst:($48,$8B,$A4,$24);addr:0),
(inst:($90,$48,$8B,$AD);addr:0),
(inst:($90,$48,$8B,$B6);addr:0),
(inst:($90,$48,$8B,$BF);addr:0),
(inst:($90,$4D,$8B,$80);addr:0),
(inst:($90,$4D,$8B,$89);addr:0),
(inst:($90,$4D,$8B,$92);addr:0),
(inst:($90,$4D,$8B,$9B);addr:0),
(inst:($4D,$8B,$A4,$24);addr:0),
(inst:($90,$4D,$8B,$AD);addr:0),
(inst:($90,$4D,$8B,$B6);addr:0),
(inst:($90,$4D,$8B,$BF);addr:0)
);
c_jmpq64_trampoline:t_jmpq64_trampoline=(inst:$25FF;offset:0;addr:0);
c_call32_trampoline:t_call32_trampoline=(inst:$E8;addr:0);
c_jmpl32_trampoline:t_call32_trampoline=(inst:$E9;addr:0);
function IndexInstr(var pbuf:Pointer;pend:Pointer;var offset:Int64):Integer;
procedure patch_original(const info:t_instr_index_info;delta:Integer;addr_out:Pointer);
var
psrc:Pointer;
W:DWORD;
trampoline:t_call32_trampoline;
begin
Result:=-1;
psrc:=pbuf;
while (psrc<pend) do
begin
W:=PDWORD(psrc)^;
//fill nop
FillChar(addr_out^,info.inlen,$90);
Case W of
$048B4864:Result:= 0; //fs_rax
$0C8B4864:Result:= 1; //fs_rcx
$148B4864:Result:= 2; //fs_rdx
$1C8B4864:Result:= 3; //fs_rbx
$248B4864:Result:= 4; //fs_rsp
$2C8B4864:Result:= 5; //fs_rbp
$348B4864:Result:= 6; //fs_rsi
$3C8B4864:Result:= 7; //fs_rdi
$048B4C64:Result:= 8; //fs_r8
$0C8B4C64:Result:= 9; //fs_r9
$148B4C64:Result:=10; //fs_r10
$1C8B4C64:Result:=11; //fs_r11
$248B4C64:Result:=12; //fs_r12
$2C8B4C64:Result:=13; //fs_r13
$348B4C64:Result:=14; //fs_r14
$3C8B4C64:Result:=15; //fs_r15
$00A14864:Result:=16; //fs_rax64
$048B4865:Result:=17; //gs_rax
$0C8B4865:Result:=18; //gs_rcx
$148B4865:Result:=19; //gs_rdx
$1C8B4865:Result:=20; //gs_rbx
$248B4865:Result:=21; //gs_rsp
$2C8B4865:Result:=22; //gs_rbp
$348B4865:Result:=23; //gs_rsi
$3C8B4865:Result:=24; //gs_rdi
$048B4C65:Result:=25; //gs_r8
$0C8B4C65:Result:=26; //gs_r9
$148B4C65:Result:=27; //gs_r10
$1C8B4C65:Result:=28; //gs_r11
$248B4C65:Result:=29; //gs_r12
$2C8B4C65:Result:=30; //gs_r13
$348B4C65:Result:=31; //gs_r14
$3C8B4C65:Result:=32; //gs_r15
$00A14865:Result:=33; //gs_rax64
$49000000,
$49000001,
$49000002:Result:=34; //syscall
//shft 8
$8B486400..$8B4864FF, //fs
$8B4C6400..$8B4C64FF, //fs
$A1486400..$A14864FF, //fs
$8B486500..$8B4865FF, //gs
$8B4C6500..$8B4C65FF, //gs
$A1486500..$A14865FF, //gs
$00000000..$000002FF: //sv
begin
Inc(psrc,1);
Continue;
end;
//shft 16
$48640000..$4864FFFF, //fs
$4C640000..$4C64FFFF, //fs
$48650000..$4865FFFF, //gs
$4C650000..$4C65FFFF, //gs
$00000300..$0002FFFF: //sv
begin
Inc(psrc,2);
Continue;
end;
//shft 24
$64000000..$64FFFFFF, //fs
$65000000..$65FFFFFF, //gs
$00030000..$00A14863, //sv
$00A14866..$02FFFFFF: //sv
begin
Inc(psrc,3);
Continue;
end;
else
begin
Inc(psrc,4);
Continue;
end;
end;
Case Result of
0..15,
17..32:
begin
if (PBYTE(psrc)[4]<>$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;
end;
16,
33:
begin
offset:=PInt64(@PBYTE(psrc)[3])^;
if (offset>+65536) or
(offset<-65536) then
begin
Inc(psrc,4);
Continue;
end;
end;
34:
begin
offset:=0;
if (PDWORD(@PBYTE(psrc)[4])^<>$050FCA89) then
begin
Inc(psrc,4);
Continue;
end;
//Write(HexStr(PBYTE(psrc)[0],2),' ');
//Write(HexStr(PBYTE(psrc)[1],2),' ');
//Write(HexStr(PBYTE(psrc)[2],2),' ');
//Write(HexStr(PBYTE(psrc)[3],2),' ');
//Write(HexStr(PBYTE(psrc)[4],2),' ');
//Write(HexStr(PBYTE(psrc)[5],2),' ');
//Write(HexStr(PBYTE(psrc)[6],2),' ');
//Write(HexStr(PBYTE(psrc)[7],2),' ');
//Write(HexStr(PBYTE(psrc)[8],2),' ');
//Write(HexStr(PBYTE(psrc)[9],2),' ');
Case PBYTE(psrc)[8] of
$41,
$48,
$5f,
$72,
$c3:{Writeln('True')};
else
begin
//Writeln('False');
Inc(psrc,4);
Continue;
end;
end;
end;
else;
end;
if (Result<>-1) then
begin
pbuf:=psrc;
exit;
end;
Inc(psrc);
case info.instr of
I_MOV_BASE32:trampoline:=c_jmpl32_trampoline;
I_MOV_BASE64:trampoline:=c_jmpl32_trampoline;
I_SYSCALL :trampoline:=c_call32_trampoline;
else;
end;
Result:=-1;
trampoline.addr:=delta;
p_call32_trampoline(addr_out)^:=trampoline;
end;
procedure vm_add_syscall_patch(_obj,vaddr,addr_out:Pointer);
procedure vm_add_mov_base_patch(const info:t_instr_index_info;_obj,vaddr,addr_out:Pointer);
var
stub:p_stub_chunk;
jmpq64_trampoline:t_jmpq64_trampoline;
call32_trampoline:t_call32_trampoline;
trampoline:t_base_data_trampoline;
delta:Int64;
begin
stub:=p_alloc(vaddr,SizeOf(t_base_data_trampoline));
delta:=Int64(@stub^.body)-(Int64(vaddr)+SizeOf(t_call32_trampoline));
Assert(delta<High(Integer),'vm_add_mov_base_patch');
patch_original(info,Integer(delta),addr_out);
case info.sbase of
FSBASE:trampoline.bseg:=patch_fs_table[info.inreg];
GSBASE:trampoline.bseg:=patch_gs_table[info.inreg];
else;
end;
Assert(info.osize=4,'info.osize=4');
trampoline.data:=patch_mov_rel_table[info.inreg];
trampoline.data.addr:=Integer(info.offst);
trampoline.bjmp:=c_jmpq64_trampoline;
trampoline.bjmp.addr:=(Int64(vaddr)+SizeOf(t_call32_trampoline));
p_base_data_trampoline(@stub^.body)^:=trampoline;
md_cacheflush(@stub^.body,SizeOf(trampoline),ICACHE);
case info.sbase of
FSBASE:vm_add_patch_link(_obj,vaddr,pt_fsbase,stub);
GSBASE:vm_add_patch_link(_obj,vaddr,pt_gsbase,stub);
else;
end;
end;
procedure vm_add_syscall_patch(const info:t_instr_index_info;_obj,vaddr,addr_out:Pointer);
var
stub:p_stub_chunk;
trampoline:t_jmpq64_trampoline;
delta:Int64;
begin
stub:=p_alloc(vaddr,SizeOf(t_jmpq64_trampoline));
@ -470,33 +447,42 @@ begin
delta:=Int64(@stub^.body)-(Int64(vaddr)+SizeOf(t_call32_trampoline));
Assert(delta<High(Integer),'vm_add_syscall_patch');
jmpq64_trampoline:=c_jmpq64_trampoline;
call32_trampoline:=c_call32_trampoline;
patch_original(info,Integer(delta),addr_out);
jmpq64_trampoline.addr:=QWORD(@fast_syscall);
call32_trampoline.addr:=Integer(delta);
trampoline:=c_jmpq64_trampoline;
trampoline.addr:=QWORD(@fast_syscall);
p_jmpq64_trampoline(@stub^.body)^:=trampoline;
p_jmpq64_trampoline(@stub^.body)^:=jmpq64_trampoline;
p_call32_trampoline(addr_out)^:=call32_trampoline;
md_cacheflush(@stub^.body,SizeOf(t_jmpq64_trampoline),ICACHE);
md_cacheflush(@stub^.body,SizeOf(trampoline),ICACHE);
vm_add_patch_link(_obj,vaddr,pt_syscall,stub);
end;
procedure vm_add_patch(const info:t_instr_index_info;_obj,vaddr,addr_out:Pointer);
begin
case info.instr of
I_MOV_BASE32:vm_add_mov_base_patch(info,_obj,vaddr,addr_out);
I_MOV_BASE64:vm_add_mov_base_patch(info,_obj,vaddr,addr_out);
I_SYSCALL :vm_add_syscall_patch (info,_obj,vaddr,addr_out);
else;
end;
end;
procedure patcher_process_section(_obj,data,vaddr:Pointer;filesz:QWORD);
var
addr:Pointer;
pend:Pointer;
offset:Int64;
info:t_instr_index_info;
i,len:Integer;
len:Integer;
b:Boolean;
fs_count:Integer;
gs_count:Integer;
sv_count:Integer;
{
procedure do_patch_base_zero(addr:PByte;i:Integer;ptype:t_patch_type);
var
v:Pointer;
@ -515,6 +501,16 @@ var
vm_add_syscall_patch(_obj,v,addr);
end;
}
procedure do_patch_syscall(addr:PByte);
var
v:Pointer;
begin
v:=vaddr+(Int64(addr)-Int64(data));
vm_add_patch(info,_obj,v,addr);
end;
begin
Assert(_obj<>nil,'patcher_process_section');
@ -526,49 +522,22 @@ begin
addr:=data;
pend:=addr+filesz;
repeat
offset:=0;
i:=IndexInstr(addr,pend,offset);
info:=Default(t_instr_index_info);
if (i=-1) then Break;
b:=IndexInstr(addr,pend,info);
Case i of
0..33:
begin
len:=patch_table[i].C[0];
//
if (not b) then Break;
if (offset=0) then
begin
Case i of
0..16:
begin
Inc(fs_count);
do_patch_base_zero(addr,i,pt_fsbase);
end;
17..33:
begin
Inc(gs_count);
do_patch_base_zero(addr,i,pt_gsbase);
end
else;
end;
end else
begin
//Writeln('patch with offset:',offset);
end;
end;
34:
begin
Inc(sv_count);
//
do_patch_syscall(addr+3);
len:=9;
end
else
Assert(False);
do_patch_syscall(addr);
case info.instr of
I_MOV_BASE32:Inc(fs_count);
I_MOV_BASE64:Inc(gs_count);
I_SYSCALL :Inc(sv_count);
else;
end;
Inc(addr,len);
Inc(addr,info.inlen);
until false;

View File

@ -69,6 +69,7 @@ const
KERN_PROC_IDTABLE =37; //ID table information
KERN_PROC_SANITIZER =41; //kern_sanitizer (Sanitizing mode)
KERN_PROC_PTC =43; //Process time counter (value at program start)
KERN_PROC_TEXT_SEGMENT=44; //kern_dynlib_get_libkernel_text_segment
@ -416,6 +417,11 @@ begin
Result:=SYSCTL_OUT(req,@g_vmspace.sv_usrstack,SizeOf(Pointer));
end;
function sysctl_kern_proc_ptc(oidp:p_sysctl_oid;arg1:Pointer;arg2:ptrint;req:p_sysctl_req):Integer;
begin
Result:=SYSCTL_OUT(req,@p_proc.p_ptc,SizeOf(Int64));
end;
function sysctl_handle_int(oidp:p_sysctl_oid;arg1:Pointer;arg2:ptrint;req:p_sysctl_req):Integer;
var
tmpout:Integer;
@ -449,6 +455,13 @@ begin
oid[2]:=KERN_CPUS;
len^ :=3;
end;
'kern.proc.ptc':
begin
oid[0]:=CTL_KERN;
oid[1]:=KERN_PROC;
oid[2]:=KERN_PROC_PTC;
len^ :=3;
end;
else
Writeln(StdErr,'Unhandled name2oid:',name);
@ -485,7 +498,7 @@ begin
case name[0] of
KERN_PROC_APPINFO:Result:=SYSCTL_HANDLE(noid,name,$C0040001,@sysctl_kern_proc_appinfo);
KERN_PROC_PTC :Result:=SYSCTL_HANDLE(noid,name,$90040009,@sysctl_kern_proc_ptc);
else
begin
Writeln(StdErr,'Unhandled sysctl_kern_proc:',name[0]);

View File

@ -315,6 +315,8 @@ var
p_sdk_version:Integer;
p_sce_replay_exec:Integer;
p_ptc:Int64;
p_nsignals:Int64;
p_nvcsw :Int64;
p_nivcsw :Int64;
@ -331,7 +333,8 @@ var
implementation
uses
kern_event;
kern_event,
md_time;
function curkthread:p_kthread; assembler; nostackframe;
asm
@ -539,6 +542,7 @@ begin
mtx_unlock(p_proc.p_mtx);
end;
procedure PROC_INIT;
begin
FillChar(p_proc,SizeOf(p_proc),0);
@ -547,6 +551,8 @@ begin
knlist_init_mtx(@p_proc.p_klist,@p_proc.p_mtx);
p_proc.p_randomized_path:='system';
p_proc.p_ptc:=rdtsc;
end;
//

View File

@ -11,6 +11,12 @@ uses
Procedure md_timeinit;
function rdtsc:Int64; assembler;
function tsc_calibrate:Int64;
function get_proc_time:Int64;
function get_proc_time_freq:Int64;
function get_unit_uptime:Int64;
procedure unittime(time:PInt64);
procedure calcru_proc(user,syst:PInt64);
@ -37,6 +43,72 @@ begin
NtSetTimerResolution(max,True,@cur);
end;
function rdtsc:Int64; assembler; nostackframe;
asm
rdtsc
shl $0x20,%rdx
or %rdx,%rax
end;
function tsc_calibrate:Int64;
const
samples=20;
var
i:Integer;
tsc_freq :Int64;
qpc_begin:Int64;
tsc_begin:Int64;
qpc_end :Int64;
tsc_end :Int64;
qpc_freq :Int64;
begin
tsc_freq:=0;
qpc_freq:=get_proc_time_freq;
For i:=0 to samples-1 do
begin
qpc_begin:=get_proc_time;
tsc_begin:=rdtsc;
Sleep(2);
qpc_end:=get_proc_time;
tsc_end:=rdtsc;
tsc_freq:=tsc_freq + (tsc_end - tsc_begin) * qpc_freq div (qpc_end - qpc_begin);
end;
tsc_freq:=tsc_freq div samples;
Result:=tsc_freq;
end;
function get_proc_time:Int64;
var
pc:QWORD;
pf:QWORD;
begin
pc:=0;
pf:=1;
NtQueryPerformanceCounter(@pc,@pf);
Result:=pc;
end;
function get_proc_time_freq:Int64;
var
pc:QWORD;
pf:QWORD;
begin
pc:=0;
pf:=1;
NtQueryPerformanceCounter(@pc,@pf);
Result:=pf;
end;
function mul_div_u64(m,d,v:QWORD):QWORD; sysv_abi_default; assembler; nostackframe;
asm
movq v,%rax

View File

@ -621,6 +621,10 @@
<Filename Value="..\kern\kern_authinfo.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="..\..\rtl\x86_index_instr.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>