首页
社区
课程
招聘
[求助]ios越狱过程中的设置HSP4是做什么的
发表于: 2020-10-27 22:57 16134

[求助]ios越狱过程中的设置HSP4是做什么的

2020-10-27 22:57
16134

class SetHSP4 {
let offsets = Offsets.shared

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
private let IO_BITS_KOBJECT = UInt32(0x800)
private let IO_ACTIVE = UInt32(0x80000000)
 
private let IKOT_TASK = UInt32(2)
private let IKOT_HOST = UInt32(3)
private let IKOT_HOST_PRIV = UInt32(4)
 
private let IOT_PORT = UInt32(0)
 
private var fake_host_priv_port = mach_port_t(MACH_PORT_NULL)
 
let IE_BITS_SEND = UInt32(1<<16)
let IE_BITS_RECEIVE = UInt32(1<<17)
 
private let tfp0: mach_port_t
private let our_task: UInt64
private let electra: Electra
 
private func fake_host_priv() -> mach_port_t {
    if fake_host_priv_port != MACH_PORT_NULL {
        return fake_host_priv_port
    }
 
    let hostport_addr = electra.findPort(port: mach_host_self())
    let realhost = rk64(hostport_addr + offsets.ipc_port.ip_kobject)
 
    let err = mach_port_allocate(mach_task_self_, MACH_PORT_RIGHT_RECEIVE, &fake_host_priv_port)
    guard err == KERN_SUCCESS else {
        print("failed to allocate port")
        return mach_port_t(MACH_PORT_NULL)
    }
 
    mach_port_insert_right(mach_task_self_, fake_host_priv_port, fake_host_priv_port, mach_msg_type_name_t(MACH_MSG_TYPE_MAKE_SEND))
 
    let port_addr = electra.findPort(port: fake_host_priv_port)
    wk32(port_addr + offsets.ipc_port.io_bits, IO_ACTIVE | IO_BITS_KOBJECT | IKOT_HOST_PRIV)
 
    let ipc_space_kernel = rk64(electra.findPort(port: mach_task_self_) + offsets.ipc_port.ip_receiver)
    wk64(port_addr + offsets.ipc_port.ip_receiver, ipc_space_kernel)
    wk64(port_addr + offsets.ipc_port.ip_kobject, realhost)
 
    return fake_host_priv_port
}
 
private func kalloc_wired(size: UInt) -> UInt64 {
    let ksize = (size & ~vm_kernel_page_mask) + vm_kernel_page_mask
 
    var addr = kalloc(ksize + 0x4000)
    addr += 0x3fff
    addr &= ~UInt64(0x3fff)
 
    let err = mach_vm_wire(fake_host_priv(), tfp0, addr, mach_vm_size_t(ksize), VM_PROT_READ | VM_PROT_WRITE)
    if err != KERN_SUCCESS {
        print(String(format: "unable to wire memory via tfp0: %s", mach_error_string(err)))
        sleep(3)
    }
    return addr
}
 
private func make_fake_task(vm_map: UInt64) -> UInt64 {
    var fake_task = kalloc_wired(size: 0x1000)
    var objType = UInt16(isArm64e() ? 57 : 58) //zone_require
    if #available(iOS 13.4, *) {
        objType = UInt16(isArm64e() ? 59 : 60) //zone require
    }
    kwrite(fake_task + 0x16, &objType, 2)
 
    fake_task += 0x100
    wk32(fake_task + offsets.task.ref_count, 0xd00d) //leak refrerences
    wk32(fake_task + offsets.task.active, 1)
    wk64(fake_task + offsets.task.vm_map, vm_map)
 
    var mtx = UInt8(0x22)
    kwrite(fake_task + offsets.task.lck_mtx_type, &mtx, 1)
    kwrite(fake_task + offsets.task.itk_lck_mtx_type, &mtx, 1)
    return fake_task
}
 
private func convert_port_to_task_port(port: mach_port_t, task_kaddr: UInt64) {
    let port_kaddr = electra.findPort(port: port)
    let space = rk64(electra.findPort(port: mach_task_self_) + offsets.ipc_port.ip_receiver)
 
    wk32(port_kaddr + offsets.ipc_port.io_bits, IO_ACTIVE | IO_BITS_KOBJECT | IKOT_TASK)
    wk32(port_kaddr + offsets.ipc_port.io_references, 0xf00d)
    wk32(port_kaddr + offsets.ipc_port.ip_srights, 0xf00d)
    wk64(port_kaddr + offsets.ipc_port.ip_receiver, space)
    wk64(port_kaddr + offsets.ipc_port.ip_kobject, task_kaddr)
 
    //swap our receive right for a send right
    let task_addr = our_task
    let itk_space = rk64(task_addr + offsets.task.itk_space)
    let is_table = rk64(itk_space + offsets.ipc_space.is_table)
 
    let port_index = UInt32(port) >> 8
    let sizeof_ipc_entry_t = UInt32(0x18)
 
    let bits_addr = is_table + UInt64(port_index * sizeof_ipc_entry_t) + 8
    var bits = rk32(bits_addr) //8 = offset of ie_bits in struct ipc_entry
 
    bits &= (~IE_BITS_RECEIVE)
    bits |= IE_BITS_SEND
 
    wk32(bits_addr, bits)
}
 
init(electra: Electra, tfp0: mach_port_t, slide: UInt64, kernel_proc: UInt64, our_proc: UInt64, old_realhost: mach_port_t) {
    self.electra = electra
    self.tfp0 = tfp0
    our_task = rk64(our_proc + offsets.proc.task)
 
    let oldhost_addr = electra.findPort(port: old_realhost)
    var host_type = rk32(oldhost_addr + offsets.ipc_port.io_bits)
    host_type &= ~(IKOT_HOST_PRIV)
    host_type |= IKOT_HOST
    wk32(oldhost_addr + offsets.ipc_port.io_bits, host_type)
    mach_port_destroy(mach_task_self_, old_realhost)
 
    let kernel_task = rk64(kernel_proc + offsets.proc.task)
    let kernel_map = rk64(kernel_task + offsets.task.vm_map)
 
    var new_port = mach_port_t(MACH_PORT_NULL)
 
    let ret = mach_port_allocate(mach_task_self_, MACH_PORT_RIGHT_RECEIVE, &new_port)
    if ret != KERN_SUCCESS {
        print(String(format: "[hsp4] Unable to allocate port... %s", mach_error_string(ret) ?? ""))
    }
 
    let km_fake_task_kptr = make_fake_task(vm_map: kernel_map)
    var buf = [UInt8](repeating: 0, count: 0xf00)
    kread(kernel_task, &buf, 0xf00)
    kwrite(km_fake_task_kptr, &buf, 0xf00)
 
    wk64(km_fake_task_kptr + offsets.task.all_image_info_addr, slide + 0xFFFFFFF007004000) //store kbase and slide
    wk64(km_fake_task_kptr + offsets.task.all_image_info_size, slide)
 
    var mtx = UInt8(0x22)
    wk64(km_fake_task_kptr + offsets.task.lck, 0)
    wk64(km_fake_task_kptr + offsets.task.lck + 8, 0)
 
    wk64(km_fake_task_kptr + offsets.task.itk_lck, 0)
    wk64(km_fake_task_kptr + offsets.task.itk_lck + 8, 0)
 
    kwrite(km_fake_task_kptr + offsets.task.lck_mtx_type, &mtx, 1)
    kwrite(km_fake_task_kptr + offsets.task.itk_lck_mtx_type, &mtx, 1)
 
    convert_port_to_task_port(port: new_port, task_kaddr: km_fake_task_kptr)
 
    let port_kaddr = electra.findPort(port: new_port)
 
    let host_priv_kaddr = electra.findPort(port: mach_host_self())
    let realhost_kaddr = rk64(host_priv_kaddr + offsets.ipc_port.ip_kobject)
    wk64(realhost_kaddr + offsets.host.special + UInt64(4 * MemoryLayout<UInt64>.size), port_kaddr)
    print("[hsp4] successfully set hsp4")
}

}


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 28
活跃值: (107)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2

允许任何以 root 权限执行的进程通过 host_get_special_port(mach_host_self(), HOST_LOCAL_NODE, 4, &kernel_task); 的方式获取 kernel task port.

2020-10-28 18:23
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
谢谢了
2020-10-30 11:33
0
游客
登录 | 注册 方可回帖
返回
//