Skip to content

Commit de61050

Browse files
unkn0wNameunkn0wName
authored andcommitted
feat: 累计更新2026-4-21,修复大量bug
1 parent e02ed0a commit de61050

2 files changed

Lines changed: 258 additions & 0 deletions

File tree

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
#include "patch_kernel_root.h"
2+
#include "analyze/base_func.h"
3+
#include "analyze/symbol_analyze.h"
4+
#include "patch_do_execve.h"
5+
#include "patch_current_avc_check.h"
6+
#include "patch_avc_denied.h"
7+
#include "patch_audit_log_start.h"
8+
#include "patch_filldir64.h"
9+
10+
#include "3rdparty/find_mrs_register.h"
11+
#include "3rdparty/find_imm_register_offset.h"
12+
#include "3rdparty/find_adrp_target.h"
13+
14+
struct PatchKernelOffset {
15+
size_t cred_offset = 0;
16+
size_t cred_uid_offset = 0;
17+
size_t seccomp_offset = 0;
18+
uint64_t huawei_kti_addr = 0;
19+
};
20+
21+
struct PatchKernelResult {
22+
bool patched = false;
23+
size_t root_key_start = 0;
24+
};
25+
26+
bool check_file_path(const char* file_path) {
27+
return std::filesystem::path(file_path).extension() != ".img";
28+
}
29+
30+
bool parser_cred_offset(const std::vector<char>& file_buf, const SymbolRegion &symbol, size_t& cred_offset) {
31+
using namespace a64_find_mrs_register;
32+
std::vector<track_reg_info>track_info;
33+
if (!find_current_task_next_register_offset(file_buf, symbol.offset, symbol.offset + symbol.size, track_info)) return false;
34+
cred_offset = 0;
35+
for (auto& t : track_info) {
36+
if (t.load_offset > 0x400) { cred_offset = t.load_offset; break; }
37+
}
38+
return cred_offset > 0;
39+
}
40+
41+
bool parse_cred_uid_offset(const std::vector<char>& file_buf, const SymbolRegion& symbol, size_t cred_offset, size_t& cred_uid_offset) {
42+
using namespace a64_find_imm_register_offset;
43+
cred_uid_offset = 0;
44+
KernelVersionParser kernel_ver(file_buf);
45+
size_t min_off = 8;
46+
if (kernel_ver.is_kernel_version_less("6.6.8")) min_off = 4;
47+
48+
std::vector<int64_t> candidate_offsets;
49+
if (!find_imm_register_offset(file_buf, symbol.offset, symbol.offset + symbol.size, candidate_offsets)) return false;
50+
51+
auto it = std::find(candidate_offsets.begin(), candidate_offsets.end(), cred_offset);
52+
if (it != candidate_offsets.end()) {
53+
for (++it; it != candidate_offsets.end(); ++it) {
54+
if (*it > 0x20 || *it < min_off) continue;
55+
cred_uid_offset = *it;
56+
break;
57+
}
58+
}
59+
return cred_uid_offset != 0;
60+
}
61+
62+
bool parser_seccomp_offset(const std::vector<char>& file_buf, const SymbolRegion& symbol, size_t& seccomp_offset) {
63+
using namespace a64_find_mrs_register;
64+
std::vector<track_reg_info>track_info;
65+
if (!find_current_task_next_register_offset(file_buf, symbol.offset, symbol.offset + symbol.size, track_info)) return false;
66+
seccomp_offset = 0;
67+
for (auto& t : track_info) {
68+
if (t.load_offset > 0x400) { seccomp_offset = t.load_offset; break; }
69+
}
70+
return seccomp_offset > 0;
71+
}
72+
73+
bool parser_huawei_kti_addr(const std::vector<char>& file_buf, const SymbolRegion& symbol, uint64_t& kti_addr) {
74+
using namespace a64_find_adrp_target;
75+
if (symbol.size == 0) return false;
76+
if (!find_adrp_target(file_buf, symbol.offset, symbol.offset + symbol.size, kti_addr)) return false;
77+
return kti_addr > 0;
78+
}
79+
80+
void cfi_bypass(const std::vector<char>& file_buf, KernelSymbolOffset &sym, std::vector<patch_bytes_data>& vec_patch_bytes_data) {
81+
if (sym.__cfi_check.offset) PATCH_AND_CONSUME(sym.__cfi_check, patch_ret_cmd(file_buf, sym.__cfi_check.offset, vec_patch_bytes_data));
82+
patch_ret_cmd(file_buf, sym.__cfi_check_fail, vec_patch_bytes_data);
83+
patch_ret_cmd(file_buf, sym.__cfi_slowpath_diag, vec_patch_bytes_data);
84+
patch_ret_cmd(file_buf, sym.__cfi_slowpath, vec_patch_bytes_data);
85+
patch_ret_cmd(file_buf, sym.__ubsan_handle_cfi_check_fail_abort, vec_patch_bytes_data);
86+
patch_ret_cmd(file_buf, sym.__ubsan_handle_cfi_check_fail, vec_patch_bytes_data);
87+
patch_ret_1_cmd(file_buf, sym.report_cfi_failure, vec_patch_bytes_data);
88+
}
89+
90+
void huawei_bypass(const std::vector<char>& file_buf, KernelSymbolOffset &sym, std::vector<patch_bytes_data>& vec_patch_bytes_data) {
91+
patch_ret_0_cmd(file_buf, sym.hkip_check_uid_root, vec_patch_bytes_data);
92+
patch_ret_0_cmd(file_buf, sym.hkip_check_gid_root, vec_patch_bytes_data);
93+
patch_ret_0_cmd(file_buf, sym.hkip_check_xid_root, vec_patch_bytes_data);
94+
}
95+
96+
PatchKernelResult patch_kernel_handler(const std::vector<char>& file_buf, const PatchKernelOffset& off, KernelSymbolOffset& sym, std::vector<patch_bytes_data>& vec_patch_bytes_data) {
97+
KernelVersionParser kernel_ver(file_buf);
98+
PatchBase patchBase(file_buf, off.cred_uid_offset, { .kti_addr = off.huawei_kti_addr });
99+
PatchDoExecve patchDoExecve(patchBase, sym);
100+
PatchCurrentAvcCheck patchCurrentAvcCheck(patchBase);
101+
PatchAvcDenied patchAvcDenied(patchBase, sym.avc_denied);
102+
PatchAuditLogStart patchAuditLogStart(patchBase, sym.audit_log_start);
103+
PatchFilldir64 patchFilldir64(patchBase, sym.filldir64);
104+
105+
bool patched = true;
106+
PatchKernelResult r;
107+
if (kernel_ver.is_kernel_version_less("6.1.0")) {
108+
SymbolRegion next_empty_region = { 0x200, 0x300 };
109+
if (sym.__cfi_check.offset && sym.__cfi_check.size > next_empty_region.size) next_empty_region = sym.__cfi_check;
110+
auto start_b_location = next_empty_region.offset;
111+
PATCH_AND_CONSUME(next_empty_region, 4);
112+
r.root_key_start = next_empty_region.offset;
113+
PATCH_AND_CONSUME(next_empty_region, patchDoExecve.patch_do_execve(next_empty_region, off.cred_offset, off.seccomp_offset, vec_patch_bytes_data));
114+
PATCH_AND_CONSUME(next_empty_region, patchFilldir64.patch_filldir64_root_key_guide(r.root_key_start, next_empty_region, vec_patch_bytes_data));
115+
PATCH_AND_CONSUME(next_empty_region, patchFilldir64.patch_filldir64_core(next_empty_region, vec_patch_bytes_data));
116+
auto current_avc_check_bl_func = next_empty_region.offset;
117+
PATCH_AND_CONSUME(next_empty_region, patchCurrentAvcCheck.patch_current_avc_check_bl_func(next_empty_region, off.cred_offset, vec_patch_bytes_data));
118+
PATCH_AND_CONSUME(next_empty_region, patchAvcDenied.patch_avc_denied(next_empty_region, current_avc_check_bl_func, vec_patch_bytes_data));
119+
PATCH_AND_CONSUME(next_empty_region, patchAuditLogStart.patch_audit_log_start(next_empty_region, current_avc_check_bl_func, vec_patch_bytes_data));
120+
auto end_b_location = next_empty_region.offset;
121+
patchBase.patch_jump(start_b_location, end_b_location, vec_patch_bytes_data);
122+
} else if (sym.die.offset && sym.__drm_puts_coredump.offset && sym.__drm_printfn_coredump.offset) {
123+
PATCH_AND_CONSUME(sym.__drm_printfn_coredump, patch_ret_cmd(file_buf, sym.__drm_printfn_coredump.offset, vec_patch_bytes_data));
124+
PATCH_AND_CONSUME(sym.__drm_puts_coredump, patch_ret_cmd(file_buf, sym.__drm_puts_coredump.offset, vec_patch_bytes_data));
125+
r.root_key_start = sym.die.offset;
126+
PATCH_AND_CONSUME(sym.die, patchDoExecve.patch_do_execve(sym.die, off.cred_offset, off.seccomp_offset, vec_patch_bytes_data));
127+
PATCH_AND_CONSUME(sym.die, patchFilldir64.patch_filldir64_root_key_guide(r.root_key_start, sym.die, vec_patch_bytes_data));
128+
PATCH_AND_CONSUME(sym.die, patchFilldir64.patch_jump(sym.die.offset, sym.__drm_puts_coredump.offset, vec_patch_bytes_data));
129+
PATCH_AND_CONSUME(sym.__drm_puts_coredump, patchFilldir64.patch_filldir64_core(sym.__drm_puts_coredump, vec_patch_bytes_data));
130+
auto current_avc_check_bl_func = sym.__drm_printfn_coredump.offset;
131+
PATCH_AND_CONSUME(sym.__drm_printfn_coredump, patchCurrentAvcCheck.patch_current_avc_check_bl_func(sym.__drm_printfn_coredump, off.cred_offset, vec_patch_bytes_data));
132+
PATCH_AND_CONSUME(sym.__drm_printfn_coredump, patchAvcDenied.patch_avc_denied(sym.__drm_printfn_coredump, current_avc_check_bl_func, vec_patch_bytes_data));
133+
PATCH_AND_CONSUME(sym.__drm_printfn_coredump, patchAuditLogStart.patch_audit_log_start(sym.__drm_printfn_coredump, current_avc_check_bl_func, vec_patch_bytes_data));
134+
} else {
135+
patched = false;
136+
}
137+
r.patched = patched;
138+
return r;
139+
}
140+
141+
void write_all_patch(const char* file_path, std::vector<patch_bytes_data>& vec_patch_bytes_data) {
142+
for (auto& item : vec_patch_bytes_data) {
143+
std::shared_ptr<char> spData(new (std::nothrow) char[item.str_bytes.length() / 2], std::default_delete<char[]>());
144+
hex2bytes((uint8_t*)item.str_bytes.c_str(), (uint8_t*)spData.get());
145+
if (!write_file_bytes(file_path, item.write_addr, spData.get(), item.str_bytes.length() / 2)) {
146+
std::cout << "写入文件发生错误" << std::endl;
147+
}
148+
}
149+
if (vec_patch_bytes_data.size()) std::cout << "Done." << std::endl;
150+
}
151+
152+
int main(int argc, char* argv[]) {
153+
++argv;
154+
--argc;
155+
156+
std::cout << "本工具用于生成SKRoot(Lite) ARM64 Linux内核ROOT提权代码 V12" << std::endl << std::endl;
157+
158+
#ifdef _DEBUG
159+
#else
160+
if (argc < 1) {
161+
std::cout << "无输入文件" << std::endl;
162+
system("pause");
163+
return 0;
164+
}
165+
#endif
166+
167+
#ifdef _DEBUG
168+
#else
169+
const char* file_path = argv[0];
170+
#endif
171+
std::cout << file_path << std::endl << std::endl;
172+
if (!check_file_path(file_path)) {
173+
std::cout << "Please enter the correct Linux kernel binary file path. " << std::endl;
174+
std::cout << "For example, if it is boot.img, you need to first decompress boot.img and then extract the kernel file inside." << std::endl;
175+
system("pause");
176+
return 0;
177+
}
178+
179+
std::vector<char> file_buf = read_file_buf(file_path);
180+
if (!file_buf.size()) {
181+
std::cout << "Fail to open file:" << file_path << std::endl;
182+
system("pause");
183+
return 0;
184+
}
185+
186+
SymbolAnalyze symbol_analyze(file_buf);
187+
if (!symbol_analyze.analyze_kernel_symbol()) {
188+
std::cout << "Failed to analyze kernel symbols" << std::endl;
189+
system("pause");
190+
return 0;
191+
}
192+
KernelSymbolOffset sym = symbol_analyze.get_symbol_offset();
193+
uint64_t anchor_off = sym.die.offset;
194+
195+
PatchKernelOffset off;
196+
if (!parser_cred_offset(file_buf, sym.sys_getuid, off.cred_offset)) {
197+
std::cout << "Failed to parse cred offset" << std::endl;
198+
system("pause");
199+
return 0;
200+
}
201+
202+
if (!parse_cred_uid_offset(file_buf, sym.sys_getuid, off.cred_offset, off.cred_uid_offset)) {
203+
std::cout << "Failed to parse cred uid offset" << std::endl;
204+
system("pause");
205+
return 0;
206+
}
207+
std::cout << "cred uid offset:" << off.cred_uid_offset << std::endl;
208+
209+
if (!parser_seccomp_offset(file_buf, sym.prctl_get_seccomp, off.seccomp_offset)) {
210+
std::cout << "Failed to parse seccomp offset" << std::endl;
211+
system("pause");
212+
return 0;
213+
}
214+
std::cout << "cred offset:" << off.cred_offset << std::endl;
215+
std::cout << "seccomp offset:" << off.seccomp_offset << std::endl;
216+
217+
parser_huawei_kti_addr(file_buf, sym.kti_randomize_init, off.huawei_kti_addr);
218+
if(off.huawei_kti_addr) std::cout << "kti addr:" << off.huawei_kti_addr << std::endl;
219+
220+
std::vector<patch_bytes_data> vec_patch_bytes_data;
221+
cfi_bypass(file_buf, sym, vec_patch_bytes_data);
222+
huawei_bypass(file_buf, sym, vec_patch_bytes_data);
223+
224+
size_t first_hook_start = 0;
225+
PatchKernelResult pr = patch_kernel_handler(file_buf, off, sym, vec_patch_bytes_data);
226+
if (!pr.patched) {
227+
std::cout << "Failed to find hook start addr" << std::endl;
228+
system("pause");
229+
return 0;
230+
}
231+
232+
std::string str_root_key;
233+
size_t is_need_create_root_key = 0;
234+
std::cout << std::endl << "请选择是否需要自动随机生成ROOT密匙(1需要;2不需要):" << std::endl;
235+
std::cin >> std::dec >> is_need_create_root_key;
236+
if (is_need_create_root_key == 1) {
237+
str_root_key = generate_random_str(ROOT_KEY_LEN);
238+
} else {
239+
std::cout << "请输入ROOT密匙(48个字符的字符串,包含大小写和数字):" << std::endl;
240+
std::cin >> str_root_key;
241+
std::cout << std::endl;
242+
}
243+
std::string write_key = str_root_key;
244+
write_key.erase(write_key.size() - 1);
245+
patch_data(file_buf, pr.root_key_start, (void*)write_key.c_str(), write_key.length() + 1, vec_patch_bytes_data);
246+
247+
std::cout << "#获取ROOT权限的密匙(Key): " << str_root_key.c_str() << std::endl << std::endl;
248+
249+
size_t need_write_modify_in_file = 0;
250+
std::cout << "#是否需要立即写入修改到文件?(1需要;2不需要):" << std::endl;
251+
std::cin >> need_write_modify_in_file;
252+
if (need_write_modify_in_file == 1) {
253+
std::cout << "#正在写入,请稍后..." << std::endl;
254+
write_all_patch(file_path, vec_patch_bytes_data);
255+
}
256+
system("pause");
257+
return 0;
258+
}
Binary file not shown.

0 commit comments

Comments
 (0)