Skip to content

Commit 5eb5c5a

Browse files
committed
fix: reverting cuz it doesnt work
1 parent 211fa33 commit 5eb5c5a

File tree

5 files changed

+124
-65
lines changed

5 files changed

+124
-65
lines changed

Config.xcconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@
99
// https://developer.apple.com/documentation/xcode/adding-a-build-configuration-file-to-your-project
1010

1111
VERSION = 0.9.0
12-
BUILD_NUMBER = 20260223.96.US.seanistethered
12+
BUILD_NUMBER = 20260223.102.US.seanistethered

Nyxian/LindChain/Debugger/Utils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ bool thread_restore_state_arm64(thread_act_t thread, struct arm64_thread_full_st
9595
void state_back_trace(struct arm64_thread_full_state *state, uint64_t maxdepth);
9696

9797
kern_return_t task_thread_index(task_t task, thread_t target, mach_msg_type_number_t *index);
98+
kern_return_t task_thread_get_unique_id(thread_t thread, uint64_t *unique_id);
99+
kern_return_t task_thread_for_unique_id(task_t task, uint64_t unique_id, thread_t *out_thread);
98100

99101
uint64_t get_next_pc(struct arm64_thread_full_state *state);
100102
bool pc_at_software_breakpoint(struct arm64_thread_full_state *state);

Nyxian/LindChain/Debugger/Utils.m

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,67 @@ kern_return_t task_thread_index(task_t task,
130130
return kr;
131131
}
132132

133+
kern_return_t task_thread_get_unique_id(thread_t thread,
134+
uint64_t *unique_id)
135+
{
136+
if(thread == MACH_PORT_NULL || unique_id == NULL)
137+
{
138+
return KERN_INVALID_ARGUMENT;
139+
}
140+
141+
thread_identifier_info_data_t info;
142+
mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
143+
kern_return_t kr = thread_info(thread, THREAD_IDENTIFIER_INFO, (thread_info_t)&info, &count);
144+
if(kr != KERN_SUCCESS)
145+
{
146+
return kr;
147+
}
148+
149+
*unique_id = info.thread_id;
150+
return KERN_SUCCESS;
151+
}
152+
153+
kern_return_t task_thread_for_unique_id(task_t task,
154+
uint64_t unique_id,
155+
thread_t *out_thread)
156+
{
157+
if(task == MACH_PORT_NULL || out_thread == NULL)
158+
{
159+
return KERN_INVALID_ARGUMENT;
160+
}
161+
162+
thread_act_array_t threads;
163+
mach_msg_type_number_t count;
164+
165+
kern_return_t kr = task_threads(task, &threads, &count);
166+
if(kr != KERN_SUCCESS)
167+
{
168+
return kr;
169+
}
170+
171+
kern_return_t result = KERN_FAILURE;
172+
*out_thread = MACH_PORT_NULL;
173+
174+
for(mach_msg_type_number_t i = 0; i < count; i++)
175+
{
176+
uint64_t tid = 0;
177+
kern_return_t ikr = task_thread_get_unique_id(threads[i], &tid);
178+
179+
if(ikr == KERN_SUCCESS && tid == unique_id)
180+
{
181+
*out_thread = threads[i];
182+
result = KERN_SUCCESS;
183+
}
184+
else
185+
{
186+
mach_port_deallocate(mach_task_self(), threads[i]);
187+
}
188+
}
189+
190+
vm_deallocate(mach_task_self(), (vm_address_t)threads, count * sizeof(thread_act_t));
191+
return result;
192+
}
193+
133194
static bool evaluate_condition(uint32_t cond,
134195
uint32_t cpsr)
135196
{

Nyxian/LindChain/ProcEnvironment/Syscall/mach_syscall_client.m

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,14 @@ int64_t syscall_invoke(syscall_client_t *client,
136136
buffer.req.header.msgh_local_port = client->reply_port;
137137
buffer.req.header.msgh_size = sizeof(syscall_request_t);
138138
buffer.req.header.msgh_id = syscall_num;
139-
buffer.req.thread = mach_thread_self();
139+
140+
kern_return_t kr = task_thread_get_unique_id(mach_thread_self(), &(buffer.req.thread));
141+
142+
if(kr != KERN_SUCCESS)
143+
{
144+
errno = EAGAIN;
145+
return -1;
146+
}
140147

141148
/* telling cutie patootie ksurface what syscall we wanna call ^^ */
142149
buffer.req.syscall_num = syscall_num;
@@ -169,7 +176,7 @@ int64_t syscall_invoke(syscall_client_t *client,
169176
* uses the same buffer for both operations. The receive buffer size
170177
* must be large enough to hold the reply plus any trailer.
171178
*/
172-
kern_return_t kr = mach_msg(&buffer.req.header, MACH_SEND_MSG | MACH_RCV_MSG, sizeof(syscall_request_t), sizeof(buffer), client->reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
179+
kr = mach_msg(&buffer.req.header, MACH_SEND_MSG | MACH_RCV_MSG, sizeof(syscall_request_t), sizeof(buffer), client->reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
173180

174181
/* checking for succession */
175182
if(kr != KERN_SUCCESS)

Nyxian/LindChain/ProcEnvironment/Syscall/mach_syscall_server.m

Lines changed: 51 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -212,78 +212,67 @@ static void send_reply(mach_msg_header_t *request,
212212
}
213213
else
214214
{
215-
kr = mach_port_mod_refs(task, req->thread, MACH_PORT_RIGHT_SEND, 1);
216-
217-
if(kr != KERN_SUCCESS)
218-
{
219-
goto skip_thread_port_extraction;
220-
}
221-
222-
kr = mach_port_extract_right(task, req->thread, MACH_MSG_TYPE_COPY_SEND, &thread, NULL);
223-
215+
kr = task_thread_for_unique_id(task, req->thread, &thread);
224216
if(kr != KERN_SUCCESS)
225217
{
226-
mach_port_mod_refs(task, req->thread, MACH_PORT_RIGHT_SEND, -1);
227-
req->thread = MACH_PORT_NULL;
228-
goto skip_thread_port_extraction;
218+
err = EAGAIN;
219+
result = -1;
220+
goto cleanup;
229221
}
230222
}
231223

232-
skip_thread_port_extraction:
224+
/* getting the syscall handler the kernel virtualisation layer previously has set */
225+
syscall_handler_t handler = NULL;
226+
227+
/* checking syscall bounds */
228+
if(req->syscall_num < MAX_SYSCALLS)
233229
{
234-
/* getting the syscall handler the kernel virtualisation layer previously has set */
235-
syscall_handler_t handler = NULL;
236-
237-
/* checking syscall bounds */
238-
if(req->syscall_num < MAX_SYSCALLS)
239-
{
240-
/* getting handler if bounds are valid */
241-
handler = server->handlers[req->syscall_num];
242-
}
243-
244-
/* checking if the handler was set by the kernel virtualisation layer */
245-
if(!handler)
246-
{
247-
klog_log(@"syscall", @"syscall from pid %d failed (EXCEPTION: %d is not a valid syscall)", proc_getpid(proc_copy), req->syscall_num);
248-
err = ENOSYS;
249-
result = -1;
250-
goto cleanup;
251-
}
252-
253-
/* calling syscall handler */
254-
result = handler(task, thread, proc_copy, req->args, (req->oolp.disposition == MACH_MSG_TYPE_MOVE_RECEIVE) ? NULL: (mach_port_t*)(req->oolp.address), (req->oolp.disposition == MACH_MSG_TYPE_MOVE_RECEIVE) ? 0 : req->oolp.count, &out_ports, &out_ports_cnt, &err, &name, (req->oolp.disposition == MACH_MSG_TYPE_MOVE_RECEIVE) ? *((mach_port_t*)req->oolp.address) : MACH_PORT_NULL);
255-
256-
cleanup:
257-
258-
/* deallocate what the guest requested via input ports (avoiding port leaks is a extremely good idea ^^) */
259-
vm_deallocate(mach_task_self(), (mach_vm_address_t)req->oolp.address, req->oolp.count * sizeof(mach_port_t));
260-
261-
/* destroying copy of process */
262-
if(proc_copy != NULL)
263-
{
264-
/* check for errno and log if errno is indeed set */
265-
if(err != 0 && err != ENOSYS)
266-
{
267-
klog_log(@"syscall", @"syscall(%s) from pid %d failed (ERRNO=%s)", name, proc_getpid(proc_copy), strerror(err));
268-
}
269-
270-
proc_copy_destroy(proc_copy);
271-
}
272-
273-
/* checking task and thread */
274-
if(task != MACH_PORT_NULL)
275-
{
276-
mach_port_deallocate(mach_task_self(), task);
277-
}
278-
279-
if(thread != MACH_PORT_NULL)
230+
/* getting handler if bounds are valid */
231+
handler = server->handlers[req->syscall_num];
232+
}
233+
234+
/* checking if the handler was set by the kernel virtualisation layer */
235+
if(!handler)
236+
{
237+
klog_log(@"syscall", @"syscall from pid %d failed (EXCEPTION: %d is not a valid syscall)", proc_getpid(proc_copy), req->syscall_num);
238+
err = ENOSYS;
239+
result = -1;
240+
goto cleanup;
241+
}
242+
243+
/* calling syscall handler */
244+
result = handler(task, thread, proc_copy, req->args, (req->oolp.disposition == MACH_MSG_TYPE_MOVE_RECEIVE) ? NULL: (mach_port_t*)(req->oolp.address), (req->oolp.disposition == MACH_MSG_TYPE_MOVE_RECEIVE) ? 0 : req->oolp.count, &out_ports, &out_ports_cnt, &err, &name, (req->oolp.disposition == MACH_MSG_TYPE_MOVE_RECEIVE) ? *((mach_port_t*)req->oolp.address) : MACH_PORT_NULL);
245+
246+
cleanup:
247+
248+
/* deallocate what the guest requested via input ports (avoiding port leaks is a extremely good idea ^^) */
249+
vm_deallocate(mach_task_self(), (mach_vm_address_t)req->oolp.address, req->oolp.count * sizeof(mach_port_t));
250+
251+
/* destroying copy of process */
252+
if(proc_copy != NULL)
253+
{
254+
/* check for errno and log if errno is indeed set */
255+
if(err != 0 && err != ENOSYS)
280256
{
281-
mach_port_deallocate(mach_task_self(), thread);
257+
klog_log(@"syscall", @"syscall(%s) from pid %d failed (ERRNO=%s)", name, proc_getpid(proc_copy), strerror(err));
282258
}
283259

284-
/* reply !!!AFTER!!! deallocation */
285-
send_reply(&buffer.header, result, out_ports, out_ports_cnt, err);
260+
proc_copy_destroy(proc_copy);
286261
}
262+
263+
/* checking task and thread */
264+
if(task != MACH_PORT_NULL)
265+
{
266+
mach_port_deallocate(mach_task_self(), task);
267+
}
268+
269+
if(thread != MACH_PORT_NULL)
270+
{
271+
mach_port_deallocate(mach_task_self(), thread);
272+
}
273+
274+
/* reply !!!AFTER!!! deallocation */
275+
send_reply(&buffer.header, result, out_ports, out_ports_cnt, err);
287276
}
288277

289278
return NULL;

0 commit comments

Comments
 (0)