Subversion Repositories freemyipod

Rev

Rev 864 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
146 farthen 1
#!/usr/bin/env python
2
#
3
#
4
#    Copyright 2010 TheSeven
5
#
6
#
7
#    This file is part of TheSeven's iPod tools.
8
#
9
#    TheSeven's iBugger is free software: you can redistribute it and/or
10
#    modify it under the terms of the GNU General Public License as
11
#    published by the Free Software Foundation, either version 2 of the
12
#    License, or (at your option) any later version.
13
#
14
#    TheSeven's iBugger is distributed in the hope that it will be useful,
15
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
16
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
#    See the GNU General Public License for more details.
18
#
19
#    You should have received a copy of the GNU General Public License along
20
#    with TheSeven's iPod tools.  If not, see <http://www.gnu.org/licenses/>.
21
#
22
#
23
 
24
 
25
import sys
26
import struct
27
import usb.core
28
 
29
 
30
class ipoddfu:
31
  def __init__(self, generation = 0, type = 0):
864 user890104 32
    # iPod Nano 2G, Bootrom DFU
239 theseven 33
    try:
34
      self.dev = usb.core.find(idVendor=0x05ac, idProduct=0x1220)
35
      if self.dev and generation in [0, 2] and type in [0, 1]:
36
        self.dev.set_configuration(1)
37
        self.generation = 2;
38
        self.type = 1;
39
        print("Connected to S5L8701 Bootrom DFU mode, USB version %s"  % self.dev.bcdDevice)
40
        return
41
    except usb.core.USBError: pass
864 user890104 42
    # iPod Nano 3G and iPod Classic 1G/2G/3G, Bootrom DFU
239 theseven 43
    try:
864 user890104 44
      self.dev = usb.core.find(idVendor=0x05ac, idProduct=0x1223)
45
      if self.dev and generation in [0, 3] and type in [0, 1]:
239 theseven 46
        self.dev.set_configuration(1)
864 user890104 47
        self.generation = 3;
48
        self.type = 1;
49
        print("Connected to S5L8702 Bootrom DFU mode, USB version %s"  % self.dev.bcdDevice)
239 theseven 50
        return
51
    except usb.core.USBError: pass
864 user890104 52
    # iPod Nano 3G, Bootrom DFU
239 theseven 53
    try:
864 user890104 54
      self.dev = usb.core.find(idVendor=0x05ac, idProduct=0x1224)
239 theseven 55
      if self.dev and generation in [0, 3] and type in [0, 1]:
56
        self.dev.set_configuration(1)
57
        self.generation = 3;
58
        self.type = 1;
59
        print("Connected to S5L8702 Bootrom DFU mode, USB version %s"  % self.dev.bcdDevice)
60
        return
61
    except usb.core.USBError: pass
864 user890104 62
    # iPod Nano 4G, Bootrom DFU
239 theseven 63
    try:
864 user890104 64
      self.dev = usb.core.find(idVendor=0x05ac, idProduct=0x1225)
65
      if self.dev and generation in [0, 4] and type in [0, 1]:
66
        self.dev.set_configuration(1)
67
        self.generation = 4;
68
        self.type = 1;
69
        print("Connected to S5L8720 Bootrom DFU mode, USB version %s"  % self.dev.bcdDevice)
70
        return
71
    except usb.core.USBError: pass
72
    # iPod Nano 5G, Bootrom DFU
73
    try:
74
      self.dev = usb.core.find(idVendor=0x05ac, idProduct=0x1231)
75
      if self.dev and generation in [0, 5] and type in [0, 1]:
76
        self.dev.set_configuration(1)
77
        self.generation = 5;
78
        self.type = 1;
79
        print("Connected to S5L8730 Bootrom DFU mode, USB version %s"  % self.dev.bcdDevice)
80
        return
81
    except usb.core.USBError: pass
82
    # iPod Nano 6G, Bootrom DFU
83
    try:
84
      self.dev = usb.core.find(idVendor=0x05ac, idProduct=0x1225)
85
      if self.dev and generation in [0, 6] and type in [0, 1]:
86
        self.dev.set_configuration(1)
87
        self.generation = 6;
88
        self.type = 1;
89
        print("Connected to S5L8723 Bootrom DFU mode, USB version %s"  % self.dev.bcdDevice)
90
        return
91
    except usb.core.USBError: pass
92
 
93
    # iPod Nano 2G, NOR DFU
94
    try:
95
      self.dev = usb.core.find(idVendor=0x05ac, idProduct=0x1240)
96
      if self.dev and generation in [0, 2] and type in [0, 2]:
97
        self.dev.set_configuration(1)
98
        self.generation = 2;
99
        self.type = 2;
100
        print("Connected to iPod Nano 2G NOR DFU mode, USB version %s"  % self.dev.bcdDevice)
101
        return
102
    except usb.core.USBError: pass
103
    # iPod Nano 3G, WTF
104
    try:
239 theseven 105
      self.dev = usb.core.find(idVendor=0x05ac, idProduct=0x1242)
106
      if self.dev and generation in [0, 3] and type in [0, 2]:
107
        self.dev.set_configuration(1)
108
        self.generation = 3;
109
        self.type = 2;
110
        print("Connected to iPod Nano 3G WTF mode, USB version %s"  % self.dev.bcdDevice)
111
        return
112
    except usb.core.USBError: pass
864 user890104 113
    # iPod Classic 1G, WTF
239 theseven 114
    try:
805 theseven 115
      self.dev = usb.core.find(idVendor=0x05ac, idProduct=0x1241)
116
      if self.dev and generation in [0, 11] and type in [0, 2]:
117
        self.dev.set_configuration(1)
118
        self.generation = 11;
119
        self.type = 2;
120
        print("Connected to iPod Classic 1G WTF mode, USB version %s"  % self.dev.bcdDevice)
121
        return
809 user890104 122
    except usb.core.USBError: pass
864 user890104 123
    # iPod Classic 2G, WTF
805 theseven 124
    try:
125
      self.dev = usb.core.find(idVendor=0x05ac, idProduct=0x1245)
126
      if self.dev and generation in [0, 12] and type in [0, 2]:
127
        self.dev.set_configuration(1)
128
        self.generation = 12;
129
        self.type = 2;
130
        print("Connected to iPod Classic 2G WTF mode, USB version %s"  % self.dev.bcdDevice)
131
        return
809 user890104 132
    except usb.core.USBError: pass
864 user890104 133
    # iPod Classic 3G, WTF
805 theseven 134
    try:
135
      self.dev = usb.core.find(idVendor=0x05ac, idProduct=0x1247)
136
      if self.dev and generation in [0, 13] and type in [0, 2]:
137
        self.dev.set_configuration(1)
138
        self.generation = 13;
139
        self.type = 2;
140
        print("Connected to iPod Classic 3G WTF mode, USB version %s"  % self.dev.bcdDevice)
141
        return
142
    except usb.core.USBError: pass
864 user890104 143
    # iPod Nano 4G, WTF
805 theseven 144
    try:
864 user890104 145
      self.dev = usb.core.find(idVendor=0x05ac, idProduct=0x1243)
146
      if self.dev and generation in [0, 4] and type in [0, 2]:
239 theseven 147
        self.dev.set_configuration(1)
148
        self.generation = 4;
864 user890104 149
        self.type = 2;
150
        print("Connected to iPod Nano 4G WTF mode, USB version %s"  % self.dev.bcdDevice)
239 theseven 151
        return
152
    except usb.core.USBError: pass
864 user890104 153
    # iPod Nano 5G, WTF
239 theseven 154
    try:
155
      self.dev = usb.core.find(idVendor=0x05ac, idProduct=0x1243)
864 user890104 156
      if self.dev and generation in [0, 5] and type in [0, 2]:
239 theseven 157
        self.dev.set_configuration(1)
864 user890104 158
        self.generation = 5;
239 theseven 159
        self.type = 2;
864 user890104 160
        print("Connected to iPod Nano 5G WTF mode, USB version %s"  % self.dev.bcdDevice)
239 theseven 161
        return
162
    except usb.core.USBError: pass
864 user890104 163
    # iPod Nano 6G, WTF
164
    try:
165
      self.dev = usb.core.find(idVendor=0x05ac, idProduct=0x1243)
166
      if self.dev and generation in [0, 6] and type in [0, 2]:
167
        self.dev.set_configuration(1)
168
        self.generation = 6;
169
        self.type = 2;
170
        print("Connected to iPod Nano 6G WTF mode, USB version %s"  % self.dev.bcdDevice)
171
        return
172
    except usb.core.USBError: pass
146 farthen 173
 
174
    raise Exception("Could not find specified DFU device (generation = %d, type = %d)" % (generation, type))
175
 
176
  @staticmethod
177
  def crc32(data):
178
    crc_table = []
179
    for i in range(256):
180
      t = i;
181
      for j in range(8):
182
        if t & 1:
183
          t = (t >> 1) ^ 0xedb88320
184
        else:
185
          t = t >> 1
186
      crc_table.append(t)
187
 
188
    crc = 0xffffffff
189
    for i in range(len(data)):
900 user890104 190
      crc = (crc >> 8) ^ crc_table[(crc ^ struct.unpack("B", data[i:i+1])[0]) & 0xff];
146 farthen 191
 
192
    return crc
193
 
194
 
195
  def getcpu(self):
196
    result = self.handle.controlMsg(0xa1, 0xff, 0x3f, 2, 0, 100)
197
    return struct.pack("%dB" % len(result), *result)
198
 
199
 
200
  def upload(self, data, exploit = 0):
201
    if exploit == 1 and self.generation == 2 and self.type == 1:
789 theseven 202
      data = f.read().ljust(0x200f0, b"\0") \
203
           + b"\xb8\x48\x02\x22\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" \
204
           + b"\0\0\0\x22\0\0\0\x22\0\0\0\x22\0\0\0\x22" \
205
           + b"\0\0\0\x22\0\0\0\x22\0\0\0\x22\0\0\0\x22" \
206
           + b"\0\0\0\x22\0\0\0\x22\0\0\0\x22\0\0\0\x22" \
207
           + b"\0\0\0\x22\0\0\0\x22\0\0\0\x22\0\0\0\x22" \
208
           + b"\0\0\0\x22\0\0\0\x22\0\0\0\x22\0\0\0\x22" \
209
           + b"\0\0\0\x22\0\0\0\x22\0\0\0\x22\0\0\0\x22" \
210
           + b"\0\0\0\x22\0\0\0\x22\0\0\0\x22\0\0\0\x22" \
211
           + b"\0\0\0\x22\0\0\0\x22\0\0\0\x22\0\0\0\x22"
146 farthen 212
 
213
    data = data + struct.pack("<I", self.crc32(data))
214
 
215
    sys.stdout.write("Upload: .")
216
    sys.stdout.flush()
217
    for index in range((len(data) + 2047) // 2048):
218
      self.dev.ctrl_transfer(0x21, 1, index, 0, data[2048 * index : 2048 * (index + 1)],   100)
219
      result = (0, 0, 0, 0, 0, 0)
220
      while result[4] != 0x05:
221
        result = self.dev.ctrl_transfer(0xa1, 3, 0, 0, 6, 100)
222
      sys.stdout.write(".")
223
      sys.stdout.flush()
224
 
225
    self.dev.ctrl_transfer(0x21, 1, index, 0, "",  100)
226
    result = (0, 0, 0, 0, 0, 0)
227
    index = 0
228
    try:
229
      while result[4] != 0x02 and index < 1000:
230
        result = self.dev.ctrl_transfer(0xa1, 3, 0, 0, 6, 100)
231
        index = index + 1
232
    except:
233
      pass
234
 
235
    if (exploit == 0 and (index == 1000 or result[4] == 0x02)) or \
236
       (exploit == 1 and (index == 1000 or result[4] != 0x04)):
237
      print(" failed: %X / %X" % (result[4], result[0]))
238
      raise Exception("DFU upload failed! (%X / %X)" % (result[4], result[0]))
239
    else:
240
      print(" done")
241
 
242
 
243
  def uploadfile(self, file, exploit = 0):
244
    f = open(file, "rb")
245
    data = f.read()
246
    f.close()
247
    self.upload(data, exploit)