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 | //extern "C" kern_return_t mach_vm_region(
vm_map_t target_task,
vm_address_t *address,
vm_size_t *size,
vm_region_flavor_t flavor,
vm_region_info_t info,
mach_msg_type_number_t *infoCnt,
mach_port_t *object_name
);//template <typename TYPE> NS_INLINE bool FakeCode(TYPE *addr, TYPE code){
mach_port_t task;
vm_size_t region_size = 0;
vm_address_t region = (vm_address_t)addr;
/* Get region boundaries */#if defined(_MAC64) || defined(__LP64__) vm_region_basic_info_data_64_t info;
mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
vm_region_flavor_t flavor = VM_REGION_BASIC_INFO_64;
if (mach_vm_region(mach_task_self(), ®ion, ®ion_size, flavor, (vm_region_info_t)&info, (mach_msg_type_number_t*)&info_count, (mach_port_t*)&task) != KERN_SUCCESS)
{
return false;
}#else vm_region_basic_info_data_t info;
mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT;
vm_region_flavor_t flavor = VM_REGION_BASIC_INFO;
if (vm_region(mach_task_self(), ®ion, ®ion_size, flavor, (vm_region_info_t)&info, (mach_msg_type_number_t*)&info_count, (mach_port_t*)&task) != KERN_SUCCESS)
{
return false;
}#endif
/* Change memory protections to rw- */
if (vm_protect(mach_task_self(), region, region_size, false, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY) != KERN_SUCCESS)
{
_LineLog();
return false;
}
/* Actually perform the write */
*addr = code;
/* Flush CPU data cache to save write to RAM */
sys_dcache_flush(addr, sizeof(code));
/* Invalidate instruction cache to make the CPU read patched instructions from RAM */
sys_icache_invalidate(addr, sizeof(code));
/* Change memory protections back to r-x */
vm_protect(mach_task_self(), region, region_size, false, VM_PROT_EXECUTE | VM_PROT_READ);
return true;} |