mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2024-11-30 06:30:48 +00:00
Basic TLS with patching + int 0x80
This commit is contained in:
parent
af18453950
commit
724c56d8aa
@ -19,8 +19,34 @@ void Flush() {
|
||||
spdlog::details::registry::instance().flush_all();
|
||||
}
|
||||
|
||||
thread_local uint8_t TLS[1024];
|
||||
|
||||
uint64_t tls_access(int64_t tls_offset) {
|
||||
if (tls_offset == 0) {
|
||||
return (uint64_t)TLS;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
static LONG WINAPI ExceptionHandler(PEXCEPTION_POINTERS pExp) noexcept {
|
||||
if (*(uint8_t *)pExp->ContextRecord->Rip == 0xcd) {
|
||||
int reg = *(uint8_t *)(pExp->ContextRecord->Rip + 1) - 0x80;
|
||||
int sizes = *(uint8_t *)(pExp->ContextRecord->Rip + 2);
|
||||
int pattern_size = sizes & 0xF;
|
||||
int imm_size = sizes >> 4;
|
||||
|
||||
int64_t tls_offset;
|
||||
if (imm_size == 4)
|
||||
tls_offset = *(int32_t *)(pExp->ContextRecord->Rip + pattern_size);
|
||||
else
|
||||
tls_offset = *(int64_t *)(pExp->ContextRecord->Rip + pattern_size);
|
||||
|
||||
(&pExp->ContextRecord->Rax)[reg] = tls_access(tls_offset); /* TLS_ACCESS */
|
||||
pExp->ContextRecord->Rip += pattern_size + imm_size;
|
||||
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
||||
const u32 ec = pExp->ExceptionRecord->ExceptionCode;
|
||||
switch (ec) {
|
||||
case EXCEPTION_ACCESS_VIOLATION: {
|
||||
|
@ -95,8 +95,62 @@ Module* Linker::FindModule(/*u32 id*/)
|
||||
return &m_modules[0];
|
||||
}
|
||||
|
||||
void Linker::LoadModuleToMemory(Module* m)
|
||||
{
|
||||
struct TLSPattern{
|
||||
uint8_t pattern[5];
|
||||
uint8_t pattern_size;
|
||||
uint8_t imm_size;
|
||||
uint8_t target_reg;
|
||||
};
|
||||
|
||||
constexpr TLSPattern tls_patterns[] = {
|
||||
{{0x64, 0x48, 0xA1}, 3, 8, 0}, // 64 48 A1 | 00 00 00 00 00 00 00 00 # mov rax, qword ptr fs:[64b imm]
|
||||
|
||||
{{0x64, 0x48, 0x8B, 0x4, 0x25}, 5, 4, 0}, // 64 48 8B 04 25 | 00 00 00 00 # mov rax,qword ptr fs:[0]
|
||||
{{0x64, 0x48, 0x8B, 0xC, 0x25}, 5, 4, 1}, // rcx
|
||||
{{0x64, 0x48, 0x8B, 0x14, 0x25}, 5, 4, 2}, // rdx
|
||||
{{0x64, 0x48, 0x8B, 0x1C, 0x25}, 5, 4, 3}, // rbx
|
||||
{{0x64, 0x48, 0x8B, 0x24, 0x25}, 5, 4, 4}, // rsp
|
||||
{{0x64, 0x48, 0x8B, 0x2C, 0x25}, 5, 4, 5}, // rbp
|
||||
{{0x64, 0x48, 0x8B, 0x34, 0x25}, 5, 4, 6}, // rsi
|
||||
{{0x64, 0x48, 0x8B, 0x3C, 0x25}, 5, 4, 7}, // rdi
|
||||
{{0x64, 0x4C, 0x8B, 0x4, 0x25}, 5, 4, 8}, // r8
|
||||
{{0x64, 0x4C, 0x8B, 0xC, 0x25}, 5, 4, 9}, // r9
|
||||
{{0x64, 0x4C, 0x8B, 0x14, 0x25}, 5, 4, 10},// r10
|
||||
{{0x64, 0x4C, 0x8B, 0x1C, 0x25}, 5, 4, 11},// r11
|
||||
{{0x64, 0x4C, 0x8B, 0x24, 0x25}, 5, 4, 12},// r12
|
||||
{{0x64, 0x4C, 0x8B, 0x2C, 0x25}, 5, 4, 13},// r13
|
||||
{{0x64, 0x4C, 0x8B, 0x34, 0x25}, 5, 4, 14},// r14
|
||||
{{0x64, 0x4C, 0x8B, 0x3C, 0x25}, 5, 4, 15},// r15
|
||||
};
|
||||
|
||||
void PatchTLS(u64 segment_addr, u64 segment_size) {
|
||||
uint8_t* code = (uint8_t*)segment_addr;
|
||||
auto remaining_size = segment_size;
|
||||
|
||||
while (remaining_size) {
|
||||
for (auto& tls_pattern : tls_patterns) {
|
||||
auto total_size = tls_pattern.pattern_size + tls_pattern.imm_size;
|
||||
if (remaining_size >= total_size) {
|
||||
if (memcmp(code, tls_pattern.pattern, tls_pattern.pattern_size) == 0) {
|
||||
if (tls_pattern.imm_size == 4)
|
||||
printf("PATTERN32 FOUND @ %p, reg: %d offset: %X\n", code, tls_pattern.target_reg, *(uint32_t*)(code + tls_pattern.pattern_size));
|
||||
else
|
||||
printf("PATTERN64 FOUND @ %p, reg: %d offset: %lX\n", code, tls_pattern.target_reg, *(uint64_t*)(code + tls_pattern.pattern_size));
|
||||
code[0] = 0xcd;
|
||||
code[1] = 0x80 + tls_pattern.target_reg;
|
||||
code[2] = tls_pattern.pattern_size | (tls_pattern.imm_size << 4);
|
||||
code += total_size - 1;
|
||||
remaining_size -= total_size - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
code++;
|
||||
remaining_size--;
|
||||
}
|
||||
}
|
||||
|
||||
void Linker::LoadModuleToMemory(Module* m) {
|
||||
//get elf header, program header
|
||||
const auto elf_header = m->elf.GetElfHeader();
|
||||
const auto elf_pheader = m->elf.GetProgramHeader();
|
||||
@ -130,6 +184,10 @@ void Linker::LoadModuleToMemory(Module* m)
|
||||
LOG_INFO_IF(debug_loader, "segment_mode ..........: {}\n", segment_mode);
|
||||
|
||||
m->elf.LoadSegment(segment_addr, elf_pheader[i].p_offset, segment_file_size);
|
||||
|
||||
if (elf_pheader[i].p_flags & PF_EXEC) {
|
||||
PatchTLS(segment_addr, segment_file_size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user