mirror of
https://github.com/Karmaz95/Snake_Apple.git
synced 2026-03-30 14:00:16 +02:00
Adding example Mach IPC client-server with and without MIG
This commit is contained in:
26
X. NU/custom/mach_ipc/client_server_mig/Makefile
Normal file
26
X. NU/custom/mach_ipc/client_server_mig/Makefile
Normal file
@@ -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
|
||||
29
X. NU/custom/mach_ipc/client_server_mig/client.c
Normal file
29
X. NU/custom/mach_ipc/client_server_mig/client.c
Normal file
@@ -0,0 +1,29 @@
|
||||
// client.c - MIG version
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <mach/mach.h>
|
||||
#include <servers/bootstrap.h>
|
||||
#include "message.h" // MIG-generated header
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// Validate command line arguments
|
||||
if (argc != 2) {
|
||||
printf("Usage: %s <message>\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;
|
||||
}
|
||||
17
X. NU/custom/mach_ipc/client_server_mig/message.defs
Normal file
17
X. NU/custom/mach_ipc/client_server_mig/message.defs
Normal file
@@ -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 <mach/mach_types.defs>
|
||||
#include <mach/std_types.defs>
|
||||
|
||||
// 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
|
||||
39
X. NU/custom/mach_ipc/client_server_mig/server.c
Normal file
39
X. NU/custom/mach_ipc/client_server_mig/server.c
Normal file
@@ -0,0 +1,39 @@
|
||||
// server.c - MIG version
|
||||
#include <stdio.h>
|
||||
#include <mach/mach.h>
|
||||
#include <servers/bootstrap.h>
|
||||
#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;
|
||||
}
|
||||
22
X. NU/custom/mach_ipc/client_server_no_mig/Makefile
Normal file
22
X. NU/custom/mach_ipc/client_server_no_mig/Makefile
Normal file
@@ -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
|
||||
77
X. NU/custom/mach_ipc/client_server_no_mig/client.c
Normal file
77
X. NU/custom/mach_ipc/client_server_no_mig/client.c
Normal file
@@ -0,0 +1,77 @@
|
||||
// client.c
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <mach/mach.h>
|
||||
#include <servers/bootstrap.h>
|
||||
|
||||
/*
|
||||
* 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 <message>\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;
|
||||
}
|
||||
55
X. NU/custom/mach_ipc/client_server_no_mig/server.c
Normal file
55
X. NU/custom/mach_ipc/client_server_no_mig/server.c
Normal file
@@ -0,0 +1,55 @@
|
||||
// server.c
|
||||
#include <stdio.h>
|
||||
#include <mach/mach.h>
|
||||
#include <servers/bootstrap.h>
|
||||
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user