mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +02:00
loader: keep the caller's flags in the TLS stubs (#1571)
A patched TLS load calls TlsRegStub and SafeCall, which moved RSP past the red zone with sub/add rsp,0x80. ADD and SUB write the arithmetic flags, so the sub ran before SafeCall's pushfq saved them and the add ran after its popfq restored them: guest code that compares, loads fs:[0] and then branches on the flags could branch the wrong way. lea moves RSP without touching the flags. The entry lea plus a two-byte nop keeps every patched offset in both stubs; the exit lea is one byte longer and moves only ret. TlsStubsPreserveFlags calls the stubs with two flag patterns and checks the status flags, the output register and RAX; it fails with the old bytes. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+11
-9
@@ -58,16 +58,17 @@ struct TlsRegStub {
|
||||
}
|
||||
static uint64_t GetSize() { return 32; }
|
||||
|
||||
// sub rsp,0x80
|
||||
// lea rsp,[rsp-0x80]
|
||||
// nop
|
||||
// push rax
|
||||
// call safe_call
|
||||
// mov <reg>,rax
|
||||
// pop rax
|
||||
// add rsp,0x80
|
||||
// lea rsp,[rsp+0x80]
|
||||
// ret
|
||||
uint8_t code[32] = {0x48, 0x81, 0xEC, 0x80, 0x00, 0x00, 0x00, 0x50, 0xE8, 0x00, 0x00,
|
||||
0x00, 0x00, 0x48, 0x89, 0xC0, 0x58, 0x48, 0x81, 0xC4, 0x80, 0x00,
|
||||
0x00, 0x00, 0xC3, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
|
||||
uint8_t code[32] = {0x48, 0x8D, 0x64, 0x24, 0x80, 0x66, 0x90, 0x50, 0xE8, 0x00, 0x00,
|
||||
0x00, 0x00, 0x48, 0x89, 0xC0, 0x58, 0x48, 0x8D, 0xA4, 0x24, 0x80,
|
||||
0x00, 0x00, 0x00, 0xC3, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
|
||||
};
|
||||
|
||||
struct SafeCall {
|
||||
@@ -78,7 +79,8 @@ struct SafeCall {
|
||||
static uint64_t GetSize() { return 0x1000; }
|
||||
|
||||
uint8_t code[0x90] = {
|
||||
/*00*/ 0x48, 0x81, 0xec, 0x80, 0x00, 0x00, 0x00, // sub rsp,0x80
|
||||
/*00*/ 0x48, 0x8d, 0x64, 0x24, 0x80, // lea rsp,[rsp-0x80]
|
||||
/*05*/ 0x66, 0x90, // nop
|
||||
/*07*/ 0x9c, // pushfq
|
||||
/*08*/ 0x51, // push rcx
|
||||
/*09*/ 0x52, // push rdx
|
||||
@@ -108,9 +110,9 @@ struct SafeCall {
|
||||
/*40*/ 0x5a, // pop rdx
|
||||
/*41*/ 0x59, // pop rcx
|
||||
/*42*/ 0x9d, // popfq
|
||||
/*43*/ 0x48, 0x81, 0xc4, 0x80, 0x00, 0x00,
|
||||
0x00, // add rsp,0x80
|
||||
/*4a*/ 0xc3, // ret
|
||||
/*43*/ 0x48, 0x8d, 0xa4, 0x24, 0x80, 0x00, 0x00,
|
||||
0x00, // lea rsp,[rsp+0x80]
|
||||
/*4b*/ 0xc3, // ret
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user