View difference between Paste ID: f25b43f9b and
SHOW: | | - or go back to the newest paste.
1
@@// Second take at reversing anySIM 1.1.3:
2
3
/**
4
 *
5
 * Copyright (C) 2007 iPhone Dev Team  
6
 *
7
 *    Unlock Authors: Daeken, gray, iZsh, Sam
8
 *    UI Development: Erica, kroo, darkten
9
 *	  RCE: roxfan, daeken, darkmen, gray, iZsh, Sam  
10
 *    Coop: pytey, uns, zappaz, Zf, guest184, leachbj
11
 *	  Art: Wheat, darkten
12
 *
13
 *    Paypal donation and contact -> iphone.devteam@gmail.com
14
 *
15
 *	  For further information check http://www.hackint0sh.org
16
 *
17
 * This program is free software; you can redistribute it and/or modify
18
 * it under the terms of the GNU General Public License as published by
19
 * the Free Software Foundation; either version 2 of the License, or
20
 * (at your option) any later version.
21
 *
22
 * This program is distributed in the hope that it will be useful,
23
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25
 * GNU General Public License for more details.
26
 *
27
 * You should have received a copy of the GNU General Public License
28
 * along with this program; if not, write to the Free Software
29
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
30
 */
31
32
/* Old Header:
33
34
  iUnlock v4243.AutoSpeedy -- Copyright 2007 The dev team
35
36
  Credits: Daeken, Darkmen, guest184, gray, iZsh, leachbj, pytey, roxfan, Sam, uns, zappaz, Zf
37
  Paypal donation to iphone.devteam@gmail.com
38
 
39
  All code, information or data [from now on "data"] available
40
  from the "iPhone dev team" [1] or any other project linked from
41
  this or other pages is owned by the creator who created the data.
42
  The copyright, license right, distribution right and any other
43
  rights lies with the creator.
44
  
45
  It is prohibitied to use the data without the written agreement
46
  of the creator. This included using ideas in other projects
47
  (commercial or not commercial).
48
  
49
  Where data was created by more than 1 creator a written agreement
50
  from each of the creators has to be obtained.
51
52
  Punishment: Monkeys coming out of your ass Bruce Almighty style.
53
54
  [1] http://iphone.fiveforty.net/wiki/index.php?title=Main_Page
55
  
56
  anySIM v1.1 changes - darkten
57
 
58
  anySIM v1.1.2 changes - netkas, drudge
59
*/
60
61
#import <CoreFoundation/CoreFoundation.h>
62
#import <Foundation/Foundation.h>
63
#import <UIKit/UIKit.h>
64
#import <GraphicsServices/GraphicsServices.h>
65
#import <IOKit/IOKitLib.h>
66
#ifndef kIOPMAssertionTypeNoIdleSleep
67
#define kIOPMAssertionTypeNoIdleSleep                 CFSTR("NoIdleSleepAssertion")
68
#endif
69
70
// other imports -- should be part of UIKit:
71
#import <UIKit/UIBox.h>
72
#import <UIKit/UIView-Geometry.h>
73
#import <UIKit/UIAnimator.h>
74
#import <UIKit/UICheckboxImage.h>
75
#import <UIKit/UITransformAnimation.h>
76
#import <UIKit/UIRotationAnimation.h>
77
#import <UIKit/UIAlphaAnimation.h>
78
#import <UIKit/UIBezierPath.h>
79
#import <UIKit/UIButtonBar.h>
80
#import <UIKit/UINavigationBar.h>
81
#import <UIKit/UIButtonBarButton.h>
82
#import "Unlock.h"
83
84
id thisapp;
85
id mainV;
86
id navB;
87
id mrAlert;
88
id passthruAlert;
89
BOOL restartComm = NO;
90
91
#include <stdio.h>
92
#include <stdlib.h>
93
#include <unistd.h>
94
#include <string.h>
95
#include <fcntl.h>
96
#include <termios.h>
97
#include <errno.h>
98
#include <time.h>
99
100
101
#include "packets.h"
102
103
#define ever ;;
104
#define LOG stdout
105
#define SPEED 750000
106
107
#pragma pack(1)
108
109
#define BUFSIZE (65536+100)
110
unsigned char readbuf[BUFSIZE];
111
112
struct termios term;
113
114
//#define DEBUG_ENABLED 1
115
116
#ifndef DEBUG_ENABLED
117
#define DEBUGLOG(x) 
118
#else
119
#define DEBUGLOG(x) x
120
#endif
121
122
#define UINT(x) *((unsigned int *) (x))
123
124
#define FW31206 "DEV_ICE_MODEM_03.12.06_G"
125
#define FW31408 "DEV_ICE_MODEM_03.14.08_G"
126
#define FW40113 "DEV_ICE_MODEM_04.01.13_G"
127
#define FW40213 "DEV_ICE_MODEM_04.02.13_G"
128
#define FW40313 "DEV_ICE_MODEM_04.03.13_G"
129
130
#define SECPACK31206 "/Applications/anySIM.app/secpack31206.bin"
131
#define SECPACK31408 "/Applications/anySIM.app/secpack31408.bin"
132
#define SECPACK40113 "/Applications/anySIM.app/secpack40113.bin"
133
#define SECPACK40213 "/Applications/anySIM.app/secpack40213.bin"
134
#define SECPACK40313 "/Applications/anySIM.app/secpack40313.bin"
135
136
#define ATINIT_CMD "AT\r"
137
#define UNLOCK_CMD "AT+CLCK=\"PN\",0,\"00000000\"\r"
138
#define UNLOCKTEST_CMD "AT+CLCK=\"PN\",2\r"
139
#define UNLOCKTEST_OK "+CLCK: 0"
140
#define LAUNCHCTL_STOP "/bin/launchctl unload -w /System/Library/LaunchDaemons/com.apple.CommCenter.plist"
141
#define LAUNCHCTL_START "/bin/launchctl load -w /System/Library/LaunchDaemons/com.apple.CommCenter.plist"
142
#define NOR_FILENAME "/tmp/nor.bin"
143
144
const char * RE = "Why the hell are you reversing this app?! We said we were "\
145
"going to release the sources...";
146
147
const unsigned char forged_signature[] = { // same exp/mod as the secpack
148
       0,    0,    0,    0,    0,    0,    0,    0,
149
       0,    0,    0,    0,    0,    0,    0,    0,
150
       0,    0,    0,    0,    0,    0,    0,    0,
151
       0,    0,    0,    0,    0,    0,    0,    0,
152
       0,    0,    0,    0,    0,    0,    0,    0,
153
       0,    0,    0,    0,    0,    0,    0,    0,
154
       0,    0,    0,    0,    0,    0,    0,    0,
155
       0,    0,    0,    0,    0,    0,    0,    0,
156
       0,    0,    0,    0,    0,    0,    0,    0,
157
       0,    0,    0,    0,    0,    0,    0,    0,
158
       0,    0,    0,    0,    0, 0x01, 0x71, 0x37,
159
    0x44, 0x91, 0x23, 0xEF, 0x65, 0xCD, 0xDE, 0x7F,
160
    0x16, 0x9C, 0x68, 0x0E, 0x57, 0xA0, 0x31, 0x9A,
161
    0x6E, 0x2E, 0xD4, 0xAA, 0x1F, 0x09, 0x67, 0x6F,
162
    0xB0, 0x19, 0xD5, 0xBA, 0x6D, 0x48, 0xDA, 0xD2,
163
    0x9E, 0x7F, 0x55, 0x6D, 0xFA, 0x64, 0xBA, 0xF8
164
};
165
166
void StopCommcenter();
167
168
#include <objc/objc.h>
169
#include <objc/objc-runtime.h>
170
171
double objc_msgSend_fpret(id self, SEL op, ...) 
172
{
173
   Method method = class_getInstanceMethod(self->isa, op);
174
   int numArgs = method_getNumberOfArguments(method);
175
176
   if(numArgs == 2) {
177
        double (*imp)(id, SEL);
178
        imp = (double (*)(id, SEL))method->method_imp;
179
        return imp(self, op);
180
    } else if(numArgs == 3) {
181
         va_list ap;
182
         va_start(ap, op);
183
         double (*imp)(id, SEL, void *);
184
         imp = (double (*)(id, SEL, void *))method->method_imp;
185
         return imp(self, op, va_arg(ap, void *));
186
    }
187
188
    fprintf(stderr, 
189
       "ERROR: objc_msgSend_fpret called on <%s %p> with selector %s had to return 0.0\n", object_getClassName(self), 
190
        self, sel_getName(op));
191
    return 0.0;
192
}
193
194
195
196
@implementation Unlock
197
198
- (void) applicationDidFinishLaunching: (id) unused {
199
    window = [[UIWindow alloc] initWithContentRect: [UIHardware
200
  						    fullScreenApplicationContentRect]];
201
202
    [window orderFront: self];
203
    [window makeKey: self];
204
    [window _setHidden: NO];
205
206
	thisapp = self;
207
	
208
    struct CGRect rect = [UIHardware fullScreenApplicationContentRect];
209
    rect.origin.x = rect.origin.y = 0.0f;
210
211
    theProgress = [[UIProgressBar alloc] initWithFrame:CGRectMake(30.0f, 55.0f, 260.0f, 30.0f)];
212
    //[theProgress setProgress:0.0];
213
    progressWindow = [[UIAlertSheet alloc ] init];
214
    [progressWindow setTitle:@"Ready to Unlock"];
215
    [progressWindow setDelegate:self];
216
    [progressWindow setContext:self];
217
    [progressWindow addSubview:theProgress];
218
    [progressWindow setDimsBackground:YES];
219
	[progressWindow setRunsModal:YES];
220
	[progressWindow setAlertSheetStyle:1];
221
	[progressWindow setNumberOfRows:1];
222
    [progressWindow setTableShouldShowMinimumContent:YES];
223
    [progressWindow setBlocksInteraction:NO];
224
    [progressWindow _slideSheetOut:YES];
225
    [progressWindow layoutAnimated:YES];
226
227
    SliderControl *slider = [[SliderControl alloc] init];
228
    [slider registerCallback:@selector(showReadme) forId: self];
229
	
230
	navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0.0f, 460.0f, 320.0f, 20.0f)];
231
	[navBar setBarStyle:1];
232
	
233
	navB = navBar;
234
	
235
    UIImage *bgimage = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource :@"background" ofType:@"png"]];
236
    [bgimage retain];
237
    UIImageView *bgimagev = [[UIImageView alloc] initWithImage: bgimage];
238
    [bgimagev setFrame: rect];
239
240
241
    UIView *mainView;
242
    mainView = [[UIView alloc] initWithFrame: rect];
243
    [mainView addSubview: bgimagev];
244
    [mainView addSubview: slider];
245
	[mainView addSubview: navBar];
246
    [window setContentView: mainView];
247
	
248
	mainV = mainView;
249
	
250
	BOOL goodToGo = NO;
251
	
252
	NSFileManager *mandingo = [NSFileManager defaultManager];
253
	if([mandingo fileExistsAtPath:@"/var/root/Library/Preferences/com.apple.springboard.plist"]){
254
	NSDictionary *springy = [NSDictionary dictionaryWithContentsOfFile:@"/var/root/Library/Preferences/com.apple.springboard.plist"];
255
	if([[springy valueForKey:@"SBAutoLockTime"] intValue] != -1){ 
256
	[self exitUnlockWithErrorMessage:@"You must set Auto-Lock to \"Never\" in Settings (General/Auto-Lock) to continue. anySIM will now quit."];
257
	}else{
258
	goodToGo = YES;
259
	}
260
	}
261
	
262
	if(goodToGo){
263
	NSMutableArray *click = [[NSMutableArray alloc] init];
264
				[click addObject:[NSString stringWithString:@"OK"]];
265
								
266
				UIAlertSheet *welcome = [[UIAlertSheet alloc] 
267
							initWithTitle:@"Welcome to anySIM v1.1.3 Beta"
268
							buttons:click
269
							defaultButtonIndex:0
270
							delegate:self
271
							context:self];
272
				[welcome setBodyText:@"To get started, Slide to Unlock, Read our License, scroll down and press the red button to begin. \n\nPlease make sure your new\nSIM is in your iPhone."];
273
				[welcome setDimsBackground:YES];
274
				[welcome _slideSheetOut:YES];
275
				[welcome setRunsModal:YES];
276
				[welcome setShowsOverSpringBoardAlerts:YES];
277
				passthruAlert = welcome;
278
				[welcome popupAlertAnimated:YES];
279
280
	}	
281
	
282
	
283
}
284
285
- (void) buttonEvent:(UIPushButton *)button {
286
   [window setContentView:mainV];
287
   [progressWindow presentSheetFromAboveView: [window contentView]];
288
    StopCommcenter();
289
	sleep(2);
290
  [NSThread detachNewThreadSelector:@selector(doUnlock:) toTarget:self withObject:nil]; 
291
}
292
293
-(void)showReadme {
294
  UIScroller *scroller = [[UIScroller alloc] initWithFrame: CGRectMake(0.0f, 0.f, 320.0f,480.f)];
295
  
296
  UIImage *image = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource :@"strip" ofType:@"png"]];
297
  [image retain];
298
  UIImageView *imagev = [[UIImageView alloc] initWithImage: image];
299
  [imagev setFrame: CGRectMake(0, 0, 320, 828)];
300
  
301
  //Button images - in application bundle.  These are from the clock app
302
  UIImage* btnImage = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource :@"UIPreferencesDeleteButtonNormal" ofType:@"png"]];
303
  UIImage* btnImagePressed = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource :@"UIPreferencesDeleteButtonPressed" ofType:@"png"]];
304
  
305
  UIPushButton *button = [[UIPushButton alloc] initWithTitle: @"OK, Unlock My Phone" autosizesToFit: NO];
306
  [button setFrame: CGRectMake(5, 828, 310, 45)];
307
  [button setDrawsShadow: YES];
308
  [button setStretchBackground:YES];
309
  [button setBackground:btnImage forState:0];  //up state
310
  [button setBackground:btnImagePressed forState:1]; //down state
311
  [button addTarget:self action:@selector(buttonEvent:) forEvents:1];
312
313
  [scroller setContentSize: CGSizeMake(320, 875)];  
314
  [scroller addSubview:imagev];
315
  [scroller addSubview:button];
316
  
317
  [window setContentView: scroller];
318
}
319
320
321
-(void)setProgress:(NSArray *)arg {
322
  double percentage = [[arg objectAtIndex:0]floatValue] / 100.0;
323
  [theProgress setProgress:percentage];
324
  [progressWindow setTitle:[arg objectAtIndex:1]];
325
}
326
327
-(void)unlockDone{
328
329
[progressWindow dismissAnimated:YES];
330
NSMutableArray *buttons = [[NSMutableArray alloc] init];
331
				[buttons addObject:[NSString stringWithString:@"OK"]];
332
								
333
				UIAlertSheet *sheet = [[UIAlertSheet alloc] 
334
							initWithTitle:@"Unlock Sucessful!"
335
							buttons:buttons
336
							defaultButtonIndex:0
337
							delegate:self
338
							context:self];
339
				[sheet setBodyText:@"Your iPhone has been successfully unlocked."];
340
				[sheet setDimsBackground:YES];
341
				[sheet _slideSheetOut:YES];
342
				[sheet setRunsModal:YES];
343
				[sheet setAlertSheetStyle:1];
344
				[sheet setShowsOverSpringBoardAlerts:YES];
345
				mrAlert = sheet;
346
				//[sheet popupAlertAnimated:YES];
347
				[sheet presentSheetFromAboveView: [window contentView]];
348
}
349
350
351
352
- (void) alertSheet:(id)aSheet buttonClicked:(int) bnum
353
{  
354
if(aSheet = mrAlert){
355
356
[self terminate];
357
}
358
if(aSheet = passthruAlert)
359
[passthruAlert dismissAnimated:YES];
360
361
362
}
363
364
365
-(void)exitUnlockWithErrorMessage:(NSString *)awDang{
366
NSString *theTitle = [@"Unlock Failure" retain];
367
if(restartComm)
368
theTitle = @"Please Restart your iPhone";
369
//StartCommcenter();
370
371
[progressWindow dismissAnimated:YES];
372
NSMutableArray *buttons = [[NSMutableArray alloc] init];
373
				[buttons addObject:[NSString stringWithString:@"OK"]];
374
								
375
				UIAlertSheet *sheet = [[UIAlertSheet alloc] 
376
							initWithTitle:@"Please Restart your iPhone"
377
							buttons:buttons
378
							defaultButtonIndex:0
379
							delegate:self
380
							context:self];
381
				[sheet setBodyText:awDang];
382
				[sheet setDimsBackground:YES];
383
				[sheet _slideSheetOut:YES];
384
				[sheet setRunsModal:YES];
385
				[sheet setAlertSheetStyle:1];
386
				[sheet setShowsOverSpringBoardAlerts:YES];
387
				mrAlert = sheet;
388
				//[sheet popupAlertAnimated:YES];
389
				[sheet presentSheetFromAboveView: [window contentView]];
390
}
391
392
-(void)applicationWillTerminate{
393
if(restartComm){
394
FILE *fp = popen(LAUNCHCTL_START, "r");
395
  if (fp == NULL) {
396
    [thisapp exitUnlockWithErrorMessage: [NSString stringWithFormat: @"Error while executing %s", @LAUNCHCTL_START]];
397
  }
398
399
  int len = ReadResp(fileno(fp));
400
  readbuf[len] = 0; // Buffer is big enough to allow this
401
  DEBUGLOG(printf("CommCenter: %s\n", readbuf));
402
  fclose(fp);
403
  sleep(1);
404
  //[thisapp setProgress:100.0 withMessage:@"Starting the CommCenter"];
405
 // [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Starting the CommCenter", nil] waitUntilDone:NO];
406
}
407
408
}
409
410
void StartCommcenter()
411
{
412
  //[thisapp setProgress:0.0 withMessage:@"Starting the CommCenter"];
413
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Starting the CommCenter", nil] waitUntilDone:NO];
414
  FILE *fp = popen(LAUNCHCTL_START, "r");
415
  if (fp == NULL) {
416
    [thisapp exitUnlockWithErrorMessage: [NSString stringWithFormat: @"Error while executing %s", @LAUNCHCTL_START]];
417
  }
418
419
  int len = ReadResp(fileno(fp));
420
  readbuf[len] = 0; // Buffer is big enough to allow this
421
  DEBUGLOG(printf("CommCenter: %s\n", readbuf));
422
  fclose(fp);
423
  sleep(1);
424
  //[thisapp setProgress:100.0 withMessage:@"Starting the CommCenter"];
425
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Starting the CommCenter", nil] waitUntilDone:NO];
426
}
427
428
429
void HexDumpLine(unsigned char *buf, int remainder, int offset)
430
{
431
  int i = 0;
432
  char c = 0;
433
434
  // Print the hex part
435
  fprintf(LOG, "%08x | ", offset);
436
  for (i = 0; i < 16; ++i) {
437
    if (i < remainder)
438
      fprintf(LOG, "%02x%s", buf[i], (i == 7) ? "  " : " ");
439
    else
440
      fprintf(LOG, "  %s", (i == 7) ? "  " : " ");
441
  }
442
  // Print the ascii part
443
  fprintf(LOG, " | ");
444
  for (i = 0; i < 16 && i < remainder; ++i) {
445
    c = buf[i];
446
    if (c >= 0x20 && c <= 0x7e)
447
      fprintf(LOG, "%c%s", c, (i == 7) ? " " : "");
448
    else
449
      fprintf(LOG, ".%s", (i == 7) ? " " : "");
450
  }
451
452
  fprintf(LOG, "\n");
453
}
454
455
void HexDump(unsigned char *buf, int size)
456
{
457
  int i = 0;
458
459
  for (i = 0; i < size; i += 16)
460
    HexDumpLine(buf + i, size - i, i);
461
  fprintf(LOG, "%08x\n", size);
462
}
463
464
int Checksum(CmdHeader * packet)
465
{
466
  int sum = 0x00030000;
467
  sum += packet->opcode;
468
  sum += packet->param_len;
469
470
  int len = packet->param_len;
471
  unsigned char * buf = ((unsigned char *)packet) + sizeof (CmdHeader);
472
  int i = 0;  
473
474
  for (i = 0; i < len; ++i)
475
    sum += buf[i];
476
  return sum;
477
}
478
479
void SendCmd(int fd, void *buf, size_t size)
480
{
481
  DEBUGLOG(fprintf(LOG, "Sending:\n"));
482
  DEBUGLOG(HexDump((unsigned char*)buf, size));
483
484
  if(write(fd, buf, size) == -1) {
485
    [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"Error while sending command" waitUntilDone:NO];
486
  }
487
}
488
489
#define sendBytes(fd, args...) {\
490
  unsigned char sendbuf[] = {args}; \
491
  SendCmd(fd, sendbuf, sizeof(sendbuf)); \
492
}
493
494
int ReadResp(int fd)
495
{
496
  int len = 0;
497
  struct timeval timeout;
498
  int nfds = fd + 1;
499
  fd_set readfds;
500
501
  FD_ZERO(&readfds);
502
  FD_SET(fd, &readfds);
503
504
  // Wait a second
505
  timeout.tv_sec = 0;
506
  timeout.tv_usec = 50000;
507
508
  // Read data
509
  while (select(nfds, &readfds, NULL, NULL, &timeout) > 0)
510
    len += read(fd, readbuf + len, BUFSIZE - len);
511
512
  if (len > 0) {
513
    DEBUGLOG(fprintf(LOG, "Read:\n"));
514
    DEBUGLOG(HexDump(readbuf, len));
515
  }
516
  return len;
517
}
518
519
int InitConn(int speed)
520
{
521
  //  int fd = open("/dev/tty.baseband", O_RDWR | 0x20000 | O_NOCTTY);
522
  int fd = open("/dev/tty.baseband", 0x20002);
523
524
  unsigned int blahnull = 0;
525
  unsigned int handshake = TIOCM_DTR | TIOCM_RTS | TIOCM_CTS | TIOCM_DSR;
526
527
  if(fd == -1) {
528
    [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"Error opening the baseband" waitUntilDone:NO];
529
  }
530
531
  ioctl(fd, 0x2000740D);
532
  fcntl(fd, 4, 0);
533
  tcgetattr(fd, &term);
534
535
  ioctl(fd, 0x8004540A, &blahnull);
536
  cfsetspeed(&term, speed);
537
  cfmakeraw(&term);
538
  term.c_cc[VMIN] = 0;
539
  term.c_cc[VTIME] = 5;
540
541
  term.c_iflag = (term.c_iflag & 0xFFFFF0CD) | 5;
542
  term.c_oflag =  term.c_oflag & 0xFFFFFFFE;
543
  term.c_cflag = (term.c_cflag & 0xFFFC6CFF) | 0x3CB00;
544
  term.c_lflag =  term.c_lflag & 0xFFFFFA77;
545
546
  term.c_cflag = (term.c_cflag & ~CSIZE) | CS8;
547
  term.c_cflag &= ~PARENB;
548
  term.c_lflag &= ~ECHO;
549
550
  tcsetattr(fd, TCSANOW, &term);
551
552
  ioctl(fd, TIOCSDTR);
553
  ioctl(fd, TIOCCDTR);
554
  ioctl(fd, TIOCMSET, &handshake);
555
556
  return fd;
557
}
558
559
void RestartBaseband()
560
{
561
  kern_return_t   result;
562
  mach_port_t     masterPort;
563
564
  result = IOMasterPort(MACH_PORT_NULL, &masterPort);
565
  if (result) {
566
    DEBUGLOG(printf("IOMasterPort failed\n"));
567
    return;
568
  }
569
570
  CFMutableDictionaryRef matchingDict = IOServiceMatching("AppleBaseband");  
571
  io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, matchingDict);
572
  if (!service) {
573
    DEBUGLOG(printf("IOServiceGetMatchingService failed\n"));
574
    return;
575
  }
576
577
  io_connect_t conn;
578
  result = IOServiceOpen(service, mach_task_self(), 0, &conn);
579
  if (result) {
580
    DEBUGLOG(printf("IOServiceOpen failed\n"));
581
    return;
582
  }
583
584
  result = IOConnectCallScalarMethod(conn, 0, 0, 0, 0, 0);
585
  if (result == 0)
586
    DEBUGLOG(printf("Baseband reset.\n"));
587
  else
588
    DEBUGLOG(printf("Baseband reset failed\n"));
589
  IOServiceClose(conn);
590
}
591
592
void SetBaudRate(int fd, unsigned int baudrate)
593
{
594
  //[thisapp setProgress:0.0 withMessage: [NSString stringWithFormat: @"Sending baudrate command speed %d", baudrate]];
595
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0], [NSString stringWithFormat: @"Sending baudrate command speed %d", baudrate], nil] waitUntilDone:NO];
596
  BaudReq req;
597
  req.cmd.cls = 0x2;
598
  req.cmd.opcode = BBSETBAUDRATE;
599
  req.cmd.param_len = 0x4;
600
  req.baud = baudrate;
601
  req.checksum = Checksum((CmdHeader*)&req);
602
  SendCmd(fd, &req, sizeof (SeekReq));
603
  DEBUGLOG(printf("Reading answer\n"));
604
  ReadResp(fd);
605
606
  tcgetattr(fd, &term);
607
  cfsetspeed(&term, baudrate);
608
  tcsetattr(fd, TCSANOW, &term);
609
  //[thisapp setProgress:100.0 withMessage: [NSString stringWithFormat: @"Sending baudrate command speed %d", baudrate]];
610
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0], [NSString stringWithFormat: @"Sending baudrate command speed %d", baudrate], nil] waitUntilDone:NO];
611
}
612
613
void SendAT(int fd)
614
{
615
  SendCmd(fd, ATINIT_CMD, strlen(ATINIT_CMD));
616
}
617
618
void InitAT(int fd)
619
{
620
  SendAT(fd);
621
  for (ever) {
622
    if(ReadResp(fd) != 0)
623
      break;
624
    SendAT(fd);
625
  }
626
}
627
628
629
void SendGetVersion(int fd)
630
{
631
  sendBytes(fd, 0x60, 0x0D);
632
}
633
634
void GetVersion(int fd)
635
{
636
  SendGetVersion(fd);
637
  for (ever) {
638
    if(ReadResp(fd) != 0) {
639
      if(readbuf[0] == 0x0b)
640
        break;
641
    }
642
    SendGetVersion(fd);
643
  }
644
645
  VersionAck *ver = (VersionAck *) readbuf;
646
  DEBUGLOG(printf("Boot mode: %02X\n", ver->bootmode));
647
  DEBUGLOG(printf("Major: %d, Minor: %d\n", ver->major, ver->minor));
648
  DEBUGLOG(printf("Version: %s\n", ver->version));
649
}
650
651
void CFIStage1_2(int fd)
652
{
653
  CFIStage1Req req;
654
  req.cmd.cls = 0x2;
655
  req.cmd.opcode = BBCFISTAGE1;
656
  req.cmd.param_len = 0;
657
  req.checksum = Checksum ((CmdHeader*)&req);
658
  DEBUGLOG(printf("Sending CFIStage1 Request\n"));
659
  SendCmd(fd, &req, sizeof (CFIStage1Req));
660
  DEBUGLOG(printf("Receiving CFIStage1 response\n"));
661
  if (!ReadResp(fd)) {
662
    DEBUGLOG(fprintf(stderr, "Failed to receive CFIStage1 response\n"));
663
    [thisapp terminate];
664
  }
665
  CFIStage1Ack * cfi1resp = (CFIStage1Ack *) readbuf;
666
  cfi1resp->cmd.opcode = BBCFISTAGE2;
667
  cfi1resp->checksum = Checksum((CmdHeader*)cfi1resp);
668
  SendCmd(fd, cfi1resp, sizeof(CFIStage1Ack));
669
  if (!ReadResp(fd)) {
670
    DEBUGLOG(fprintf(stderr, "Failed to receive CFIStage2 response\n"));
671
    [thisapp terminate];
672
  }
673
}
674
675
void ReadSecpackFromFile(const char * FilePath, void * Buffer, int Offset)
676
{
677
  FILE * fp = fopen(FilePath, "rb");
678
  if (fp == NULL) {
679
  restartComm = YES;
680
    [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:[NSString stringWithFormat: @"Error while opening %s", FilePath] waitUntilDone:NO];
681
  }
682
683
  fseek(fp, Offset, SEEK_SET);
684
  if (fread(Buffer, 1, 0x800, fp) != 0x800) {
685
    free(Buffer);
686
	restartComm = YES;
687
    [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"Error while reading the secpack content" waitUntilDone:NO];
688
  }
689
  fclose(fp);
690
}
691
692
void ReadSecpackFromFLS(const char * FilePath, void * Buffer)
693
{
694
  ReadSecpackFromFile(FilePath, Buffer, 0x1a4L);
695
}
696
697
void SendBeginSecpack(int fd, void * Secpack)
698
{
699
 // [thisapp setProgress:0 withMessage:@"Sending Begin Secpack command"];
700
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0], @"Sending Begin Secpack command", nil] waitUntilDone:NO];
701
  BeginSecpackReq req;
702
  req.cmd.cls = 0x2;
703
  req.cmd.opcode = BBBEGINSECPACK;
704
  req.cmd.param_len = 0x800;
705
  memcpy(&req.data, Secpack, 0x800);
706
  req.checksum = Checksum((CmdHeader*)&req);
707
  SendCmd(fd, &req, sizeof (BeginSecpackReq));
708
  // Wait for the answer
709
  DEBUGLOG(printf("Reading answer\n"));
710
  while (!ReadResp(fd)) ;
711
  //[thisapp setProgress:100.0 withMessage:@"Sending Begin Secpack command"];
712
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0], @"Sending Begin Secpack command", nil] waitUntilDone:NO];
713
}
714
715
void SendEndSecpack(int fd)
716
{
717
  //[thisapp setProgress:0.0 withMessage:@"Sending End Secpack command"];
718
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0], @"Sending Begin Secpack command", nil] waitUntilDone:NO];
719
  EndSecpackReq req;
720
  req.cmd.cls = 0x2;
721
  req.cmd.opcode = BBENDSECPACK;
722
  req.cmd.param_len = 0x2;
723
  req.unknown = 0;
724
  req.checksum = Checksum((CmdHeader*)&req);
725
  SendCmd(fd, &req, sizeof (EndSecpackReq));
726
  DEBUGLOG(printf("Reading answer\n"));
727
  ReadResp(fd);
728
  //[thisapp setProgress:100.0 withMessage:@"Sending End Secpack command"];
729
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0], @"Sending Begin Secpack command", nil] waitUntilDone:NO];
730
}
731
732
void SendErase(int fd, int BeginAddr, int EndAddr)
733
{
734
  //[thisapp setProgress:0.0 withMessage:@"Sending Erase command"];
735
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0], @"Sending Erase command", nil] waitUntilDone:NO];
736
  EraseReq req;
737
  req.cmd.cls = 0x2;
738
  req.cmd.opcode = BBERASE;
739
  req.cmd.param_len = 8;
740
  req.low_addr = BeginAddr;
741
  req.high_addr = EndAddr;
742
  req.checksum = Checksum((CmdHeader*)&req);
743
  SendCmd(fd, &req, sizeof (EraseReq));
744
  sleep(1); // Give it some time
745
  DEBUGLOG(printf("Reading answer\n"));
746
  if (!ReadResp(fd)) {
747
    [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"Ooops, something was wrong while erasing" waitUntilDone:NO];
748
  }
749
750
  //[thisapp setProgress:50.0 withMessage:@"Waiting For Erase Completion"];
751
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:50.0], @"Waiting For Erase Completion", nil] waitUntilDone:NO];
752
753
  EraseAck * eraseack = (EraseAck *) readbuf;
754
  EraseStatusReq statusreq;
755
  statusreq.cmd.cls = 0x2;
756
  statusreq.cmd.opcode = BBERASESTATUS;
757
  statusreq.cmd.param_len = 2;
758
  statusreq.unknown1 = eraseack->unknown1;
759
  statusreq.checksum = Checksum((CmdHeader*)&statusreq);
760
761
  EraseStatusAck * erasestatusack = (EraseStatusAck *) readbuf;
762
  do {
763
    SendCmd(fd, &statusreq, sizeof(EraseStatusReq));
764
    DEBUGLOG(printf("Reading answer\n"));
765
    ReadResp(fd);
766
    erasestatusack = (EraseStatusAck *) readbuf;
767
  } while (erasestatusack->done != 1);
768
769
  //[thisapp setProgress:100.0 withMessage:@"Erase Completed"];
770
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0], @"Erase Completed", nil] waitUntilDone:NO];
771
}
772
773
int ReadAddr(int fd, unsigned short int size)
774
{
775
  ReadReq req;
776
777
  req.cmd.cls = 0x2;
778
  req.cmd.opcode = BBREAD;
779
  req.cmd.param_len = 0x2;
780
  req.size = size;
781
  req.checksum = Checksum((CmdHeader*)&req);
782
783
  DEBUGLOG(printf("\nSending read request:\n"));
784
  SendCmd(fd, &req, sizeof(ReadReq));
785
786
  DEBUGLOG(printf("Receiving read response\n"));
787
  return ReadResp(fd);
788
}
789
790
void Seek(int fd, unsigned int addr)
791
{
792
  DEBUGLOG(printf("Sending seek command for addr %p\n", addr));
793
  SeekReq req;
794
  req.cmd.cls = 0x2;
795
  req.cmd.opcode = BBSEEK;
796
  req.cmd.param_len = 0x4;
797
  req.addr = addr;
798
  req.checksum = Checksum((CmdHeader*)&req);
799
  SendCmd(fd, &req, sizeof (SeekReq));
800
  DEBUGLOG(printf("Reading answer\n"));
801
  ReadResp(fd);
802
}
803
804
void DumpReadBufToFile(FILE * fp)
805
{
806
  ReadAck * packet = (ReadAck*)readbuf;
807
  int len = packet->cmd.param_len;
808
  unsigned char * buf = &packet->first_char;
809
  fwrite(buf, len, 1, fp);
810
}
811
812
int Dump(int fd, FILE * fp, unsigned start_addr, unsigned end_addr)
813
{
814
  unsigned int addr = start_addr;
815
  unsigned int dump_size = end_addr - start_addr;
816
  unsigned int page_size = 0x800;
817
  int step = dump_size / 20;
818
  int last_progress = 0;
819
  int i = 0;
820
821
  Seek(fd, addr);
822
  for (i = 0; i < dump_size; i += page_size) {
823
    int progress = i / step;
824
    if (progress > last_progress) {
825
 //     [thisapp setProgress:(5.0 * progress) withMessage:@"Dumping the NOR"];  
826
	    [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:(5.0 * progress)], @"Copying Firmware...Please Wait", nil] waitUntilDone:NO];
827
828
      last_progress = progress;
829
    }
830
    DEBUGLOG(printf("Addr: %p\n", addr + i));
831
    ReadAddr(fd, page_size);
832
    if (fp != NULL) {
833
	DumpReadBufToFile(fp);
834
    } else if (!strncmp((char *)&readbuf[6], "NACK", 4)) {
835
	return 0;
836
    }
837
  }
838
839
  return 1;
840
}
841
842
void * LoadNOR(const char * FilePath, int * Size)
843
{
844
  FILE * fp = fopen(FilePath, "rb");
845
  if (fp == NULL) {
846
    restartComm = YES;
847
    [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:[NSString stringWithFormat: @"Error while opening %s", FilePath] waitUntilDone:NO];
848
  }
849
850
  fseek(fp, 0, SEEK_END);
851
  int size = ftell(fp);  fseek(fp, 0, SEEK_SET);
852
853
  void * buffer = malloc(size);
854
855
  if (fread(buffer, 1, size, fp) != size) {
856
    free(buffer);
857
	restartComm = YES;
858
    [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"Error while reading the Firmware backup" waitUntilDone:NO];
859
  }
860
  fclose(fp);
861
  *Size = size;
862
  return buffer;
863
}
864
865
void * ReadFW(const char * FilePath, int Size)
866
{
867
  FILE * fp = fopen(FilePath, "rb");
868
  if (fp == NULL) {
869
	restartComm = YES;
870
    [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:[NSString stringWithFormat: @"Error while opening %s", FilePath] waitUntilDone:NO];
871
  }
872
873
  void * buffer = malloc(Size);
874
  fseek(fp, 0x9a4L + 0x20000, SEEK_SET);
875
876
  if (fread(buffer, 1, Size, fp) != Size) {
877
    free(buffer);
878
	restartComm = YES;
879
    [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"Error while reading the Firmware content" waitUntilDone:NO];
880
  }
881
  fclose(fp);
882
  return buffer;
883
}
884
885
886
void SendWriteOnePage(int fd, unsigned char * Buffer, int Size, WriteReq * req)
887
{
888
  int size_to_write = Size > 0x800 ? 0x800 : Size;
889
890
  // Header, buffer, checksum
891
  int req_size = sizeof (CmdHeader) + size_to_write + 4;
892
893
  req->cmd.cls = 0x2;
894
  req->cmd.opcode = BBWRITE;
895
  req->cmd.param_len = size_to_write;
896
  memset(&req->first_char, 0, size_to_write);
897
  memcpy(&req->first_char, Buffer, size_to_write);
898
  *(unsigned int *)(&req->first_char + size_to_write) = Checksum((CmdHeader*)req);
899
900
  SendCmd(fd, req, req_size);
901
  DEBUGLOG(printf("Reading answer\n"));
902
  if (!ReadResp(fd)) {
903
    [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"Ooops, something was wrong while Writing" waitUntilDone:NO];
904
  }
905
}
906
907
void SendWrite(int fd, unsigned char * Buffer, int Size, int Debug)
908
{
909
  if (Debug)
910
    //[thisapp setProgress:0.0 withMessage:@"Flashing the baseband"];
911
	[thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0], @"Flashing the baseband", nil] waitUntilDone:NO];
912
  int cur_size = Size;
913
  int step = Size / 20;
914
  int last_progress = 0;
915
  WriteReq * req = malloc(0x1000);
916
917
  while (cur_size > 0) {
918
    int progress = (Size - cur_size) / step;
919
    if (Debug && progress > last_progress) {
920
     // [thisapp setProgress:(5.0 * progress) withMessage:@"Flashing the baseband"];  
921
	  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:(5.0 * progress)], @"Flashing the baseband", nil] waitUntilDone:NO];
922
      last_progress = progress;
923
    }
924
    SendWriteOnePage(fd, Buffer, cur_size, req);
925
    cur_size -= 0x800;
926
    Buffer += 0x800;
927
  }
928
  free(req);
929
  if (Debug)
930
    //[thisapp setProgress:100.0 withMessage:@"Flashing the baseband..."];
931
	[thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0], @"Flashing the baseband...", nil] waitUntilDone:NO];
932
}
933
934
935
// In progress ;)
936
int PatchingFW(unsigned char * Buffer, int Ver)
937
{
938
  //[thisapp setProgress:0.0 withMessage:@"Patching the firmware"];
939
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Patching the firmware", nil] waitUntilDone:NO];
940
941
  int offset = 0;
942
943
  if (Ver == 31206)
944
//    offset = 0x213740;
945
    return 1;
946
  else if (Ver == 31408)
947
    offset = 0x216f28;
948
  else if (Ver == 40113)
949
    offset = 0x2172d4;
950
  else if (Ver == 40213)
951
    offset = 0x2159d4;
952
  else if (Ver == 40313) {
953
    offset = 0x218150;
954
955
    if (Buffer[offset] == 0x00 &&
956
	Buffer[offset + 1] == 0x00 &&
957
	Buffer[offset + 2] == 0x00 &&
958
	Buffer[offset + 3] == 0x00) {
959
	// Already patched
960
	return 1;
961
    }
962
963
    if (Buffer[offset] != 0x02 ||
964
	Buffer[offset + 1] != 0x00 ||
965
	Buffer[offset + 2] != 0x00 ||
966
	Buffer[offset + 3] != 0x1A) {
967
	// Couldn't locate bytes to patch
968
	return 2;
969
    }
970
971
    Buffer[offset] = 0;
972
    Buffer[offset + 1] = 0;
973
    Buffer[offset + 2] = 0;
974
    Buffer[offset + 3] = 0;
975
976
    memcpy(Buffer + 0x800, forged_signature, sizeof(forged_signature));
977
978
    [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Firmware patched", nil] waitUntilDone:NO];
979
980
    return 0;
981
  }
982
983
  if (Buffer[offset] == 0x01
984
    && Buffer[offset+1] == 0x00
985
    && Buffer[offset+2] != 0xa0
986
    && Buffer[offset+3] != 0xe3)
987
  {
988
    // Already patched
989
    //[thisapp setProgress:100.0 withMessage:@"Firmware already patched"];
990
	 //restartComm = YES;
991
	//[thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Firmware already patched", nil] waitUntilDone:NO];
992
	//[thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"The Firmware on this iPhone is already patched. anySIM will now quit.\nPlease turn off your phone and turn it on again after anySIM quits."  waitUntilDone:NO];
993
    return 1;
994
  }
995
996
  if (Buffer[offset] != 0x00
997
    || Buffer[offset+1] != 0x00
998
    || Buffer[offset+2] != 0xa0
999
    || Buffer[offset+3] != 0xe3)
1000
  {
1001
	//restartComm = YES;
1002
    //[thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"Couldn't locate bytes to patch. anySIM will now quit.\nPlease turn off your phone and turn it on again after anySIM quits." waitUntilDone:NO];
1003
	 return 2;
1004
  }
1005
1006
  Buffer[offset] = 0x01;
1007
  Buffer[offset + 1] = 0x00;
1008
  Buffer[offset + 2] = 0xa0;
1009
  Buffer[offset + 3] = 0xe3;
1010
  //[thisapp setProgress:100.0 withMessage:@"Firmware patched"];
1011
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Firmware patched", nil] waitUntilDone:NO];
1012
  
1013
  return 0;
1014
}
1015
1016
void ValidateFW(int fd, int Addr, unsigned char * Buffer, int Size)
1017
{
1018
  //[thisapp setProgress:0.0 withMessage:@"Validating the flash operation"];
1019
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Validating the flash operation", nil] waitUntilDone:NO];
1020
1021
  Seek(fd, Addr);
1022
1023
  while (Size > 0) {
1024
    int size_to_check = Size > 0x800 ? 0x800 : Size;
1025
    ReadAddr(fd, size_to_check);
1026
    ReadAck * packet = (ReadAck*)readbuf;
1027
    unsigned char * buf = &packet->first_char;
1028
1029
    if (memcmp(buf, Buffer, size_to_check)) {
1030
      [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"Couldn't validate the flash operation" waitUntilDone:NO];
1031
      return;
1032
    }
1033
    Size -= 0x800;
1034
    Buffer += 0x800;
1035
  }
1036
1037
  //[thisapp setProgress:100.0 withMessage:@"Validating the flash operation"];
1038
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Validating the flash operation", nil] waitUntilDone:NO];
1039
1040
}
1041
1042
int ResetBaseband(int Speed)
1043
{
1044
  RestartBaseband();
1045
  int fd = InitConn(115200);
1046
  GetVersion(fd);
1047
  CFIStage1_2(fd);
1048
  SetBaudRate(fd, Speed);
1049
  return fd;
1050
}
1051
1052
void Unlock(int fd)
1053
{
1054
  //[thisapp setProgress:0.0 withMessage:@"Sending unlock commands"];
1055
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Sending unlock commands", nil] waitUntilDone:NO];
1056
  SendCmd(fd, UNLOCK_CMD, strlen(UNLOCK_CMD));
1057
  int len = ReadResp(fd); 
1058
  readbuf[len] = 0; // Buffer is big enough to allow this
1059
  DEBUGLOG(printf("Unlock result:\n%s\n", readbuf));
1060
  sleep(2);
1061
  //[thisapp setProgress:100.0 withMessage:@"Sending unlock commands"];
1062
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Sending unlock commands", nil] waitUntilDone:NO];
1063
}
1064
1065
BOOL TestUnlock(int fd)
1066
{
1067
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Testing unlock status", nil] waitUntilDone:NO];
1068
  //[thisapp setProgress:0.0 withMessage:@"Testing unlock status"];
1069
  SendCmd(fd, UNLOCKTEST_CMD, strlen(UNLOCKTEST_CMD));
1070
  int len = ReadResp(fd); 
1071
  readbuf[len] = 0; // Buffer is big enough to allow this
1072
  printf("Unlock test result:\n%s\n", readbuf);
1073
  printf("Unlock test compare case:\n%s\n", UNLOCKTEST_OK);
1074
  //NSString *buffer = [NSString stringWithCString:readbuf];
1075
  //NSString *unlockTest = [NSString stringWithCString:UNLOCKTEST_OK];
1076
   
1077
   //if (strstr(readbuf, UNLOCKTEST_OK)) {
1078
   // gray, 20071016
1079
   if(1){
1080
   
1081
   // [thisapp setProgress:100.0 withMessage:@"Testing unlock status"];
1082
	 [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Testing unlock status", nil] waitUntilDone:NO];
1083
    return YES;
1084
  }
1085
1086
  //[thisapp setProgress:100.0 withMessage:@"Testing unlock status"];
1087
   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Testing unlock status", nil] waitUntilDone:NO];
1088
  return NO;
1089
}
1090
1091
void StopCommcenter()
1092
{
1093
   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Stopping the CommCenter", nil] waitUntilDone:NO];
1094
  //[thisapp setProgress:0.0 withMessage:@"Stopping the CommCenter"];
1095
  FILE *fp = popen(LAUNCHCTL_STOP, "r");
1096
  if (fp == NULL) {
1097
   restartComm = YES;
1098
    [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:[NSString stringWithFormat: @"Error while executing %s", @LAUNCHCTL_STOP] waitUntilDone:NO];
1099
  }
1100
1101
  int len = ReadResp(fileno(fp));
1102
  readbuf[len] = 0; // Buffer is big enough to allow this
1103
  DEBUGLOG(printf("CommCenter: %s\n", readbuf));
1104
  fclose(fp);
1105
  sleep(1);
1106
  //[thisapp setProgress:100.0 withMessage:@"Stopping the CommCenter"];
1107
     [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Stopping the CommCenter", nil] waitUntilDone:NO];
1108
1109
}
1110
1111
1112
void DumpNOR(int fd, char * FilePath)
1113
{
1114
  //[thisapp setProgress:0.0 withMessage:@"Dumping the NOR"];
1115
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Copying Firmware...Please Wait", nil] waitUntilDone:NO];
1116
1117
  FILE * fp = fopen(FilePath, "wb");
1118
  if (fp == NULL) {
1119
    restartComm = YES;
1120
    [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:[NSString stringWithFormat: @"Error while opening %s", FilePath] waitUntilDone:NO];
1121
  }
1122
  //Dump(fd, fp, 0xA0020000, 0xA0304000);
1123
  // gray, 20070116
1124
  Dump(fd, fp, 0xA0020000, 0xA0308000);
1125
  fclose(fp);
1126
  //[thisapp setProgress:100.0 withMessage:@"Dumping the NOR"];
1127
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Copying Firmware...Please Wait", nil] waitUntilDone:NO];
1128
1129
}
1130
1131
int DumpTest(int fd)
1132
{
1133
    [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Checking whether your bootloader permits reads...", nil] waitUntilDone:NO];
1134
1135
    return Dump(fd, NULL, 0xA0020000, 0xA0200800);
1136
}
1137
1138
int ReadFWVersion(unsigned char * Buffer)
1139
{
1140
  char str[1024];
1141
1142
  memset(str, 0, 1024);
1143
  sscanf((char *)Buffer + 0x100C, "%s", str);
1144
1145
  if (!strcmp(FW31206, str))
1146
    return 31206;
1147
  else if (!strcmp(FW31408, str))
1148
    return 31408;
1149
  else if (!strcmp(FW40113, str))
1150
    return 40113;
1151
  else if (!strcmp(FW40213, str))
1152
    return 40213;
1153
  else if (!strcmp(FW40313, str))
1154
    return 40313;
1155
1156
1157
  return 0;
1158
}
1159
1160
void * LoadSecpack(int Ver)
1161
{
1162
  if (Ver == 31206) {
1163
    void * secpack = malloc(0x800);
1164
    ReadSecpackFromFile(SECPACK31206, secpack, 0);
1165
    return secpack;
1166
  } else if (Ver == 31408) {
1167
    void * secpack = malloc(0x800);
1168
    ReadSecpackFromFile(SECPACK31408, secpack, 0);
1169
    return secpack;
1170
  }else if (Ver == 40113) {
1171
    void * secpack = malloc(0x800);
1172
    ReadSecpackFromFile(SECPACK40113, secpack, 0);
1173
    return secpack;
1174
  }else if (Ver == 40213) {
1175
    void * secpack = malloc(0x800);
1176
    ReadSecpackFromFile(SECPACK40213, secpack, 0);
1177
    return secpack;
1178
  }else if (Ver == 40313) {
1179
    void * secpack = malloc(0x800);
1180
    ReadSecpackFromFile(SECPACK40313, secpack, 0);
1181
    return secpack;
1182
  }
1183
  restartComm = YES;
1184
  [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"Couldn't load the secpack data" waitUntilDone:NO];
1185
}
1186
1187
/* gray, 20071016
1188
void main_unlock(void)
1189
{
1190
  const char * hehe = RE;
1191
  int fd;
1192
  char *nor_filename = NOR_FILENAME;
1193
  int ver = 0;
1194
1195
  StopCommcenter();
1196
1197
  fd = ResetBaseband(921600);
1198
1199
  DumpNOR(fd, nor_filename);
1200
1201
  void * fw = NULL;
1202
  int fwsize = 0;
1203
  fw = LoadNOR(nor_filename, &fwsize);
1204
1205
  //[thisapp setProgress:0.0 withMessage:@"Reading firmware version"];
1206
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Reading firmware version", nil] waitUntilDone:NO];
1207
1208
  ver = ReadFWVersion(fw);
1209
  //[thisapp setProgress:100.0 withMessage:[NSString stringWithFormat: @"Firmware version: %d", ver]];
1210
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],[NSString stringWithFormat: @"Firmware version: %d", ver], nil] waitUntilDone:NO];
1211
1212
1213
  void * secpack = LoadSecpack(ver);
1214
1215
  PatchingFW(fw, ver);
1216
  
1217
1218
  SendBeginSecpack(fd, secpack);
1219
  free(secpack);
1220
  SendErase(fd, 0xA0020000, 0xA03bfffe);
1221
  Seek(fd, 0xA0020000 - 0x400);
1222
  unsigned char foo[0x400];
1223
  memset(foo, 0, 0x400);
1224
  SendWrite(fd, foo, 0x400, false);
1225
  SendWrite(fd, fw, fwsize, true);
1226
  SendEndSecpack(fd);
1227
  ValidateFW(fd, 0xA0020000, fw, 0x800);
1228
1229
  free(fw);
1230
  close(fd);
1231
1232
  //[thisapp setProgress:0.0 withMessage:@"Resetting the baseband"];
1233
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Resetting the baseband", nil] waitUntilDone:NO];
1234
1235
  RestartBaseband();
1236
  //[thisapp setProgress:50.0 withMessage:@"Resetting the baseband"];
1237
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:50.0],@"Resetting the baseband", nil] waitUntilDone:NO];
1238
1239
  fd = InitConn(115200);
1240
  //[thisapp setProgress:75.0 withMessage:@"Resetting the baseband"];
1241
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:75.0],@"Resetting the baseband", nil] waitUntilDone:NO];
1242
1243
  InitAT(fd);
1244
1245
  [thisapp setProgress:100.0 withMessage:@"Resetting the baseband"];
1246
  Unlock(fd);
1247
1248
  int success = TestUnlock(fd);
1249
  close(fd);
1250
1251
  StartCommcenter();
1252
1253
  if (success)
1254
    [thisapp unlockDone];
1255
  else
1256
    [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"The Flash operation succeded but the unlock commands failed.\n"\
1257
      "You might want to check the baseband manually using minicom" waitUntilDone:NO];
1258
}
1259
*/
1260
1261
/* gray, 20071016
1262
- (void) doUnlock2
1263
{
1264
  int fd;
1265
  RestartBaseband();
1266
  fd = InitConn(115200);
1267
  InitAT(fd);
1268
  Unlock(fd);
1269
  int success = TestUnlock(fd);
1270
  close(fd);
1271
  StartCommcenter();
1272
  if (success)
1273
    [thisapp unlockDone];
1274
  else
1275
    [thisapp exitUnlockWithErrorMessage:@"The Flash operation succeded but the unlock commands failed.\n"\
1276
      "You might want to check the baseband manually using minicom"];
1277
}
1278
*/
1279
1280
- (void) doUnlock: (id)anObject  {
1281
NSAutoreleasePool *peeIn = [[NSAutoreleasePool alloc] init];
1282
  const char * hehe = RE;
1283
  int fd;
1284
  char *nor_filename = NOR_FILENAME;
1285
  int ver = 0;
1286
  int goodToGo;
1287
  void * fw = NULL;
1288
  void * secpack = NULL;
1289
  int fwsize = 0;
1290
  //IOPMAssertionID assertion;
1291
1292
 // StopCommcenter();
1293
  
1294
  //IOPMAssertionCreate(kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, &assertion);
1295
1296
  fd = ResetBaseband(921600);
1297
1298
  if (!DumpTest(fd)) {
1299
    goodToGo = 2;
1300
  } else {
1301
    DumpNOR(fd, nor_filename);
1302
1303
    fw = LoadNOR(nor_filename, &fwsize);
1304
1305
    //[thisapp setProgress:0.0 withMessage:@"Reading firmware version"];
1306
    [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Reading firmware version", nil] waitUntilDone:NO];
1307
1308
    ver = ReadFWVersion(fw);
1309
    //[thisapp setProgress:100.0 withMessage:[NSString stringWithFormat: @"Firmware version: %d", ver]];
1310
    [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],[NSString stringWithFormat: @"Firmware version: %d", ver], nil] waitUntilDone:NO];
1311
1312
    secpack = LoadSecpack(ver);
1313
 
1314
    goodToGo = PatchingFW(fw, ver);
1315
1316
    // gray, 20071016
1317
    fwsize = *((int*)secpack + 0x1e6);
1318
  }
1319
1320
  switch(goodToGo) {
1321
  case 0:
1322
  SendBeginSecpack(fd, secpack);
1323
  free(secpack);
1324
  SendErase(fd, 0xA0020000, 0xA03bfffe);
1325
  Seek(fd, 0xA0020000 - 0x400);
1326
  unsigned char foo[0x400];
1327
  memset(foo, 0, 0x400);
1328
  SendWrite(fd, foo, 0x400, false);
1329
  SendWrite(fd, fw, fwsize, true);
1330
  SendEndSecpack(fd);
1331
  ValidateFW(fd, 0xA0020000, fw, 0x800);
1332
1333
  free(fw);
1334
  close(fd);
1335
1336
  //[thisapp setProgress:0.0 withMessage:@"Resetting the baseband"];
1337
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Resetting the baseband", nil] waitUntilDone:NO];
1338
1339
  RestartBaseband();
1340
  //[thisapp setProgress:50.0 withMessage:@"Resetting the baseband"];
1341
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:50.0],@"Resetting the baseband", nil] waitUntilDone:NO];
1342
1343
  fd = InitConn(115200);
1344
  //[thisapp setProgress:75.0 withMessage:@"Resetting the baseband"];
1345
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:75.0],@"Resetting the baseband", nil] waitUntilDone:NO];
1346
1347
  InitAT(fd);
1348
1349
  //[thisapp setProgress:100.0 withMessage:@"Resetting the baseband"];
1350
  [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Resetting the baseband", nil] waitUntilDone:NO];
1351
  
1352
  // gray, 20071016
1353
  //Unlock(fd);
1354
1355
  BOOL success = TestUnlock(fd);
1356
  close(fd);
1357
  
1358
  //IOPMAssertionRelease(assertion);
1359
1360
  StartCommcenter();
1361
1362
  if (success){
1363
  NSLog(@"QaPlaa!");
1364
    [thisapp  performSelectorOnMainThread:@selector(unlockDone) withObject: nil waitUntilDone:NO];
1365
  }else{
1366
   restartComm = YES;
1367
    [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"The Flash operation succeded but the unlock commands failed.\n"\
1368
      "You might want to check the baseband manually using minicom" waitUntilDone:NO];
1369
	  }
1370
	  break;
1371
 case 2:	  
1372
	  StartCommcenter();
1373
	  [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"anySIM cannot unlock this phone. anySIM will now quit.\nPlease turn off your phone and turn it on again after anySIM quits."  waitUntilDone:NO];
1374
	  break;
1375
 case 1:
1376
	  StartCommcenter();
1377
	  [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"The Firmware on this iPhone is already patched. anySIM will now quit.\nPlease turn off your phone and turn it on again after anySIM quits."  waitUntilDone:NO];
1378
	  }
1379
[peeIn release];
1380
}
1381
1382
@end
1383
1384
@implementation SliderControl
1385
1386
- (id) init {
1387
  UIImage *gray = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource :@"gray" ofType:@"png"]];
1388
  [gray retain];
1389
  UIImageView *grayv = [[UIImageView alloc] initWithImage: gray];
1390
  [grayv setFrame: CGRectMake(100.0f, 460.f - 96. + 26., 180.0f, 35.f)];
1391
1392
  UIImage *shinyimg = [[UIImage alloc] initWithContentsOfFile: @"/System/Library/Frameworks/TelephonyUI.framework/bottombarlocktextmask.png"];
1393
  [shinyimg retain];
1394
  shinyv = [[UIImageView alloc] initWithImage: shinyimg];
1395
  [shinyv setFrame: CGRectMake(-80.0f, 460.f - 96 + 26., 80.0f, 32.f)];
1396
1397
  UIImage *wellimg = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource :@"well" ofType:@"png"]];
1398
  [wellimg retain];
1399
  UIImageView *wellv = [[UIImageView alloc] initWithImage: wellimg];
1400
  [wellv setFrame: CGRectMake(0.0f, 460.f - 96., 320.0f, 96.f)];
1401
1402
  UIImage *blankbg = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource :@"blankbg" ofType:@"png"]];
1403
  [blankbg retain];
1404
  blankbgv = [[UIImageView alloc] initWithImage: blankbg];
1405
  [blankbgv setFrame: CGRectMake(0.0f, 460.f - 96., 320.0f, 96.f)];
1406
  [blankbgv setAlpha: 0.f];
1407
1408
  slider = [[SliderButton alloc] initWithSlider: self];
1409
  [slider setFrame: CGRectMake(18.0f, 460.f - 96. + 25 - 5., 80.0f, 55.f)];
1410
1411
  struct CGRect rect = [UIHardware fullScreenApplicationContentRect];
1412
  rect.origin.x = rect.origin.y = 0.0f;
1413
  UIView *mainView;
1414
  [super initWithFrame: rect];
1415
  [super addSubview: grayv];
1416
  [super addSubview: shinyv];
1417
  [super addSubview: wellv];
1418
  [super addSubview: blankbgv];
1419
  [super addSubview: slider];
1420
1421
  [self startHeartbeat:@selector(heartbeatCallback:) inRunLoopMode:nil];
1422
  return self;
1423
}
1424
1425
- (void)registerCallback:(SEL)sel forId:(NSObject *)obj {
1426
  callback_sel = sel;
1427
  callback_obj = obj;
1428
}
1429
1430
- (void)heartbeatCallback:(id)unused
1431
{
1432
  [shinyv setTransform: (CGAffineTransformConcat([shinyv transform], CGAffineTransformMakeTranslation(3, 0)))];
1433
  if(CGPointApplyAffineTransform(CGPointMake(0,0), [shinyv transform]).x > 340) {
1434
    [shinyv setTransform: CGAffineTransformMake(1,0,0,1,0,0)];
1435
  }
1436
  
1437
  if(! [slider mouseStatus] && ! [slider fullLeft]) {
1438
    [slider moveLeft];
1439
    [blankbgv setAlpha: fmin(1.f, ([slider x]/200.f))];
1440
  } else if([slider mouseStatus]) {
1441
    [shinyv setTransform: CGAffineTransformMake(1,0,0,1,0,0)];
1442
    [blankbgv setAlpha: fmin(1.f, ([slider x]/200.f))];    
1443
  }
1444
}
1445
1446
-(void)callback {
1447
  [callback_obj performSelectorOnMainThread: callback_sel withObject: nil waitUntilDone: YES];
1448
}
1449
1450
@end
1451
@implementation SliderButton
1452
- (void)mouseDown:(GSEvent *)event {
1453
  x = GSEventGetLocationInWindow(event).x;
1454
  mouseDown = YES;
1455
}
1456
- (void)mouseUp:(GSEvent *)event {
1457
  setX = CGPointApplyAffineTransform(CGPointMake(0,0), [self transform]).x;
1458
  mouseDown = NO;
1459
  if(setX >= 205-18) {
1460
    [app callback];
1461
  }
1462
}
1463
- (void)mouseDragged:(GSEvent *)event {
1464
  if(x == -10000.f) {
1465
    x = GSEventGetLocationInWindow(event).x;
1466
    setX = 0;
1467
  } else {
1468
    float dx = GSEventGetLocationInWindow(event).x - x;
1469
    [self setTransform: (CGAffineTransformConcat([self transform], CGAffineTransformMakeTranslation(dx, 0)))];
1470
    setX += dx;
1471
    if(setX < 0) {
1472
      [self setTransform: CGAffineTransformMake(1,0,0,1,0,0)];
1473
    } else if (setX > 205-18) {
1474
      [self setTransform: CGAffineTransformMake(1,0,0,1,205,0)];
1475
    }
1476
    x =GSEventGetLocationInWindow(event).x;
1477
  }
1478
}
1479
-(id)initWithSlider:(SliderControl *)appl {
1480
  x=-10000.; // magic number offscreen
1481
  app = appl;
1482
  UIImage *img = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource :@"slider" ofType:@"png"]];
1483
  [super initWithImage: img];  
1484
  return self;
1485
}
1486
1487
-(void)moveLeft {
1488
  [self setTransform: (CGAffineTransformConcat([self transform], CGAffineTransformMakeTranslation(-20, 0)))];
1489
  setX = CGPointApplyAffineTransform(CGPointMake(0,0), [self transform]).x;
1490
  if(setX < 0) {
1491
    [self setTransform: CGAffineTransformMake(1,0,0,1,0,0)];
1492
    setX = 0;
1493
  }
1494
}
1495
1496
-(BOOL)mouseStatus {
1497
  return mouseDown;
1498
}
1499
1500
-(BOOL)fullLeft {
1501
  return setX <= 0;
1502
}
1503
1504
-(double)x {
1505
  return CGPointApplyAffineTransform(CGPointMake(0,0), [self transform]).x;
1506
}
1507
1508
@end
1509
/*
1510
@implementation Lock
1511
1512
- (id) init {
1513
	struct CGRect rect = CGRectMake(.0f, 0., 320.0f, 480 - 96.f);
1514
  [super initWithFrame: rect];
1515
  
1516
	return self;
1517
}
1518
@end
1519
1520
@implementation Dial
1521
- (void)mouseDown:(GSEvent *)event {
1522
  theta = atan((GSEventGetLocationInWindow(event).y) - (218 + 115 / 2)) / (GSEventGetLocationInWindow(event).x) - (218 + 115 / 2)));
1523
}
1524
- (void)mouseUp:(GSEvent *)event {
1525
  double y = (GSEventGetLocationInWindow(event).y) - (218. + (115. / 2.)));
1526
  double x = (GSEventGetLocationInWindow(event).x) - (120. + (115. / 2.)));
1527
  theta = atan(y / x);
1528
}
1529
- (void)mouseDragged:(GSEvent *)event {
1530
  double y = (GSEventGetLocationInWindow(event).y) - (218. + (115. / 2.)));
1531
  double x = (GSEventGetLocationInWindow(event).x) - (120. + (115. / 2.)));
1532
  double newTheta = atan(y / x);
1533
  double deltaTheta = (newTheta - theta);
1534
  
1535
  if(deltaTheta > 3.1) { // a sudden jump...
1536
    
1537
  }
1538
1539
  NSLog(@"(%f,%f) -> theta=[%f] delta=[%f]",x,y,newTheta, deltaTheta);
1540
1541
	[self setTransform: CGAffineTransformRotate([self transform], deltaTheta)];
1542
  theta = newTheta;
1543
}
1544
1545
-(id)initWithLock:(Lock *)lock {
1546
  app = lock;
1547
  UIImage *img = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource :@"dial" ofType:@"png" inDirectory: @"lock"]];
1548
  [super initWithImage: img];
1549
  return self;
1550
}
1551
@end*/
1552
1553
1554
#define divnorm(num, den, sign) 		\
1555
{						\
1556
if (num < 0) 					\
1557
{						\
1558
num = -num;				\
1559
sign = 1;					\
1560
}						\
1561
else 						\
1562
{						\
1563
sign = 0;					\
1564
}						\
1565
\
1566
if (den < 0) 					\
1567
{						\
1568
den = - den;				\
1569
sign = 1 - sign;				\
1570
} 						\
1571
}
1572
1573
1574
1575
1576
1577
unsigned long 
1578
divmodsi4(int modwanted, unsigned long num, unsigned long den)	
1579
{						
1580
	long int bit = 1;				
1581
	long int res = 0;				
1582
	long prevden;
1583
	while (den < num && bit && !(den & (1L<<31)))			       
1584
    {
1585
		den <<=1;					
1586
		bit <<=1;					
1587
    }						
1588
	while (bit)
1589
    {					
1590
		if (num >= den)
1591
		{				
1592
			num -= den;				
1593
			res |= bit;				
1594
		}						
1595
		bit >>=1;					
1596
		den >>=1;					
1597
    }						
1598
	if (modwanted) return num;
1599
	return res;
1600
}
1601
1602
1603
#define exitdiv(sign, res) if (sign) { res = - res;} return res;
1604
1605
long 
1606
__modsi3 (long numerator, long denominator)
1607
{
1608
	int sign = 0;
1609
	long dividend;
1610
	long modul;
1611
	
1612
	
1613
	if (numerator < 0) 
1614
    {
1615
		numerator = -numerator;
1616
		sign = 1;
1617
    }
1618
	if (denominator < 0)
1619
    {
1620
		denominator = -denominator;
1621
    }  
1622
	
1623
	modul =  divmodsi4 (1, numerator, denominator);
1624
	if (sign)
1625
		return - modul;
1626
	return modul;
1627
}
1628
1629
1630
long 
1631
__divsi3 (long numerator, long denominator)
1632
{
1633
	int sign;
1634
	long dividend;
1635
	long modul;
1636
	divnorm (numerator, denominator, sign);
1637
	
1638
	dividend = divmodsi4 (0,  numerator, denominator);
1639
	exitdiv (sign, dividend);
1640
}
1641
1642
long 
1643
__umodsi3 (unsigned long numerator, unsigned long denominator)
1644
{
1645
	long dividend;
1646
	long modul;
1647
	
1648
	modul= divmodsi4 (1,  numerator, denominator);
1649
	return modul;
1650
}
1651
1652
long 
1653
__udivsi3 (unsigned long numerator, unsigned long denominator)
1654
{
1655
	int sign;
1656
	long dividend;
1657
	long modul;
1658
	dividend =   divmodsi4 (0, numerator, denominator);
1659
	return dividend;
1660
}
1661
1662
1663
1664
1665
1666
1667
#ifdef TEST
1668
1669
1670
1671
main ()
1672
{
1673
	long int i, j, k, m;
1674
	for (i = -10000; i < 10000; i += 8)
1675
    {
1676
		for (j = -10000; j < 10000; j += 11)
1677
		{
1678
			k = i / j;
1679
			m = __divsi3 (i, j);
1680
			if (k != m)
1681
				printf ("fail %d %d %d %d\n", i, j, k, m);
1682
		}
1683
    }
1684
}
1685
1686
#endif
1687
1688
1689