- Joined
- Dec 3, 2010
- Messages
- 460
- Motherboard
- Gigabyte GA-H55M-S2V
- CPU
- Intel i3-530
- Graphics
- HIS HD 6570
- Mac
- Mobile Phone
Those who took a closer look at Mavericks may have noticed many new kexts, this article focuses on one particularly novel one: AppleHWAccess. This new kext allows a process running as root to read and write anywhere in memory. With this power comes significant responsibilities, any wrong move will almost certainly crash the system or cause a permanent hang while the kernel tries to read from write-only memory. Nevertheless I am posting a sample .m file which provides an example implementation of this feature, note that it can only perform the in/out b/w/l/q family of ioctl commands.
Code:
//
// main.m
// HWAccessor
//
// Created by PHPdev32 on 6/27/13.
// Licensed under GPLv3, full text at http://www.gnu.org/licenses/gpl-3.0.txt
//
#import <Foundation/Foundation.h>
#import <IOKit/IOKitLib.h>
#define kAppleHWAccessClass "AppleHWAccess"
#define kAppleHWRead 0
#define kAppleHWWrite 1
#define kHWAtom 0x40
struct __attribute__ ((packed)) HWRequest {
UInt32 width;
UInt64 offset;
UInt64 data;
};
/*!
* \brief Access physical memory
*
* Uses Mavericks' AppleHWAccess kernel extension to access physical memory in quanta up to 64 bits long, determining direction from the state of the NSData object passed in.
* \param address The address to begin reading/writing from
* \param length The length to ready/write
* \param data The NSData object to read to, or write from
*/
void HWAccess(UInt64 address, UInt64 length, NSMutableData *data) {
if (!length+data.length) return;
io_service_t service;
if ((service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching(kAppleHWAccessClass)))) {
io_connect_t connect;
if (IOServiceOpen(service, mach_task_self(), 0, &connect) == KERN_SUCCESS) {
bool write = data.length;
struct HWRequest in = {kHWAtom, address},out;
size_t size = sizeof(struct HWRequest);
while (in.offset < address+length) {
if (write) [data getBytes:&in.data range:NSMakeRange(in.offset-address, kHWAtom)];
if (IOConnectCallStructMethod(connect, write, &in, size, &out, &size) != KERN_SUCCESS)
break;
if (!write) [data appendBytes:&out.data length:in.width/8];
in.offset+=in.width/8;
}
IOServiceClose(connect);
IOObjectRelease(connect);
}
IOObjectRelease(service);
}
}
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSMutableData *data = [NSMutableData data];
HWAccess(0xF0000, 0xFFFF, data);
}
return 0;
}