/*
* This patches MobileSafari in the 1.1.1 ipod touch (and probably iphone) to allow
* access to local files. It tweaks two instructions to eliminate the effects of
* isFileURL checks.
*
* If run with no arguments, it will look for MobileSafari in its default location. When
* run with an argument, it will patch that file. (For use outside of the touch.)
*
* This assumes a little endian platform - it won't work on the PPC, sorry.
*
* The C code was adapted from a springboard patch I found on pastebin.
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#define MS_SIZE 432940
#define MS_FILE "/Applications/MobileSafari.app/MobileSafari"
struct Patch {
unsigned int offset;
unsigned int old;
unsigned int new;
};
struct Patch patches[] = {
{ 0x21694, 0x13a04000, 0xe1a04004}, // Changes a conditional mov to a nop mov
{ 0x21940, 0x0a00000e, 0xea00000e}, // Changes a conditional branch to unconditional
{ 0, 0, 0 }
};
int main(int argc, char** argv) {
unsigned int DATA[(MS_SIZE)/4+1];
FILE *fd;
struct stat s;
char* filename = MS_FILE;
/*
* This patches MobileSafari in the 1.1.1 ipod touch (and probably iphone) to allow
* access to local files. It tweaks two instructions to eliminate the effects of
* isFileURL checks.
*
* If run with no arguments, it will look for MobileSafari in its default location. When
* run with an argument, it will patch that file. (For use outside of the touch.)
*
* This assumes a little endian platform - it won't work on the PPC, sorry.
*
* The C code was adapted from a springboard patch I found on pastebin.
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#define MS_SIZE 432940
#define MS_FILE "/Applications/MobileSafari.app/MobileSafari"
struct Patch {
unsigned int offset;
unsigned int old;
unsigned int new;
};
struct Patch patches[] = {
{ 0x21694, 0x13a04000, 0xe1a04004}, // Changes a conditional mov to a nop mov
{ 0x21940, 0x0a00000e, 0xea00000e}, // Changes a conditional branch to unconditional
{ 0, 0, 0 }
};
int main(int argc, char** argv) {
unsigned int DATA[(MS_SIZE)/4+1];
FILE *fd;
struct stat s;
char* filename = MS_FILE;
if (argc > 1) {
filename = argv[1];
}
/* Patch MobileSafari */
printf("Patching %s\n", filename);
if (stat(filename, &s)) {
fprintf(stderr, "Could not stat file '%s': %s\n", filename, strerror(errno));
exit(-1);
}
if (s.st_size != MS_SIZE) {
fprintf(stderr, "%s: file size mismatch: %d; expecting %d\n", filename, s.st_size, MS_SIZE);
exit(-1);
}
fd = fopen(filename, "rb");
if (!fd) {
fprintf(stderr, "Could not open '%s' for reading: %s\n", filename, strerror(errno));
exit(-1);
}
fread(&DATA, MS_SIZE, 1, fd);
fclose(fd);
struct Patch *patch = patches;
while (patch->offset) {
fprintf(stderr,"Patch %08x: %08x -> %08x\n", patch->offset, patch->old, patch->new);
int offset = patch->offset / 4;
unsigned int old = DATA[offset];
if (old != patch->old) {
fprintf(stderr, "Mismatch at %08x: got %08x instead of %08x\n",
patch->offset, DATA[offset], patch->old);
exit(-1);
}
DATA[offset] = patch->new;
patch++;
}
fd = fopen(filename, "wb");
if (!fd) {
fprintf(stderr, "Could not open '%s' for writing: %s\n", filename, strerror(errno));
exit(-1);
}
fwrite(&DATA, MS_SIZE, 1, fd);
fclose(fd);
return 0;
}