mirror of https://github.com/red-prig/fpPS4.git
580 lines
16 KiB
Plaintext
580 lines
16 KiB
Plaintext
unit kern_patcher;
|
|
|
|
{$mode ObjFPC}{$H+}
|
|
{$CALLING SysV_ABI_CDecl}
|
|
|
|
interface
|
|
|
|
uses
|
|
kern_stub;
|
|
|
|
procedure patcher_process_section(_imgp,data,vaddr:Pointer;filesz,memsz:QWORD;prot:Byte);
|
|
|
|
implementation
|
|
|
|
uses
|
|
kern_thr,
|
|
md_map,
|
|
vm_patch_link,
|
|
trap,
|
|
x86_index_instr,
|
|
kern_rtld;
|
|
|
|
{
|
|
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]
|
|
64 48 8B 0C 25 [00000000] mov rcx,fs:[$00000000] -> 65 48 8B 0C 25 [08070000] mov rcx,gs:[$00000708]
|
|
64 48 8B 14 25 [00000000] mov rdx,fs:[$00000000] -> 65 48 8B 14 25 [08070000] mov rdx,gs:[$00000708]
|
|
64 48 8B 1C 25 [00000000] mov rbx,fs:[$00000000] -> 65 48 8B 1C 25 [08070000] mov rbx,gs:[$00000708]
|
|
64 48 8B 24 25 [00000000] mov rsp,fs:[$00000000] -> 65 48 8B 24 25 [08070000] mov rsp,gs:[$00000708]
|
|
64 48 8B 2C 25 [00000000] mov rbp,fs:[$00000000] -> 65 48 8B 2C 25 [08070000] mov rbp,gs:[$00000708]
|
|
64 48 8B 34 25 [00000000] mov rsi,fs:[$00000000] -> 65 48 8B 34 25 [08070000] mov rsi,gs:[$00000708]
|
|
64 48 8B 3C 25 [00000000] mov rdi,fs:[$00000000] -> 65 48 8B 3C 25 [08070000] mov rdi,gs:[$00000708]
|
|
64 4C 8B 04 25 [00000000] mov r8 ,fs:[$00000000] -> 65 4C 8B 04 25 [08070000] mov r8 ,gs:[$00000708]
|
|
64 4C 8B 0C 25 [00000000] mov r9 ,fs:[$00000000] -> 65 4C 8B 0C 25 [08070000] mov r9 ,gs:[$00000708]
|
|
64 4C 8B 14 25 [00000000] mov r10,fs:[$00000000] -> 65 4C 8B 14 25 [08070000] mov r10,gs:[$00000708]
|
|
64 4C 8B 1C 25 [00000000] mov r11,fs:[$00000000] -> 65 4C 8B 1C 25 [08070000] mov r11,gs:[$00000708]
|
|
64 4C 8B 24 25 [00000000] mov r12,fs:[$00000000] -> 65 4C 8B 24 25 [08070000] mov r12,gs:[$00000708]
|
|
64 4C 8B 2C 25 [00000000] mov r13,fs:[$00000000] -> 65 4C 8B 2C 25 [08070000] mov r13,gs:[$00000708]
|
|
64 4C 8B 34 25 [00000000] mov r14,fs:[$00000000] -> 65 4C 8B 34 25 [08070000] mov r14,gs:[$00000708]
|
|
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
|
|
|
|
[49 89 ca]:MOV R10,RCX
|
|
|
|
[0f 05]:SYSCALL
|
|
|
|
[72 01]:JC LAB
|
|
|
|
[c3]:RET
|
|
|
|
///////////////////
|
|
|
|
[48 c7 c0 | dd 01 00 00]:MOV RAX,0x1dd
|
|
|
|
[49 89 ca]:MOV R10,RCX
|
|
|
|
[0f 05]:SYSCALL
|
|
|
|
[72 01]:JC LAB
|
|
|
|
[c3]:RET
|
|
|
|
//////////
|
|
|
|
48 c7 c0 01 | 00 00 00 MOV RAX,0x1
|
|
49 89 ca MOV R10,RCX
|
|
0f 05 SYSCALL
|
|
41 5c POP R12
|
|
5b POP RBX
|
|
|
|
[00 00 00 | 49 89 ca | 0f 05 | 41 5c]
|
|
|
|
//////////
|
|
|
|
48 c7 c0 fb | 00 00 00 MOV RAX,0xfb
|
|
49 89 ca MOV R10,RCX
|
|
0f 05 SYSCALL
|
|
72 1f JC LAB_
|
|
83 fa 00 CMP EDX,0x0
|
|
75 04 JNZ LAB_
|
|
41 5c POP R12
|
|
|
|
[00 00 00 | 49 89 ca | 0f 05 | 72 1f]
|
|
|
|
//////////
|
|
|
|
48 c7 c0 01 | 00 00 00 MOV RAX,0x1
|
|
49 89 ca MOV R10,RCX
|
|
0f 05 SYSCALL
|
|
41 5c POP R12
|
|
5b POP RBX
|
|
|
|
//////////
|
|
|
|
48 c7 c0 3b | 00 00 00 MOV RAX,0x3b
|
|
49 89 ca MOV R10,RCX
|
|
0f 05 SYSCALL
|
|
48 8d 15 c0 LEA RDX,[FUN_]
|
|
ff ff ff
|
|
ff e2 JMP RDX=>FUN_
|
|
|
|
[00 00 00 | 49 89 ca | 0f 05 | 48 8d]
|
|
|
|
//////////
|
|
|
|
48 c7 c0 a5 | 01 00 00 MOV RAX,0x1a5
|
|
49 89 ca MOV R10,RCX
|
|
0f 05 SYSCALL
|
|
72 06 JC LAB_
|
|
48 83 c4 08 ADD RSP,0x8
|
|
ff e6 JMP RSI
|
|
|
|
[01 00 00 | 49 89 ca | 0f 05 | 72 06]
|
|
|
|
//////////
|
|
|
|
48 c7 c0 2a | 00 00 00 MOV RAX,0x2a
|
|
49 89 ca MOV R10,RCX
|
|
0f 05 SYSCALL
|
|
72 0d JC LAB_
|
|
89 07 MOV dword ptr
|
|
|
|
[00 00 00 | 49 89 ca | 0f 05 | 72 0d]
|
|
|
|
//////////
|
|
|
|
48 c7 c0 37 | 00 00 00 MOV RAX,0x37
|
|
49 89 ca MOV R10,RCX
|
|
0f 05 SYSCALL
|
|
72 02 JC LAB_
|
|
48 cf IRETQ
|
|
|
|
[00 00 00 | 49 89 ca | 0f 05 | 72 02]
|
|
|
|
//////////
|
|
|
|
48 c7 c0 32 | 00 00 00 MOV RAX,0x32
|
|
49 89 ca MOV R10,RCX
|
|
0f 05 SYSCALL
|
|
72 0e JC LAB_
|
|
48 8d 15 a3 e1 08 00 LEA RDX,[DAT_]
|
|
|
|
[00 00 00 | 49 89 ca | 0f 05 | 72 0e]
|
|
|
|
//////////
|
|
|
|
48 c7 c0 42 | 00 00 00 MOV RAX,0x42
|
|
49 89 ca MOV R10,RCX
|
|
0f 05 SYSCALL
|
|
72 02 JC LAB_
|
|
ff e6 JMP RSI
|
|
|
|
[00 00 00 | 49 89 ca | 0f 05 | 72 02]
|
|
|
|
//////////
|
|
|
|
48 c7 c0 54 | 01 00 00 MOV RAX,0x154
|
|
49 89 ca MOV R10,RCX
|
|
0f 05 SYSCALL
|
|
5f POP RDI
|
|
48 81 bf 18 CMP qword ptr [RDI + 0x118],0x20001
|
|
01 00 00 01
|
|
00 02 00
|
|
|
|
[01 00 00 | 49 89 ca | 0f 05 | 5f 48]
|
|
|
|
//////////
|
|
|
|
48 c7 c0 c6 | 01 00 00 MOV RAX,0x1c6
|
|
49 89 ca MOV R10,RCX
|
|
0f 05 SYSCALL
|
|
c3 RET
|
|
90 ?? 90h
|
|
|
|
[01 00 00 | 49 89 ca | 0f 05 | c3 90]
|
|
|
|
//////////
|
|
|
|
0 1 2 3 4 5 6 7 8 9
|
|
[0X 00 00 | 49 89 ca | 0f 05 | 41 5c]
|
|
[0X 00 00 | 49 89 ca | 0f 05 | 72 01]
|
|
[0X 00 00 | 49 89 ca | 0f 05 | 72 1f]
|
|
[0X 00 00 | 49 89 ca | 0f 05 | 48 8d]
|
|
[0X 00 00 | 49 89 ca | 0f 05 | 72 06]
|
|
[0X 00 00 | 49 89 ca | 0f 05 | 72 0d]
|
|
[0X 00 00 | 49 89 ca | 0f 05 | 72 02]
|
|
[0X 00 00 | 49 89 ca | 0f 05 | 72 0e]
|
|
[0X 00 00 | 49 89 ca | 0f 05 | 5f 48]
|
|
[0X 00 00 | 49 89 ca | 0f 05 | c3 90]
|
|
X=0,1,2
|
|
}
|
|
|
|
{
|
|
jmpq 0(%rip) -> [FF 25 | 00 00 00 00]
|
|
callq 0(%rip) -> [FF 15 | 00 00 00 00]
|
|
|
|
jmpl [32] -> [E9 | 00 00 00 00]
|
|
calll [32] -> [E8 | 00 00 00 00]
|
|
}
|
|
|
|
type
|
|
{
|
|
p_patch_base_long=^t_patch_base_long;
|
|
t_patch_base_long=packed record
|
|
len :Byte ; //12
|
|
inst:array[0..2] of Byte;
|
|
addr:Int64; //teb_tcb/teb_gsbase
|
|
end;
|
|
|
|
p_patch_base_short=^t_patch_base_short;
|
|
t_patch_base_short=packed record
|
|
len :Byte ; //9
|
|
inst:array[0..4] of Byte;
|
|
addr:Integer; //teb_tcb/teb_gsbase
|
|
end;
|
|
|
|
t_patch_inst=packed record
|
|
case Byte of
|
|
0:(A:t_patch_base_long);
|
|
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
|
|
inst :Word; //FF 25
|
|
offset:DWORD; //00
|
|
addr :QWORD;
|
|
end;
|
|
|
|
p_call32_trampoline=^t_call32_trampoline;
|
|
t_call32_trampoline=packed record
|
|
inst:Byte; //E8
|
|
addr:Integer;
|
|
end;
|
|
|
|
p_jmp32_trampoline=^t_jmp32_trampoline;
|
|
t_jmp32_trampoline=t_call32_trampoline;
|
|
|
|
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=(
|
|
(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 )),
|
|
(B:(len: 9;inst:($65,$48,$8B,$1C,$25);addr:teb_tcb )),
|
|
(B:(len: 9;inst:($65,$48,$8B,$24,$25);addr:teb_tcb )),
|
|
(B:(len: 9;inst:($65,$48,$8B,$2C,$25);addr:teb_tcb )),
|
|
(B:(len: 9;inst:($65,$48,$8B,$34,$25);addr:teb_tcb )),
|
|
(B:(len: 9;inst:($65,$48,$8B,$3C,$25);addr:teb_tcb )),
|
|
(B:(len: 9;inst:($65,$4C,$8B,$04,$25);addr:teb_tcb )),
|
|
(B:(len: 9;inst:($65,$4C,$8B,$0C,$25);addr:teb_tcb )),
|
|
(B:(len: 9;inst:($65,$4C,$8B,$14,$25);addr:teb_tcb )),
|
|
(B:(len: 9;inst:($65,$4C,$8B,$1C,$25);addr:teb_tcb )),
|
|
(B:(len: 9;inst:($65,$4C,$8B,$24,$25);addr:teb_tcb )),
|
|
(B:(len: 9;inst:($65,$4C,$8B,$2C,$25);addr:teb_tcb )),
|
|
(B:(len: 9;inst:($65,$4C,$8B,$34,$25);addr:teb_tcb )),
|
|
(B:(len: 9;inst:($65,$4C,$8B,$3C,$25);addr:teb_tcb )),
|
|
(A:(len:12;inst:($65,$48,$A1 );addr:teb_tcb )),
|
|
//
|
|
(B:(len: 9;inst:($65,$48,$8B,$04,$25);addr:teb_gsbase)),
|
|
(B:(len: 9;inst:($65,$48,$8B,$0C,$25);addr:teb_gsbase)),
|
|
(B:(len: 9;inst:($65,$48,$8B,$14,$25);addr:teb_gsbase)),
|
|
(B:(len: 9;inst:($65,$48,$8B,$1C,$25);addr:teb_gsbase)),
|
|
(B:(len: 9;inst:($65,$48,$8B,$24,$25);addr:teb_gsbase)),
|
|
(B:(len: 9;inst:($65,$48,$8B,$2C,$25);addr:teb_gsbase)),
|
|
(B:(len: 9;inst:($65,$48,$8B,$34,$25);addr:teb_gsbase)),
|
|
(B:(len: 9;inst:($65,$48,$8B,$3C,$25);addr:teb_gsbase)),
|
|
(B:(len: 9;inst:($65,$4C,$8B,$04,$25);addr:teb_gsbase)),
|
|
(B:(len: 9;inst:($65,$4C,$8B,$0C,$25);addr:teb_gsbase)),
|
|
(B:(len: 9;inst:($65,$4C,$8B,$14,$25);addr:teb_gsbase)),
|
|
(B:(len: 9;inst:($65,$4C,$8B,$1C,$25);addr:teb_gsbase)),
|
|
(B:(len: 9;inst:($65,$4C,$8B,$24,$25);addr:teb_gsbase)),
|
|
(B:(len: 9;inst:($65,$4C,$8B,$2C,$25);addr:teb_gsbase)),
|
|
(B:(len: 9;inst:($65,$4C,$8B,$34,$25);addr:teb_gsbase)),
|
|
(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_fsbase),
|
|
(inst:($65,$48,$8B,$0C,$25);addr:teb_fsbase),
|
|
(inst:($65,$48,$8B,$14,$25);addr:teb_fsbase),
|
|
(inst:($65,$48,$8B,$1C,$25);addr:teb_fsbase),
|
|
(inst:($65,$48,$8B,$24,$25);addr:teb_fsbase),
|
|
(inst:($65,$48,$8B,$2C,$25);addr:teb_fsbase),
|
|
(inst:($65,$48,$8B,$34,$25);addr:teb_fsbase),
|
|
(inst:($65,$48,$8B,$3C,$25);addr:teb_fsbase),
|
|
(inst:($65,$4C,$8B,$04,$25);addr:teb_fsbase),
|
|
(inst:($65,$4C,$8B,$0C,$25);addr:teb_fsbase),
|
|
(inst:($65,$4C,$8B,$14,$25);addr:teb_fsbase),
|
|
(inst:($65,$4C,$8B,$1C,$25);addr:teb_fsbase),
|
|
(inst:($65,$4C,$8B,$24,$25);addr:teb_fsbase),
|
|
(inst:($65,$4C,$8B,$2C,$25);addr:teb_fsbase),
|
|
(inst:($65,$4C,$8B,$34,$25);addr:teb_fsbase),
|
|
(inst:($65,$4C,$8B,$3C,$25);addr:teb_fsbase)
|
|
);
|
|
|
|
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_jmp32_trampoline =(inst:$E9;addr:0);
|
|
|
|
procedure patch_original(const info:t_instr_index_info;delta:Integer;addr_out:Pointer);
|
|
var
|
|
trampoline:t_call32_trampoline;
|
|
begin
|
|
//fill nop
|
|
FillChar(addr_out^,info.inlen,$90);
|
|
|
|
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;
|
|
|
|
trampoline.addr:=delta;
|
|
p_call32_trampoline(addr_out)^:=trampoline;
|
|
end;
|
|
|
|
procedure vm_add_mov_base_patch(const info:t_instr_index_info;_obj,vaddr,addr_out:Pointer);
|
|
var
|
|
stub:p_stub_chunk;
|
|
|
|
trampoline:t_base_data_trampoline;
|
|
|
|
delta:Int64;
|
|
begin
|
|
stub:=p_alloc(vaddr,SizeOf(t_base_data_trampoline),True);
|
|
|
|
delta:=Int64(@stub^.body)-(Int64(vaddr)+SizeOf(t_call32_trampoline));
|
|
Assert(abs(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,info.inlen,pt_fsbase,stub);
|
|
GSBASE:vm_add_patch_link(_obj,vaddr,info.inlen,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),True);
|
|
|
|
delta:=Int64(@stub^.body)-(Int64(vaddr)+SizeOf(t_call32_trampoline));
|
|
Assert(abs(delta)<High(Integer),'vm_add_syscall_patch');
|
|
|
|
patch_original(info,Integer(delta),addr_out);
|
|
|
|
trampoline:=c_jmpq64_trampoline;
|
|
trampoline.addr:=QWORD(@fast_syscall);
|
|
p_jmpq64_trampoline(@stub^.body)^:=trampoline;
|
|
|
|
md_cacheflush(@stub^.body,SizeOf(trampoline),ICACHE);
|
|
|
|
vm_add_patch_link(_obj,vaddr,info.inlen,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(_imgp,data,vaddr:Pointer;filesz,memsz:QWORD;prot:Byte);
|
|
var
|
|
addr:Pointer;
|
|
pend:Pointer;
|
|
|
|
info:t_instr_index_info;
|
|
|
|
b:Boolean;
|
|
|
|
fs_count:Integer;
|
|
gs_count:Integer;
|
|
sv_count:Integer;
|
|
|
|
imgp:p_image_params;
|
|
|
|
{
|
|
procedure do_patch_base_zero(addr:PByte;i:Integer;ptype:t_patch_type);
|
|
var
|
|
v:Pointer;
|
|
begin
|
|
Move(patch_table[i].C[1],addr^,patch_table[i].C[0]);
|
|
|
|
v:=vaddr+(Int64(addr)-Int64(data));
|
|
vm_add_patch_link(imgp^.obj,v,ptype,nil);
|
|
end;
|
|
|
|
procedure do_patch_syscall(addr:PByte);
|
|
var
|
|
v:Pointer;
|
|
begin
|
|
v:=vaddr+(Int64(addr)-Int64(data));
|
|
|
|
vm_add_syscall_patch(imgp^.obj,v,addr);
|
|
end;
|
|
}
|
|
|
|
procedure do_patch_syscall(addr:PByte);
|
|
var
|
|
v:Pointer;
|
|
begin
|
|
v:=vaddr+(Int64(addr)-Int64(data));
|
|
|
|
vm_add_patch(info,imgp^.obj,v,addr);
|
|
end;
|
|
|
|
begin
|
|
Assert(_imgp<>nil,'patcher_process_section');
|
|
|
|
imgp:=_imgp;
|
|
|
|
{
|
|
if Pos('libkernel',imgp^.execpath)<>0 then
|
|
begin
|
|
//103040
|
|
if (prot=3) then
|
|
begin
|
|
if (memsz>103040) then
|
|
begin
|
|
PInteger(data+103040)^:=-1;
|
|
end;
|
|
end;
|
|
end;
|
|
}
|
|
|
|
Exit;
|
|
|
|
fs_count:=0;
|
|
gs_count:=0;
|
|
sv_count:=0;
|
|
|
|
addr:=data;
|
|
pend:=addr+filesz;
|
|
repeat
|
|
info:=Default(t_instr_index_info);
|
|
|
|
b:=IndexInstr(addr,pend,info);
|
|
|
|
if (not b) then Break;
|
|
|
|
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,info.inlen);
|
|
|
|
until false;
|
|
|
|
Writeln('[patcher_vaddr]:0x',HexStr(qword(vaddr),12),'..',HexStr(qword(vaddr)+filesz,12));
|
|
Writeln(' fs_count:',fs_count);
|
|
Writeln(' gs_count:',gs_count);
|
|
Writeln(' sv_count:',sv_count);
|
|
|
|
Writeln;
|
|
|
|
//readln;
|
|
end;
|
|
|
|
|
|
|
|
end.
|
|
|