@@ -54,28 +54,40 @@ geode::Result<uint32_t> DarwinTarget::getProtection(void* address) {
54
54
return geode::Ok (info.protection );
55
55
}
56
56
57
+ void DarwinTarget::internalProtectMemory (void * address, size_t size, uint32_t protection, int & errorCode) {
58
+ errorCode = vm_protect (
59
+ mach_task_self (),
60
+ reinterpret_cast <vm_address_t >(address),
61
+ size,
62
+ false ,
63
+ protection
64
+ );
65
+ }
66
+ void DarwinTarget::internalWriteMemory (void * destination, void const * source, size_t size, int & errorCode) {
67
+ errorCode = vm_write (
68
+ mach_task_self (),
69
+ reinterpret_cast <vm_address_t >(destination),
70
+ reinterpret_cast <vm_offset_t >(source),
71
+ static_cast <mach_msg_type_number_t >(size)
72
+ );
73
+ }
74
+
57
75
geode::Result<> DarwinTarget::protectMemory (void * address, size_t size, uint32_t protection) {
58
76
kern_return_t status;
59
77
60
- status = vm_protect (mach_task_self (), reinterpret_cast <vm_address_t >(address), size, false , protection);
61
-
78
+ this ->internalProtectMemory (address, size, protection, status);
62
79
if (status != KERN_SUCCESS) {
63
- return geode::Err (" Couldn't protect memory" );
80
+ return geode::Err (" Couldn't protect memory: " + std::to_string (status) );
64
81
}
65
82
return geode::Ok ();
66
83
}
67
84
68
85
geode::Result<> DarwinTarget::rawWriteMemory (void * destination, void const * source, size_t size) {
69
86
kern_return_t status;
70
87
71
- status = vm_write (
72
- mach_task_self (),
73
- reinterpret_cast <vm_address_t >(destination),
74
- reinterpret_cast <vm_offset_t >(source),
75
- static_cast <mach_msg_type_number_t >(size)
76
- );
88
+ this ->internalWriteMemory (destination, source, size, status);
77
89
if (status != KERN_SUCCESS) {
78
- return geode::Err (" Couldn't write memory, status : " + std::to_string (status));
90
+ return geode::Err (" Couldn't write memory: " + std::to_string (status));
79
91
}
80
92
return geode::Ok ();
81
93
}
@@ -85,16 +97,24 @@ geode::Result<> DarwinTarget::writeMemory(void* destination, void const* source,
85
97
86
98
// with no wx pages, we run into the risk of accidentally marking our code as rw
87
99
// (this causes a crash in the result destructor, which is not very good)
100
+ // should be fixed now i think
88
101
89
- auto r1 = this ->protectMemory (destination, size, this ->getWritableProtection ());
90
- auto r2 = r1.and_ (this ->rawWriteMemory (destination, source, size));
91
- auto r3 = r2.and_ (this ->protectMemory (destination, size, oldProtection));
102
+ kern_return_t s1, s2, s3;
103
+ this ->internalProtectMemory (destination, size, this ->getWritableProtection (), s1);
104
+ if (s1 != KERN_SUCCESS) {
105
+ return geode::Err (" Couldn't protect memory to rwc: " + std::to_string (s1));
106
+ }
92
107
93
- // permissions restored, it's safe to do result stuff now
94
- if (r3.isErr ()) {
95
- // return the first error
96
- return geode::Err (r3.unwrapErr ());
108
+ this ->internalWriteMemory (destination, source, size, s2);
109
+ if (s2 != KERN_SUCCESS) {
110
+ return geode::Err (" Couldn't write memory: " + std::to_string (s2));
97
111
}
112
+
113
+ this ->internalProtectMemory (destination, size, oldProtection, s3);
114
+ if (s3 != KERN_SUCCESS) {
115
+ return geode::Err (" Couldn't protect memory back: " + std::to_string (s3));
116
+ }
117
+
98
118
return geode::Ok ();
99
119
}
100
120
0 commit comments