195 lines
5.1 KiB
C
195 lines
5.1 KiB
C
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <netinet/in.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/mount.h>
|
|
#include <CoreFoundation/CoreFoundation.h>
|
|
#include "util.h"
|
|
|
|
void printBytesToHex(const uint8_t* buffer, size_t bytes)
|
|
{
|
|
while(bytes > 0) {
|
|
printf("%02x", *buffer);
|
|
buffer++;
|
|
bytes--;
|
|
}
|
|
}
|
|
|
|
void printHexString(const char* description, const uint8_t* buffer, size_t bytes)
|
|
{
|
|
printf("%s : ", description);
|
|
printBytesToHex(buffer, bytes);
|
|
printf("\n");
|
|
}
|
|
|
|
int write_file(const char* filename, uint8_t* data, size_t len)
|
|
{
|
|
int fd = open(filename, O_CREAT | O_RDWR);
|
|
if (fd < 0)
|
|
return -1;
|
|
if (write(fd, data, len) != len)
|
|
return -1;
|
|
close(fd);
|
|
return 0;
|
|
}
|
|
|
|
void writePlistToStdout(CFDictionaryRef out)
|
|
{
|
|
CFDataRef d = CFPropertyListCreateData(kCFAllocatorDefault, out, kCFPropertyListXMLFormat_v1_0, 0, NULL);
|
|
if (d == NULL)
|
|
return;
|
|
write(1, CFDataGetBytePtr(d), CFDataGetLength(d));
|
|
}
|
|
|
|
int mountDataPartition(const char* mountpoint)
|
|
{
|
|
char* diskname = "/dev/disk0s2s1";
|
|
int err;
|
|
printf("Trying to mount data partition\n");
|
|
err = mount("hfs","/mnt2", MNT_RDONLY | MNT_NOATIME | MNT_NODEV | MNT_LOCAL, &diskname);
|
|
if (!err)
|
|
return 0;
|
|
|
|
diskname = "/dev/disk0s1s2";
|
|
err = mount("hfs","/mnt2", MNT_RDONLY | MNT_NOATIME | MNT_NODEV | MNT_LOCAL, &diskname);
|
|
if (!err)
|
|
return 0;
|
|
diskname = "/dev/disk0s2";
|
|
err = mount("hfs","/mnt2", MNT_RDONLY | MNT_NOATIME | MNT_NODEV | MNT_LOCAL, &diskname);
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
int getHFSInfos(struct HFSInfos *infos)
|
|
{
|
|
char buf[8192] = {0};
|
|
struct HFSPlusVolumeHeader* header;
|
|
unsigned int i;
|
|
|
|
int fd = open("/dev/rdisk0s2", O_RDONLY);
|
|
if (fd < 0 )
|
|
fd = open("/dev/rdisk0s1s2", O_RDONLY); //ios5 lwvm
|
|
if (fd < 0 )
|
|
return fd;
|
|
lseek(fd, 0, SEEK_SET);
|
|
|
|
if (read(fd, buf, 8192) != 8192)
|
|
return -1;
|
|
close(fd);
|
|
|
|
header = (struct HFSPlusVolumeHeader*) &buf[0x400];
|
|
|
|
uint32_t blockSize = CFSwapInt32BigToHost(header->blockSize);
|
|
|
|
infos->volumeUUID = header->volumeUUID;
|
|
infos->blockSize = blockSize;
|
|
|
|
if (blockSize != 0x1000 && blockSize != 0x2000)
|
|
{
|
|
fprintf(stderr, "getHFSInfos: Unknown block size %x\n", blockSize);
|
|
}
|
|
else
|
|
{
|
|
fd = open("/dev/rdisk0", O_RDONLY);
|
|
if (fd < 0 )
|
|
return fd;
|
|
|
|
if (read(fd, buf, 8192) != 8192)
|
|
return -1;
|
|
|
|
if (!memcmp(buf, LwVMType, 16))
|
|
{
|
|
LwVM* lwvm = (LwVM*) buf;
|
|
|
|
if (lwvm->chunks[0] != 0xF000)
|
|
{
|
|
fprintf(stderr, "getHFSInfos: lwvm->chunks[0] != 0xF000\n");
|
|
return -1;
|
|
}
|
|
|
|
for(i=0; i < 0x400; i++)
|
|
{
|
|
if(lwvm->chunks[i] == 0x1000) //partition 1 block 0
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
uint32_t LwVM_rangeShiftValue = 32 - __builtin_clz((lwvm->mediaSize - 1) >> 10);
|
|
|
|
infos->dataVolumeOffset = (i << LwVM_rangeShiftValue) / blockSize;
|
|
}
|
|
else
|
|
{
|
|
lseek(fd, 2*blockSize, SEEK_SET);
|
|
|
|
if (read(fd, buf, 8192) != 8192)
|
|
return -1;
|
|
close(fd);
|
|
|
|
infos->dataVolumeOffset = ((unsigned int*)buf)[0xA0/4];
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
CFMutableStringRef CreateHexaCFString(uint8_t* buffer, size_t len)
|
|
{
|
|
int i;
|
|
|
|
CFMutableStringRef s = CFStringCreateMutable(kCFAllocatorDefault, len*2);
|
|
|
|
for(i=0; i < len; i++)
|
|
{
|
|
CFStringAppendFormat(s, NULL, CFSTR("%02x"), buffer[i]);
|
|
}
|
|
return s;
|
|
}
|
|
|
|
void addHexaString(CFMutableDictionaryRef out, CFStringRef key, uint8_t* buffer, size_t len)
|
|
{
|
|
CFMutableStringRef s = CreateHexaCFString(buffer, len);
|
|
CFDictionaryAddValue(out, key, s);
|
|
CFRelease(s);
|
|
}
|
|
|
|
void saveResults(CFStringRef filename, CFMutableDictionaryRef out)
|
|
{
|
|
CFURLRef fileURL = CFURLCreateWithFileSystemPath( NULL, filename, kCFURLPOSIXPathStyle, FALSE);
|
|
CFWriteStreamRef stream = CFWriteStreamCreateWithFile( NULL, fileURL);
|
|
CFWriteStreamOpen(stream);
|
|
CFPropertyListWriteToStream(out, stream, kCFPropertyListXMLFormat_v1_0, NULL);
|
|
CFWriteStreamClose(stream);
|
|
|
|
CFRelease(stream);
|
|
CFRelease(fileURL);
|
|
}
|
|
|
|
int create_listening_socket(int port)
|
|
{
|
|
struct sockaddr_in listen_addr;
|
|
int s, one = 1;
|
|
|
|
memset(&listen_addr, 0, sizeof(struct sockaddr));
|
|
listen_addr.sin_family = AF_INET;
|
|
listen_addr.sin_port = htons(port);
|
|
listen_addr.sin_addr.s_addr = INADDR_ANY;
|
|
|
|
s = socket(AF_INET, SOCK_STREAM, 0);
|
|
|
|
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
|
|
|
|
if (bind(s, (struct sockaddr *)&listen_addr, sizeof(struct sockaddr)) < 0)
|
|
{
|
|
perror("bind");
|
|
return -1;
|
|
}
|
|
listen(s, 10);
|
|
|
|
return s;
|
|
}
|