Friday, August 13, 2010

How to use the mount(2) function to mount an hfs volume

After two days of searching through documents on the mount(2) function, I was finally relieved with the help of a forum poster Alex B on stackoverflow.

The particular need for my want to learn how to use mount(), opposed to just setting up a system() call, is quite odd and has to do with encryption algorithms temporarily writing to a disk... I won't get into that, but I will show you how to force an update on a volume that has already been mounted in single user mode as read only, in this case it will be "/"




#import //For mount()
#import //for hfs_mount_args
#import // for #define'd constants

// Outline of an hfs specific struct
/*
 struct hfs_mount_args {
 char     *fspec; ****name of the device e.g:"/dev/disk0s2"
uid_t     hfs_uid; 
gid_t     hfs_gid;
mode_t    hfs_mask;
u_int32_t hfs_encoding;
struct    timezone hfs_timezone;
int       flags;
int       journal_tbuffer_size;
int       journal_flags;
int       journal_disable;
};

*/

int main (int argc, const char * argv[]) {
struct hfs_mount_args some_data; //Declare your struct
int options = 0; //Declare your options variable
int result = 0 //Declare a return variable
some_data.fspec = strdup("/dev/disk0s2"); //Specify a device to be mounted
options = MNT_UPDATE | MNT_NOEXEC; //Forces the volume to not allow executables to run
result = mount("hfs", "/", options ,&some_data);//Mount it
NSLog(@"%d",result);//should return 0 on a successful mount
/* add some more code here*/
return 0;//exit
}

Thursday, August 12, 2010

Don't forget your implicit casts

I recently answered a question on the apple forums regarding an error that arose from passing an NSDictionary object to a function that requires a CFDictionaryRef, although apple states that they are a toll free bridge to eachother, you still need to implicitly cast them.

example:
NSDictionary * someNSDictionary = [[NSDictionary alloc]initWithContentsOfFile:@"/SomePath"];
CFDictionaryRef someCFDictionary = (CFDictionaryRef)someNSDictionary;

Friday, July 30, 2010

Trapping Global Keyboard Events Using Carbon

I came across the question "How do I trap keyboard events in kernel space", I answered this question with a question, why do you need to trap keyboard events in kernel space?...You don't, most of the time. The person then proceeded to tell me he didn't want to have to deal with a Graphical User Interface (gui) and so I thought ok i'll just google "trap key events without a gui mac os x" for him since he probably just skipped that part. Turns out there isn't a guide on creating an application that traps global keyboard events without using a graphical user interface. However it is very possible so I decided to write one.
since this is for tutorial purposes assume that all of this is in main.m (or .c) , also this will only compile properly under an i386 architecture because carbon event loops aren't support by 64 bit archs yet...go figure.
Post a comment with any questions


// *This code is meant to be for tutorial purposes*





#import <Carbon/Carbon.h>
//our callback for the event this is called every time 'your' event happens
OSStatus keyHandler(EventHandlerCallRef nextHandler, EventRef anEvent, void *userData){
printf("Hey! I trapped a global key event\n");
return noErr;
}
//register interest in the events you would like to receive notifications about
void setupEventHandler(){
EventHotKeyRef hotKeyRef;
EventHotKeyID hotKeyID;
EventTypeSpec eventType;
eventType.eventClass = kEventClassKeyboard;
eventType.eventKind = kEventHotKeyPressed;
InstallEventHandler(GetApplicationEventTarget(),
                                            &keyHandler,
                                                      1,
                                             &eventType,
                                                   NULL,
                                                   NULL);
hotKeyID.signature = '1';
hotKeyID.id = 1;
        RegisterEventHotKey(123,
                      optionKey,
                       hotKeyID,
     GetApplicationEventTarget(),
                               0,
                     &hotKeyRef);
}

int main (int argc, const char * argv[]) {
setupEventHandler();
RunApplicationEventLoop();
    
return 0;
}



Thursday, July 29, 2010

How to save a headache using Jeff LaMarche's NSData-AES category

So after about 30 or so minutes of trying to figure why I could not get my data to decrypt properly after I encrypted it I came across a post by someone finding relief to this problem by changing the encryption keybits to 128 (located in the NSData-AES category *.h file) which did end up doing the trick....sort of, my data had a trailing tail of <202020 202020 202020 202020> which is...you guessed it, whitespace. This was very irritating because as I'm sure you can imagine comparing data with trailing whitespace does not yield nice results. So here is a solution I wrote. There may be more elegant ways to do this but this works for now.

NSData * encryptedData; 
NSString * trimString;
NSData * decryptedData;

encryptedData = [self returnSomeEncryptedDataUsingAPassword:@"password"];
decryptedData = [encryptedData AESDecryptWithAPassphrase:@"password"];
trimString = [[NSString alloc]initWithData:decryptedData

                                                     encoding:NSASCIIStringEncoding];
[
trimString autorelease]; 
trimString = [trimString stringByTrimmingCharactersInSet:[NSCharacterSet whiteSpaceCharacterSet]]; 

decryptedData = [trimString dataUsingEncoding:NSASCIIStringEncoding];






There are of course variations to this for example you could use a temp string opposed to autoreleasing the trim string or instead of creating your own character set you could also use [NSCharacterSet whiteSpaceAndNewlineCharacterSet]; but for this we don't need new lines in the mix




Here is a link to the AES Catergories (NSFileManager works with 256 bit encryption)
http://iphonedevelopment.blogspot.com/2009/02/strong-encryption-for-cocoa-cocoa-touch.html