mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
798b0b2cce
commit
6d2a57bd31
|
@ -39,7 +39,8 @@ implementation
|
|||
|
||||
uses
|
||||
errno,
|
||||
elf_nid_utils;
|
||||
elf_nid_utils,
|
||||
kern_stub;
|
||||
|
||||
function convert_raw_symbol_str_to_base64(symbol:pchar):RawByteString;
|
||||
var
|
||||
|
@ -363,6 +364,45 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
//48 8D 3D 00 00 00 00 lea rdi,[rip+$00000000] lea (%rip),%rdi
|
||||
|
||||
type
|
||||
p_jmpq64_trampoline=^t_jmpq64_trampoline;
|
||||
t_jmpq64_trampoline=packed record
|
||||
lea:array[0..6] of Byte;
|
||||
//
|
||||
inst :Word; //FF 25
|
||||
offset:DWORD; //00
|
||||
addr :QWORD;
|
||||
str :PChar;
|
||||
end;
|
||||
|
||||
const
|
||||
c_jmpq64_trampoline:t_jmpq64_trampoline=(lea:($48,$8D,$3D,$F9,$FF,$FF,$FF);inst:$25FF;offset:0;addr:0);
|
||||
|
||||
procedure _unresolve_symbol(data:p_jmpq64_trampoline);
|
||||
begin
|
||||
Writeln('_unresolve_symbol:',data^.str);
|
||||
readln;
|
||||
end;
|
||||
|
||||
function get_unresolve_ptr(str:PChar):Pointer;
|
||||
var
|
||||
stub:p_stub_chunk;
|
||||
begin
|
||||
stub:=p_alloc(nil,SizeOf(t_jmpq64_trampoline));
|
||||
|
||||
p_jmpq64_trampoline(@stub^.body)^:=c_jmpq64_trampoline;
|
||||
p_jmpq64_trampoline(@stub^.body)^.addr:=QWORD(@_unresolve_symbol);
|
||||
p_jmpq64_trampoline(@stub^.body)^.str:=str;
|
||||
|
||||
Result:=@stub^.body;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
//kern_stub
|
||||
|
||||
function find_symdef(symnum:QWORD;refobj:p_lib_info;var defobj_out:p_lib_info;flags:DWORD;cache:p_SymCache):p_elf64_sym;
|
||||
var
|
||||
req:t_SymLook;
|
||||
|
@ -370,8 +410,14 @@ var
|
|||
ref:p_elf64_sym;
|
||||
defobj:p_lib_info;
|
||||
str:pchar;
|
||||
count:Integer;
|
||||
err:Integer;
|
||||
ST_BIND:Integer;
|
||||
|
||||
nModuleId,nLibraryId:WORD;
|
||||
nNid:QWORD;
|
||||
|
||||
fname:RawByteString;
|
||||
begin
|
||||
Result:=nil;
|
||||
|
||||
|
@ -389,8 +435,8 @@ begin
|
|||
def:=nil;
|
||||
defobj_out:=nil;
|
||||
|
||||
err:=refobj^.rel_data^.symtab_size div SizeOf(elf64_sym);
|
||||
if (symnum<=err) then Exit(nil);
|
||||
count:=refobj^.rel_data^.symtab_size div SizeOf(elf64_sym);
|
||||
if (symnum>=count) then Exit(nil);
|
||||
|
||||
ref:=refobj^.rel_data^.symtab_addr + symnum;
|
||||
|
||||
|
@ -411,9 +457,20 @@ begin
|
|||
req:=Default(t_SymLook);
|
||||
|
||||
req.symbol:=str;
|
||||
req.flags :=(flags or SYMLOOK_MANGLED);
|
||||
req.flags :=(flags{ or SYMLOOK_MANGLED});
|
||||
req.obj :=refobj;
|
||||
|
||||
if DecodeEncName(str,nModuleId,nLibraryId,nNid) then
|
||||
begin
|
||||
req.modname:=get_mod_name(refobj,nModuleId);
|
||||
req.libname:=get_lib_name(refobj,nLibraryId);
|
||||
|
||||
fname:=BaseEncName(str);
|
||||
|
||||
req.name:=pchar(fname);
|
||||
end;
|
||||
|
||||
|
||||
//convert_mangled_name_to_long
|
||||
//req.libname
|
||||
//req.name
|
||||
|
@ -432,6 +489,15 @@ begin
|
|||
begin
|
||||
def :=@dynlibs_info.sym_zero;
|
||||
defobj:=dynlibs_info.libprogram;
|
||||
end else
|
||||
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));
|
||||
|
||||
def :=@dynlibs_info.sym_nops;
|
||||
defobj:=dynlibs_info.libprogram;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
|
|
|
@ -9,93 +9,16 @@ uses
|
|||
mqueue,
|
||||
kern_stub;
|
||||
|
||||
type
|
||||
t_patch_type=(pt_fsbase,pt_gsbase,pt_syscall);
|
||||
|
||||
p_patch_node=^t_patch_node;
|
||||
t_patch_node=record
|
||||
link :TAILQ_ENTRY;
|
||||
vaddr:Pointer;
|
||||
ptype:t_patch_type;
|
||||
stub :p_stub_chunk;
|
||||
end;
|
||||
|
||||
procedure add_patch_link (_obj,vaddr:Pointer;ptype:t_patch_type;stub:p_stub_chunk);
|
||||
procedure free_patch_link(_obj:Pointer;node:p_patch_node);
|
||||
procedure vm_object_patch_remove(_obj:Pointer;start,__end:DWORD);
|
||||
|
||||
procedure patcher_process_section(_obj,data,vaddr:Pointer;filesz:QWORD);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
hamt,
|
||||
kern_rwlock,
|
||||
kern_thr,
|
||||
vm,
|
||||
vmparam,
|
||||
vm_map,
|
||||
vm_mmap,
|
||||
vm_object,
|
||||
vm_pmap,
|
||||
vm_patch_link,
|
||||
trap;
|
||||
|
||||
procedure add_patch_link(_obj,vaddr:Pointer;ptype:t_patch_type;stub:p_stub_chunk);
|
||||
var
|
||||
obj:vm_object_t;
|
||||
node:p_patch_node;
|
||||
begin
|
||||
Writeln('patch:vaddr=0x',HexStr(vaddr),' type:',ptype);
|
||||
|
||||
obj:=_obj;
|
||||
node:=AllocMem(SizeOf(t_patch_node));
|
||||
node^.vaddr:=vaddr;
|
||||
node^.ptype:=ptype;
|
||||
node^.stub :=stub;
|
||||
|
||||
p_inc_ref(stub);
|
||||
|
||||
TAILQ_INSERT_TAIL(@obj^.patchq,node,@node^.link);
|
||||
end;
|
||||
|
||||
procedure free_patch_link(_obj:Pointer;node:p_patch_node);
|
||||
var
|
||||
obj:vm_object_t;
|
||||
begin
|
||||
obj:=_obj;
|
||||
TAILQ_REMOVE(@obj^.patchq,node,@node^.link);
|
||||
|
||||
p_dec_ref(node^.stub);
|
||||
FreeMem(node);
|
||||
end;
|
||||
|
||||
function OFF_TO_IDX(x:Pointer):DWORD; inline;
|
||||
begin
|
||||
Result:=QWORD(x) shr PAGE_SHIFT;
|
||||
end;
|
||||
|
||||
procedure vm_object_patch_remove(_obj:Pointer;start,__end:DWORD);
|
||||
var
|
||||
obj:vm_object_t;
|
||||
entry,next:p_patch_node;
|
||||
begin
|
||||
obj:=_obj;
|
||||
|
||||
entry:=TAILQ_FIRST(@obj^.patchq);
|
||||
while (entry<>nil) do
|
||||
begin
|
||||
next:=TAILQ_NEXT(entry,@entry^.link);
|
||||
//
|
||||
if ((start=0) or (OFF_TO_IDX(entry^.vaddr)>=start)) and
|
||||
((__end=0) or (OFF_TO_IDX(entry^.vaddr)<=__end)) then
|
||||
begin
|
||||
free_patch_link(_obj,entry);
|
||||
end;
|
||||
//
|
||||
entry:=next;
|
||||
end;
|
||||
end;
|
||||
|
||||
{
|
||||
64 48 A1 [0000000000000000] mov rax,fs:[$0000000000000000] -> 65 48 A1 [0807000000000000] mov rax,gs:[$0000000000000708]
|
||||
64 48 8B 04 25 [00000000] mov rax,fs:[$00000000] -> 65 48 8B 04 25 [08070000] mov rax,gs:[$00000708]
|
||||
|
@ -533,10 +456,32 @@ begin
|
|||
Result:=-1;
|
||||
end;
|
||||
|
||||
procedure _fast_syscall; assembler; nostackframe;
|
||||
asm
|
||||
mov %rax,%rax
|
||||
jmp fast_syscall
|
||||
procedure vm_add_syscall_patch(_obj,vaddr,addr_out:Pointer);
|
||||
var
|
||||
stub:p_stub_chunk;
|
||||
|
||||
jmpq64_trampoline:t_jmpq64_trampoline;
|
||||
call32_trampoline:t_call32_trampoline;
|
||||
|
||||
delta:Int64;
|
||||
begin
|
||||
stub:=p_alloc(vaddr,SizeOf(t_jmpq64_trampoline));
|
||||
|
||||
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;
|
||||
|
||||
jmpq64_trampoline.addr:=QWORD(@fast_syscall);
|
||||
call32_trampoline.addr:=Integer(delta);
|
||||
|
||||
p_jmpq64_trampoline(@stub^.body)^:=jmpq64_trampoline;
|
||||
p_call32_trampoline(addr_out)^:=call32_trampoline;
|
||||
|
||||
md_cacheflush(@stub^.body,SizeOf(t_jmpq64_trampoline),ICACHE);
|
||||
|
||||
vm_add_patch_link(_obj,vaddr,pt_syscall,stub);
|
||||
end;
|
||||
|
||||
procedure patcher_process_section(_obj,data,vaddr:Pointer;filesz:QWORD);
|
||||
|
@ -559,36 +504,16 @@ var
|
|||
Move(patch_table[i].C[1],addr^,patch_table[i].C[0]);
|
||||
|
||||
v:=vaddr+(Int64(addr)-Int64(data));
|
||||
add_patch_link(_obj,v,ptype,nil);
|
||||
vm_add_patch_link(_obj,v,ptype,nil);
|
||||
end;
|
||||
|
||||
procedure do_patch_syscall(addr:PByte);
|
||||
var
|
||||
v:Pointer;
|
||||
stub:p_stub_chunk;
|
||||
|
||||
jmpq64_trampoline:t_jmpq64_trampoline;
|
||||
call32_trampoline:t_call32_trampoline;
|
||||
|
||||
d:Int64;
|
||||
begin
|
||||
v:=vaddr+(Int64(addr)-Int64(data));
|
||||
|
||||
stub:=p_alloc(v,SizeOf(t_jmpq64_trampoline));
|
||||
|
||||
d:=Int64(@stub^.body)-(Int64(v)+SizeOf(t_call32_trampoline));
|
||||
Assert(d<High(Integer),'do_patch_syscall');
|
||||
|
||||
jmpq64_trampoline:=c_jmpq64_trampoline;
|
||||
call32_trampoline:=c_call32_trampoline;
|
||||
|
||||
jmpq64_trampoline.addr:=QWORD(@_fast_syscall);
|
||||
call32_trampoline.addr:=Integer(d);
|
||||
|
||||
p_jmpq64_trampoline(@stub^.body)^:=jmpq64_trampoline;
|
||||
p_call32_trampoline(addr)^:=call32_trampoline;
|
||||
|
||||
add_patch_link(_obj,v,pt_syscall,stub);
|
||||
vm_add_syscall_patch(_obj,v,addr);
|
||||
end;
|
||||
|
||||
begin
|
||||
|
@ -629,7 +554,7 @@ begin
|
|||
end;
|
||||
end else
|
||||
begin
|
||||
Writeln('patch with offset:',offset);
|
||||
//Writeln('patch with offset:',offset);
|
||||
end;
|
||||
end;
|
||||
34:
|
||||
|
|
|
@ -44,7 +44,8 @@ begin
|
|||
((relro_addr + obj^.relro_size) < (where + size))
|
||||
) then
|
||||
begin
|
||||
Exit(ENOEXEC);
|
||||
//dont check with special callbacks
|
||||
//Exit(ENOEXEC);
|
||||
end;
|
||||
|
||||
Result:=0;
|
||||
|
|
|
@ -42,7 +42,7 @@ uses
|
|||
|
||||
var
|
||||
chunk_alloc:TSTUB_HAMT64;
|
||||
chunk_free :TAILQ_HEAD=(tqh_first:nil;tqh_last:@chunk_free .tqh_first);
|
||||
chunk_free :TAILQ_HEAD=(tqh_first:nil;tqh_last:@chunk_free.tqh_first);
|
||||
|
||||
chunk_lock :Pointer=nil;
|
||||
|
||||
|
@ -169,7 +169,7 @@ begin
|
|||
if (entry^.curr_size>=(size+SizeOf(stub_chunk))) then
|
||||
begin
|
||||
delta:=abs(Int64(vaddr)-Int64(@entry^.body));
|
||||
if (delta<High(Integer)) then
|
||||
if (vaddr=nil) or (delta<High(Integer)) then
|
||||
begin
|
||||
TAILQ_REMOVE(@chunk_free,entry,@entry^.link);
|
||||
Exit(entry);
|
||||
|
|
|
@ -33,11 +33,10 @@ const
|
|||
KERN_PROC_SDK_VERSION =36; //SDK version of the executable file
|
||||
KERN_PROC_IDTABLE =37; //ID table information
|
||||
|
||||
KERN_PROC_SANITIZER =41; //kern_sanitizer (Sanitizing mode)
|
||||
KERN_PROC_TEXT_SEGMENT=44; //kern_dynlib_get_libkernel_text_segment
|
||||
|
||||
|
||||
|
||||
|
||||
//SYSCTL_HANDLER_ARGS oidp:p_sysctl_oid;arg1:Pointer;arg2:ptrint;req:p_sysctl_req
|
||||
|
||||
type
|
||||
|
@ -65,6 +64,7 @@ type
|
|||
t_oid_handler=function(oidp:p_sysctl_oid;arg1:Pointer;arg2:ptrint;req:p_sysctl_req):Integer;
|
||||
|
||||
t_sysctl_oid=record
|
||||
oid_name :PInteger;
|
||||
oid_handler:t_oid_handler;
|
||||
end;
|
||||
|
||||
|
@ -85,7 +85,8 @@ uses
|
|||
vmparam,
|
||||
kern_thr,
|
||||
kern_sx,
|
||||
md_arc4random;
|
||||
md_arc4random,
|
||||
md_proc;
|
||||
|
||||
var
|
||||
sysctllock :t_sx;
|
||||
|
@ -122,8 +123,9 @@ begin
|
|||
Result:=req^.oldfunc(req,p,s);
|
||||
end;
|
||||
|
||||
function SYSCTL_HANDLE(noid:p_sysctl_oid;func:Pointer):Integer; inline;
|
||||
function SYSCTL_HANDLE(noid:p_sysctl_oid;name:PInteger;func:Pointer):Integer; inline;
|
||||
begin
|
||||
noid^.oid_name :=name+1;
|
||||
noid^.oid_handler:=t_oid_handler(func);
|
||||
Result:=0
|
||||
end;
|
||||
|
@ -217,12 +219,102 @@ begin
|
|||
Result:=SYSCTL_OUT(req,@data,len);
|
||||
end;
|
||||
|
||||
const
|
||||
//eLoadOptions
|
||||
LOAD_OPTIONS_DEFAULT =$0000;
|
||||
LOAD_OPTIONS_LOAD_SUSPENDED =$0001;
|
||||
LOAD_OPTIONS_USE_SYSTEM_LIBRARY_VERIFICATION =$0002;
|
||||
LOAD_OPTIONS_SLV_MODE_WARN =$0004;
|
||||
LOAD_OPTIONS_ARG_STACK_SIZE =$0008;
|
||||
LOAD_OPTIONS_FULL_DEBUG_REQUIRED =$0010;
|
||||
|
||||
//mmap_flags
|
||||
//bit 1 -> is_big_app
|
||||
//bit 2 -> first find addr is (1 shl 33) ->
|
||||
// _sceKernelMapFlexibleMemory
|
||||
// _sceKernelMapDirectMemory
|
||||
// sceKernelMapDirectMemory2
|
||||
|
||||
//excp_flags
|
||||
//bit 1 -> use in [libkernel_exception] ->
|
||||
// -> sceKernelInstallExceptionHandler
|
||||
// -> sceKernelRemoveExceptionHandler
|
||||
// -> sceKernelAddGpuExceptionEvent
|
||||
// -> sceKernelDeleteGpuExceptionEvent
|
||||
// -> sceKernelBacktraceSelf
|
||||
//bit 2 -> sys_mdbg_service
|
||||
|
||||
type
|
||||
TCUSANAME=array[0..9] of AnsiChar;
|
||||
|
||||
PSCE_APP_ENV=^TSCE_APP_ENV;
|
||||
TSCE_APP_ENV=packed record
|
||||
AppId :Integer; //4
|
||||
mmap_flags :Integer; //4
|
||||
excp_flags :Integer; //4
|
||||
AppType :Integer; //4 5?
|
||||
CUSANAME :TCUSANAME; //10
|
||||
debug_level:Byte; //1
|
||||
slv_flags :Byte; //1 eLoadOptions
|
||||
f_1c :Byte;
|
||||
f_1d :Byte;
|
||||
f_1e :Byte;
|
||||
f_1f :Byte;
|
||||
f_20 :QWORD;
|
||||
f_28 :Integer;
|
||||
f_2c :Integer;
|
||||
f_30 :Integer;
|
||||
f_34 :Integer;
|
||||
f_38 :QWORD;
|
||||
f_40 :QWORD;
|
||||
end;
|
||||
{$IF sizeof(TSCE_APP_ENV)<>72}{$STOP sizeof(TSCE_APP_ENV)<>72}{$ENDIF}
|
||||
|
||||
var
|
||||
G_APPINFO:TSCE_APP_ENV;
|
||||
|
||||
function sysctl_kern_proc_appinfo(oidp:p_sysctl_oid;arg1:Pointer;arg2:ptrint;req:p_sysctl_req):Integer;
|
||||
var
|
||||
pid:Integer;
|
||||
|
||||
APPINFO:TSCE_APP_ENV;
|
||||
begin
|
||||
if (req^.oldlen > 72) then Exit(EINVAL);
|
||||
|
||||
pid:=PInteger(arg1)^;
|
||||
|
||||
if (pid<>g_pid) then Exit(EINVAL);
|
||||
|
||||
//sceSblACMgrIsSystemUcred()!=0 -> any proc
|
||||
//sceSblACMgrIsSystemUcred()==0 -> cur proc
|
||||
|
||||
Result:=SYSCTL_OUT(req,@G_APPINFO,SizeOf(TSCE_APP_ENV));
|
||||
|
||||
if (Result=0) and (req^.newlen=SizeOf(TSCE_APP_ENV)) then
|
||||
begin
|
||||
Result:=SYSCTL_IN(req,@APPINFO,SizeOf(TSCE_APP_ENV));
|
||||
if (Result=0) then
|
||||
begin
|
||||
G_APPINFO:=APPINFO;
|
||||
end;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
function sysctl_kern_proc(name:PInteger;namelen:DWORD;noid:p_sysctl_oid;req:p_sysctl_req):Integer;
|
||||
begin
|
||||
if (namelen=0) then Exit(ENOTDIR);
|
||||
Result:=ENOENT;
|
||||
|
||||
Writeln(StdErr,'sysctl_kern_proc:',name[0]);
|
||||
case name[0] of
|
||||
KERN_PROC_APPINFO:Result:=SYSCTL_HANDLE(noid,name,@sysctl_kern_proc_appinfo);
|
||||
|
||||
else
|
||||
begin
|
||||
Writeln(StdErr,'Unhandled sysctl_kern_proc:',name[0]);
|
||||
Assert(False);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function sysctl_kern(name:PInteger;namelen:DWORD;noid:p_sysctl_oid;req:p_sysctl_req):Integer;
|
||||
|
@ -233,10 +325,11 @@ begin
|
|||
case name[0] of
|
||||
KERN_PROC:Result:=sysctl_kern_proc(name+1,namelen-1,noid,req);
|
||||
|
||||
KERN_ARND:Result:=SYSCTL_HANDLE(noid,@sysctl_kern_arandom);
|
||||
KERN_ARND:Result:=SYSCTL_HANDLE(noid,name,@sysctl_kern_arandom);
|
||||
else
|
||||
begin
|
||||
Writeln(StdErr,'Unhandled sysctl_kern:',name[0]);
|
||||
Assert(False);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
@ -253,7 +346,8 @@ begin
|
|||
CTL_KERN:Result:=sysctl_kern(name+1,namelen-1,noid,req);
|
||||
else
|
||||
begin
|
||||
Writeln(StdErr,'Unhandled sysctl_find_oid:',name[0]);
|
||||
Writeln(StdErr,'Unhandled sysctl_root:',name[0]);
|
||||
Assert(False);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
@ -264,6 +358,7 @@ function sysctl_root(oidp:p_sysctl_oid;
|
|||
req :p_sysctl_req):Integer;
|
||||
var
|
||||
oid:t_sysctl_oid;
|
||||
indx:Integer;
|
||||
begin
|
||||
oid:=Default(t_sysctl_oid);
|
||||
|
||||
|
@ -271,6 +366,12 @@ begin
|
|||
if (Result<>0) then Exit;
|
||||
|
||||
if (oid.oid_handler=nil) then Exit(EINVAL);
|
||||
if (oid.oid_name =nil) then Exit(EINVAL);
|
||||
|
||||
indx:=oid.oid_name-arg1;
|
||||
|
||||
arg1:=arg1 + indx;
|
||||
arg2:=arg2 - indx;
|
||||
|
||||
//if ((oid.oid_kind and CTLTYPE)=CTLTYPE_NODE) then
|
||||
//begin
|
||||
|
|
|
@ -209,6 +209,7 @@ type
|
|||
sysc_e00:Pointer;
|
||||
|
||||
sym_zero:elf64_sym;
|
||||
sym_nops:elf64_sym;
|
||||
|
||||
dyn_non_exist:Integer;
|
||||
end;
|
||||
|
@ -2200,7 +2201,7 @@ begin
|
|||
Result:=nil;
|
||||
err:=0;
|
||||
|
||||
fname:=ExtractFileName(path);
|
||||
fname:=dynlib_basename(path);
|
||||
|
||||
obj:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
||||
while (obj<>nil) do
|
||||
|
@ -2239,6 +2240,8 @@ begin
|
|||
fname:=ChangeFileExt(fname,'.prx');
|
||||
if rtld_file_exists(pchar(fname)) then goto _do_load;
|
||||
|
||||
Writeln(StdErr,' prx module not found:',path);
|
||||
|
||||
err:=ENOENT;
|
||||
Exit(nil);
|
||||
|
||||
|
|
|
@ -605,6 +605,10 @@
|
|||
<Filename Value="..\md\md_arc4random.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="..\vm\vm_patch_link.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
|
|
@ -108,7 +108,7 @@ uses
|
|||
vmparam,
|
||||
vnode,
|
||||
vfs_subr,
|
||||
kern_patcher;
|
||||
vm_patch_link;
|
||||
|
||||
function IDX_TO_OFF(x:DWORD):QWORD; inline;
|
||||
begin
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
unit vm_patch_link;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
{$CALLING SysV_ABI_CDecl}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
mqueue,
|
||||
kern_stub;
|
||||
|
||||
type
|
||||
t_patch_type=(pt_fsbase,pt_gsbase,pt_syscall);
|
||||
|
||||
p_patch_node=^t_patch_node;
|
||||
t_patch_node=record
|
||||
link :TAILQ_ENTRY;
|
||||
vaddr:Pointer;
|
||||
ptype:t_patch_type;
|
||||
stub :p_stub_chunk;
|
||||
end;
|
||||
|
||||
procedure vm_add_patch_link(_obj,vaddr:Pointer;ptype:t_patch_type;stub:p_stub_chunk);
|
||||
procedure vm_object_patch_remove(_obj:Pointer;start,__end:DWORD);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
vmparam,
|
||||
vm_object;
|
||||
|
||||
procedure vm_add_patch_link(_obj,vaddr:Pointer;ptype:t_patch_type;stub:p_stub_chunk);
|
||||
var
|
||||
obj:vm_object_t;
|
||||
node:p_patch_node;
|
||||
begin
|
||||
//Writeln('patch:vaddr=0x',HexStr(vaddr),' type:',ptype);
|
||||
|
||||
obj:=_obj;
|
||||
node:=AllocMem(SizeOf(t_patch_node));
|
||||
node^.vaddr:=vaddr;
|
||||
node^.ptype:=ptype;
|
||||
node^.stub :=stub;
|
||||
|
||||
p_inc_ref(stub);
|
||||
|
||||
VM_OBJECT_LOCK(obj);
|
||||
TAILQ_INSERT_TAIL(@obj^.patchq,node,@node^.link);
|
||||
VM_OBJECT_UNLOCK(obj);
|
||||
end;
|
||||
|
||||
procedure vm_free_patch_link(_obj:Pointer;node:p_patch_node);
|
||||
var
|
||||
obj:vm_object_t;
|
||||
begin
|
||||
obj:=_obj;
|
||||
TAILQ_REMOVE(@obj^.patchq,node,@node^.link);
|
||||
|
||||
p_dec_ref(node^.stub);
|
||||
FreeMem(node);
|
||||
end;
|
||||
|
||||
function OFF_TO_IDX(x:Pointer):DWORD; inline;
|
||||
begin
|
||||
Result:=QWORD(x) shr PAGE_SHIFT;
|
||||
end;
|
||||
|
||||
procedure vm_object_patch_remove(_obj:Pointer;start,__end:DWORD);
|
||||
var
|
||||
obj:vm_object_t;
|
||||
entry,next:p_patch_node;
|
||||
begin
|
||||
obj:=_obj;
|
||||
|
||||
VM_OBJECT_LOCK(obj);
|
||||
|
||||
entry:=TAILQ_FIRST(@obj^.patchq);
|
||||
while (entry<>nil) do
|
||||
begin
|
||||
next:=TAILQ_NEXT(entry,@entry^.link);
|
||||
//
|
||||
if ((start=0) or (OFF_TO_IDX(entry^.vaddr)>=start)) and
|
||||
((__end=0) or (OFF_TO_IDX(entry^.vaddr)<=__end)) then
|
||||
begin
|
||||
vm_free_patch_link(_obj,entry);
|
||||
end;
|
||||
//
|
||||
entry:=next;
|
||||
end;
|
||||
|
||||
VM_OBJECT_UNLOCK(obj);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
Loading…
Reference in New Issue