Basic TLS with patching + int 0x80

This commit is contained in:
Stefanos Kornilios Mitsis Poiitidis 2024-01-20 14:29:23 +02:00
parent af18453950
commit 724c56d8aa
2 changed files with 86 additions and 2 deletions

View file

@ -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
{