-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathpatch_selinux_6_6.cpp
More file actions
128 lines (99 loc) · 4.81 KB
/
Copy pathpatch_selinux_6_6.cpp
File metadata and controls
128 lines (99 loc) · 4.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "patch_selinux_6_6.h"
#include "analyze/base_func.h"
#include "3rdparty/aarch64_asm_helper.h"
using namespace asmjit;
using namespace asmjit::a64;
using namespace asmjit::a64::Predicate;
PatchSelinux66::PatchSelinux66(const PatchBase66& patch_base)
: PatchBase66(patch_base) {}
PatchSelinux66::~PatchSelinux66() {}
// 生成SELinux禁用代码
// 该代码将selinux_enforcing设为0,使SELinux进入permissive模式
size_t PatchSelinux66::patch_selinux_disable(
const SymbolRegion& hook_func_start_region,
size_t selinux_enforcing_addr,
std::vector<patch_bytes_data>& vec_out_patch_bytes_data)
{
size_t hook_func_start_addr = hook_func_start_region.offset;
if (hook_func_start_addr == 0 || selinux_enforcing_addr == 0) {
std::cout << "[奥创版] SELinux禁用: selinux_enforcing符号未找到,跳过" << std::endl;
return 0;
}
std::cout << "[奥创版] 生成SELinux禁用代码 at: 0x" << std::hex << hook_func_start_addr << std::endl;
std::cout << " selinux_enforcing地址: 0x" << selinux_enforcing_addr << std::endl << std::endl;
aarch64_asm_ctx asm_ctx = init_aarch64_asm();
auto a = asm_ctx.assembler();
// ========== KASLR支持 ==========
// 使用ADR计算运行时kernel_base
uint32_t adr_instr = 0x10000000 | 10; // ADR x10, #0
a->embed((const uint8_t*)&adr_instr, sizeof(adr_instr));
size_t adr_file_offset = hook_func_start_addr + a->offset() - 4;
aarch64_asm_mov_x(a, x11, adr_file_offset);
a->sub(x10, x10, x11); // x10 = kernel_base
// 计算selinux_enforcing的运行时地址
aarch64_asm_mov_x(a, x11, selinux_enforcing_addr);
a->add(x11, x10, x11); // x11 = runtime selinux_enforcing addr
// 将selinux_enforcing设为0 (permissive模式)
a->str(wzr, ptr(x11));
// 返回(该函数应被其他代码调用)
a->ret(x30);
std::cout << print_aarch64_asm(a) << std::endl;
std::vector<uint8_t> bytes = aarch64_asm_to_bytes(a);
if (bytes.size() == 0) return 0;
std::string str_bytes = bytes2hex((const unsigned char*)bytes.data(), bytes.size());
size_t shellcode_size = str_bytes.length() / 2;
if (shellcode_size > hook_func_start_region.size) {
std::cout << "[发生错误] patch_selinux_disable failed: not enough kernel space." << std::endl;
return 0;
}
vec_out_patch_bytes_data.push_back({ str_bytes, hook_func_start_addr });
std::cout << "[奥创版] SELinux禁用代码大小: " << std::dec << shellcode_size << " bytes" << std::endl;
return shellcode_size;
}
// 生成动态SELinux控制代码
// 可被通信处理器CMD 9调用,动态切换SELinux状态
size_t PatchSelinux66::patch_selinux_toggle(
const SymbolRegion& hook_func_start_region,
size_t selinux_enforcing_addr,
std::vector<patch_bytes_data>& vec_out_patch_bytes_data)
{
size_t hook_func_start_addr = hook_func_start_region.offset;
if (hook_func_start_addr == 0 || selinux_enforcing_addr == 0) {
std::cout << "[奥创版] SELinux切换: selinux_enforcing符号未找到,跳过" << std::endl;
return 0;
}
std::cout << "[奥创版] 生成SELinux切换代码 at: 0x" << std::hex << hook_func_start_addr << std::endl;
std::cout << " selinux_enforcing地址: 0x" << selinux_enforcing_addr << std::endl << std::endl;
aarch64_asm_ctx asm_ctx = init_aarch64_asm();
auto a = asm_ctx.assembler();
// 输入: x0 = 新状态 (0=permissive, 1=enforcing)
// 输出: x0 = 旧状态
// ========== KASLR支持 ==========
uint32_t adr_instr = 0x10000000 | 10; // ADR x10, #0
a->embed((const uint8_t*)&adr_instr, sizeof(adr_instr));
size_t adr_file_offset = hook_func_start_addr + a->offset() - 4;
aarch64_asm_mov_x(a, x11, adr_file_offset);
a->sub(x10, x10, x11); // x10 = kernel_base
// 计算selinux_enforcing的运行时地址
aarch64_asm_mov_x(a, x11, selinux_enforcing_addr);
a->add(x11, x10, x11); // x11 = runtime selinux_enforcing addr
// 读取旧状态
a->ldr(w12, ptr(x11));
// 写入新状态
a->str(w0, ptr(x11));
// 返回旧状态
a->mov(x0, x12);
a->ret(x30);
std::cout << print_aarch64_asm(a) << std::endl;
std::vector<uint8_t> bytes = aarch64_asm_to_bytes(a);
if (bytes.size() == 0) return 0;
std::string str_bytes = bytes2hex((const unsigned char*)bytes.data(), bytes.size());
size_t shellcode_size = str_bytes.length() / 2;
if (shellcode_size > hook_func_start_region.size) {
std::cout << "[发生错误] patch_selinux_toggle failed: not enough kernel space." << std::endl;
return 0;
}
vec_out_patch_bytes_data.push_back({ str_bytes, hook_func_start_addr });
std::cout << "[奥创版] SELinux切换代码大小: " << std::dec << shellcode_size << " bytes" << std::endl;
return shellcode_size;
}