mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
8857e2aab9
commit
9dcba4f540
|
@ -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.
|
||||
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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;
|
||||
|
||||
//
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue