├── README.md ├── dbltool.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── posixninja.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── posixninja.xcuserdatad │ ├── xcdebugger │ └── Breakpoints.xcbkptlist │ └── xcschemes │ ├── dbltool.xcscheme │ └── xcschememanagement.plist └── dbltool ├── Package └── DEBIAN │ └── control ├── PackageVersion.plist ├── dbl.h ├── dbl.mm ├── main.mm ├── sock.cpp ├── sock.h ├── usb.h ├── usb.mm ├── util.h └── util.mm /README.md: -------------------------------------------------------------------------------- 1 | iOS Baseband Tools 2 | 3 | https://github.com/posixninja/BBTool 4 | https://github.com/posixninja/DLOADTool 5 | https://github.com/posixninja/DBLTool 6 | https://github.com/posixninja/iOSUSBEnum 7 | 8 | Description: 9 | 10 | These are just some little tools I made for interfacing with the Qualcomm baseband in iOS. They should work on iPhone4s and iPhone5 (although I've only tested them on iPhone4s CDMA). 11 | 12 | Setup: 13 | 14 | To build these tools you need Xcode with the iOS SDK, and iOSOpenDev installed and setup (http://www.iosopendev.com/). In the terminal switch the each directory and type "xcodebuild" to build the tool. 15 | 16 | Usage: 17 | 18 | Before you can use any of the tools (other than iOSUSBEnum) you should first upload CommCenter so it won't interfere. First SSH onto the device and type the following command to unload CommCenter. 19 | 20 | launchctl unload /System/Library/LaunchDaemons/com.apple.CommCenter.plist 21 | 22 | Once CommCenter is uploaded you can type "iosusbenum" to verify that the Qualcomm baseband is no longer showing up in the device list. Since the baseband no longer has any internal flash to store the baseband firmware, all the firmware is located on the device filesystem. To access these firmware files you first need to unzip them. To do this type 23 | 24 | (for 6.x) 25 | cd /usr/local/standalone/firmware/Baseband/Trek 26 | unzip Trek-personalized.zip 27 | 28 | (for 5.x) 29 | cd /usr/standalone/firmware/Trek 30 | unzip Trek-personalized.zip 31 | 32 | After the firmware has been unzipped you'll see a few different files. The important ones are bbticket.der, dbl.mbn, osbl.mbn, and amss.mbn. Next you need to use bbtool to tell the device to enter DLOAD mode (basically baseband's bootrom or DFU mode). Type 33 | 34 | bbtool enter-dload 35 | 36 | You can then verify the device has entered DLOAD mode by using "iosusbenum" once again, you should see something like this. 37 | 38 | Device Name: QHSUSB_DLOAD 39 | Vendor ID: 0x5c6 40 | Product ID: 0x9008 41 | Version: 0x0 42 | Location: 0x1200000 43 | Configuration: 0 44 | Length: 0x9 45 | Descriptor Type: 0x2 46 | Total Length: 0x20 47 | Num Interfaces: 0x1 48 | Configuration Value: 0x1 49 | Configuration: 0x0 50 | Attributes: 0x80 51 | Max Power: 0x1 52 | Interface 53 | Length: 0x9 54 | Descriptor Type: 0x4 55 | Interface Number: 0x0 56 | Alternate Setting: 0x0 57 | Num Endpoints: 0x2 58 | Interface Class: Vendor Specific 59 | Interface SubClass: 0xff 60 | Interface Protocol: 0xff 61 | Endpoint 62 | Length: 0x7 63 | Descriptor Type: 0x5 64 | Endpoint Address: 0x81 65 | Attributes: 0x2 66 | Transfer Type: Bulk 67 | Max Packet Size: 0x200 68 | Interval: 0x0 69 | Endpoint 70 | Length: 0x7 71 | Descriptor Type: 0x5 72 | Endpoint Address: 0x1 73 | Attributes: 0x2 74 | Transfer Type: Bulk 75 | Max Packet Size: 0x200 76 | Interval: 0x0 77 | 78 | Once you've verified the baseband is in DLOAD mode you can then just DLOADTool to boot the device into DBL (or SAH) mode. Depending on where your baseband firmware files are at just send the following command. 79 | 80 | dloadtool -f /usr/local/standalone/firmware/Baseband/Trek/dbl.mbn 81 | 82 | You should see a bunch of send and recv messages followed by "Closing Interface". Now the device should be in DBL mode. You can verify this by using "iosusbenum" once again. You should see output that looks similar to 83 | 84 | Device Name: Qualcomm CDMA Technologies MSM 85 | Vendor ID: 0x5c6 86 | Product ID: 0x900e 87 | Version: 0x0 88 | Location: 0x1200000 89 | Configuration: 0 90 | Length: 0x9 91 | Descriptor Type: 0x2 92 | Total Length: 0x20 93 | Num Interfaces: 0x1 94 | Configuration Value: 0x1 95 | Configuration: 0x1 96 | Attributes: 0xe0 97 | Max Power: 0x32 98 | Interface 99 | Length: 0x9 100 | Descriptor Type: 0x4 101 | Interface Number: 0x0 102 | Alternate Setting: 0x0 103 | Num Endpoints: 0x2 104 | Interface Class: Vendor Specific 105 | Interface SubClass: 0xff 106 | Interface Protocol: 0xff 107 | Endpoint 108 | Length: 0x7 109 | Descriptor Type: 0x5 110 | Endpoint Address: 0x81 111 | Attributes: 0x2 112 | Transfer Type: Bulk 113 | Max Packet Size: 0x200 114 | Interval: 0x20 115 | Endpoint 116 | Length: 0x7 117 | Descriptor Type: 0x5 118 | Endpoint Address: 0x1 119 | Attributes: 0x2 120 | Transfer Type: Bulk 121 | Max Packet Size: 0x200 122 | Interval: 0x20 123 | 124 | Now that the device is in DBL mode you can use DBLTool to continue to boot the baseband up to it's normal operating mode. To do this you must pass the path to bbticket, osbl, and amss into DBLTool using the following command. 125 | 126 | dbltool -b /usr/local/standalone/firmware/Baseband/Trek/bbticket.der -o /usr/local/standalone/firmware/Baseband/Trek/osbl.mbn -a /usr/local/standalone/firmware/Baseband/Trek/amss.mbn 127 | 128 | You should see a bunch of send and recvs once again followed by "Closing Interface". AMSS usually takes a little while to load, but after about 10-20 seconds, you can verify the baseband has fully booted up without the help of CommCenter by using "iosusbenum" once again. There are a bunch of interfaces in AMSS mode, but you should get output similar to the following. 129 | 130 | Device Name: Qualcomm CDMA Technologies MSM 131 | Vendor ID: 0x5c6 132 | Product ID: 0x9001 133 | Version: 0x0 134 | Location: 0x1200000 135 | Configuration: 0 136 | Length: 0x9 137 | Descriptor Type: 0x2 138 | Total Length: 0x118 139 | Num Interfaces: 0xd 140 | Configuration Value: 0x1 141 | Configuration: 0x1 142 | Attributes: 0xe0 143 | Max Power: 0x32 144 | Interface 145 | Length: 0x9 146 | Descriptor Type: 0x4 147 | Interface Number: 0x0 148 | Alternate Setting: 0x0 149 | Num Endpoints: 0x2 150 | Interface Class: Vendor Specific 151 | Interface SubClass: 0xff 152 | Interface Protocol: 0xff 153 | Endpoint 154 | Length: 0x7 155 | Descriptor Type: 0x5 156 | Endpoint Address: 0x81 157 | Attributes: 0x2 158 | Transfer Type: Bulk 159 | Max Packet Size: 0x200 160 | Interval: 0x20 161 | Endpoint 162 | Length: 0x7 163 | Descriptor Type: 0x5 164 | Endpoint Address: 0x1 165 | Attributes: 0x2 166 | Transfer Type: Bulk 167 | Max Packet Size: 0x200 168 | Interval: 0x20 169 | Interface 170 | Length: 0x9 171 | Descriptor Type: 0x4 172 | Interface Number: 0x1 173 | Alternate Setting: 0x0 174 | Num Endpoints: 0x2 175 | Interface Class: Vendor Specific 176 | Interface SubClass: 0xff 177 | Interface Protocol: 0xff 178 | Endpoint 179 | Length: 0x7 180 | Descriptor Type: 0x5 181 | Endpoint Address: 0x82 182 | Attributes: 0x2 183 | Transfer Type: Bulk 184 | Max Packet Size: 0x200 185 | Interval: 0x20 186 | Endpoint 187 | Length: 0x7 188 | Descriptor Type: 0x5 189 | Endpoint Address: 0x2 190 | Attributes: 0x2 191 | Transfer Type: Bulk 192 | Max Packet Size: 0x200 193 | Interval: 0x20 194 | Interface 195 | Length: 0x9 196 | Descriptor Type: 0x4 197 | Interface Number: 0x2 198 | Alternate Setting: 0x0 199 | Num Endpoints: 0x3 200 | Interface Class: Vendor Specific 201 | Interface SubClass: 0xff 202 | Interface Protocol: 0xff 203 | Endpoint 204 | Length: 0x7 205 | Descriptor Type: 0x5 206 | Endpoint Address: 0x83 207 | Attributes: 0x3 208 | Transfer Type: Interrupt 209 | Max Packet Size: 0x40 210 | Interval: 0x5 211 | Endpoint 212 | Length: 0x7 213 | Descriptor Type: 0x5 214 | Endpoint Address: 0x84 215 | Attributes: 0x2 216 | Transfer Type: Bulk 217 | Max Packet Size: 0x200 218 | Interval: 0x20 219 | Endpoint 220 | Length: 0x7 221 | Descriptor Type: 0x5 222 | Endpoint Address: 0x3 223 | Attributes: 0x2 224 | Transfer Type: Bulk 225 | Max Packet Size: 0x200 226 | Interval: 0x20 227 | Interface 228 | Length: 0x9 229 | Descriptor Type: 0x4 230 | Interface Number: 0x3 231 | Alternate Setting: 0x0 232 | Num Endpoints: 0x1 233 | Interface Class: Vendor Specific 234 | Interface SubClass: 0xff 235 | Interface Protocol: 0xff 236 | Endpoint 237 | Length: 0x7 238 | Descriptor Type: 0x5 239 | Endpoint Address: 0x85 240 | Attributes: 0x3 241 | Transfer Type: Interrupt 242 | Max Packet Size: 0x40 243 | Interval: 0x5 244 | Interface 245 | Length: 0x9 246 | Descriptor Type: 0x4 247 | Interface Number: 0x4 248 | Alternate Setting: 0x0 249 | Num Endpoints: 0x2 250 | Interface Class: Communication Data 251 | Interface SubClass: 0x0 252 | Interface Protocol: 0x0 253 | Endpoint 254 | Length: 0x7 255 | Descriptor Type: 0x5 256 | Endpoint Address: 0x86 257 | Attributes: 0x2 258 | Transfer Type: Bulk 259 | Max Packet Size: 0x200 260 | Interval: 0x20 261 | Endpoint 262 | Length: 0x7 263 | Descriptor Type: 0x5 264 | Endpoint Address: 0x4 265 | Attributes: 0x2 266 | Transfer Type: Bulk 267 | Max Packet Size: 0x200 268 | Interval: 0x20 269 | Interface 270 | Length: 0x9 271 | Descriptor Type: 0x4 272 | Interface Number: 0x5 273 | Alternate Setting: 0x0 274 | Num Endpoints: 0x1 275 | Interface Class: Vendor Specific 276 | Interface SubClass: 0xff 277 | Interface Protocol: 0xff 278 | Endpoint 279 | Length: 0x7 280 | Descriptor Type: 0x5 281 | Endpoint Address: 0x87 282 | Attributes: 0x3 283 | Transfer Type: Interrupt 284 | Max Packet Size: 0x40 285 | Interval: 0x5 286 | Interface 287 | Length: 0x9 288 | Descriptor Type: 0x4 289 | Interface Number: 0x6 290 | Alternate Setting: 0x0 291 | Num Endpoints: 0x2 292 | Interface Class: Communication Data 293 | Interface SubClass: 0x0 294 | Interface Protocol: 0x0 295 | Endpoint 296 | Length: 0x7 297 | Descriptor Type: 0x5 298 | Endpoint Address: 0x88 299 | Attributes: 0x2 300 | Transfer Type: Bulk 301 | Max Packet Size: 0x200 302 | Interval: 0x20 303 | Endpoint 304 | Length: 0x7 305 | Descriptor Type: 0x5 306 | Endpoint Address: 0x5 307 | Attributes: 0x2 308 | Transfer Type: Bulk 309 | Max Packet Size: 0x200 310 | Interval: 0x20 311 | Interface 312 | Length: 0x9 313 | Descriptor Type: 0x4 314 | Interface Number: 0x7 315 | Alternate Setting: 0x0 316 | Num Endpoints: 0x1 317 | Interface Class: Vendor Specific 318 | Interface SubClass: 0xff 319 | Interface Protocol: 0xff 320 | Endpoint 321 | Length: 0x7 322 | Descriptor Type: 0x5 323 | Endpoint Address: 0x89 324 | Attributes: 0x3 325 | Transfer Type: Interrupt 326 | Max Packet Size: 0x40 327 | Interval: 0x5 328 | Interface 329 | Length: 0x9 330 | Descriptor Type: 0x4 331 | Interface Number: 0x8 332 | Alternate Setting: 0x0 333 | Num Endpoints: 0x2 334 | Interface Class: Communication Data 335 | Interface SubClass: 0x0 336 | Interface Protocol: 0x0 337 | Endpoint 338 | Length: 0x7 339 | Descriptor Type: 0x5 340 | Endpoint Address: 0x8a 341 | Attributes: 0x2 342 | Transfer Type: Bulk 343 | Max Packet Size: 0x200 344 | Interval: 0x20 345 | Endpoint 346 | Length: 0x7 347 | Descriptor Type: 0x5 348 | Endpoint Address: 0x6 349 | Attributes: 0x2 350 | Transfer Type: Bulk 351 | Max Packet Size: 0x200 352 | Interval: 0x20 353 | Interface 354 | Length: 0x9 355 | Descriptor Type: 0x4 356 | Interface Number: 0x9 357 | Alternate Setting: 0x0 358 | Num Endpoints: 0x1 359 | Interface Class: Vendor Specific 360 | Interface SubClass: 0xff 361 | Interface Protocol: 0xff 362 | Endpoint 363 | Length: 0x7 364 | Descriptor Type: 0x5 365 | Endpoint Address: 0x8b 366 | Attributes: 0x3 367 | Transfer Type: Interrupt 368 | Max Packet Size: 0x40 369 | Interval: 0x5 370 | Interface 371 | Length: 0x9 372 | Descriptor Type: 0x4 373 | Interface Number: 0xa 374 | Alternate Setting: 0x0 375 | Num Endpoints: 0x2 376 | Interface Class: Communication Data 377 | Interface SubClass: 0x0 378 | Interface Protocol: 0x0 379 | Endpoint 380 | Length: 0x7 381 | Descriptor Type: 0x5 382 | Endpoint Address: 0x8c 383 | Attributes: 0x2 384 | Transfer Type: Bulk 385 | Max Packet Size: 0x200 386 | Interval: 0x20 387 | Endpoint 388 | Length: 0x7 389 | Descriptor Type: 0x5 390 | Endpoint Address: 0x7 391 | Attributes: 0x2 392 | Transfer Type: Bulk 393 | Max Packet Size: 0x200 394 | Interval: 0x20 395 | Interface 396 | Length: 0x9 397 | Descriptor Type: 0x4 398 | Interface Number: 0xb 399 | Alternate Setting: 0x0 400 | Num Endpoints: 0x1 401 | Interface Class: Vendor Specific 402 | Interface SubClass: 0xff 403 | Interface Protocol: 0xff 404 | Endpoint 405 | Length: 0x7 406 | Descriptor Type: 0x5 407 | Endpoint Address: 0x8d 408 | Attributes: 0x3 409 | Transfer Type: Interrupt 410 | Max Packet Size: 0x40 411 | Interval: 0x5 412 | Interface 413 | Length: 0x9 414 | Descriptor Type: 0x4 415 | Interface Number: 0xc 416 | Alternate Setting: 0x0 417 | Num Endpoints: 0x2 418 | Interface Class: Communication Data 419 | Interface SubClass: 0x0 420 | Interface Protocol: 0x0 421 | Endpoint 422 | Length: 0x7 423 | Descriptor Type: 0x5 424 | Endpoint Address: 0x8e 425 | Attributes: 0x2 426 | Transfer Type: Bulk 427 | Max Packet Size: 0x200 428 | Interval: 0x20 429 | Endpoint 430 | Length: 0x7 431 | Descriptor Type: 0x5 432 | Endpoint Address: 0x8 433 | Attributes: 0x2 434 | Transfer Type: Bulk 435 | Max Packet Size: 0x200 436 | Interval: 0x20 437 | 438 | There you have it. You've successfully used the tools to boot up the baseband without any help from CommCenter. If you want to shutdown the baseband again or if you had problems during any of the steps just use "bbtool reset" to reset the baseband and try again. I will try to finish up my QMITool and DIAGTool for sending commands to the baseband shortly as well as documenting what each interface exposed by AMSS is used for. 439 | 440 | Thanks for the interest!! 441 | @p0sixninja 442 | 443 | -------------------------------------------------------------------------------- /dbltool.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 8A5F2FD816CEF3B800E3C5C7 /* sock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A5F2FD616CEF3B800E3C5C7 /* sock.cpp */; }; 11 | 8AAD04DB16C05A0C0024FB2B /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8AAD04DA16C05A0C0024FB2B /* main.mm */; }; 12 | 8AAD04E216C05AC60024FB2B /* IOKit in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AAD04E116C05AC60024FB2B /* IOKit */; }; 13 | 8AAD04E416C05AD00024FB2B /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AAD04E316C05AD00024FB2B /* CoreFoundation.framework */; }; 14 | 8AAD04EA16C05B180024FB2B /* usb.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8AAD04E616C05B180024FB2B /* usb.mm */; }; 15 | 8AAD04EB16C05B180024FB2B /* util.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8AAD04E816C05B180024FB2B /* util.mm */; }; 16 | 8ADD3BBC16C18B2100EC1F03 /* dbl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8ADD3BBA16C18B2100EC1F03 /* dbl.mm */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | 8A5F2FD616CEF3B800E3C5C7 /* sock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sock.cpp; sourceTree = ""; }; 21 | 8A5F2FD716CEF3B800E3C5C7 /* sock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sock.h; sourceTree = ""; }; 22 | 8AAD04CD16C05A0C0024FB2B /* dbltool */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dbltool; sourceTree = BUILT_PRODUCTS_DIR; }; 23 | 8AAD04D316C05A0C0024FB2B /* control.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = control.txt; path = Package/DEBIAN/control.txt; sourceTree = ""; }; 24 | 8AAD04D416C05A0C0024FB2B /* control */ = {isa = PBXFileReference; lastKnownFileType = text; name = control; path = Package/DEBIAN/control; sourceTree = ""; }; 25 | 8AAD04D616C05A0C0024FB2B /* PackageVersion.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = PackageVersion.plist; sourceTree = ""; }; 26 | 8AAD04D916C05A0C0024FB2B /* 0xdeadfa11 */ = {isa = PBXFileReference; lastKnownFileType = text; name = 0xdeadfa11; path = Package/usr/bin/0xdeadfa11; sourceTree = ""; }; 27 | 8AAD04DA16C05A0C0024FB2B /* main.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = ""; }; 28 | 8AAD04E116C05AC60024FB2B /* IOKit */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = IOKit; path = System/Library/Frameworks/IOKit.framework/IOKit; sourceTree = SDKROOT; }; 29 | 8AAD04E316C05AD00024FB2B /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; 30 | 8AAD04E616C05B180024FB2B /* usb.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = usb.mm; sourceTree = ""; }; 31 | 8AAD04E716C05B180024FB2B /* usb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = usb.h; sourceTree = ""; }; 32 | 8AAD04E816C05B180024FB2B /* util.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = util.mm; sourceTree = ""; }; 33 | 8AAD04E916C05B180024FB2B /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = ""; }; 34 | 8ADD3BBA16C18B2100EC1F03 /* dbl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = dbl.mm; sourceTree = ""; }; 35 | 8ADD3BBB16C18B2100EC1F03 /* dbl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dbl.h; sourceTree = ""; }; 36 | /* End PBXFileReference section */ 37 | 38 | /* Begin PBXFrameworksBuildPhase section */ 39 | 8AAD04CA16C05A0C0024FB2B /* Frameworks */ = { 40 | isa = PBXFrameworksBuildPhase; 41 | buildActionMask = 2147483647; 42 | files = ( 43 | 8AAD04E416C05AD00024FB2B /* CoreFoundation.framework in Frameworks */, 44 | 8AAD04E216C05AC60024FB2B /* IOKit in Frameworks */, 45 | ); 46 | runOnlyForDeploymentPostprocessing = 0; 47 | }; 48 | /* End PBXFrameworksBuildPhase section */ 49 | 50 | /* Begin PBXGroup section */ 51 | 8AAD04C216C05A0C0024FB2B = { 52 | isa = PBXGroup; 53 | children = ( 54 | 8AAD04D016C05A0C0024FB2B /* dbltool */, 55 | 8AAD04CE16C05A0C0024FB2B /* Products */, 56 | 8AAD04E516C05AD30024FB2B /* Frameworks */, 57 | ); 58 | sourceTree = ""; 59 | }; 60 | 8AAD04CE16C05A0C0024FB2B /* Products */ = { 61 | isa = PBXGroup; 62 | children = ( 63 | 8AAD04CD16C05A0C0024FB2B /* dbltool */, 64 | ); 65 | name = Products; 66 | sourceTree = ""; 67 | }; 68 | 8AAD04D016C05A0C0024FB2B /* dbltool */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | 8A5F2FD616CEF3B800E3C5C7 /* sock.cpp */, 72 | 8A5F2FD716CEF3B800E3C5C7 /* sock.h */, 73 | 8ADD3BBA16C18B2100EC1F03 /* dbl.mm */, 74 | 8ADD3BBB16C18B2100EC1F03 /* dbl.h */, 75 | 8AAD04E616C05B180024FB2B /* usb.mm */, 76 | 8AAD04E716C05B180024FB2B /* usb.h */, 77 | 8AAD04E816C05B180024FB2B /* util.mm */, 78 | 8AAD04E916C05B180024FB2B /* util.h */, 79 | 8AAD04DA16C05A0C0024FB2B /* main.mm */, 80 | 8AAD04D116C05A0C0024FB2B /* Package */, 81 | 8AAD04D516C05A0C0024FB2B /* Supporting Files */, 82 | ); 83 | path = dbltool; 84 | sourceTree = ""; 85 | }; 86 | 8AAD04D116C05A0C0024FB2B /* Package */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 8AAD04D216C05A0C0024FB2B /* DEBIAN */, 90 | 8AAD04D716C05A0C0024FB2B /* usr */, 91 | ); 92 | name = Package; 93 | sourceTree = ""; 94 | }; 95 | 8AAD04D216C05A0C0024FB2B /* DEBIAN */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | 8AAD04D316C05A0C0024FB2B /* control.txt */, 99 | 8AAD04D416C05A0C0024FB2B /* control */, 100 | ); 101 | name = DEBIAN; 102 | sourceTree = ""; 103 | }; 104 | 8AAD04D516C05A0C0024FB2B /* Supporting Files */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 8AAD04D616C05A0C0024FB2B /* PackageVersion.plist */, 108 | ); 109 | name = "Supporting Files"; 110 | sourceTree = ""; 111 | }; 112 | 8AAD04D716C05A0C0024FB2B /* usr */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 8AAD04D816C05A0C0024FB2B /* bin */, 116 | ); 117 | name = usr; 118 | sourceTree = ""; 119 | }; 120 | 8AAD04D816C05A0C0024FB2B /* bin */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | 8AAD04D916C05A0C0024FB2B /* 0xdeadfa11 */, 124 | ); 125 | name = bin; 126 | sourceTree = ""; 127 | }; 128 | 8AAD04E516C05AD30024FB2B /* Frameworks */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | 8AAD04E316C05AD00024FB2B /* CoreFoundation.framework */, 132 | 8AAD04E116C05AC60024FB2B /* IOKit */, 133 | ); 134 | name = Frameworks; 135 | sourceTree = ""; 136 | }; 137 | /* End PBXGroup section */ 138 | 139 | /* Begin PBXNativeTarget section */ 140 | 8AAD04CC16C05A0C0024FB2B /* dbltool */ = { 141 | isa = PBXNativeTarget; 142 | buildConfigurationList = 8AAD04DE16C05A0C0024FB2B /* Build configuration list for PBXNativeTarget "dbltool" */; 143 | buildPhases = ( 144 | 8AAD04C916C05A0C0024FB2B /* Sources */, 145 | 8AAD04CA16C05A0C0024FB2B /* Frameworks */, 146 | 8AAD04CB16C05A0C0024FB2B /* ShellScript */, 147 | ); 148 | buildRules = ( 149 | ); 150 | dependencies = ( 151 | ); 152 | name = dbltool; 153 | productName = dbltool; 154 | productReference = 8AAD04CD16C05A0C0024FB2B /* dbltool */; 155 | productType = "com.apple.product-type.tool"; 156 | }; 157 | /* End PBXNativeTarget section */ 158 | 159 | /* Begin PBXProject section */ 160 | 8AAD04C416C05A0C0024FB2B /* Project object */ = { 161 | isa = PBXProject; 162 | attributes = { 163 | LastUpgradeCheck = 0450; 164 | }; 165 | buildConfigurationList = 8AAD04C716C05A0C0024FB2B /* Build configuration list for PBXProject "dbltool" */; 166 | compatibilityVersion = "Xcode 3.2"; 167 | developmentRegion = English; 168 | hasScannedForEncodings = 0; 169 | knownRegions = ( 170 | en, 171 | ); 172 | mainGroup = 8AAD04C216C05A0C0024FB2B; 173 | productRefGroup = 8AAD04CE16C05A0C0024FB2B /* Products */; 174 | projectDirPath = ""; 175 | projectRoot = ""; 176 | targets = ( 177 | 8AAD04CC16C05A0C0024FB2B /* dbltool */, 178 | ); 179 | }; 180 | /* End PBXProject section */ 181 | 182 | /* Begin PBXShellScriptBuildPhase section */ 183 | 8AAD04CB16C05A0C0024FB2B /* ShellScript */ = { 184 | isa = PBXShellScriptBuildPhase; 185 | buildActionMask = 2147483647; 186 | files = ( 187 | ); 188 | inputPaths = ( 189 | ); 190 | outputPaths = ( 191 | ); 192 | runOnlyForDeploymentPostprocessing = 0; 193 | shellPath = /bin/sh; 194 | shellScript = "/opt/iOSOpenDev/bin/iosod --xcbp"; 195 | }; 196 | /* End PBXShellScriptBuildPhase section */ 197 | 198 | /* Begin PBXSourcesBuildPhase section */ 199 | 8AAD04C916C05A0C0024FB2B /* Sources */ = { 200 | isa = PBXSourcesBuildPhase; 201 | buildActionMask = 2147483647; 202 | files = ( 203 | 8AAD04DB16C05A0C0024FB2B /* main.mm in Sources */, 204 | 8AAD04EA16C05B180024FB2B /* usb.mm in Sources */, 205 | 8AAD04EB16C05B180024FB2B /* util.mm in Sources */, 206 | 8ADD3BBC16C18B2100EC1F03 /* dbl.mm in Sources */, 207 | 8A5F2FD816CEF3B800E3C5C7 /* sock.cpp in Sources */, 208 | ); 209 | runOnlyForDeploymentPostprocessing = 0; 210 | }; 211 | /* End PBXSourcesBuildPhase section */ 212 | 213 | /* Begin XCBuildConfiguration section */ 214 | 8AAD04DC16C05A0C0024FB2B /* Debug */ = { 215 | isa = XCBuildConfiguration; 216 | buildSettings = { 217 | COPY_PHASE_STRIP = NO; 218 | EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = "*.nib *.lproj *.gch (*) .DS_Store CVS .svn .git .hg *.xcodeproj *.xcode *.pbproj *.pbxproj"; 219 | FRAMEWORK_SEARCH_PATHS = ( 220 | "$(iOSOpenDevPath)/frameworks/**", 221 | "$(SDKROOT)/System/Library/PrivateFrameworks", 222 | ); 223 | GCC_C_LANGUAGE_STANDARD = gnu99; 224 | GCC_DYNAMIC_NO_PIC = NO; 225 | GCC_OPTIMIZATION_LEVEL = 0; 226 | GCC_PREPROCESSOR_DEFINITIONS = ( 227 | "DEBUG=1", 228 | "$(inherited)", 229 | ); 230 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 231 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 232 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 233 | GCC_WARN_UNUSED_VARIABLE = YES; 234 | HEADER_SEARCH_PATHS = "$(iOSOpenDevPath)/include/**"; 235 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 236 | LIBRARY_SEARCH_PATHS = "$(iOSOpenDevPath)/lib/**"; 237 | ONLY_ACTIVE_ARCH = YES; 238 | SDKROOT = iphoneos; 239 | TARGETED_DEVICE_FAMILY = "1,2"; 240 | VALIDATE_PRODUCT = NO; 241 | iOSOpenDevPath = /opt/iOSOpenDev; 242 | }; 243 | name = Debug; 244 | }; 245 | 8AAD04DD16C05A0C0024FB2B /* Release */ = { 246 | isa = XCBuildConfiguration; 247 | buildSettings = { 248 | COPY_PHASE_STRIP = YES; 249 | EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = "*.nib *.lproj *.gch (*) .DS_Store CVS .svn .git .hg *.xcodeproj *.xcode *.pbproj *.pbxproj"; 250 | FRAMEWORK_SEARCH_PATHS = ( 251 | "$(iOSOpenDevPath)/frameworks/**", 252 | "$(SDKROOT)/System/Library/PrivateFrameworks", 253 | ); 254 | GCC_C_LANGUAGE_STANDARD = gnu99; 255 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 256 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 257 | GCC_WARN_UNUSED_VARIABLE = YES; 258 | HEADER_SEARCH_PATHS = "$(iOSOpenDevPath)/include/**"; 259 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 260 | LIBRARY_SEARCH_PATHS = "$(iOSOpenDevPath)/lib/**"; 261 | SDKROOT = iphoneos; 262 | TARGETED_DEVICE_FAMILY = "1,2"; 263 | VALIDATE_PRODUCT = YES; 264 | iOSOpenDevPath = /opt/iOSOpenDev; 265 | }; 266 | name = Release; 267 | }; 268 | 8AAD04DF16C05A0C0024FB2B /* Debug */ = { 269 | isa = XCBuildConfiguration; 270 | buildSettings = { 271 | INSTALL_PATH = /usr/bin; 272 | IPHONEOS_DEPLOYMENT_TARGET = 5.1; 273 | LIBRARY_SEARCH_PATHS = ( 274 | "$(inherited)", 275 | "\"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/IOKit.framework\"", 276 | ); 277 | PRODUCT_NAME = "$(TARGET_NAME)"; 278 | iOSOpenDevBuildPackageOnAnyBuild = NO; 279 | iOSOpenDevCopyOnBuild = NO; 280 | iOSOpenDevDevice = aphone4; 281 | iOSOpenDevInstallOnAnyBuild = NO; 282 | iOSOpenDevInstallOnProfiling = YES; 283 | iOSOpenDevRespringOnInstall = NO; 284 | iOSOpenDevUsePackageVersionPList = YES; 285 | }; 286 | name = Debug; 287 | }; 288 | 8AAD04E016C05A0C0024FB2B /* Release */ = { 289 | isa = XCBuildConfiguration; 290 | buildSettings = { 291 | INSTALL_PATH = /usr/bin; 292 | IPHONEOS_DEPLOYMENT_TARGET = 5.1; 293 | LIBRARY_SEARCH_PATHS = ( 294 | "$(inherited)", 295 | "\"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/IOKit.framework\"", 296 | ); 297 | PRODUCT_NAME = "$(TARGET_NAME)"; 298 | iOSOpenDevBuildPackageOnAnyBuild = NO; 299 | iOSOpenDevCopyOnBuild = NO; 300 | iOSOpenDevDevice = aphone4; 301 | iOSOpenDevInstallOnAnyBuild = NO; 302 | iOSOpenDevInstallOnProfiling = YES; 303 | iOSOpenDevRespringOnInstall = NO; 304 | iOSOpenDevUsePackageVersionPList = YES; 305 | }; 306 | name = Release; 307 | }; 308 | /* End XCBuildConfiguration section */ 309 | 310 | /* Begin XCConfigurationList section */ 311 | 8AAD04C716C05A0C0024FB2B /* Build configuration list for PBXProject "dbltool" */ = { 312 | isa = XCConfigurationList; 313 | buildConfigurations = ( 314 | 8AAD04DC16C05A0C0024FB2B /* Debug */, 315 | 8AAD04DD16C05A0C0024FB2B /* Release */, 316 | ); 317 | defaultConfigurationIsVisible = 0; 318 | defaultConfigurationName = Release; 319 | }; 320 | 8AAD04DE16C05A0C0024FB2B /* Build configuration list for PBXNativeTarget "dbltool" */ = { 321 | isa = XCConfigurationList; 322 | buildConfigurations = ( 323 | 8AAD04DF16C05A0C0024FB2B /* Debug */, 324 | 8AAD04E016C05A0C0024FB2B /* Release */, 325 | ); 326 | defaultConfigurationIsVisible = 0; 327 | defaultConfigurationName = Release; 328 | }; 329 | /* End XCConfigurationList section */ 330 | }; 331 | rootObject = 8AAD04C416C05A0C0024FB2B /* Project object */; 332 | } 333 | -------------------------------------------------------------------------------- /dbltool.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /dbltool.xcodeproj/project.xcworkspace/xcuserdata/posixninja.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/posixninja/DBLTool/d8156379fcd35c9d46884b5e3f0ed8829fa40cf2/dbltool.xcodeproj/project.xcworkspace/xcuserdata/posixninja.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /dbltool.xcodeproj/xcuserdata/posixninja.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 18 | 19 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /dbltool.xcodeproj/xcuserdata/posixninja.xcuserdatad/xcschemes/dbltool.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /dbltool.xcodeproj/xcuserdata/posixninja.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | dbltool.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 8AAD04CC16C05A0C0024FB2B 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /dbltool/Package/DEBIAN/control: -------------------------------------------------------------------------------- 1 | Package: com.posixninja.qmi.dbltool 2 | Name: dbltool 3 | Version: 1.0-1 4 | Description: 5 | Section: System 6 | Depends: firmware (>= 5.0) 7 | Conflicts: 8 | Replaces: 9 | Priority: optional 10 | Architecture: iphoneos-arm 11 | Author: Joshua Hill 12 | dev: 13 | Homepage: 14 | Depiction: 15 | Maintainer: 16 | Icon: 17 | 18 | -------------------------------------------------------------------------------- /dbltool/PackageVersion.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BugFix 6 | 7 | Major 8 | 1 9 | Minor 10 | 0 11 | PackageRevision 12 | 1 13 | Stage 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /dbltool/dbl.h: -------------------------------------------------------------------------------- 1 | // 2 | // dbl.h 3 | // dbltool 4 | // 5 | // Created by Joshua Hill on 2/5/13. 6 | // 7 | // 8 | 9 | #ifndef __dbltool__dbl__ 10 | #define __dbltool__dbl__ 11 | 12 | #include 13 | #include 14 | 15 | #include "usb.h" 16 | 17 | #define DBL_PARAM_REQ 0x01 18 | #define DBL_PARAM_RESP 0x02 19 | #define DBL_MEMORY_REQ 0x03 20 | #define DBL_MEMORY_RESP 0x04 21 | #define DBL_EXECUTE_REQ 0x05 22 | #define DBL_EXECUTE_RESP 0x06 23 | 24 | #define DBL_BBTICKET_REQ 0xa0 25 | #define DBL_BBTICKET_RESP 0xa1 26 | #define DBL_BBTICKET_DATA_REQ 0xa2 27 | #define DBL_BBTICKET_DATA_RESP 0xa3 28 | #define DBL_BBTICKET_RESULT 0xa4 29 | #define DBL_BBTICKET_EXECUTE_REQ 0xa5 30 | #define DBL_BBTICKET_EXECUTE_RESP 0xa6 31 | 32 | #define DBL_MEMORY_REQ_AMSS 0x02 33 | #define DBL_MEMORY_REQ_OSBL 0x0b 34 | 35 | typedef struct { 36 | unsigned int code; 37 | unsigned int size; 38 | } dbl_header_t; 39 | 40 | typedef struct { // 0x01 41 | dbl_header_t header; 42 | unsigned int unknown1; //02 00 00 00 // 0x02?? 43 | unsigned int unknown2; //01 00 00 00 // 0x01?? 44 | unsigned int unknown3; //00 40 00 00 // 0x4000?? 45 | unsigned int file; //00 01 00 00 // 0x100?? 46 | unsigned int unknown5; //02 00 00 00 // 0x02?? 47 | unsigned int unknown6; //00 00 00 00 // 0x0?? 48 | unsigned int unknown7; //00 00 00 00 // 0x0?? 49 | unsigned int unknown8; //00 00 00 00 // 0x0?? 50 | unsigned int unknown9; //00 00 00 00 // 0x0?? 51 | unsigned int unknown10; //00 00 00 00 // 0x0?? 52 | } dbl_param_req_t; 53 | 54 | typedef struct { // 0x02 55 | dbl_header_t header; 56 | unsigned int unknown1; //01 00 00 00 // 0x01?? 57 | unsigned int unknown2; //01 00 00 00 // 0x01?? 58 | unsigned int unknown3; //00 00 00 00 // 0x00?? 59 | unsigned int file; //00 01 00 00 // 0x100?? 60 | unsigned int unknown5; //00 00 00 00 // 0x0 61 | unsigned int unknown6; //00 00 00 00 // 0x0 62 | unsigned int unknown7; //00 00 00 00 // 0x0 63 | unsigned int unknown8; //00 00 00 00 // 0x0 64 | unsigned int unknown9; //00 00 00 00 // 0x0 65 | unsigned int unknown10; //00 00 00 00 // 0x0 66 | } dbl_param_resp_t; 67 | 68 | typedef struct { // 0x03 69 | dbl_header_t header; 70 | unsigned int file; 71 | unsigned int offset; 72 | unsigned int length; 73 | } dbl_memory_req_t; 74 | 75 | typedef struct { // 0x04 76 | dbl_header_t header; 77 | unsigned int file; //0b 00 00 00 // File?? 78 | unsigned int response; //00 00 00 00 79 | } dbl_memory_resp_t; 80 | 81 | typedef struct { // 0x05 82 | dbl_header_t header; 83 | } dbl_execute_req_t; 84 | 85 | typedef struct { // 0x06 86 | dbl_header_t header; 87 | unsigned int file; //00 01 00 00 // 0x100 = BBTicket, 0x0 = OSBL, 0x01 = AMSS ?? 88 | } dbl_execute_resp_t; 89 | 90 | typedef struct { // 0xa0 91 | dbl_header_t header; 92 | } dbl_bbticket_req_t; 93 | 94 | typedef struct { // 0xa1 95 | dbl_header_t header; 96 | unsigned int unknown1; 97 | } dbl_bbticket_resp_t; 98 | 99 | typedef struct { // 0xa2 100 | dbl_header_t header; 101 | unsigned int unknown1; 102 | unsigned char nonce[20]; 103 | unsigned int bbsernum; 104 | unsigned int bbchipid; 105 | } dbl_bbticket_data_req_t; 106 | 107 | typedef struct { // 0xa3 108 | dbl_header_t header; 109 | unsigned char data[0]; 110 | } dbl_bbticket_data_resp_t; 111 | 112 | typedef struct { // 0xa4 113 | dbl_header_t header; 114 | } dbl_bbticket_result_t; 115 | 116 | typedef struct { // 0xa5 117 | dbl_header_t header; 118 | 119 | unsigned int unknown1; //00 00 00 00 120 | unsigned int unknown2; //00 00 00 00 121 | unsigned int unknown3; //00 00 00 00 122 | unsigned int unknown4; //00 00 00 00 123 | unsigned int unknown5; //00 00 00 00 124 | unsigned int unknown6; //00 00 00 00 125 | unsigned int unknown7; //00 00 00 00 126 | unsigned int unknown8; //00 00 00 00 127 | unsigned int unknown9; //00 00 00 00 128 | unsigned int unknown10; //00 00 00 00 129 | unsigned int unknown11; //00 00 00 00 130 | unsigned int unknown12; //00 00 00 00 131 | unsigned int unknown13; //00 00 00 00 132 | unsigned int unknown14; //00 00 00 00 133 | unsigned int unknown15; //00 00 00 00 134 | } dbl_bbticket_execute_req_t; 135 | 136 | typedef struct { // 0xa6 137 | dbl_header_t header; 138 | unsigned int result; 139 | } dbl_bbticket_execute_resp_t; 140 | 141 | int dbl_send_params(USBInterface interface, dbl_param_req_t* request); 142 | int dbl_send_memory(USBInterface interface, dbl_memory_req_t* request, const char* osbl, const char* amss); 143 | int dbl_send_execute(USBInterface interface); 144 | int dbl_send_bbticket_params(USBInterface interface); 145 | int dbl_send_bbticket_memory(USBInterface interface, dbl_bbticket_data_req_t* request, const char* bbticket); 146 | int dbl_send_bbticket_execute(USBInterface interface); 147 | 148 | #endif /* defined(__dbltool__dbl__) */ 149 | -------------------------------------------------------------------------------- /dbltool/dbl.mm: -------------------------------------------------------------------------------- 1 | // 2 | // dbl.cpp 3 | // dbltool 4 | // 5 | // Created by Joshua Hill on 2/5/13. 6 | // 7 | // 8 | 9 | #include 10 | #include 11 | 12 | #include "dbl.h" 13 | #include "usb.h" 14 | #include "sock.h" 15 | #include "util.h" 16 | 17 | int dbl_send_params(USBInterface interface, dbl_param_req_t* request) { 18 | dbl_param_resp_t response; 19 | //02 00 00 00 // Command 20 | response.header.code = DBL_PARAM_RESP; 21 | //30 00 00 00 // Size 22 | response.header.size = sizeof(dbl_param_resp_t); 23 | //01 00 00 00 // 0x01?? 24 | response.unknown1 = 0x1; 25 | //01 00 00 00 // 0x01?? 26 | response.unknown2 = 0x1; 27 | //00 00 00 00 // 0x00?? 28 | response.unknown3 = 0x0; 29 | //00 01 00 00 // 0x100?? 30 | response.file = request->file; 31 | //00 00 00 00 // 0x0 32 | response.unknown5 = 0x0; 33 | //00 00 00 00 // 0x0 34 | response.unknown6 = 0x0; 35 | //00 00 00 00 // 0x0 36 | response.unknown7 = 0x0; 37 | //00 00 00 00 // 0x0 38 | response.unknown8 = 0x0; 39 | //00 00 00 00 // 0x0 40 | response.unknown9 = 0x0; 41 | //00 00 00 00 // 0x0 42 | response.unknown10 = 0x0; 43 | WriteBulk(interface, 2, &response, sizeof(response)); 44 | hexdump((unsigned char*) &response, sizeof(response)); 45 | return 0; 46 | } 47 | 48 | int dbl_send_memory(USBInterface interface, dbl_memory_req_t* request, const char* osbl, const char* amss) { 49 | FILE* fd = NULL; 50 | unsigned char* buffer = NULL; 51 | if(request->file == DBL_MEMORY_REQ_OSBL) { 52 | // Send OSBL data 53 | fd = fopen(osbl, "rb"); 54 | if(fd) { 55 | buffer = (unsigned char*) malloc(request->length); 56 | if(buffer) { 57 | fseek(fd, request->offset, SEEK_SET); 58 | int x = fread(buffer, 1, request->length, fd); 59 | if(x == request->length) { 60 | WriteBulk(interface, 2, buffer, x); 61 | //hexdump((unsigned char*) buffer, x); 62 | } 63 | } 64 | fclose(fd); 65 | } 66 | } else if(request->file == DBL_MEMORY_REQ_AMSS) { 67 | // Send AMSS data 68 | fd = fopen(amss, "rb"); 69 | if(fd) { 70 | buffer = (unsigned char*) malloc(request->length); 71 | if(buffer) { 72 | fseek(fd, request->offset, SEEK_SET); 73 | int x = fread(buffer, 1, request->length, fd); 74 | if(x == request->length) { 75 | WriteBulk(interface, 2, buffer, x); 76 | //hexdump((unsigned char*) buffer, x); 77 | } 78 | } 79 | fclose(fd); 80 | } 81 | } else { 82 | printf("Request from unknown file\n"); 83 | } 84 | 85 | if(buffer != NULL) free(buffer); 86 | return 0; 87 | } 88 | 89 | int dbl_send_execute(USBInterface interface) { 90 | dbl_execute_req_t response; 91 | response.header.code = DBL_EXECUTE_REQ; 92 | response.header.size = sizeof(dbl_execute_req_t); 93 | WriteBulk(interface, 2, &response, sizeof(response)); 94 | hexdump((unsigned char*) &response, sizeof(response)); 95 | return 0; 96 | } 97 | 98 | int dbl_send_bbticket_params(USBInterface interface) { 99 | dbl_bbticket_resp_t response; 100 | response.header.code = DBL_BBTICKET_RESP; 101 | response.header.size = sizeof(dbl_bbticket_resp_t); 102 | response.unknown1 = 0x0; 103 | WriteBulk(interface, 2, &response, sizeof(response)); 104 | hexdump((unsigned char*) &response, sizeof(response)); 105 | return 0; 106 | } 107 | 108 | int dbl_send_bbticket_memory(USBInterface interface, dbl_bbticket_data_req_t* request, const char* bbticket) { 109 | if(request->bbchipid != 0 && request->bbsernum != 0) { 110 | printf("Found a NONCE, please connect\n"); 111 | 112 | int x = 0; 113 | int s = sock_listen(10000); 114 | if(s > 0) { 115 | x = sock_accept_connection(s); 116 | if(x > 0) { 117 | hexdump(request->nonce, sizeof(request->nonce)); 118 | sock_send(x, request->nonce, sizeof(request->nonce)); 119 | printf("Nonce sent\n"); 120 | 121 | unsigned int size = 0; 122 | unsigned char data[0x2000]; 123 | size = sock_recv(x, data, sizeof(data)); 124 | printf("BBTicket received\n"); 125 | printf("Got data of size 0x%x\n", size); 126 | 127 | // And then upload it to the baseband 128 | dbl_bbticket_data_resp_t* response = NULL; 129 | response = (dbl_bbticket_data_resp_t*) malloc(sizeof(dbl_bbticket_data_resp_t) + size); 130 | response->header.code = DBL_BBTICKET_DATA_RESP; 131 | response->header.size = sizeof(dbl_bbticket_data_resp_t) + size; 132 | memcpy(response->data, data, size); 133 | WriteBulk(interface, 2, response, response->header.size); 134 | hexdump((unsigned char*) response, response->header.size); 135 | } 136 | } 137 | 138 | } else { 139 | unsigned int size = 0; 140 | unsigned char data[0x2000]; 141 | dbl_bbticket_data_resp_t* response = NULL; 142 | FILE* fd = fopen(bbticket, "r"); 143 | if(fd) { 144 | size = fread(data, 1, 0x2000, fd); 145 | if(size > 0) { 146 | response = (dbl_bbticket_data_resp_t*) malloc(sizeof(dbl_bbticket_data_resp_t) + size); 147 | response->header.code = DBL_BBTICKET_DATA_RESP; 148 | response->header.size = sizeof(dbl_bbticket_data_resp_t) + size; 149 | memcpy(response->data, data, size); 150 | WriteBulk(interface, 2, response, response->header.size); 151 | hexdump((unsigned char*) response, response->header.size); 152 | } 153 | fclose(fd); 154 | } 155 | } 156 | return 0; 157 | } 158 | 159 | int dbl_send_bbticket_execute(USBInterface interface) { 160 | dbl_bbticket_execute_resp_t response; 161 | response.header.code = DBL_BBTICKET_EXECUTE_RESP; 162 | response.header.size = sizeof(dbl_bbticket_execute_resp_t); 163 | response.result = 0x1; 164 | WriteBulk(interface, 2, &response, sizeof(response)); 165 | hexdump((unsigned char*) &response, sizeof(response)); 166 | return 0; 167 | } -------------------------------------------------------------------------------- /dbltool/main.mm: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // dloadtool 4 | // 5 | // Created by Joshua Hill on 1/30/13. 6 | // Copyright (c) 2013 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "usb.h" 17 | #include "util.h" 18 | #include "dbl.h" 19 | 20 | void usage() { 21 | printf("Usage: dbltool -b -o -a \n"); 22 | exit(1); 23 | } 24 | 25 | int main (int argc, const char * argv[]) { 26 | int arg = 1; 27 | UInt8 config = 0; 28 | USBDevice device; 29 | USBInterface iface; 30 | const char* osbl = NULL; 31 | const char* amss = NULL; 32 | const char* bbticket = NULL; 33 | 34 | if(argc != 7) { 35 | usage(); 36 | } 37 | 38 | while(arg < argc) { 39 | if(strcmp(argv[arg], "-b") == 0) { 40 | arg++; 41 | bbticket = argv[arg++]; 42 | continue; 43 | 44 | } else if(strcmp(argv[arg], "-o") == 0) { 45 | arg++; 46 | osbl = argv[arg++]; 47 | continue; 48 | 49 | } else if(strcmp(argv[arg], "-a") == 0) { 50 | arg++; 51 | amss = argv[arg++]; 52 | continue; 53 | 54 | } else { 55 | usage(); 56 | } 57 | } 58 | 59 | printf("Starting DBLTool\n"); 60 | if(!bbticket || !osbl || !amss) { 61 | usage(); 62 | } 63 | 64 | //Vendor ID: 0x5c6 65 | //Product ID: 0x900e 66 | device = OpenDevice(0x5c6, 0x900e); 67 | if(device) { 68 | printf("Device Opened\n"); 69 | config = SetConfiguration(device, 1); 70 | if(config == 1) { 71 | printf("Configuration %hhx set\n", config); 72 | iface = OpenInterface(device, 0, 0); 73 | if(iface) { 74 | printf("Interface Opened\n"); 75 | /* 76 | if(argc > 1) { 77 | int i = 0; 78 | int v = 0; 79 | unsigned char input[0x200]; 80 | unsigned char output[0x200]; 81 | printf("Recv:\n"); 82 | UInt32 insize = sizeof(input); 83 | ReadBulk(iface, 1, input, &insize); 84 | if(insize > 0) { 85 | hexdump(input, insize); 86 | } 87 | for(v = 1; v < argc; v++) { 88 | const char* arg = (const char*) argv[v]; 89 | unsigned int size = strlen(arg) / 2; 90 | memset(output,'\0', sizeof(output)); 91 | memset(input, '\0', sizeof(input)); 92 | for(i = 0; i < size; i++) { 93 | unsigned int byte = 0; 94 | sscanf(arg, "%02x", &byte); 95 | output[i] = byte; 96 | arg += 2; 97 | } 98 | 99 | printf("Send:\n"); 100 | if(size > 0) { 101 | WriteBulk(iface, 2, output, size); 102 | hexdump(output, size); 103 | } else { 104 | fprintf(stderr, "Invalid size\n"); 105 | } 106 | 107 | printf("Recv:\n"); 108 | UInt32 insize = sizeof(input); 109 | ReadBulk(iface, 1, input, &insize); 110 | if(insize > 0) { 111 | hexdump(input, insize); 112 | } 113 | } 114 | 115 | } else { 116 | */ 117 | int done = 0; 118 | unsigned char input[0x2000]; 119 | dbl_header_t* request = NULL; 120 | dbl_execute_resp_t* response = NULL; 121 | 122 | while(!done) { 123 | printf("Recv:\n"); 124 | memset(input, '\0', 0x2000); 125 | UInt32 insize = sizeof(input); 126 | ReadBulk(iface, 1, input, &insize); 127 | if(insize > 0) { 128 | if(insize == -1) done = 1; 129 | hexdump(input, insize); 130 | request = (dbl_header_t*) input; 131 | switch(request->code) { 132 | case DBL_PARAM_REQ: 133 | printf("Got DBL Parameter request\n"); 134 | dbl_send_params(iface, (dbl_param_req_t*) input); 135 | break; 136 | 137 | case DBL_MEMORY_REQ: 138 | printf("Got DBL Memory Request\n"); 139 | dbl_send_memory(iface, (dbl_memory_req_t*) input, osbl, amss); 140 | break; 141 | 142 | case DBL_MEMORY_RESP: 143 | printf("Got DBL Memory Response\n"); 144 | dbl_send_execute(iface); 145 | break; 146 | 147 | case DBL_EXECUTE_REQ: 148 | printf("Got DBL Execute Request\n"); 149 | break; 150 | 151 | case DBL_EXECUTE_RESP: 152 | printf("Got DBL Execute Response\n"); 153 | response = (dbl_execute_resp_t*) input; 154 | if(response->file == 0x1) done = 1; 155 | break; 156 | 157 | case DBL_BBTICKET_REQ: 158 | printf("Got BBTicket Request\n"); 159 | dbl_send_bbticket_params(iface); 160 | break; 161 | 162 | case DBL_BBTICKET_DATA_REQ: 163 | printf("Got BBTicket Data Request\n"); 164 | dbl_send_bbticket_memory(iface, (dbl_bbticket_data_req_t*) request, bbticket); 165 | break; 166 | 167 | case DBL_BBTICKET_EXECUTE_REQ: 168 | printf("Got BBTicket Execute Request\n"); 169 | dbl_send_bbticket_execute(iface); 170 | break; 171 | 172 | case DBL_BBTICKET_EXECUTE_RESP: 173 | printf("Got BBTicket Execute Response\n"); 174 | break; 175 | 176 | case DBL_BBTICKET_RESULT: 177 | printf("Got BBTicket Result\n"); 178 | dbl_send_execute(iface); 179 | break; 180 | 181 | default: 182 | printf("Got Unknown Request\n"); 183 | break; 184 | } 185 | } 186 | //} 187 | } 188 | printf("Closing Interface\n"); 189 | CloseInterface(iface); 190 | 191 | } else { 192 | fprintf(stderr, "Couldn't open device interface\n"); 193 | } 194 | } 195 | 196 | 197 | CloseDevice(device); 198 | } 199 | 200 | return 0; 201 | } 202 | 203 | -------------------------------------------------------------------------------- /dbltool/sock.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // sock.cpp 3 | // dbltool 4 | // 5 | // Created by Joshua Hill on 2/15/13. 6 | // 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #include "sock.h" 18 | #include "util.h" 19 | 20 | int sock_listen(unsigned short portnum) { 21 | int s; 22 | struct sockaddr_in sa; 23 | 24 | s = socket(AF_INET, SOCK_STREAM, 0); 25 | if(s < 0) { 26 | printf("Unable to open socket\n"); 27 | return -1; 28 | } 29 | 30 | memset(&sa, 0, sizeof(struct sockaddr_in)); 31 | sa.sin_port = htons(portnum); 32 | sa.sin_family = PF_INET; 33 | int x = bind(s, (struct sockaddr*)&sa, sizeof(struct sockaddr_in)); 34 | if(x < 0) { 35 | printf("Unable to bind to socket address\n"); 36 | close(s); 37 | return -1; 38 | } 39 | 40 | listen(s, 3); 41 | return s; 42 | } 43 | 44 | int sock_accept_connection(int sock) { 45 | int x = accept(sock, NULL, NULL); 46 | return x; 47 | } 48 | 49 | 50 | int sock_send(int sock, unsigned char* data, unsigned int size) { 51 | //hexdump(data, size); 52 | int x = send(sock, data, size, 0); 53 | return x; 54 | } 55 | 56 | int sock_recv(int sock, unsigned char* data, unsigned int size) { 57 | int x = recv(sock, data, size, 0); 58 | //hexdump(data, x); 59 | return x; 60 | } -------------------------------------------------------------------------------- /dbltool/sock.h: -------------------------------------------------------------------------------- 1 | // 2 | // sock.h 3 | // dbltool 4 | // 5 | // Created by Joshua Hill on 2/15/13. 6 | // 7 | // 8 | 9 | #ifndef __dbltool__sock__ 10 | #define __dbltool__sock__ 11 | 12 | int sock_listen(unsigned short portnum); 13 | int sock_accept_connection(int sock); 14 | int sock_send(int sock, unsigned char* data, unsigned int size); 15 | int sock_recv(int sock, unsigned char* data, unsigned int size); 16 | 17 | #endif /* defined(__dbltool__sock__) */ 18 | -------------------------------------------------------------------------------- /dbltool/usb.h: -------------------------------------------------------------------------------- 1 | // 2 | // usb.h 3 | // dloadtool 4 | // 5 | // Created by Joshua Hill on 1/31/13. 6 | // 7 | // 8 | 9 | #ifndef dloadtool_usb_h 10 | #define dloadtool_usb_h 11 | 12 | #include 13 | 14 | typedef IOUSBDeviceInterface** USBDevice; 15 | typedef IOUSBInterfaceInterface** USBInterface; 16 | 17 | void CloseDevice(USBDevice device); 18 | USBDevice OpenDevice(SInt32 vendorId, SInt32 productId); 19 | 20 | UInt8 SetConfiguration(USBDevice device, UInt8 configuration); 21 | 22 | USBInterface OpenInterface(USBDevice device, UInt8 interface, UInt8 alt_interface); 23 | void CloseInterface(USBInterface interface); 24 | 25 | int WriteBulk(USBInterface iface, UInt8 pipe, void* buf, UInt32 size); 26 | int ReadBulk(USBInterface iface, UInt8 pipe, void* buf, UInt32* size); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /dbltool/usb.mm: -------------------------------------------------------------------------------- 1 | // 2 | // usb.cpp 3 | // dloadtool 4 | // 5 | // Created by Joshua Hill on 1/31/13. 6 | // 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "usb.h" 17 | 18 | void CloseDevice(USBDevice device) { 19 | (*device)->USBDeviceClose(device); 20 | (*device)->Release(device); 21 | } 22 | 23 | USBDevice OpenDevice(SInt32 vendorId, SInt32 productId) { 24 | SInt32 score; 25 | HRESULT result; 26 | kern_return_t kr; 27 | io_service_t service; 28 | mach_port_t masterPort; 29 | IOCFPlugInInterface** plugin; 30 | IOUSBDeviceInterface** device; 31 | CFMutableDictionaryRef matchingDict; 32 | 33 | SInt32 vendor = vendorId; 34 | SInt32 product = productId; 35 | 36 | kr = IOMasterPort(MACH_PORT_NULL, &masterPort); 37 | if (kr || !masterPort) { 38 | fprintf(stderr, "Couldn’t create a master IOKit port\n"); 39 | return NULL; 40 | } 41 | 42 | matchingDict = IOServiceMatching(kIOUSBDeviceClassName); 43 | if (!matchingDict) { 44 | fprintf(stderr, "Couldn’t create a USB matching dictionary\n"); 45 | mach_port_deallocate(mach_task_self(), masterPort); 46 | return NULL; 47 | } 48 | 49 | CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorName), 50 | CFNumberCreate(kCFAllocatorDefault, 51 | kCFNumberSInt32Type, &vendor)); 52 | CFDictionarySetValue(matchingDict, CFSTR(kUSBProductName), 53 | CFNumberCreate(kCFAllocatorDefault, 54 | kCFNumberSInt32Type, &product)); 55 | 56 | service = IOServiceGetMatchingService(masterPort, matchingDict); 57 | if(!service) { 58 | fprintf(stderr, "Couldn't find matching USB service\n"); 59 | mach_port_deallocate(mach_task_self(), masterPort); 60 | return NULL; 61 | } 62 | 63 | kr = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &score); 64 | if(kr != kIOReturnSuccess) { 65 | fprintf(stderr, "Couldn't create USB device interface plugin\n"); 66 | mach_port_deallocate(mach_task_self(), masterPort); 67 | return NULL; 68 | } 69 | IOObjectRelease(service); 70 | 71 | result = (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID*) &device); 72 | (*plugin)->Release(plugin); 73 | 74 | if(result || !device) { 75 | fprintf(stderr, "Couldn't query USB device interface plugin\n"); 76 | mach_port_deallocate(mach_task_self(), masterPort); 77 | return NULL; 78 | } 79 | 80 | kr = (*device)->USBDeviceOpen(device); 81 | if(kr) { 82 | fprintf(stderr, "Couldn't open USB device\n"); 83 | mach_port_deallocate(mach_task_self(), masterPort); 84 | (*device)->Release(device); 85 | return NULL; 86 | } 87 | 88 | return device; 89 | } 90 | 91 | 92 | UInt8 SetConfiguration(USBDevice device, UInt8 configuration) { 93 | UInt8 num; 94 | UInt8 config; 95 | UInt8 current; 96 | kern_return_t kr; 97 | if(device) { 98 | kr = (*device)->GetConfiguration(device, ¤t); 99 | if(current != configuration) { 100 | kr = (*device)->GetNumberOfConfigurations(device, &num); 101 | if(configuration <= num) { 102 | (*device)->SetConfiguration(device, configuration); 103 | config = configuration; 104 | } else config = current; 105 | } else config = current; 106 | } else config = -1; 107 | 108 | return config; 109 | } 110 | 111 | 112 | USBInterface OpenInterface(USBDevice device, UInt8 interface, UInt8 alt_interface) { 113 | UInt8 alt; 114 | UInt8 current; 115 | SInt32 score; 116 | HRESULT result; 117 | kern_return_t kr; 118 | io_service_t service; 119 | io_iterator_t iterator; 120 | IOCFPlugInInterface** plugin; 121 | IOUSBInterfaceInterface** iface; 122 | IOUSBFindInterfaceRequest request; 123 | 124 | if(device) { 125 | request.bInterfaceClass = kIOUSBFindInterfaceDontCare; 126 | request.bAlternateSetting = kIOUSBFindInterfaceDontCare; 127 | request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; 128 | request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; 129 | 130 | kr = (*device)->CreateInterfaceIterator(device, &request, &iterator); 131 | if(kr != kIOReturnSuccess) { 132 | fprintf(stderr, "Couldn't create USB device interface iterator\n"); 133 | return NULL; 134 | } 135 | 136 | while((service = IOIteratorNext(iterator))) { 137 | kr = IOCreatePlugInInterfaceForService(service, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, 138 | &plugin, &score); 139 | if(kr != kIOReturnSuccess) { 140 | fprintf(stderr, "Couldn't create USB device interface plugin\n"); 141 | continue; 142 | } 143 | IOObjectRelease(service); 144 | 145 | result = (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (LPVOID*) &iface); 146 | (*plugin)->Release(plugin); 147 | 148 | if(result || !iface) { 149 | fprintf(stderr, "Couldn't query USB device interface plugin\n"); 150 | continue; 151 | } 152 | 153 | kr = (*iface)->GetInterfaceNumber(iface, ¤t); 154 | if(kr != kIOReturnSuccess) { 155 | fprintf(stderr, "Couldn't get current USB device interface\n"); 156 | (*iface)->Release(iface); 157 | continue; 158 | } 159 | 160 | if(current == interface) { 161 | kr = (*iface)->USBInterfaceOpen(iface); 162 | if(kr != kIOReturnSuccess) { 163 | fprintf(stderr, "Couldn't open USB device interface\n"); 164 | (*iface)->Release(iface); 165 | return NULL; 166 | } 167 | 168 | if(alt_interface != 0) { 169 | kr = (*iface)->GetAlternateSetting(iface, &alt); 170 | if(kr != kIOReturnSuccess) { 171 | fprintf(stderr, "Couldn't get USB device interface alternate setting\n"); 172 | (*iface)->USBInterfaceClose(iface); 173 | (*iface)->Release(iface); 174 | return NULL; 175 | } 176 | if(alt_interface == alt) { 177 | kr = (*iface)->SetAlternateInterface(iface, alt); 178 | } else { 179 | fprintf(stderr, "Invalid alternate interface\n"); 180 | } 181 | } 182 | break; 183 | } 184 | } 185 | } 186 | 187 | return iface; 188 | } 189 | 190 | void CloseInterface(USBInterface iface) { 191 | (*iface)->USBInterfaceClose(iface); 192 | (*iface)->Release(iface); 193 | } 194 | 195 | int WriteBulk(USBInterface iface, UInt8 pipe, void* buf, UInt32 size) { 196 | kern_return_t kr; 197 | if(iface) { 198 | kr = (*iface)->WritePipe(iface, pipe, buf, size); 199 | if(kr != kIOReturnSuccess) { 200 | fprintf(stderr, "Couldn't write to USB device interface\n"); 201 | return -1; 202 | } 203 | } 204 | return 0; 205 | } 206 | 207 | int ReadBulk(USBInterface iface, UInt8 pipe, void* buf, UInt32* size) { 208 | kern_return_t kr; 209 | if(iface) { 210 | kr = (*iface)->ReadPipe(iface, pipe, buf, size); 211 | if(kr != kIOReturnSuccess) { 212 | fprintf(stderr, "Couldn't read from USB device interface\n"); 213 | return -1; 214 | } 215 | } 216 | return 0; 217 | } 218 | 219 | -------------------------------------------------------------------------------- /dbltool/util.h: -------------------------------------------------------------------------------- 1 | // 2 | // util.h 3 | // usblogger 4 | // 5 | // Created by Joshua Hill on 1/29/13. 6 | // 7 | // 8 | 9 | #ifndef usblogger_util_h 10 | #define usblogger_util_h 11 | 12 | void hexdump (unsigned char *data, unsigned int amount); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /dbltool/util.mm: -------------------------------------------------------------------------------- 1 | // 2 | // util.h 3 | // dloadtool 4 | // 5 | // Created by Joshua Hill on 1/31/13. 6 | // 7 | // 8 | 9 | #ifndef __dloadtool__util__ 10 | #define __dloadtool__util__ 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | #include "util.h" 23 | 24 | void hexdump (unsigned char *data, unsigned int amount) { 25 | unsigned int dp, p; /* data pointer */ 26 | const char trans[] = 27 | "................................ !\"#$%&'()*+,-./0123456789" 28 | ":;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm" 29 | "nopqrstuvwxyz{|}~...................................." 30 | "....................................................." 31 | "........................................"; 32 | 33 | 34 | for (dp = 1; dp <= amount; dp++) { 35 | fprintf (stderr, "%02x ", data[dp-1]); 36 | if ((dp % 8) == 0) 37 | fprintf (stderr, " "); 38 | if ((dp % 16) == 0) { 39 | fprintf (stderr, "| "); 40 | p = dp; 41 | for (dp -= 16; dp < p; dp++) 42 | fprintf (stderr, "%c", trans[data[dp]]); 43 | fflush (stderr); 44 | fprintf (stderr, "\n"); 45 | } 46 | fflush (stderr); 47 | } 48 | // tail 49 | if ((amount % 16) != 0) { 50 | p = dp = 16 - (amount % 16); 51 | for (dp = p; dp > 0; dp--) { 52 | fprintf (stderr, " "); 53 | if (((dp % 8) == 0) && (p != 8)) 54 | fprintf (stderr, " "); 55 | fflush (stderr); 56 | } 57 | fprintf (stderr, " | "); 58 | for (dp = (amount - (16 - p)); dp < amount; dp++) 59 | fprintf (stderr, "%c", trans[data[dp]]); 60 | fflush (stderr); 61 | } 62 | fprintf (stderr, "\n"); 63 | 64 | return; 65 | } 66 | 67 | #endif /* defined(__dloadtool__util__) */ 68 | --------------------------------------------------------------------------------