|Informative Information for the Uninformed|
Due to the fact that Mach was designed as a micro-kernel and designed to function across multiple processors and machines, a large portion of the functionality is implemented by sending messages between tasks. In order to facilitate this process, IPC interfaces must be defined to provide the added functionality.
To achieve this, Mach (and Apple) use a language called "Mach Interface Generator" (MIG). MIG is a subset of the Matchmaker language, which generates C or C++ interfaces for sending messages between tasks.
When using MIG, files with the extension ".defs" are written containing a description of the interface. These files are compiled into a .c/.cpp file and a .h header file. This is done using the /usr/bin/mig tool on Mac OS X. These generated files contain the appropriate C or C++ stub code in order to handle the messages defined in the defs file.
This can be confusing for someone from a UNIX or Windows background who is new to Mach/Mac OS X. Many of the Mach functions discussed in this paper are actually implemented as a .defs file. These files are shipped with the xnu source (which is no longer available).
An example from one of these files (osfmk/mach/mach_vm.defs) showing the definition of the vm_allocate() function is provided below.
/* * Allocate zero-filled memory in the address space * of the target task, either at the specified address, * or wherever space can be found (controlled by flags), * of the specified size. The address at which the * allocation actually took place is returned. */ #if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) routine mach_vm_allocate( #else routine vm_allocate( #endif target : vm_task_entry_t; inout address : mach_vm_address_t; size : mach_vm_size_t; flags : int);
It's useful to compile these .defs files with the /usr/bin/mig tool and then read the generated c code to work out what should be done when writing shellcode with the mach_msg mach trap.