diff --git a/X. NU/custom/mach_ipc/client_server_mig/Makefile b/X. NU/custom/mach_ipc/client_server_mig/Makefile new file mode 100644 index 0000000..ad4d950 --- /dev/null +++ b/X. NU/custom/mach_ipc/client_server_mig/Makefile @@ -0,0 +1,26 @@ +# Makefile for Mach IPC example with MIG + +# Compiler settings +CC = gcc +CFLAGS = -Wall -Werror + +# Default target +all: server client + +# Generate MIG files from definition +mig_files: message.defs + mig message.defs + +# Build server with MIG-generated files +server: mig_files server.c messageServer.c + $(CC) $(CFLAGS) server.c messageServer.c -o server + +# Build client with MIG-generated files +client: mig_files client.c messageUser.c + $(CC) $(CFLAGS) client.c messageUser.c -o client + +# Clean generated files and executables +clean: + rm -f server client message.h messageUser.c messageServer.c + +.PHONY: all clean mig_files diff --git a/X. NU/custom/mach_ipc/client_server_mig/client.c b/X. NU/custom/mach_ipc/client_server_mig/client.c new file mode 100644 index 0000000..5e9a9ca --- /dev/null +++ b/X. NU/custom/mach_ipc/client_server_mig/client.c @@ -0,0 +1,29 @@ +// client.c - MIG version +#include +#include +#include +#include +#include "message.h" // MIG-generated header + +int main(int argc, char *argv[]) { + // Validate command line arguments + if (argc != 2) { + printf("Usage: %s \n", argv[0]); + return 1; + } + + // Get bootstrap port for service lookup + mach_port_t port; + kern_return_t kr = bootstrap_look_up(bootstrap_port, + "xyz.hacktricks.mig", + &port); + if (kr != KERN_SUCCESS) { + printf("Service not found\n"); + return 1; + } + + // Use MIG-generated function to send message + // This handles all the message structure creation internally + USER_send_message(port, (pointer_t)argv[1], strlen(argv[1])); + return 0; +} \ No newline at end of file diff --git a/X. NU/custom/mach_ipc/client_server_mig/message.defs b/X. NU/custom/mach_ipc/client_server_mig/message.defs new file mode 100644 index 0000000..4fdd8ed --- /dev/null +++ b/X. NU/custom/mach_ipc/client_server_mig/message.defs @@ -0,0 +1,17 @@ +// message.defs - MIG Interface Definition +subsystem message 400; // Define subsystem name and ID + +// Prefix for generated client and server function names +userprefix USER_; +serverprefix SERVER_; + +// Include necessary Mach type definitions +#include +#include + +// Define our message passing routine +// 'simpleroutine' means one-way communication (no reply expected) +// pointer_t is used for variable-length data +simpleroutine send_message( + server_port : mach_port_t; // Port to send message to + message : pointer_t); // Message data \ No newline at end of file diff --git a/X. NU/custom/mach_ipc/client_server_mig/server.c b/X. NU/custom/mach_ipc/client_server_mig/server.c new file mode 100644 index 0000000..bb663ff --- /dev/null +++ b/X. NU/custom/mach_ipc/client_server_mig/server.c @@ -0,0 +1,39 @@ +// server.c - MIG version +#include +#include +#include +#include "message.h" + +// Function prototype for MIG-generated server function +extern boolean_t message_server( + mach_msg_header_t *InHeadP, + mach_msg_header_t *OutHeadP); + +// Implementation of our message handling function +// This is called by MIG-generated code when a message arrives +kern_return_t SERVER_send_message( + mach_port_t server_port, + vm_offset_t message, + mach_msg_type_number_t messageCnt) +{ + // Simply print the received message + printf("Received message: %s\n", (char*)message); + return KERN_SUCCESS; +} + +int main() { + mach_port_t port; + kern_return_t kr; + + // Register our service with the bootstrap server + kr = bootstrap_check_in(bootstrap_port, "xyz.hacktricks.mig", &port); + if (kr != KERN_SUCCESS) { + printf("bootstrap_check_in() failed with code 0x%x\n", kr); + return 1; + } + + // Start message handling loop using MIG-generated server function + // 4096 is the maximum message size + mach_msg_server(message_server, 4096, port, MACH_MSG_TIMEOUT_NONE); + return 0; +} \ No newline at end of file diff --git a/X. NU/custom/mach_ipc/client_server_no_mig/Makefile b/X. NU/custom/mach_ipc/client_server_no_mig/Makefile new file mode 100644 index 0000000..f44b3c7 --- /dev/null +++ b/X. NU/custom/mach_ipc/client_server_no_mig/Makefile @@ -0,0 +1,22 @@ +# Makefile for Mach IPC example without MIG + +# Compiler settings +CC = gcc +CFLAGS = -Wall -Werror + +# Default target +all: server client + +# Build server +server: server.c + $(CC) $(CFLAGS) server.c -o server + +# Build client +client: client.c + $(CC) $(CFLAGS) client.c -o client + +# Clean generated files and executables +clean: + rm -f server client + +.PHONY: all clean diff --git a/X. NU/custom/mach_ipc/client_server_no_mig/client.c b/X. NU/custom/mach_ipc/client_server_no_mig/client.c new file mode 100644 index 0000000..2972af4 --- /dev/null +++ b/X. NU/custom/mach_ipc/client_server_no_mig/client.c @@ -0,0 +1,77 @@ +// client.c +#include +#include +#include +#include + +/* + * Message structure for IPC communication + * Consists of two parts: + * 1. mach_msg_header_t h - Standard Mach message header required for all IPC + * 2. char d[1024] - Data buffer for the actual message content + */ +typedef struct { + mach_msg_header_t h; // Header must be first member + char d[1024]; // Data buffer follows immediately after header +} msg_t; + +int main(int argc, char *argv[]) { + // Validate command line arguments + if (argc != 2) { + printf("Usage: %s \n", argv[0]); + return 1; + } + + // Step 1: Get the bootstrap port + // Bootstrap server is the central name server in Mach IPC + mach_port_t bootstrap_port; + task_get_special_port(mach_task_self(), + TASK_BOOTSTRAP_PORT, + &bootstrap_port); + + // Step 2: Look up the service port using bootstrap server + // This finds our server process using the registered name + mach_port_t service_port; + kern_return_t kr = bootstrap_look_up(bootstrap_port, + "com.crimson.message_service", + &service_port); + if (kr != KERN_SUCCESS) { + printf("Service not found\n"); + return 1; + } + + // Step 3: Prepare the message structure + // Initialize message structure to zero + msg_t message = {0}; + + // Configure message header + message.h.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_COPY_SEND); // Set message type to copy-send + message.h.msgh_size = sizeof(msg_t); // Total size of message struct + message.h.msgh_remote_port = service_port; // Destination port + message.h.msgh_local_port = MACH_PORT_NULL; // No reply port needed + message.h.msgh_id = 0; // Message ID (unused in this case) + + // Copy the user's message into data buffer + // Using strncpy to prevent buffer overflow + strncpy(message.d, argv[1], sizeof(message.d) - 1); + message.d[sizeof(message.d) - 1] = '\0'; // Ensure null termination + + // Step 4: Send the message + kr = mach_msg( + &message.h, // Message header pointer + MACH_SEND_MSG, // Send-only operation + sizeof(msg_t), // Size of entire message + 0, // Maximum receive size (unused for send) + MACH_PORT_NULL, // Destination port (unused for send) + MACH_MSG_TIMEOUT_NONE,// No timeout + MACH_PORT_NULL // No notify port + ); + + // Step 5: Check for errors and return status + if (kr != KERN_SUCCESS) { + printf("Failed to send message\n"); + return 1; + } + + return 0; +} \ No newline at end of file diff --git a/X. NU/custom/mach_ipc/client_server_no_mig/server.c b/X. NU/custom/mach_ipc/client_server_no_mig/server.c new file mode 100644 index 0000000..d04de22 --- /dev/null +++ b/X. NU/custom/mach_ipc/client_server_no_mig/server.c @@ -0,0 +1,55 @@ +// server.c +#include +#include +#include + +int main() { + // Step 1: Get the bootstrap port + mach_port_t bootstrap_port; + task_get_special_port(mach_task_self(), + TASK_BOOTSTRAP_PORT, + &bootstrap_port); + + // Step 2: Register our service with the bootstrap server + // This allows clients to find us using the service name + mach_port_t service_port; + kern_return_t kr = bootstrap_check_in(bootstrap_port, + "com.crimson.message_service", + &service_port); + if (kr != KERN_SUCCESS) { + printf("Failed to register service\n"); + return 1; + } + + printf("Server running...\n"); + + // Allocate buffer for receiving messages + // Buffer must be large enough for header + maximum message size + char buffer[2048]; + mach_msg_header_t *msg = (mach_msg_header_t*)buffer; + + // Main message receive loop + while (1) { + // Receive message + kr = mach_msg( + msg, // Buffer to receive message + MACH_RCV_MSG, // Receive-only operation + 0, // Send size (unused for receive) + sizeof(buffer), // Maximum receive size + service_port, // Port to receive on + MACH_MSG_TIMEOUT_NONE, // No timeout + MACH_PORT_NULL // No notify port + ); + + // Process received message + if (kr == KERN_SUCCESS) { + // Message data follows immediately after header + char *data = (char*)(msg + 1); + printf("Received: %s\n", data); + } else { + printf("Error receiving message\n"); + } + } + + return 0; // Never reached in this example +} \ No newline at end of file