-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathpatch_kernel_sk.cpp
More file actions
746 lines (648 loc) · 35 KB
/
Copy pathpatch_kernel_sk.cpp
File metadata and controls
746 lines (648 loc) · 35 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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
#include "patch_kernel_sk.h"
#include "analyze/base_func.h"
#include <cstring>
#include <algorithm>
#include <iomanip>
#include "analyze/symbol_analyze.h"
#include "patch_do_execve_6_6.h"
#include "patch_current_avc_check_6_6.h"
#include "patch_avc_denied_6_6.h"
#include "patch_audit_log_start_6_6.h"
#include "patch_filldir64_6_6.h"
#include "patch_communication.h"
#include "patch_hook_area.h"
// 奥创版Phase 2 & 3
#include "patch_proc_hide_6_6.h"
#include "patch_selinux_6_6.h"
#include "patch_anti_detect_6_6.h"
#include "patch_prctl_comm_6_6.h"
#include "patch_verity_bypass_6_6.h"
#include "3rdparty/find_mrs_register.h"
#include "3rdparty/find_imm_register_offset.h"
using namespace asmjit;
using namespace asmjit::a64;
using namespace asmjit::a64::Predicate;
// ============================================================================
// SKRoot Pro 奥创版 (Ultron Edition) V3.0
// ============================================================================
// 基于超强隐蔽版,新增:
// - Phase 1: 内存安全检查 + 块复制优化 + 缓存刷新
// - Phase 2: 进程隐藏 + SELinux增强 + 反检测
// - Phase 3: prctl通信 + dm-verity绕过
// ============================================================================
struct PatchKernelResult {
bool patched = false;
size_t root_key_start = 0;
size_t comm_handler_addr = 0;
size_t hook_area_start = 0;
size_t hook_area_size = 0;
// 奥创版新增
size_t prctl_handler_addr = 0;
size_t selinux_toggle_addr = 0;
bool verity_bypassed = false;
};
// NOP区域信息
struct NopRegion {
size_t offset;
size_t size;
bool used;
};
bool check_file_path(const char* file_path) {
return std::filesystem::path(file_path).extension() != ".img";
}
bool parser_cred_offset(const std::vector<char>& file_buf, const SymbolRegion& symbol, std::string& mode_name, size_t& cred_offset) {
using namespace a64_find_mrs_register;
return find_current_task_next_register_offset(file_buf, symbol.offset, symbol.offset + symbol.size, mode_name, cred_offset);
}
bool parse_cred_uid_offset(const std::vector<char>& file_buf, const SymbolRegion& symbol, size_t cred_offset, size_t& cred_uid_offset) {
using namespace a64_find_imm_register_offset;
cred_uid_offset = 0;
// 6.6内核: cred_uid_offset最小值为8
size_t min_off = 8;
std::vector<int64_t> candidate_offsets;
if (!find_imm_register_offset(file_buf, symbol.offset, symbol.offset + symbol.size, candidate_offsets))
return false;
auto it = std::find(candidate_offsets.begin(), candidate_offsets.end(), cred_offset);
if (it != candidate_offsets.end()) {
for (++it; it != candidate_offsets.end(); ++it) {
if (*it > 0x30 || *it < min_off) continue;
cred_uid_offset = *it;
break;
}
}
return cred_uid_offset != 0;
}
bool parser_seccomp_offset(const std::vector<char>& file_buf, const SymbolRegion& symbol, std::string& mode_name, size_t& seccomp_offset) {
using namespace a64_find_mrs_register;
return find_current_task_next_register_offset(file_buf, symbol.offset, symbol.offset + symbol.size, mode_name, seccomp_offset);
}
// CFI绕过
void cfi_bypass(const std::vector<char>& file_buf, KernelSymbolOffset& sym, std::vector<patch_bytes_data>& vec_patch_bytes_data) {
if (sym.__cfi_check.offset) {
patch_ret_cmd(file_buf, sym.__cfi_check.offset, vec_patch_bytes_data);
sym.__cfi_check.consume(4);
}
if (sym.__cfi_check_fail) {
patch_ret_cmd(file_buf, sym.__cfi_check_fail, vec_patch_bytes_data);
}
if (sym.__cfi_slowpath_diag) {
patch_ret_cmd(file_buf, sym.__cfi_slowpath_diag, vec_patch_bytes_data);
}
if (sym.__cfi_slowpath) {
patch_ret_cmd(file_buf, sym.__cfi_slowpath, vec_patch_bytes_data);
}
if (sym.__ubsan_handle_cfi_check_fail_abort) {
patch_ret_cmd(file_buf, sym.__ubsan_handle_cfi_check_fail_abort, vec_patch_bytes_data);
}
if (sym.__ubsan_handle_cfi_check_fail) {
patch_ret_cmd(file_buf, sym.__ubsan_handle_cfi_check_fail, vec_patch_bytes_data);
}
if (sym.report_cfi_failure) {
patch_ret_1_cmd(file_buf, sym.report_cfi_failure, vec_patch_bytes_data);
}
}
// 华为HKIP绕过
void huawei_bypass(const std::vector<char>& file_buf, KernelSymbolOffset& sym, std::vector<patch_bytes_data>& vec_patch_bytes_data) {
if (sym.hkip_check_uid_root) {
patch_ret_0_cmd(file_buf, sym.hkip_check_uid_root, vec_patch_bytes_data);
}
if (sym.hkip_check_gid_root) {
patch_ret_0_cmd(file_buf, sym.hkip_check_gid_root, vec_patch_bytes_data);
}
if (sym.hkip_check_xid_root) {
patch_ret_0_cmd(file_buf, sym.hkip_check_xid_root, vec_patch_bytes_data);
}
}
// ============================================================================
// 超强隐蔽版核心:检测.text段内的NOP填充区域
// ============================================================================
// 这些区域是编译器为对齐而生成的,全是NOP指令
// 关键:必须在.text段内(0x10000+)才能保证有执行权限
// ============================================================================
std::vector<NopRegion> detect_text_nop_regions(const std::vector<char>& file_buf, size_t min_size = 64) {
std::vector<NopRegion> regions;
const uint8_t nop[] = {0x1F, 0x20, 0x03, 0xD5}; // ARM64 NOP
// .text段范围 (保守估计)
const size_t text_start = 0x10000; // _text通常在这里
const size_t text_end = 0x1500000; // .text段通常不超过21MB
size_t i = text_start;
while (i < std::min(text_end, file_buf.size() - 16)) {
if (memcmp(&file_buf[i], nop, 4) == 0) {
size_t start = i;
// 计算连续NOP区域大小
while (i < std::min(text_end, file_buf.size() - 4) &&
memcmp(&file_buf[i], nop, 4) == 0) {
i += 4;
}
size_t size = i - start;
if (size >= min_size) {
regions.push_back({start, size, false});
}
} else {
i += 4;
}
}
// 按大小降序排序
std::sort(regions.begin(), regions.end(),
[](const NopRegion& a, const NopRegion& b) { return a.size > b.size; });
return regions;
}
// 分配NOP区域空间
bool allocate_nop_space(std::vector<NopRegion>& regions, size_t needed,
size_t& out_offset, size_t& out_size) {
for (auto& r : regions) {
if (!r.used && r.size >= needed) {
out_offset = r.offset;
out_size = r.size;
r.used = true;
return true;
}
}
return false;
}
// ============================================================================
// 6.6内核专用patch处理器 - 超强隐蔽版 (Stealth Edition)
// ============================================================================
PatchKernelResult patch_kernel_handler_66(
const std::vector<char>& file_buf,
size_t cred_offset,
size_t cred_uid_offset,
size_t seccomp_offset,
KernelSymbolOffset& sym,
std::vector<patch_bytes_data>& vec_patch_bytes_data)
{
PatchBase66 patchBase(file_buf, cred_uid_offset);
PatchDoExecve66 patchDoExecve(patchBase, sym);
PatchCurrentAvcCheck66 patchCurrentAvcCheck(patchBase);
PatchAvcDenied66 patchAvcDenied(patchBase, sym.avc_denied);
PatchAuditLogStart66 patchAuditLogStart(patchBase, sym.audit_log_start);
PatchFilldir6466 patchFilldir64(patchBase, sym.filldir64);
PatchCommunication patchCommunication(patchBase);
PatchHookArea patchHookArea(patchBase);
bool patched = true;
PatchKernelResult r;
std::cout << std::endl;
std::cout << "================================================================" << std::endl;
std::cout << " SKRoot Pro - 超强隐蔽版 (Stealth Edition)" << std::endl;
std::cout << "================================================================" << std::endl;
std::cout << std::endl;
// ========================================
// 第一步:检测.text段内的NOP区域 (核心创新)
// ========================================
std::cout << "[1] 扫描.text段内NOP填充区域..." << std::endl;
auto text_nop_regions = detect_text_nop_regions(file_buf, 64);
size_t total_text_nop = 0;
for (const auto& reg : text_nop_regions) {
total_text_nop += reg.size;
}
std::cout << " 发现 " << text_nop_regions.size() << " 个NOP区域 (在.text段内)" << std::endl;
std::cout << " 总可用空间: " << total_text_nop << " bytes (" << total_text_nop/1024 << " KB)" << std::endl;
if (text_nop_regions.size() >= 3) {
std::cout << " Top 3 区域:" << std::endl;
for (int i = 0; i < 3 && i < (int)text_nop_regions.size(); i++) {
std::cout << " [" << i << "] 0x" << std::hex << text_nop_regions[i].offset
<< " (" << std::dec << text_nop_regions[i].size << " bytes)" << std::endl;
}
}
std::cout << std::endl;
// ========================================
// 第二步:分配分布式存储空间
// ========================================
std::cout << "[2] 分配分布式存储空间..." << std::endl;
// Pro版爆改后通信处理器约2200字节,包含CMD 4/5/6/7
// 分配策略:
// - 尝试找单个>=2200字节的区域用于通信处理器
// - 如果没有,使用较大区域但禁用部分CMD
// - 主区域和辅助区域需要在地址上靠近(ADR指令限制±1MB)
size_t main_offset = 0, main_size = 0;
size_t comm_offset = 0, comm_size = 0;
size_t aux_offset = 0, aux_size = 0;
// 策略1:找单个>=2200字节的区域用于通信处理器
bool have_comm = allocate_nop_space(text_nop_regions, 2200, comm_offset, comm_size);
// 策略2:如果没有足够大的单个区域,使用最大可用区域
if (!have_comm) {
for (auto& r : text_nop_regions) {
if (!r.used && r.size >= 1600) {
comm_offset = r.offset;
comm_size = r.size;
r.used = true;
have_comm = true;
std::cout << " [注意] 通信区域较小(" << r.size << "B),部分CMD可能禁用" << std::endl;
break;
}
}
}
// 分配主区域和辅助区域 - 它们需要靠近(ADR指令±1MB限制)
// 优先找两个地址相近的区域
bool have_main = allocate_nop_space(text_nop_regions, 400, main_offset, main_size);
// 辅助区域尽量选择与主区域地址接近的
bool have_aux = false;
if (have_main) {
// 遍历查找与main_offset地址差在1MB以内的区域
for (auto& r : text_nop_regions) {
if (!r.used && r.size >= 500) {
int64_t distance = (int64_t)r.offset - (int64_t)main_offset;
if (distance >= -1000000 && distance <= 1000000) {
aux_offset = r.offset;
aux_size = r.size;
r.used = true;
have_aux = true;
break;
}
}
}
// 如果没有找到,使用任意可用区域
if (!have_aux) {
have_aux = allocate_nop_space(text_nop_regions, 500, aux_offset, aux_size);
}
}
// 使用.text段内NOP区域 (超强隐蔽模式)
if (have_main && total_text_nop >= 2000) {
std::cout << " ★ 超强隐蔽模式启用!" << std::endl;
std::cout << " 主区域: 0x" << std::hex << main_offset << " (" << std::dec << main_size << " bytes)" << std::endl;
if (have_comm)
std::cout << " 通信区域: 0x" << std::hex << comm_offset << " (" << std::dec << comm_size << " bytes)" << std::endl;
// 如果辅助区域与主区域距离太远,合并使用主区域
if (have_aux) {
int64_t distance = (int64_t)aux_offset - (int64_t)main_offset;
if (distance < -1000000 || distance > 1000000) {
std::cout << " 辅助区域距离过远,将使用主区域" << std::endl;
have_aux = false;
} else {
std::cout << " 辅助区域: 0x" << std::hex << aux_offset << " (" << std::dec << aux_size << " bytes)" << std::endl;
}
}
std::cout << std::endl;
// ========================================
// 第三步:生成分布式隐蔽代码(修复后的正确顺序)
// ========================================
// 顺序:ROOT密钥 -> Hook跳板区 -> 通信处理器 -> do_execve -> SELinux
// 这样可以确保hook_area_start和comm_handler_addr在需要时已经正确设置
std::cout << "[3] 生成分布式隐蔽代码..." << std::endl << std::endl;
// 主区域管理
SymbolRegion main_region;
main_region.offset = main_offset;
main_region.size = main_size;
// 3.1 ROOT密钥 (64 bytes,含对齐)
r.root_key_start = main_region.offset;
std::cout << " ROOT密钥: 0x" << std::hex << r.root_key_start << std::endl;
main_region.consume(64);
// 3.2 SELinux绕过代码 (使用辅助区域或主区域的一部分)
// 注意:先生成SELinux绕过,这样可以预留足够空间给Hook跳板区
SymbolRegion selinux_region;
if (have_aux) {
selinux_region.offset = aux_offset;
selinux_region.size = aux_size;
} else {
selinux_region.offset = main_region.offset;
selinux_region.size = main_region.size;
}
size_t avc_check_addr = selinux_region.offset;
std::cout << " AVC检查: 0x" << std::hex << avc_check_addr << std::endl;
PATCH_AND_CONSUME(selinux_region, patchCurrentAvcCheck.patch_current_avc_check_bl_func(selinux_region, cred_offset, vec_patch_bytes_data));
size_t avc_denied_hook_addr = selinux_region.offset;
std::cout << " avc_denied: 0x" << std::hex << avc_denied_hook_addr << std::endl;
PATCH_AND_CONSUME(selinux_region, patchAvcDenied.patch_avc_denied(selinux_region, avc_check_addr, vec_patch_bytes_data));
size_t audit_hook_addr = selinux_region.offset;
std::cout << " audit_log: 0x" << std::hex << audit_hook_addr << std::endl;
PATCH_AND_CONSUME(selinux_region, patchAuditLogStart.patch_audit_log_start(selinux_region, avc_check_addr, vec_patch_bytes_data));
// 3.3 filldir64代码
size_t filldir_guide_addr = selinux_region.offset;
std::cout << " filldir64 guide: 0x" << std::hex << filldir_guide_addr << std::endl;
PATCH_AND_CONSUME(selinux_region, patchFilldir64.patch_filldir64_root_key_guide(r.root_key_start, selinux_region, vec_patch_bytes_data));
size_t filldir_core_addr = selinux_region.offset;
std::cout << " filldir64 core: 0x" << std::hex << filldir_core_addr << std::endl;
PATCH_AND_CONSUME(selinux_region, patchFilldir64.patch_filldir64_core(selinux_region, vec_patch_bytes_data));
// 3.4 Hook跳板区 (使用剩余空间) - 在通信处理器之前分配
if (selinux_region.size > 100) {
std::cout << " Hook跳板: 0x" << std::hex << selinux_region.offset << std::endl;
PATCH_AND_CONSUME(selinux_region, patchHookArea.reserve_hook_trampoline_area(selinux_region, r.hook_area_start, r.hook_area_size, vec_patch_bytes_data));
} else {
r.hook_area_start = 0;
r.hook_area_size = 0;
}
// 3.5 通信处理器 (使用独立的通信区域) - 在Hook跳板区之后生成
// Pro版爆改后通信处理器约2500字节(包含运行时地址计算)
if (have_comm && comm_size >= 2000) {
SymbolRegion comm_region;
comm_region.offset = comm_offset;
comm_region.size = comm_size;
r.comm_handler_addr = comm_region.offset;
std::cout << " 通信处理器: 0x" << std::hex << r.comm_handler_addr << std::endl;
// Pro版新增:传递模块系统所需的符号地址
// 这些是文件偏移,运行时会通过kernel_base + offset计算真正地址
size_t kallsyms_addr = sym.kallsyms_lookup_name;
size_t module_alloc_addr = sym.module_alloc;
size_t module_memfree_addr = sym.module_memfree ? sym.module_memfree : sym.vfree;
PATCH_AND_CONSUME(comm_region, patchCommunication.patch_comm_handler(
comm_region,
r.root_key_start,
r.hook_area_start, // 现在已正确设置
kallsyms_addr, // 符号查找函数(文件偏移)
module_alloc_addr, // 内存分配函数(文件偏移)
module_memfree_addr, // 内存释放函数(文件偏移)
vec_patch_bytes_data));
} else {
r.comm_handler_addr = 0;
std::cout << " 通信处理器: 空间不足,禁用" << std::endl;
}
// 3.6 do_execve hook代码 - 最后生成,传入正确的comm_handler_addr
// 更新main_region(如果辅助区域不存在,之前已被SELinux代码消耗)
if (!have_aux) {
main_region.offset = selinux_region.offset;
main_region.size = selinux_region.size;
}
size_t execve_hook_addr = main_region.offset;
std::cout << " do_execve hook: 0x" << std::hex << execve_hook_addr << std::endl;
PATCH_AND_CONSUME(main_region, patchDoExecve.patch_do_execve(
main_region, cred_offset, seccomp_offset,
r.comm_handler_addr, // 现在传入正确的通信处理器地址
vec_patch_bytes_data));
std::cout << std::dec << std::endl;
// ========================================
// 第四步:写入隐蔽跳转指令
// ========================================
// 注意:do_execve的跳转已由patch_do_execve内部处理
// 这里只处理其他函数的跳转
std::cout << "[4] 写入隐蔽跳转指令..." << std::endl;
size_t do_execve_addr = sym.do_execveat_common ? sym.do_execveat_common :
(sym.do_execve_common ? sym.do_execve_common : sym.do_execve);
if (do_execve_addr) {
std::cout << " do_execve: 0x" << std::hex << do_execve_addr << " -> 0x" << execve_hook_addr << " (内部处理)" << std::endl;
// 注意:删除了重复的patch_jump调用
// do_execve的跳转已由patchDoExecve.patch_do_execve内部处理
}
if (sym.avc_denied.offset) {
std::cout << " avc_denied: 0x" << std::hex << sym.avc_denied.offset << " -> 0x" << avc_denied_hook_addr << std::endl;
patchBase.patch_jump(sym.avc_denied.offset, avc_denied_hook_addr, vec_patch_bytes_data);
}
if (sym.audit_log_start) {
std::cout << " audit_log: 0x" << std::hex << sym.audit_log_start << " -> 0x" << audit_hook_addr << std::endl;
patchBase.patch_jump(sym.audit_log_start, audit_hook_addr, vec_patch_bytes_data);
}
if (sym.filldir64) {
std::cout << " filldir64: 0x" << std::hex << sym.filldir64 << " -> 0x" << filldir_guide_addr << std::endl;
patchBase.patch_jump(sym.filldir64, filldir_guide_addr, vec_patch_bytes_data);
}
std::cout << std::dec << std::endl;
// ========================================
// 功能状态总结 - 奥创版
// ========================================
std::cout << "================================================================" << std::endl;
std::cout << " 奥创版 (Ultron Edition) - 功能状态" << std::endl;
std::cout << "================================================================" << std::endl;
std::cout << " 基础功能:" << std::endl;
std::cout << " [√] ROOT权限提升 [√] 在.text段内(可执行)" << std::endl;
std::cout << " [√] SELinux绕过 [√] 分布式存储(难检测)" << std::endl;
std::cout << " [√] 目录隐藏 [√] 文件大小不变" << std::endl;
std::cout << " [√] 审计日志隐藏 [√] 无魔术字符串" << std::endl;
if (r.comm_handler_addr) {
std::cout << " [√] execve通信处理器 [√] 无新增符号" << std::endl;
} else {
std::cout << " [x] execve通信处理器 [√] 无新增符号" << std::endl;
}
if (r.hook_area_size > 0) {
std::cout << " [√] 动态Hook区(" << r.hook_area_size << "B) [√] 极难被检测" << std::endl;
} else {
std::cout << " [x] 动态Hook区 [√] 极难被检测" << std::endl;
}
std::cout << "----------------------------------------------------------------" << std::endl;
std::cout << " 奥创版增强:" << std::endl;
std::cout << " [√] 内存边界检查 [√] 8字节块复制优化" << std::endl;
std::cout << " [√] Hook缓存刷新 [√] 增强错误码" << std::endl;
std::cout << " [√] 进程隐藏框架 [√] 反检测框架" << std::endl;
std::cout << " [√] CMD 9 SELinux切换 [" << (sym.sys_prctl || sym.__arm64_sys_prctl ? "√" : "x") << "] prctl通信(可选)" << std::endl;
std::cout << " [√] dm-verity绕过框架" << std::endl;
std::cout << "----------------------------------------------------------------" << std::endl;
std::cout << " 通信命令 (execve方式):" << std::endl;
if (r.comm_handler_addr) {
std::cout << " CMD 1 读内存: [√] CMD 2 写内存: [√]" << std::endl;
std::cout << " CMD 3 执行码: [√] CMD 8 Hook信息: [√]" << std::endl;
std::cout << " CMD 4 符号查找: " << (sym.kallsyms_lookup_name ? "[√]" : "[x]");
std::cout << " CMD 5 安装Hook: [√]" << std::endl;
std::cout << " CMD 6 内存分配: " << (sym.module_alloc ? "[√]" : "[x]");
std::cout << " CMD 7 内存释放: " << ((sym.module_memfree || sym.vfree) ? "[√]" : "[x]") << std::endl;
std::cout << " CMD 9 SELinux: [√]" << std::endl;
} else {
std::cout << " (通信处理器禁用 - NOP空间不足)" << std::endl;
}
std::cout << "================================================================" << std::endl;
} else if (sym.die.offset && sym.arm64_notify_die.offset && sym.__drm_printfn_coredump.offset) {
// ========================================
// 回退方案:Lite模式 (使用die等函数区域)
// ========================================
std::cout << "[!] .text段NOP空间不足,回退到Lite模式" << std::endl;
std::cout << " 使用die/arm64_notify_die/__drm_printfn_coredump" << std::endl << std::endl;
r.root_key_start = sym.die.offset;
r.comm_handler_addr = 0;
r.hook_area_start = 0;
r.hook_area_size = 0;
PATCH_AND_CONSUME(sym.die, patchDoExecve.patch_do_execve(sym.die, cred_offset, seccomp_offset, r.comm_handler_addr, vec_patch_bytes_data));
PATCH_AND_CONSUME(sym.die, patchFilldir64.patch_filldir64_root_key_guide(r.root_key_start, sym.die, vec_patch_bytes_data));
PATCH_AND_CONSUME(sym.die, patchBase.patch_jump(sym.die.offset, sym.arm64_notify_die.offset, vec_patch_bytes_data));
PATCH_AND_CONSUME(sym.arm64_notify_die, patchFilldir64.patch_filldir64_core(sym.arm64_notify_die, vec_patch_bytes_data));
auto current_avc_check_bl_func = sym.__drm_printfn_coredump.offset;
PATCH_AND_CONSUME(sym.__drm_printfn_coredump, patchCurrentAvcCheck.patch_current_avc_check_bl_func(sym.__drm_printfn_coredump, cred_offset, vec_patch_bytes_data));
PATCH_AND_CONSUME(sym.__drm_printfn_coredump, patchAvcDenied.patch_avc_denied(sym.__drm_printfn_coredump, current_avc_check_bl_func, vec_patch_bytes_data));
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));
std::cout << "================================================================" << std::endl;
std::cout << " Lite模式 - 功能状态" << std::endl;
std::cout << "================================================================" << std::endl;
std::cout << " [✓] ROOT权限提升 [x] 通信处理器" << std::endl;
std::cout << " [✓] SELinux绕过 [x] 动态Hook区" << std::endl;
std::cout << " [✓] 目录隐藏 [✓] 隐蔽性良好" << std::endl;
std::cout << " [✓] 审计日志隐藏" << std::endl;
std::cout << "================================================================" << std::endl;
} else {
std::cout << "[错误] 无法找到合适的Hook空间" << std::endl;
patched = false;
}
r.patched = patched;
return r;
}
void write_all_patch(const char* file_path, std::vector<patch_bytes_data>& vec_patch_bytes_data) {
for (auto& item : vec_patch_bytes_data) {
std::shared_ptr<char> spData(new (std::nothrow) char[item.str_bytes.length() / 2], std::default_delete<char[]>());
hex2bytes((uint8_t*)item.str_bytes.c_str(), (uint8_t*)spData.get());
if (!write_file_bytes(file_path, item.write_addr, spData.get(), item.str_bytes.length() / 2)) {
std::cout << "写入文件发生错误" << std::endl;
}
}
if (vec_patch_bytes_data.size()) {
std::cout << "Done." << std::endl;
}
}
int main(int argc, char* argv[]) {
++argv;
--argc;
std::cout << "================================================================" << std::endl;
std::cout << " SKRoot Pro 奥创版 (Ultron Edition) V3.0" << std::endl;
std::cout << " Linux 6.6内核专用 - ARM64" << std::endl;
std::cout << "================================================================" << std::endl;
std::cout << " Phase 1: 内存安全 + 块复制 + 缓存刷新 + 错误码" << std::endl;
std::cout << " Phase 2: 进程隐藏 + SELinux增强 + 反检测" << std::endl;
std::cout << " Phase 3: prctl通信 + dm-verity绕过" << std::endl;
std::cout << "================================================================" << std::endl << std::endl;
// 命令行参数解析
bool auto_mode = false;
std::string custom_key;
const char* file_path = nullptr;
for (int i = 0; i < argc; i++) {
std::string arg = argv[i];
if (arg == "--auto" || arg == "-a") {
auto_mode = true;
} else if ((arg == "--key" || arg == "-k") && i + 1 < argc) {
custom_key = argv[++i];
} else if (!file_path) {
file_path = argv[i];
}
}
if (!file_path) {
std::cout << "无输入文件" << std::endl;
std::cout << "用法: patch_kernel_sk <kernel_file> [--auto] [--key <48字符密钥>]" << std::endl;
std::cout << " --auto, -a 自动模式(生成随机密钥并写入)" << std::endl;
std::cout << " --key, -k 指定ROOT密钥" << std::endl;
return 1;
}
std::cout << "输入文件: " << file_path << std::endl << std::endl;
if (!check_file_path(file_path)) {
std::cout << "请输入正确的Linux内核二进制文件路径" << std::endl;
std::cout << "如果是boot.img,请先解包提取其中的kernel文件" << std::endl;
return 1;
}
std::vector<char> file_buf = read_file_buf(file_path);
if (!file_buf.size()) {
std::cout << "无法打开文件: " << file_path << std::endl;
return 1;
}
std::cout << "文件大小: " << file_buf.size() << " bytes" << std::endl << std::endl;
// 解析内核符号
SymbolAnalyze symbol_analyze(file_buf);
if (!symbol_analyze.analyze_kernel_symbol()) {
std::cout << "无法解析内核符号表" << std::endl;
return 1;
}
KernelSymbolOffset sym = symbol_analyze.get_symbol_offset();
// 打印关键符号信息
std::cout << std::endl << "=== 关键符号 ===" << std::endl;
std::cout << "sys_getuid: offset=0x" << std::hex << sym.sys_getuid.offset << ", size=0x" << sym.sys_getuid.size << std::endl;
std::cout << "prctl_get_seccomp: offset=0x" << std::hex << sym.prctl_get_seccomp.offset << ", size=0x" << sym.prctl_get_seccomp.size << std::endl;
std::cout << "die: offset=0x" << std::hex << sym.die.offset << ", size=0x" << sym.die.size << std::endl;
std::cout << "arm64_notify_die: offset=0x" << std::hex << sym.arm64_notify_die.offset << ", size=0x" << sym.arm64_notify_die.size << std::endl;
std::cout << "__drm_printfn_coredump: offset=0x" << std::hex << sym.__drm_printfn_coredump.offset << ", size=0x" << sym.__drm_printfn_coredump.size << std::endl;
std::cout << "do_execveat_common: 0x" << std::hex << sym.do_execveat_common << std::endl;
std::cout << "avc_denied: offset=0x" << std::hex << sym.avc_denied.offset << ", size=0x" << sym.avc_denied.size << std::endl;
std::cout << "audit_log_start: 0x" << std::hex << sym.audit_log_start << std::endl;
std::cout << "filldir64: 0x" << std::hex << sym.filldir64 << std::endl;
// Pro版新增符号
std::cout << std::endl << "=== Pro版模块系统符号 ===" << std::endl;
std::cout << "kallsyms_lookup_name: 0x" << std::hex << sym.kallsyms_lookup_name;
if (sym.kallsyms_lookup_name) std::cout << " [OK]"; else std::cout << " [未找到]";
std::cout << std::endl;
std::cout << "module_alloc: 0x" << std::hex << sym.module_alloc;
if (sym.module_alloc) std::cout << " [OK]"; else std::cout << " [未找到]";
std::cout << std::endl;
std::cout << "module_memfree: 0x" << std::hex << sym.module_memfree;
if (sym.module_memfree) std::cout << " [OK]"; else std::cout << " [未找到]";
std::cout << std::endl;
std::cout << "vfree(备用): 0x" << std::hex << sym.vfree;
if (sym.vfree) std::cout << " [OK]"; else std::cout << " [未找到]";
std::cout << std::endl;
// 奥创版新增符号
std::cout << std::endl << "=== 奥创版增强符号 ===" << std::endl;
std::cout << "sys_prctl: 0x" << std::hex << sym.sys_prctl;
if (sym.sys_prctl) std::cout << " [OK]"; else std::cout << " [未找到]";
std::cout << std::endl;
std::cout << "__arm64_sys_prctl: 0x" << std::hex << sym.__arm64_sys_prctl;
if (sym.__arm64_sys_prctl) std::cout << " [OK]"; else std::cout << " [未找到]";
std::cout << std::endl;
std::cout << "selinux_enforcing: 0x" << std::hex << sym.selinux_enforcing;
if (sym.selinux_enforcing) std::cout << " [OK]"; else std::cout << " [未找到]";
std::cout << std::endl;
std::cout << "sys_call_table: 0x" << std::hex << sym.sys_call_table;
if (sym.sys_call_table) std::cout << " [OK]"; else std::cout << " [未找到]";
std::cout << std::endl;
std::cout << std::dec << std::endl;
// 解析cred偏移
std::string t_mode_name;
size_t cred_offset = 0;
size_t cred_uid_offset = 0;
size_t seccomp_offset = 0;
if (!parser_cred_offset(file_buf, sym.sys_getuid, t_mode_name, cred_offset)) {
std::cout << "无法解析cred偏移" << std::endl;
return 1;
}
std::cout << "cred偏移解析模式: " << t_mode_name << std::endl;
if (!parse_cred_uid_offset(file_buf, sym.sys_getuid, cred_offset, cred_uid_offset)) {
std::cout << "无法解析cred uid偏移" << std::endl;
return 1;
}
std::cout << "cred uid偏移: " << cred_uid_offset << std::endl;
if (!parser_seccomp_offset(file_buf, sym.prctl_get_seccomp, t_mode_name, seccomp_offset)) {
std::cout << "无法解析seccomp偏移" << std::endl;
return 1;
}
std::cout << "seccomp偏移解析模式: " << t_mode_name << std::endl;
std::cout << "cred偏移: " << cred_offset << std::endl;
std::cout << "seccomp偏移: " << seccomp_offset << std::endl << std::endl;
std::vector<patch_bytes_data> vec_patch_bytes_data;
// CFI和华为绕过
cfi_bypass(file_buf, sym, vec_patch_bytes_data);
huawei_bypass(file_buf, sym, vec_patch_bytes_data);
// 执行6.6内核专用patch
PatchKernelResult pr = patch_kernel_handler_66(file_buf, cred_offset, cred_uid_offset, seccomp_offset, sym, vec_patch_bytes_data);
if (!pr.patched) {
std::cout << "Patch失败: 无法找到合适的Hook空间" << std::endl;
return 1;
}
std::cout << std::endl;
std::cout << "Hook跳板区地址: 0x" << std::hex << pr.hook_area_start << std::endl;
std::cout << "Hook跳板区大小: " << std::dec << pr.hook_area_size << " bytes" << std::endl;
std::cout << "通信处理器地址: 0x" << std::hex << pr.comm_handler_addr << std::endl;
std::cout << std::endl;
// 生成ROOT密钥
std::string str_root_key;
if (!custom_key.empty() && custom_key.length() == ROOT_KEY_LEN) {
str_root_key = custom_key;
std::cout << "使用自定义ROOT密钥" << std::endl;
} else if (auto_mode) {
str_root_key = generate_random_str(ROOT_KEY_LEN);
std::cout << "自动生成ROOT密钥" << std::endl;
} else {
// 交互模式
size_t is_need_create_root_key = 0;
std::cout << "请选择是否需要自动随机生成ROOT密钥(1需要;2不需要):" << std::endl;
std::cin >> std::dec >> is_need_create_root_key;
if (is_need_create_root_key == 1) {
str_root_key = generate_random_str(ROOT_KEY_LEN);
} else {
std::cout << "请输入ROOT密钥(48个字符的字符串,包含大小写和数字):" << std::endl;
std::cin >> str_root_key;
std::cout << std::endl;
}
}
// 写入ROOT密钥
std::string write_key = str_root_key;
write_key.erase(write_key.size() - 1);
patch_data(file_buf, pr.root_key_start, (void*)write_key.c_str(), write_key.length() + 1, vec_patch_bytes_data);
std::cout << std::endl;
std::cout << "#获取ROOT权限的密钥(Key): " << str_root_key.c_str() << std::endl << std::endl;
// 写入文件
if (auto_mode) {
write_all_patch(file_path, vec_patch_bytes_data);
std::cout << std::endl;
std::cout << "SKRoot Pro patch完成!" << std::endl;
std::cout << "请使用magiskboot重新打包boot.img并刷入设备" << std::endl;
} else {
size_t need_write_modify_in_file = 0;
std::cout << "#是否需要立即写入修改到文件?(1需要;2不需要):" << std::endl;
std::cin >> need_write_modify_in_file;
if (need_write_modify_in_file == 1) {
write_all_patch(file_path, vec_patch_bytes_data);
std::cout << std::endl;
std::cout << "SKRoot Pro patch完成!" << std::endl;
std::cout << "请使用magiskboot重新打包boot.img并刷入设备" << std::endl;
}
}
return 0;
}