Gunlock

From The iPhone Wiki
Revision as of 21:27, 22 October 2010 by Liamchat (talk | contribs) (added the source code)
Jump to: navigation, search

it was the first implimentation of the Minus_0x20000_with_Back_Extend_Erase in the first version of this unlock aeroplane mode needed to be switched on if it was not i will brick your phone then it was updated for 1.1.3 ( caused a bootloop )

credit

geohot

instruction's

1. Download these: gunlock and the secpack from http://iphonejtag.blogspot.com/ or the blog :) the 4.02.13 fls from http://george.zjlotto.com/index.php/baseband/

2. Downgrade your phone to 1.0.2. See all the great tutorials online to do this. Your baseband won't be downgraded, this is normal. This will probably work on other versions too, but 1.0.2 doesn't lose wifi on bb access.

3. Kill CommCenter and run "gunlock secpack ICE04.02.13_G.fls"

4. Reload CommCenter. For some reason my phone was in brick mode. Use the elite team bricktool to get out.

5. Enjoy your 1.1.2 OTB unlocked iPhone

link's

download link

road block's

Send the 1.1.3 secpack to erase 1.1.2

Second exploit, the fake secpack erase range

If a valid secpack is present in 0x3C0000, the phone won't boot

And since endpack doesn't work, I needed to find another way

source code

//geohot's 112 otb unlocker
//this code is GPLed
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <IOKit/IOKitLib.h>
#include <sys/ioctl.h>
#include <strings.h>
#include <errno.h>
#include <mach/mach_time.h>
struct termios term;
int hlen,t,u,fp;
unsigned char *data, *secpack;
FILE *f;
int adrcount;
int openport(int speed)
{
 int fd = open("/dev/tty.baseband", O_RDWR | 0x20000 | O_NOCTTY);
 unsigned int blahnull = 0;
 unsigned int handshake = TIOCM_DTR | TIOCM_RTS | TIOCM_CTS | TIOCM_DSR;
 if(fd == -1)
 {
   fprintf(stderr, "%i(%s)\n", errno, strerror(errno));
   exit(1);
 }
 ioctl(fd, 0x2000740D);
 fcntl(fd, 4, 0);
 tcgetattr(fd, &term);
 ioctl(fd, 0x8004540A, &blahnull);
 cfsetspeed(&term, speed);
 cfmakeraw(&term);
 term.c_cc[VMIN] = 0;
 term.c_cc[VTIME] = 5;
 term.c_iflag = (term.c_iflag & 0xFFFFF0CD) | 5;
 term.c_oflag =  term.c_oflag & 0xFFFFFFFE;
 term.c_cflag = (term.c_cflag & 0xFFFC6CFF) | 0x3CB00;
 term.c_lflag =  term.c_lflag & 0xFFFFFA77;
 term.c_cflag = (term.c_cflag & ~CSIZE) | CS8;
 term.c_cflag &= ~PARENB;
 term.c_lflag &= ~ECHO;
 tcsetattr(fd, TCSANOW, &term);
 ioctl(fd, TIOCSDTR);
 ioctl(fd, TIOCCDTR);
 ioctl(fd, TIOCMSET, &handshake);
 return fd;
}
void resetbaseband()
{
 kern_return_t   result;
 mach_port_t     masterPort;
 result = IOMasterPort(MACH_PORT_NULL, &masterPort);
 CFMutableDictionaryRef matchingDict = IOServiceMatching("AppleBaseband");  
 io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, matchingDict);
 io_connect_t conn;
 result = IOServiceOpen(service, mach_task_self(), 0, &conn);
 result = IOConnectCallScalarMethod(conn, 0, 0, 0, 0, 0);
 IOServiceClose(conn);
}
void getheader(unsigned int timeout)
{
fd_set nfp;
FD_ZERO(&nfp);
FD_SET(fp, &nfp);
struct timeval tv;
tv.tv_sec=0;
tv.tv_usec=timeout*1000;
hlen=0;
while(select(fp+1,&nfp,0,0,&tv)>0)
{
hlen+=read(fp,data+hlen, 0x10064-hlen);
//printf("Attempting to read[%d]...%x %x\n",hlen,data[0],data[1]);
}
}
void getcommand()	//will return when done
{
int maxlength=6;
hlen=0;
while(hlen<maxlength)
{
hlen+=read(fp,data+hlen, 6);
}
maxlength+=data[5]*0x100+data[4]+4;	//2 for checksum and 2 for end
while(hlen<maxlength)
{
hlen+=read(fp,data+hlen, 0x10064-hlen);
}
}
struct termios options;
void openbaseband()
{
int t1=0;
int t2=0x126;
fp=open("/dev/tty.baseband",0x20002);
ioctl(fp,0x2000740D);
fcntl(fp,4,0);
tcgetattr(fp,&options);
ioctl(fp,0x8004540A,&t1);
cfsetspeed(&options,115200);
cfmakeraw(&options);
options.c_cc[16]=0;
options.c_cc[17]=5;
options.c_iflag=(options.c_iflag | 0x5) & 0xFFFFF0CD;
options.c_oflag=options.c_oflag & 0xFFFFFFFE;
options.c_cflag=(options.c_cflag | 0x3CB00) & 0xFFFFEFFF;
options.c_lflag=options.c_lflag & 0xFFFFFA77;
tcsetattr(fp,0,&options);
ioctl(fp,0x20007479);
ioctl(fp,0x20007478);
ioctl(fp,0x8004746D,&t2);
printf("Opened: /dev/tty.baseband\n");
}
void printbuffer()
{
for(t=0;t<hlen;t++)
{
if(t!=0&&t%16==0) printf("\n");
printf("%2.2X ", data[t]);
}
if(hlen>0)
printf("\n");
}
struct cmd_pkt{
unsigned short int w02;
unsigned short int cmd;
unsigned short int data_size;
};
struct cmd_pkt_end{
unsigned short int checksum;
unsigned short int w03;
};
struct cmd_pkt mycmdpkt;
struct cmd_pkt_end mycmdpktend;
void cmd_write()
{
mycmdpkt.w02=2;
mycmdpktend.w03=3;
mycmdpktend.checksum=0;
for(t=0;t<mycmdpkt.data_size;t++)
{
mycmdpktend.checksum+=data[t];
}
mycmdpktend.checksum+=mycmdpkt.cmd+mycmdpkt.data_size;
write(fp,&mycmdpkt,6);
write(fp,data,mycmdpkt.data_size);
write(fp,&mycmdpktend,4);
}
void usage()
{
printf("geohot's 112 otb unlocker...\n");
}
int enterinteractive()
{
tcgetattr(fp,&options);			//baud rate upped
cfsetspeed(&options,115200);
tcsetattr(fp,0,&options);
printf("Waiting for data...\n");
do
{
data[0]=0x60; data[1]=0x0D;
if(write(fp,data,2)==-1)
 {
printf("Can't write\n");
return -1;
}
printf("Attempt...\n");
getheader(500);
} while(hlen==0||data[0]!=0xb);
printf("Got Header: %d %2.2x %2.2x\n",hlen, data[0], data[1]);
return 0;
}
void increasebaudrate()
{
printf("Increasing baud rate...\n");
mycmdpkt.cmd=0x82;
mycmdpkt.data_size=4;
data[0]=0x00; data[1]=0x10; data[2]=0x0E; data[3]=0x00;		//115200 bps
cmd_write();
getcommand();
printbuffer();
tcgetattr(fp,&options);			//baud rate upped
cfsetspeed(&options,921600);
tcsetattr(fp,0,&options);
}
void getflashid()
{
printf("Get flash ID\n");
mycmdpkt.cmd=0x801;
mycmdpkt.data_size=0;
cmd_write();
getcommand();
//printbuffer();
}
void cfistage1()
{
printf("CFI Stage 1\n");
mycmdpkt.cmd=0x84;
mycmdpkt.data_size=2;
data[0]=0; data[1]=0;
cmd_write();
getcommand();
//printbuffer();
}
void cfistage2()
{
printf("CFI Stage 2\n");
mycmdpkt.cmd=0x85;
mycmdpkt.data_size=0;
cmd_write();
getcommand();
//printbuffer();
}
void address(unsigned int addr, int print)
{
adrcount=addr;
if(print==0) printf("Address to 0x%X  ",addr);
mycmdpkt.cmd=0x802;
mycmdpkt.data_size=4;
memcpy(data,&addr,4);
cmd_write();
getcommand();
if(print==0) printbuffer();
}
void sendsecpack(char *secpack)
{
printf("Sending secpack... ");
mycmdpkt.cmd=0x204;
mycmdpkt.data_size=0x800;
memcpy(data,secpack,0x800);
cmd_write();
getcommand();
printbuffer();
}
void bbread(short int len)
{
mycmdpkt.cmd=0x803;
mycmdpkt.data_size=2;
memcpy(data,&len,2);
cmd_write();
getcommand();
printbuffer();
}
void bbwrite(unsigned int size, int print)	//put crap in data already
{
if(print==0) printf("Writing: 0x%X  ",adrcount);
mycmdpkt.cmd=0x804;
mycmdpkt.data_size=size;
cmd_write();
getcommand();
if(print==0) printbuffer();
adrcount+=size;
}
int erase(unsigned int start, unsigned int end, int debug)
{
printf("Erasing: 0x%X-0x%X  ",start, end);
mycmdpkt.cmd=0x805;
mycmdpkt.data_size=8;
memcpy(data,&start,0x4);
memcpy(&data[4],&end,0x4);
cmd_write();
getcommand();
printbuffer();
printf("Waiting for erase to finish...\n");
do{
mycmdpkt.cmd=0x806;
mycmdpkt.data_size=2;
data[0]=0; data[1]=0;
cmd_write();
getcommand();
if(debug==0) printbuffer();
usleep(100000);
}while(data[6]==0);
if(debug!=0) printbuffer();
if(data[9]!=0x31) 
{
//printf("Erase failed!\n");
return -1;
}
return 0;
}
void endsecpack()
{
printf("End Secpack  ");
mycmdpkt.cmd=0x205;
mycmdpkt.data_size=2;
data[0]=0; data[1]=0;
cmd_write();
getcommand();
printbuffer();
}
void readmem(unsigned int addr)		//you need a patched bootloader :)
{
//printf("procx102\n");
unsigned int memdata;
mycmdpkt.cmd=0x102;
mycmdpkt.data_size=4;
memcpy(data,&addr,0x4);
cmd_write();
getcommand();
memcpy(&memdata,&data[6],0x4);
printf("[0x%X]=0x%X\n",addr,memdata);
//printbuffer();
}
#define patchloc 0x2359d4	//this is for 4.02.13
int main(int argc, char *argv[])
{
usage();
if(argc<3) { printf("usage: %s <113secpack> <112fls>\n",argv[0]); return -1;}
resetbaseband();
fp = openport(115200);
//FILE *secpack=fopen(argv[1],"rb");
data=(unsigned char *)malloc(70000);
if(enterinteractive()==-1) return -1;
printf("Bootloader version: %s\n",&data[0xD]);
if(data[5]!=4)
{
printf("Incorrect bootloader version\n");
return -1;
}
increasebaudrate();
cfistage1();
cfistage2();
char *rsecpack=(char *)malloc(0x800);
FILE *secpack=fopen(argv[1],"rb");
fread(rsecpack,1,0x800,secpack);
fclose(secpack);
//Send the 1.1.3 secpack to erase 1.1.2
sendsecpack(rsecpack);
if(erase(0xA0020000, 0xA03BFFFE,1)==-1) {
printf("Erase failed\n");
printf("Hang on...we can fix that\n");
const char efakesec[]={0x00,0x00,0x02,0xA0,0x00,0x00,0x3D,0x00,0x00,0x00,0x3D,0x00,0x00,0x00,0x00,0x00};	//full range including main fw...
//2nd exploit variant for >=1.1.3
memcpy(&rsecpack[0x780],efakesec,0x10);
sendsecpack(rsecpack);
endsecpack();
erase(0xA03D0000,0xA03F0000,1);	//the only secpack free allowed erase :)
printf("Okay, lets try that again...\n");
secpack=fopen(argv[1],"rb");	//reread
fread(rsecpack,1,0x800,secpack);
fclose(secpack);
sendsecpack(rsecpack);
if(erase(0xA0020000, 0xA03BFFFE,1)==-1) {
printf("Hmm...what did you do?");
return -1;
}
}
//First exploit, the -0x20000 exploit
//This writes the firmware, in all its unsigned glory
//I guess Apple figured -0x400 was simple, -0x20000 is *much* harder
address(0xA0000000,0);		//-0x20000, like i said :)
FILE *bb=fopen(argv[2],"rb");
fseek(bb,0x9a4,SEEK_SET);		//skip bbupdater data and secpack
int a,rc=0;
do{
a=fread(data,1,0x800,bb);
if(rc<patchloc&&patchloc<(rc+a))	//patch the firmware
{
printf("Patching...\n");
data[patchloc-rc+3] = 0xe3;
data[patchloc-rc+2] = 0xa0;
data[patchloc-rc+1] = 0x00;
data[patchloc-rc]   = 0x01; 
}
if(rc%0x10000==0||a!=0x800) printf("Wrote: 0x%x 0x%x\n",a,rc);
if(a>0)
bbwrite(a,1);		//write like hell
rc+=a;
}while(a>0);
//Second exploit, the fake secpack erase range
//If a valid secpack is present in 0x3C0000, the phone won't boot
//And since endpack doesn't work, I needed to find another way
const char fakesec[]={0x00,0x00,0x3C,0xA0,0x00,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00};	//not 0xA03D0000
memcpy(&rsecpack[0x780],fakesec,0x10);
sendsecpack(rsecpack);
endsecpack();
erase(0xA03D0000,0xA03F0000,1);	//the only secpack free allowed erase :)
close(fp);
resetbaseband();
printf("Enjoy your unlocked iPhone...\n");
return 0;
}