unit UnitE1; interface uses Windows, SysUtils, Graphics, Controls, Classes, Forms, UsbMain, HexUtils, UnitMisc, Masks, Boots, UnitAndrey, UnitPavel, Unit1, uTokens; function ISIHeaderTransId():byte; function ISIHeaderMsgBody():byte; function USBControlPacket(_Class: LongWord; Length: longword; Expected:Integer):Boolean; function BB5_USB_BootRom_GetFirstBlock:integer; function GetRAPInfo():boolean; function BB5_NormalFlashing():boolean; function BB5_Flashing():boolean; function cntrel():Boolean; function BB5_DeadFlashing(mode:integer):boolean; procedure BB5_ExtractCertData (core:string; needSert:string; CertData:TMemoryStream; Result:boolean; ape : boolean); procedure BB5_ExtractBlockOfRAWLoader(core: string;RAWBlock:TMemoryStream; var Result:boolean); procedure BB5_ExtractRAWLoader(RAWBlock, RAWLoader:TMemoryStream; Result:boolean); function BB5_SendADLLoader(UAgent:TMemoryStream):Boolean; function CheckADLLoader:boolean; function GetLoaderCRC(Buf:Pointer; BufLen: integer): Word;//Функция расчета CHK UPDAPP function BB5restart2ndproto():boolean; function BB5_ADL_RestartMCU(mode: byte):boolean; function BB5_EraseFile(core: string):boolean; function BB5_EraseArea(Start, arStop: LongInt; FlashCfg, Byte1, Byte2, Byte3:byte):boolean; function BB5_EraseAreaSmallBlock(Start, arStop: LongInt; FlashCfg,Byte1,Byte2,Byte3:byte):boolean; function BB5_EraseSegment(startSegment, stopSegment:LongInt; FlashCfg, Byte1, Byte2, Byte3:byte):boolean; function BB5_EraseSector (startSector,EraseSectorSize:LongInt; FlashCfg, Byte1, Byte2, Byte3:byte):boolean; function BB5_WriteFile(core: string):boolean; function s40prep04 ():Boolean; // $04 byte adl flashing ( normal s40 ) function s40prep80():Boolean; function extractloader(core:string ; mode : integer):Boolean; function BB5_FlashingXSR15():boolean; function RebuildPartition(F:TMemoryStream; PLen: integer):boolean; function s60checkadl():Byte; function ADLBootInFlash():Boolean; function ADL06auth ():Boolean; function AdlRestart06 (rb:byte):Boolean; function ADL80auth ():Boolean; function OMAP1710boot () : boolean; function OMAPFlash():Boolean; function Omap1610extrboot(ASIC:string):boolean; function OMAP1610boot () : boolean; function OMAP2420boot () : boolean; function ADLAPErestart(rb:Byte):Boolean; function S40BuildCertBody(core:string):Boolean; function s4080Final():Boolean; function ExtractloaderXSRRap3Gv4(mode:integer):Boolean; function PrepareRAWloader(loader:TMemoryStream):TMemoryStream; function checkbootcode():Boolean; function RAPnewChkADL ():Boolean; function RapNewFinish():boolean; function RapNewFinishLocal():boolean; function CheckCMTboot():Boolean; function RAPUFinalizeboot(rapmode:integer):Boolean; function frameCrc(Buf:Pointer; buflen:Integer):Byte; function RapuYamaErase(core:string):Boolean; function RapuYamaWriteFile(core:string):Boolean; function BB5_FlashingXSR16():boolean; function NomandicBoot(mode:Integer):Boolean; function NomandicAPErawextract():Boolean; function PrepareApeNomandicloader(loader:Tmemorystream):TMemoryStream; function NomandicAPESendBoot():Boolean; function nomandicIniUpdServer():Boolean; function NomandicRawextract():Boolean; function PrepareCMTNomandicloader(loader:Tmemorystream):TMemoryStream; function NomandicSendBoot():Boolean; function NomandicFlprepare():Boolean; function NomandicEraseFile(core:string):Boolean; function NomandicWriteFile(core:string):Boolean; procedure BB5_ExtractAPERAWLoader(RAWBlock, RAWLoader:TMemoryStream; Result:boolean); function nomandicEndflash():Boolean; function BB5_FlashingNomadic():boolean; function cmtreadreq():Boolean; function apereadreq():Boolean; function readcertrequsb(CERT : string):string; function buildxsr16cert(DataStream : widestring; cert : string ): Boolean; function CertErase(CERT : string):Boolean; function RAPnewChkADLWCRT ():Boolean; function RAPnewChkADL2 ():Boolean; function contentExplore():Boolean; function s40flashprepare2ndstage():Boolean; function BB5_PerFlashing():boolean; function BB5_EraseCustomArea_USB(area:string):boolean; function getversion(algfile:string):string; type E = class(exception); TRAPInfoRecord = record SYSTEM_ASIC_ID : array[0..$13] of byte; EMx_ID : array[0..$03] of byte; PUBLIC_ID : array[0..$13] of byte; //5800 - 1FF0001841158B52064E64D3C3E9A7F38DC47E29 ASIC_MODE : byte; ROOT_KEY_HASH : array[0..$0f] of byte; //5800 - CAEEBB65D3C48E6DC73B49DC5063A2EE ROM_ID : array[0..$07] of byte; //5800 - 4B9B75103E691FF8 //Old version ASICID : array[0..$14] of byte; //5800 - 000000010000022600010006400C192101031103 [RAPIDO3G ver: 1.x] ROMID : array[0..$07] of byte; //5800 - 4B9B75103E691FF8 PublicID : array[0..$13] of byte; //5800 - 1FF0001841158B52064E64D3C3E9A7F38DC47E29 //for CMT BootID : array[0..$07] of byte; //6233 - 0803000002010000 PAPUBKEYSID : array[0..$13] of byte; //6233 - 2F36DDC4990FD844712A61A80C033211BD9602E3 FlashID : array[0..$0A] of byte; //6233 - 00EC2208012100000100 //for APE PAPUBKEYSHashCMT : array[0..$13] of byte; //5800 - 76A20187051C30162EE91C77AE5E6011F5F1BA61 EM1ID : DWord; //5800 - 00000295 EM2ID : DWord; //5800 - 00000B22 MODEID : Byte; //00 APErootkey : array[0..$0f] of Byte; APEFlashID : array [0..$0A] of byte; APEASICID : array [0..$03] of Byte; ALGO : array [0..$0F] of Byte; end; TBlockRec = record Block : Byte; OffSet : Dword; Size : Word; end; const BB5_EraseSectorSize: LongInt = $10000; var TransId : byte; MsgBody : byte; msgid : Byte; RAPInfo : TRAPInfoRecord; partition : Boolean; partitionstream : TMemoryStream; fltime : cardinal; adlmode : Byte; implementation uses FbusMain; function ISIHeaderTransId():byte; begin inc(TransId); //if TransId=0 then inc(TransId); Result:=TransId; end; function ISIHeaderMsgBody():byte; begin inc(MsgBody); //if MsgBody=0 then inc(MsgBody); Result:=MsgBody; end; //Get RAP Info function GetRAPInfo():boolean; var i,j : integer; Key : Byte; KeyLen : Byte; begin FillMemory(@RAPInfo.ROOT_KEY_HASH,$10,$00); FillMemory(@RAPInfo.APErootkey,$10,$00); FillMemory(@RAPInfo.FlashID,$A,$00); FillMemory(@RAPInfo.APEFlashID,$A,$00); FillMemory(@RAPInfo.PublicID,$14,$00); FillMemory(@RAPInfo.BootID,$8,$00); FillMemory(@RAPInfo.PAPUBKEYSID,$14,$00); Result:=false; i:=$10; USBBulkWritePort(@GETRoot, Length(GETRoot)); if Not USBBulkReadPort($FFFF) then exit; while i < Length(rxbuf) do begin Key :=rxbuf[i]; KeyLen:=rxbuf[i+1]-2; inc(i, 2); case Key of $01: begin for j:=$0 to $9 do RAPInfo.FlashID[j]:= rxbuf[i+j]; inc(i, KeyLen); end; $03: begin for j:=$0 to $9 do RAPInfo.APEFlashID[j]:= rxbuf[i+j]; inc(i, KeyLen); end; $04: begin // 0803000002010000 for j:=$0 to $7 do RAPInfo.BootID[j]:= rxbuf[i+j]; inc(i,$10); for j:=0 to $0F do RAPInfo.APErootkey[j]:= rxBuf[i+j]; inc(i, KeyLen-$10); end; $05: begin // 0A900018A8B54650B9C89AA40EEC5059B5762F38 inc(i, $0A); for j:=0 to $13 do RAPInfo.PublicID[j]:= rxbuf[i+j]; // BAF3A9C3DBFA8454937DB77F2B8852B1 inc(i, $14); for j:=0 to $0F do RAPInfo.ROOT_KEY_HASH[j]:= rxbuf[i+j]; inc(i, $10); // 2F36DDC4990FD844712A61A80C033211BD9602E3 for j:=0 to $13 do RAPInfo.PAPUBKEYSID[j]:= rxbuf[i+j]; inc(i, $14); Result:=True; inc(i, KeyLen-$42); end else inc(i, KeyLen); end;//End Of Case end; { ASICID : array[0..$14] of byte; //5800 - 000000010000022600010006400C192101031103 [RAPIDO3G ver: 1.x] ROMID : array[0..$07] of byte; //5800 - 4B9B75103E691FF8 PublicID : array[0..$13] of byte; //5800 - 1FF0001841158B52064E64D3C3E9A7F38DC47E29 //for CMT BootID : array[0..$07] of byte; //6233 - 0803000002010000 RootKeyHash : array[0..$0f] of byte; //5800 - CAEEBB65D3C48E6DC73B49DC5063A2EE PAPUBKEYSID : array[0..$14] of byte; //6233 - 2F36DDC4990FD844712A61A80C033211BD9602E3 //for APE PAPUBKEYSHashCMT : array[0..$13] of byte; //5800 - 76A20187051C30162EE91C77AE5E6011F5F1BA61 EM1ID : DWord; //5800 - 00000295 EM2ID : DWord; //5800 - 00000B22 MODEID : Byte; //00} {Processing file: RM-356_31.0.101_prd.core.C00 --- Press phone's POWER button or connect a CHARGER ! --- warning: Some new phones consume more power, please connect cable to USB host instead of USB hub. [ADL] Pooling for ADL device [ADL] Device found : nmwcdnsuc\Nokia USB Flashing Generic-2c024cda RAP SYSTEM ASIC ID: 000000010000022600010006400C192101031103 [RAPIDO3G ver: 1.x] RAP EM1 ID: 00000295 RAP EM2 ID: 00000B22 RAP PUBLIC ID: 1FF0001841158B52064E64D3C3E9A7F38DC47E29 RAP ASIC MODE ID: 00 RAP ROOT KEY HASH: CAEEBB65D3C48E6DC73B49DC5063A2EE RAP ROM ID: 4B9B75103E691FF8 [ADL] Flashing CMT Update Server Data, ULO: 0x3B80 bytes [ADL] Update Server code succesfully sent to phone [ADL] Flashing CMT Update Server Data, XSR: 0x2A3F45 bytes [ADL] RAP3NAND sent. [ADL] PASUBTOC sent. [ADL] UPDAPP sent. [ADL] Update Server code succesfully sent to phone [ADL] Pooling for ADL device} end; procedure BB5_ExtractCertData(core:string;needSert:string;CertData:TMemoryStream;Result:boolean; ape:boolean); var HdrLen, i, good : Integer; buf : array[0..$3FFFF] of byte; DataLen, CertLen, CertOffSet, tmp : LongInt; CertName : String; CertDone, NewCertBegin, NeedCertFound, CertDataBricked : Boolean; fs : TFileStream; apeb : byte; Begin Result:=False; // Form1._msg('Processing '+ExtractFileName(core)); try fs:=TFileStream.Create(core,fmOpenRead); fs.Seek(0, sofromBeginning); fs.Read(i,1); if i<>$B2 then begin Form1._msg('Invalid Image File'); USBClosePort; fs.Free; exit; end; fs.ReadBuffer(buf[0], 4);//Длина Flash Header HdrLen := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2)); fs.Seek(HdrLen,soFromCurrent); CertDone:=False;//Признак концовки текущей части сертификата CertDataBricked:=False;//Признак того, что в данных сертификата присутствует разметка Flash-token NewCertBegin:=False;//Признак начала нового сертификата NeedCertFound:=False;//Признак того, что искомый серт найден while ((fs.Position+$13)=fs.Size then break; fs.ReadBuffer(buf[0], $1); //если следующий байт не является началом разметки Cert-token, //значит данные искомого блока поделены на кусочки разметкой Flash-token if buf[0]<>$5D then begin //Warning: Data is splitted into bricks! CertDataBricked:=True; fs.Seek(fs.Position-1, sofromBeginning); continue; end; break;//найдено начало нового серта -> стоп end; if CertDataBricked and not NewCertBegin then CertData.CopyFrom(fs, DataLen) else //копирование при условии, что это кусочек искомого блока fs.Seek(DataLen, sofromCurrent); //пропуск, если левый кусочек end; $5D://Разметка Cert-token case ape of false: // CMT mode begin fs.ReadBuffer(buf[0], $3); fs.ReadBuffer(buf[0], buf[2]+1); DataLen := HexToInt(IntToHex(buf[37], 2)+IntToHex(buf[38], 2)+IntToHex(buf[39], 2)+IntToHex(buf[40], 2)); good:=0; for i:=$0 to $0F do if RAPInfo.ROOT_KEY_HASH[i]=buf[i] then inc(good); if good<$10 then begin //Начало сертификата не совпадает с Root-Hash, пропускаем fs.Seek(DataLen, sofromCurrent); continue; end; //Найдено начало нового сертификата, который совпадает с Root-Hash CertName:=''; for i:=$14 to $23 do if buf[i]=$00 then break else CertName:=CertName+Chr(buf[i]); tmp:=CertData.Size; //form1._msg(certname); //Сравнение имени найденного сертификата с искомым if not MatchesMask(CertName, '*'+needSert+'*') then //Имя текущего сертификата не совпадает с искомым begin //Если искомый серт уже был найден, то перед началом текущего находится концовка искомого if NeedCertFound then NewCertBegin:=True; fs.Seek(DataLen, sofromCurrent);//пропускаем найденный блок сертификата continue; end else //Найдено начало искомого серта begin NeedCertFound:=true; // Form1._msg('Cert: '+CertName+' Match with Root'); if Not NewCertBegin then //Если после найденного начала искомого серта не было найдено начало следующего, то begin CertData.CopyFrom(fs, DataLen);//копируем текущий блок CertDone:=True;// end; end; end; True : //APE mode begin fs.ReadBuffer(buf[0], $3); fs.ReadBuffer(buf[0], buf[2]+1); DataLen := HexToInt(IntToHex(buf[37], 2)+IntToHex(buf[38], 2)+IntToHex(buf[39], 2)+IntToHex(buf[40], 2)); apeb:=buf[32]; good:=0; if apeb<>$01 then begin fs.Seek(DataLen, sofromCurrent); continue; end; for i:=$0 to $0F do if RAPInfo.APERootkey[i]=buf[i] then inc(good); if good<$10 then begin //Начало сертификата не совпадает с Root-Hash, пропускаем fs.Seek(DataLen, sofromCurrent); continue; end; //Найдено начало нового сертификата, который совпадает с Root-Hash CertName:=''; for i:=$14 to $23 do if buf[i]=$00 then break else CertName:=CertName+Chr(buf[i]); tmp:=CertData.Size; //form1._msg(certname); //Сравнение имени найденного сертификата с искомым if not MatchesMask(CertName, '*'+needSert+'*') then //Имя текущего сертификата не совпадает с искомым begin //Если искомый серт уже был найден, то перед началом текущего находится концовка искомого if NeedCertFound then NewCertBegin:=True; fs.Seek(DataLen, sofromCurrent);//пропускаем найденный блок сертификата continue; end else //Найдено начало искомого серта begin NeedCertFound:=true; // Form1._msg('APE Cert: '+CertName+' Match with Root'); if Not NewCertBegin then //Если после найденного начала искомого серта не было найдено начало следующего, то begin CertData.CopyFrom(fs, DataLen);//копируем текущий блок CertDone:=True;// end; end; end; end; end;//end of case end;//end while fs.free; CertData.Seek(0, soFromBeginning); Result:=True; except begin fs.free; Result:=False; exit; end; end; end; procedure BB5_ExtractBlockOfRAWLoader(core: string;RAWBlock:TMemoryStream; var Result:boolean); var buf : array[0..$3] of byte; HdrLen, //Длина Flash-заголовка SeemCount : Dword; //Кол-во блоков в Flash-заголовке CurrSeem : Byte; //Текущий блок CurrSeemLen : Word; //Длина данных текущего блока fs : TFileStream; begin Result:=false; //Form1.lst1.items.add('RawLoaderExtract: Processing '+ExtractFileName(core)); try fs:=TFileStream.Create(core,fmOpenRead); fs.Read(buf[0] ,1); if buf[0]<>$B2 then //Заголовок / идентификатор begin Form1.lst1.items.add('RawLoaderExtract: Error extracting RAW-loader from '+ExtractFileName(core)); fs.Free; exit; end; fs.ReadBuffer(buf[0], 4);//Длина Flash-header'a HdrLen := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2)); fs.ReadBuffer(buf[0], 4);//Кол-во блоков в Flash-заголовке SeemCount := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2)); while (fs.Position$B0 then begin Form1._msg('RawLoader: Damaged data :('); fs.free; exit; end else begin fs.Seek(fs.Position-1, sofromBeginning); RAWBlock.CopyFrom(fs, CurrSeemLen); fs.free; Result:=True; exit; end; end;//End of Block F3 else begin fs.ReadBuffer(buf[0], 1); CurrSeemLen:=buf[0]; fs.Seek(CurrSeemLen, sofromcurrent); end; end;//end of Case end; fs.free; except begin fs.free; Form1._msg('RawLoader: Error extracting RAW-loader'); exit; end; end; end; procedure BB5_ExtractAPERAWLoader(RAWBlock, RAWLoader:TMemoryStream; Result:boolean); var b : Boolean; i, j, k, good : Integer; buf : array[0..$3] of byte; RootInBlock : array[0..$F] of byte; RAWLoaderBuf : array[0..$ffff] of byte; RAWHdrLen, BlockCount : DWord; PatchOffset, PatchLen : Word; BlockRec : array of TBlockRec; RAWLoaderLen, RAWLoaderOffset : Dword; SubstBlock : byte;//Блок подстановки begin Result:=false; RAWBlock.Seek(1, sofromBeginning);//Пропускаем идентификатор $B0, т.к. мы его проверили при извлечении RAWBlock.ReadBuffer(buf[0], 4);//Длина RAWBlock-header'a RAWHdrLen := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2)); RAWBlock.ReadBuffer(buf[0], 4);//Кол-во блоков в RAWBlock'е BlockCount := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2)); if (RAWBlock.Size$E4) and (buf[0]<>$E5) and (buf[0]<>$EA) then begin RAWBlock.ReadBuffer(buf[0], 1);//Длина блока BlockRec[i].Size:=buf[0]; BlockRec[i].OffSet:=RAWBlock.Position;//Начало данных блока end else begin RAWBlock.ReadBuffer(buf[0], 2);//Длина блока BlockRec[i].Size:=(buf[0]*$100)+buf[1]; BlockRec[i].OffSet:=RAWBlock.Position;//Начало данных блока end; RAWBlock.Seek(BlockRec[i].Size, sofromCurrent);//Пропускаем данные текущего блока inc(i); end; RAWLoaderOffSet:=RAWBlock.Position; RAWLoaderLen:=RAWBlock.Size-RAWLoaderOffSet; if RAWLoaderLen<=0 then //Проверка на наличие RAW-loader'а в RAW-Block'е begin Form1._msg('RawLoader not found...'); exit; end; //Копируем RAW-loader RAWLoader.CopyFrom(RAWBlock, RAWLoaderLen); // RAWLoader.SaveToFile('C:\Extract_RAW_Loader_extr_'+ExtractFileName(core)+'.bin'); //Патчинг RAW-loader'a i:=0; SubstBlock:=0; while i$10 then begin //Соответствие блоков длин/смещений и патчинговых блоков ($E4, $E5, $EA) if BlockRec[i].Block=$E2 then SubstBlock:=$E4; if BlockRec[i].Block=$E3 then SubstBlock:=$E5; if BlockRec[i].Block=$E9 then SubstBlock:=$EA; //Чтение данных из текущего блока длин/смещений //Данные о длине и смещении всегда располагаются в конце блока (последние 4 байта) RAWBlock.Seek((BlockRec[i].OffSet+BlockRec[i].Size-4), sofromBeginning); RAWBlock.ReadBuffer(PatchOffset, 2);//Чтение смещения PatchOffset:=Swap(PatchOffset); RAWBlock.ReadBuffer(PatchLen, 2);//Чтение длины патча PatchLen:=Swap(PatchLen); //Поиск патчинг-блока с RootHash, который совпадает с RAP-RootHash k:=0; b:=true; while (k$E4) and (buf[0]<>$E5) and (buf[0]<>$EA) then begin RAWBlock.ReadBuffer(buf[0], 1);//Длина блока BlockRec[i].Size:=buf[0]; BlockRec[i].OffSet:=RAWBlock.Position;//Начало данных блока end else begin RAWBlock.ReadBuffer(buf[0], 2);//Длина блока BlockRec[i].Size:=(buf[0]*$100)+buf[1]; BlockRec[i].OffSet:=RAWBlock.Position;//Начало данных блока end; RAWBlock.Seek(BlockRec[i].Size, sofromCurrent);//Пропускаем данные текущего блока inc(i); end; RAWLoaderOffSet:=RAWBlock.Position; RAWLoaderLen:=RAWBlock.Size-RAWLoaderOffSet; if RAWLoaderLen<=0 then //Проверка на наличие RAW-loader'а в RAW-Block'е begin Form1._msg('RawLoader not found...'); exit; end; //Копируем RAW-loader RAWLoader.CopyFrom(RAWBlock, RAWLoaderLen); // RAWLoader.SaveToFile('C:\Extract_RAW_Loader_extr_'+ExtractFileName(core)+'.bin'); //Патчинг RAW-loader'a i:=0; SubstBlock:=0; while i$10 then begin //Соответствие блоков длин/смещений и патчинговых блоков ($E4, $E5, $EA) if BlockRec[i].Block=$E2 then SubstBlock:=$E4; if BlockRec[i].Block=$E3 then SubstBlock:=$E5; if BlockRec[i].Block=$E9 then SubstBlock:=$EA; //Чтение данных из текущего блока длин/смещений //Данные о длине и смещении всегда располагаются в конце блока (последние 4 байта) RAWBlock.Seek((BlockRec[i].OffSet+BlockRec[i].Size-4), sofromBeginning); RAWBlock.ReadBuffer(PatchOffset, 2);//Чтение смещения PatchOffset:=Swap(PatchOffset); RAWBlock.ReadBuffer(PatchLen, 2);//Чтение длины патча PatchLen:=Swap(PatchLen); //Поиск патчинг-блока с RootHash, который совпадает с RAP-RootHash k:=0; b:=true; while (k Sending loader...'); Application.ProcessMessages; //Get Block - Х.з. зачем... Запрос 256 блока PM ???? //При прошивке 6233 и 7900 //запрос 6233 1B 00 10 23 00 06 00 15 54 42 01 00 //запрос 7390 1B 00 10 23 00 06 00 16 63 42 01 00 //ответ 6233 1B 10 00 23 00 16 15 36 54 43 00 01 07 10 00 00 00 00 00 00 00 02 00 00 00 00 00 00 //ответ 7390 1B 10 00 23 00 16 16 32 63 43 00 01 07 10 00 00 00 00 00 00 00 02 00 00 00 00 00 00 GetBlock[7]:=msgid; GetBlock[8]:=ISIHeaderTransId; GetBlock[9]:=$42; GetBlock[10]:=$01; GetBlock[11]:=$00; USBBulkWritePort(@GetBlock, Length(GetBlock)); USBBulkReadPort($FFFF); //Передача данных о размере и контрольной сумме ADL-loader'а //При прошивке 6233 и 7900 //запрос 6233 1B 00 10 6F 00 0F 00 15 55 02 00 1E 00 03 6E C0 F9 63 FF 00 00 --> Loader len: 224960, CHK: 0xF963 //запрос 6270 1B 00 10 6F 00 0F 00 15 1C 02 00 1E 00 03 B1 40 A4 C9 FF 00 00 --> Loader len: 241984, CHK: 0xA4C9 //запрос 7390 1B 00 10 6F 00 0F 00 16 64 02 00 1E 00 03 6E C0 FE 0F FF 00 00 //ответ 6233 1B 10 00 6F 00 06 15 48 55 22 00 00 //ответ 6270 1B 10 00 6F 00 06 15 48 1C 22 00 00 //ответ 7390 1B 10 00 6F 00 06 16 44 64 22 00 00 //SendADLCRC : array[0..20] of Byte = //($1B, $00, $10, $6F, $00, $0F, $00, $16, $64, $02, $00, $1E, $00, $03, $6E, $C0, $FE, $0F, $FF, $00, $00); SendADLCRC[7]:=msgid; MsgBody:=$01; SendADLCRC[8]:=ISIHeaderTransId; SendADLCRC[9]:=ISIHeaderMsgBody; //Длина UPDAPP SendADLCRC[12]:=UAgent.Size div $1000000; SendADLCRC[13]:=UAgent.Size div $10000; SendADLCRC[14]:=UAgent.Size div $100; SendADLCRC[15]:=UAgent.Size mod $100; //Чек UPDAPP SendADLCRC[16]:=CHK div $100; SendADLCRC[17]:=CHK mod $100; USBBulkWritePort(@SendADLCRC, Length(SendADLCRC)); USBBulkReadPort($FFFF); //Отправка агента по кусочкам b:=true; i:=1;//номер сообщения MsgBody:=2;//номер сообщения PktLen:=$0780;//длина отправляемого кусочка лоадера (длина как в Фениксе) Form1.pb1.Progress:=0; //ms:=TMemoryStream.Create;//для теста и сохранения текущего отправленного кусочка BufCopy(@SendADL[0], @txBuf[0], Length(SendADL)); //SendADL : array[0..15] of Byte = //($1B, $00, $10, $6F, $07, $8A, $00, $15, $56, $03, $00, $01, $00, $00, $07, $80); txBuf[6] := $00; txBuf[7] :=msgid; txBuf[9] := ISIHeaderMsgBody; Form1.pb1.maxvalue:=100; UAgent.Seek(0, sofromBeginning); Application.ProcessMessages; while (UAgent.Position+PktLen)<=UAgent.Size do begin UAgent.ReadBuffer(txBuf[16], PktLen); Word((@txBuf[4])^):=Swap(PktLen+$0A); txBuf[8] := ISIHeaderTransId; txBuf[11] := i; Word((@txBuf[14])^):=Swap(PktLen); //Только для сохранения отправляемых кусочков агента {ms.Seek(0, soFromBeginning); ms.WriteBuffer(txBuf[0], 16); ms.WriteBuffer(txBuf[16], PktLen); ms.SaveToFile('C:\ADL_Send\'+Int2Digs(i,4)+'.bin'); ms.Clear;} k:=USBBulkWritePort(@txbuf[0], (PktLen+$10)); if k<>(PktLen+$10) then begin USBClosePort; exit; end; if i=$0D then begin //данная команда присутствует в Phoenix'е - "включение подсветки дисплея" //Display3: array[0..11] of Byte = //($1B, $00, $10, $15, $00, $06, $00, $0C, $A4, $0E, $00, $00); USBBulkWritePort(@Display3, Length(Display3)); USBBulkReadPort($FFFF); end; USBBulkReadPort(16); if ((UAgent.Size-UAgent.position)$01 then begin USBClosePort; exit; end; TransId:=$5E; MsgBody:=$0A; Application.ProcessMessages; preflashread; b:=true; //RootHash for i := 0 to $0F do b:=b and (RAPInfo.ROOT_KEY_HASH[i]<>0); if Not b then begin Form1._msg('-> No RootKey Asic! Unable to continue flashing...'); exit; end; Application.ProcessMessages; Form1._msg('RAP_BOOT: ' + BufToHexStr(@RAPInfo.BootID[0], Length(RAPInfo.BootID))); Form1._msg('RAP_PUBLIC: ' + BufToHexStr(@RAPInfo.PublicID[0], Length(RAPInfo.PublicID))); Form1._msg('CMT_ROOTKEY: ' + BufToHexStr(@RAPInfo.ROOT_KEY_HASH[0], Length(RAPInfo.ROOT_KEY_HASH))); Form1._msg('RAP_PAPUBKEY: ' + BufToHexStr(@RAPInfo.PAPUBKEYSID[0], Length(RAPInfo.PAPUBKEYSID))); Application.ProcessMessages; // Тут будет чек и репак контента if (not Smart) and (image<>'') and (Form1.chkCNTe.Checked=true) then begin Form1._msg('Checking CNT sector PN<>FL'); cmtflash:=Swap(Word((@rxBuf[20])^)); cmtflash:=cmtflash Shl 16; cmtflash:=cmtflash+Swap(Word((@rxBuf[18])^)); phsec:=getcntsize(cmtflash); Form1._msg('PN CNT sector : '+inttostr(phsec)+' kb'); if phsec=64 then Application.ProcessMessages else begin cntc:=False; if FileExists(image+'_128') then begin Form1._msg('Converted content already exist, skip convert and using 128k'); image:=image+'_128'; end else begin cntc:=convertimages40(image); if cntc=true then image:=image+'_128'; end; end; end; Application.ProcessMessages; if not Form1.chkDEADMODE.Checked then begin if Form1.chkDOWNGRADE.Checked=true then begin if not downgradeprep then begin Form1._msg('-> Error on flash prepare! break, Uncheck DOWNGRADE'); Form1.SetReady; Form1._msg(''); exit; end; end; end; Application.ProcessMessages; starttime; Application.ProcessMessages; //Извлечение Update Agent UAgent:=TmemoryStream.Create; BB5_ExtractCertData(core, 'UPDAPP', UAgent, b, false); if Not b then begin UAgent.Free; Form1._msg('Error extracting Update Agent... ((('); Form1.SetReady; exit; end; if Not BB5_SendADLLoader(UAgent) then begin UAgent.Free; Form1.pb1.Progress:=0; Form1._msg('Sending UAgent Error... ((('); Form1.SetReady; exit; end else Form1._msg('Update Server code succesfully sent to phone!'); UAgent.Free; i:=0; repeat begin Sleep(100); Application.ProcessMessages; Inc(i) end; until (DevPresent=False) or ( i=200 ) or (catchdevice=$02); if i=200 then begin b:=False; Form1._msg('-> Error while restart phone - repower it and try again...'); Exit; end; Application.ProcessMessages; endtimecount; Form1._msg('TIME : Boot time : '+showtime(tmsres)); Application.ProcessMessages; b:=BB5_Flashing; Result:=b; end; function BB5_PerFlashing():boolean; var b : Boolean; i,phsec,flsec : integer; UAgent : TmemoryStream; s, needSert : String; cmtflash : DWord; cntc : Boolean; Begin Result:=false; phsec:=0; flsec:=0; if catchdevice<>$01 then begin USBClosePort; exit; end; if savepwds40=True then Form1._msg('MMC pwd backup saved'); TransId:=$5E; MsgBody:=$0A; msgid:=$1B; Application.ProcessMessages; preflashread; b:=true; //RootHash for i := 0 to $0F do b:=b and (RAPInfo.ROOT_KEY_HASH[i]<>0); if Not b then begin Form1._msg('-> No RootKey Asic! Unable to continue flashing...'); exit; end; Application.ProcessMessages; // Form1._msg('RAP_BOOT: ' + BufToHexStr(@RAPInfo.BootID[0], Length(RAPInfo.BootID))); // Form1._msg('RAP_PUBLIC: ' + BufToHexStr(@RAPInfo.PublicID[0], Length(RAPInfo.PublicID))); // Form1._msg('CMT_ROOTKEY: ' + BufToHexStr(@RAPInfo.ROOT_KEY_HASH[0], Length(RAPInfo.ROOT_KEY_HASH))); // Form1._msg('RAP_PAPUBKEY: ' + BufToHexStr(@RAPInfo.PAPUBKEYSID[0], Length(RAPInfo.PAPUBKEYSID))); Application.ProcessMessages; // Тут будет чек и репак контента Form1._msg('Checking CNT sector PN<>FL'); cmtflash:=Swap(Word((@rxBuf[20])^)); cmtflash:=cmtflash Shl 16; cmtflash:=cmtflash+Swap(Word((@rxBuf[18])^)); phsec:=getcntsize(cmtflash); Form1._msg('PN CNT sector : '+inttostr(phsec)+' kb'); if phsec=64 then Application.ProcessMessages else begin Form1.statusbar.Panels[0].Text:='Repack content, wait...'; if FileExists(image+'_128') then begin Form1._msg('Converted content already exist, skip convert and using 128k'); image:=image+'_128'; end else begin cntc:=convertimages40(image); if cntc=true then image:=image+'_128'; end; end; Application.ProcessMessages; //Извлечение Update Agent UAgent:=TmemoryStream.Create; BB5_ExtractCertData(core, 'UPDAPP', UAgent, b, false); if Not b then begin UAgent.Free; Form1._msg('Error extracting Update Agent... ((('); Form1.SetReady; exit; end; if Not BB5_SendADLLoader(UAgent) then begin UAgent.Free; Form1.pb1.Progress:=0; Form1._msg('Sending UAgent Error... ((('); Form1.SetReady; exit; end else Application.ProcessMessages; UAgent.Free; i:=0; repeat begin Sleep(100); Application.ProcessMessages; Inc(i) end; until (DevPresent=False) or ( i=200 ) or (catchdevice=$02); if i=200 then begin b:=False; Form1._msg('-> Error while restart phone - repower it and try again...'); Exit; end; Application.ProcessMessages; //Form1._msg('TIME : Boot time : '+showtime(tmsres)); Application.ProcessMessages; result:=true; end; function BB5_Flashing():boolean; var b,proto : Boolean; i,i2 : integer; rb : Byte; cntx : integer; n2way : Boolean; mcufl : Boolean; cntfl : Boolean; begin rb:=$04; n2way:=false; mcufl:=false; cntfl:=false; Application.ProcessMessages; Form1._msg('Reopening the connection...'); Application.ProcessMessages; Sleep(2000); Application.ProcessMessages; i:=30; while i>0 do begin Form1._msg('Waiting for response: '+inttostr(i)); Application.ProcessMessages; if catchdevice<>$02 then begin Application.ProcessMessages; sleep (1000); Application.ProcessMessages; if stop=True then begin // Stopping operation dostop('FLASH'); i:=0; Form1.pb1.progress:=0; end; sleep (1000); Application.ProcessMessages; end else i:=0; dec(i); end; if not DevPresent then begin Form1._msg('-> Phone not found... :('); Form1.SetBuzy; Form1.StatusBar.Panels[4].Text:=''; USBClosePort; exit; end; fltime:=0; //Phone in Flash Mode??? CheckADLUpload[7]:=msgid; CheckADLUpload[8]:=ISIHeaderTransId; CheckADLUpload[9]:=$00; i:=USBBulkWritePort(@CheckADLUpload, Length(CheckADLUpload)); if i<>12 then begin Sleep(200); Application.ProcessMessages; Form1._msg('Wait for device bootup'); i:=0; repeat begin Sleep(100); Application.ProcessMessages; Inc(i); if catchdevice=$02 then i2:=USBBulkWritePort(@CheckADLUpload, Length(CheckADLUpload)); Form1.statusbar.Panels[0].Text:='Wait phone '+IntToStr(100-i); end; until (i2=12) or (i=100); if i2<>12 then begin Form1._msg('-> Bootcode start in CMT fail ! Need flash via programming device :('); Form1.TimConChk.Interval:=2000; result:=False; Form1.statusbar.Panels[0].Text:=''; exit; end; Form1.statusbar.Panels[0].Text:=''; Application.ProcessMessages; end; USBBulkReadPort(12); if rxBuf[11]<>$04 then begin if rxBuf[11]<>$80 then begin Form1._msg('ADL Server not confirmed flashmode!'); Form1.SetReady; USBClosePort; exit; end else begin Form1._msg('ADL -> [2nd] changing...'); rb:=rxBuf[11]; end; end else rb:=rxBuf[11]; // Form1._msg(Byte2Str(rb)); Form1._msg('ADL Server confirm flashmode!'); Application.ProcessMessages; case rb of $04: begin s40prep04; end; $80: begin s40prep80; end; else begin Form1._msg('-> Error while prepare!'); Form1.setready; Exit; end; end; if stop=True then begin // Stopping operation dostop('FLASH'); i:=0; Form1.pb1.progress:=0; StuffFlashReset; result:=False; Exit; end; //Добавил для удобства кастом-прошивки Form1.statusbar.Panels[4].Text:='FLASHING'; Form1.statusbar.Panels[3].Text:='Connected'; Form1.TimConChk.Interval:=100; Application.ProcessMessages; if Form1.chkMCUen.Checked=true then begin Form1.chkMCUen.Enabled:=False; Form1._msg(' ===Flashing [MCU]==='); if not BB5_EraseFile(core) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not BB5_WriteFile(core) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('MCU Write done'); mcufl:=true; end; Application.ProcessMessages; if Form1.chkPPMe.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1._msg(' ===Flashing [PPM]==='); if not BB5_EraseFile(ppm) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not BB5_WriteFile(ppm) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('PPM Write done'); end; Application.ProcessMessages; if Form1.chkPPM1e.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1.chkPPM1e.Enabled:=False; Form1._msg(' ===Flashing [PPM2]==='); if not BB5_EraseFile(ppm1) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not BB5_WriteFile(ppm1) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('PPM Write done'); end; Application.ProcessMessages; if Form1.chkCNTe.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1.chkPPM1e.Enabled:=False; Form1.chkCNTe.Enabled:=False; Form1._msg(' ===Flashing [CNT]==='); if readset('verify','cntverify')=True then begin if Form1.chkDEADMODE.Checked=True then begin if mcufl=True then begin Application.ProcessMessages; Form1.pb1.Progress:=0; Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[1].Text:=''; Application.ProcessMessages; cntx:=checkcnt(image); Form1._msg('Checking content info...'); case cntx of 0:Form1._msg('Check Image : Content analyze failed, use direct write'); 1:cntfl:=True; 2:Form1._msg('Check Image : Content size is 128k, use direct write mode'); 3:Form1._msg('Check Image : Content size is not valid, use direct write'); 4:Form1._msg('Check Image : Content size not detected, use direct write'); end; Application.ProcessMessages; end; if cntfl=true then begin Form1._msg('Resetting phone...'); Form1.statusbar.Panels[0].Text:='Resetting... Wait...'; Application.ProcessMessages; BB5_ADL_RestartMCU(rb); i:=0; repeat Application.ProcessMessages; Sleep(150); Application.ProcessMessages; Form1.statusbar.Panels[0].Text:='Wait '+inttostr(400-i); Inc(i); until (i=400) or (catchdevice=$01); if i=400 then begin Form1._msg('Error while resetting phone, MCU start error'); Form1._msg('Looks like HW error or downgrade try...'); Form1._msg('Flashing failed on content check : CMT not run'); Form1._msg(''); Form1.statusbar.Panels[0].Text:=''; StuffFlashReset; result:=False; Exit; end else begin Application.ProcessMessages; Form1.statusbar.Panels[0].Text:='Reset done, preparing'; if not s40flashprepare2ndstage then begin Form1._msg('Error while prepearing phone, bootcode start error'); Form1._msg('Looks like HW or SW error or connection fault...'); Form1._msg('Flashing failed on content check : Bootcode not run'); Form1._msg(''); StuffFlashReset; result:=False; Exit; end else Application.ProcessMessages; end; end else Application.ProcessMessages; end; end; if not BB5_EraseFile(image) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not BB5_WriteFile(image) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('CNT Write done'); end; Application.ProcessMessages; if Form1.chkAPEe.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1.chkPPM1e.Enabled:=False; Form1.chkCNTe.Enabled:=False; Form1.chkAPEe.Enabled:=False; Form1._msg(' ===Flashing [APE]==='); if not BB5_EraseFile(ape) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not BB5_WriteFile(ape) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('APE Write done'); end; Application.ProcessMessages; if Form1.chkcnt3.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1.chkPPM1e.Enabled:=False; Form1.chkCNTe.Enabled:=False; Form1.chkAPEe.Enabled:=False; Form1.chkcnt3.Enabled:=False; Form1._msg(' ===Flashing [CNT3]==='); if not BB5_EraseFile(cnt3) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not BB5_WriteFile(cnt3) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('CNT Write done'); end; Application.ProcessMessages; Form1._msg('ADL : End flashing'); Form1._msg(''); Form1._msg('Flashing done!'); Form1._msg('Total flash time : '+showtime(fltime)); Form1._msg('Reboot phone now...'); Form1._msg(''); Application.ProcessMessages; fltime:=0; Form1.statusbar.Panels[0].Text:=''; Form1.pb1.ForeColor:=clNavy; Form1.pbsm1.ForeColor:=clNavy; Form1.pb1.MaxValue:=100; Form1.pb1.progress:=0; Form1.statusbar.Panels[1].Text:=''; Form1.TimConChk.Interval:=2000; if (Form1.chkMCUen.Checked=true) and (cntfl=false) then BB5_ADL_RestartMCU(rb) else begin case rb of $80: begin BB5_ADL_RestartMCU(rb); i:=0; repeat Sleep(500); Application.ProcessMessages; i:=i+1; until (catchdevice=$02) or (i=10); if i<>10 then begin s4080Final; BB5_ADL_RestartMCU(rb); end; end; $04: begin BB5_ADL_RestartMCU(rb); i:=0; repeat Sleep(500); Application.ProcessMessages; i:=i+1; until (catchdevice=$02) or (i=10); if i<>10 then begin BB5_ADL_RestartMCU(rb); end; Application.ProcessMessages; Sleep(500); Application.ProcessMessages; i:=0; repeat Application.ProcessMessages; Sleep(200); Inc(i); Form1.statusbar.Panels[0].Text:=IntToStr(100-i); Application.ProcessMessages; if catchdevice=$01 then i:=100 else BB5_ADL_RestartMCU(rb); until (i=100) or (catchdevice=$01); Form1.statusbar.Panels[0].Text:=''; Application.ProcessMessages; if (i=100) and (catchdevice=$02) then begin Form1._msg('Custom mode fail!'); Form1._msg('Need reflash mcu only in DEAD mode'); StuffFlashReset; result:=False; Exit; end; end; end; end; Form1.pb1.color:=clActiveBorder; if affenabled then Form1.afterFlashdo; Application.ProcessMessages; Sleep(200); Form1.TimConChk.Enabled:=true; Form1._msg('Done!'); Form1.chkPPMe.Enabled:=True; Form1.chkMCUen.Enabled:=True; Form1.chkPPM1e.Enabled:=True; Form1.chkCNTe.Enabled:=True; Form1.chkAPEe.Enabled:=True; Form1.chkcnt3.Enabled:=True; Result:=true; end;//End of Normal Mode Flashing function BB5_DeadFlashing(mode:integer):boolean; var i,j,n,k,PktLen : integer; UAgent, ms, RAWBlock, RAWLoader, PASUB : TmemoryStream; s, needSert : String; Key, KeyLen : Byte; PacketLen : Byte; BlockCount : Byte; CurrBlock : Byte; CurrBlockLen : Word; b, proto : Boolean; begin Result:=false; Form1._msg('Dead Mode is Selected'); Form1._msg('Waiting for USB device...'); Form1._msg('--- Press phone'+#39+'s power button or insert cable & charger! ---'); Application.ProcessMessages; //Захват Nokia USB ROM устройства //Nokia USB ROM b:=false; i:=0; repeat if (i=2500) and (b=false) then begin Form1._msg('-> Phone not found.. :('); result:=False; Form1.SetReady; Exit; end; Application.ProcessMessages; if stop=True then begin // Stopping operation dostop('BOOT'); result:=false; Form1.pb1.progress:=0; i:=2499; b:=false; end; if catchdevice=$02 then begin b:=true; Form1._msg('Connection opened successfully'); end; Application.ProcessMessages; Sleep(10); inc(i); Form1.statusbar.Panels[0].Text:='Wait for phone '+inttostr(2500-i); Application.ProcessMessages; until b ; Application.ProcessMessages; Form1.statusbar.Panels[0].Text:=''; Form1._msg('Waiting for communication response.'); //Sleep(50); Application.ProcessMessages; if BB5_USB_BootRom_GetFirstBlock<>$60 then begin Form1.setready; Form1._msg('-> Error answer from BootRom'); Form1._msg('-> 1. Try make battery charge'); Form1._msg('-> 2. Try insert charger, without pressing poweron'); Form1._msg('-> 3. Try change USB port, if driver hang - restart PC'); result:=False; StuffFlashReset; form1.BtnDisable; exit; end; Application.ProcessMessages; starttime; Application.ProcessMessages; Form1.statusbar.Panels[3].Text:='Connected'; //Парсинг Root Hash Application.ProcessMessages; FillMemory(@RAPInfo.Root_Key_Hash,$10,$00); FillMemory(@RAPInfo.APErootkey,$10,$00); FillMemory(@RAPInfo.FlashID,$A,$00); FillMemory(@RAPInfo.APEFlashID,$A,$00); FillMemory(@RAPInfo.PublicID,$14,$00); FillMemory(@RAPInfo.BootID,$8,$00); Application.ProcessMessages; //================================================================================================================================================================================================================================================================================ // Парсинг ответа 5800 (RM-356) на запрос BB5_USB_BootRom_GetFirstBlock // Лог MX-кея // RAP Data : // SYSTEM ASIC ID: 000000010000022600010006400C192101031103 [RAPIDO3G ver: 1.x] // EM1 ID: 00000295 // EM2 ID: 00000B22 // PUBLIC ID: 1FF0001841158B52064E64D3C3E9A7F38DC47E29 // ASIC MODE ID: 00 // ROOT KEY HASH: CAEEBB65D3C48E6DC73B49DC5063A2EE // ROM ID: 4B9B75103E691FF8 // RAPIDOv11_2nd.fg: [BB5] version: 1.30.0 revision: 0.0 size: 0x3AC0 // Supported RAP Ids: 0003192101002003, 000C192101002003, 4003192101002003, 400C192101002003, 4003192101011103, 400C192101011103, 4003192101021103, 400C192101021103, 4003192101031103, 400C192101031103, 4003192101011105, 400C192101011105, 400C192101021105, 400C192101031105 // FlashID0: 00EC 0040 - 0040 0121 [Samsung 2Gb DDP OneNAND,2 Gbits] type: ONENAND,RAP // ExtBUSC: 0000 0000 0000 0000 0000 0000 0000 0000 // ExtDEVC: FFFF 0000 - 0000 0000 // RAPIDOv11_algo.fg: [XSR 1.5] version: 1.35.0 revision: 0.0 size: 0x272B0 // Supported RAP Ids: 0003192101002003, 000C192101002003, 4003192101002003, 400C192101002003, 4003192101011103, 400C192101011103, 4003192101021103, 400C192101021103, 4003192101031103, 400C192101031103, 4003192101011105, 400C192101011105, 400C192101021105, 400C192101031105 // RAP PAPUBKEYS ID: 76A20187051C30162EE91C77AE5E6011F5F1BA61 // // Ответ на запрос B5_USB_BootRom_GetFirstBlock приходит в таком виде: // 6007011500000000010000022600010006400C1921010311030205000000029502050000000B221215001FF0 // 001841158B52064E64D3C3E9A7F38DC47E2913020000141100CAEEBB65D3C48E6DC73B49DC5063A2EE150900 // 4B9B75103E691FF8 // // Разбираем: // 60 - общая длина принятых данных ответа (переданных телефоном данных на запрос RootHash'a) // 07 - количество блоков данных в ответе // 0115 00 000000010000022600010006400C192101031103 - блок №1 ($01), его длина $15 - RAP SYSTEM ASIC ID // 0205 00 00000295 - блок №2 ($02), его длина $05 - RAP EM0 ID (ну или RAP EM1 ID - кто как считает с нуля или с единицы) // 0205 00 00000B22 - блок №3 ($02), его длина $05 - RAP EM1 ID (ну или RAP EM2 ID - кто как считает с нуля или с единицы) // 1215 00 1FF0001841158B52064E64D3C3E9A7F38DC47E29 - блок №4 ($12), его длина $15 - RAP PUBLIC ID // 1302 00 00 - блок №5 ($13), его длина $02 - RAP ASIC MODE ID // 1411 00 CAEEBB65D3C48E6DC73B49DC5063A2EE - блок №6 ($14), его длина $11 - RAP ROOT KEY HASH // 1509 00 4B9B75103E691FF8 - блок №7 ($15), его длина $09 - RAP ROM ID //================================================================================================================================================================================================================================================================================ i:=2; while i < Length(rxbuf) do begin Key :=rxbuf[i]; KeyLen:=rxbuf[i+1]; inc(i, 2); case Key of $01: begin for j:=$0 to KeyLen-1 do RAPInfo.FlashID[j]:= rxbuf[i+j]; inc(i, KeyLen); end; $12: begin // 0A900018A8B54650B9C89AA40EEC5059B5762F38 inc(i); for j:=0 to $13 do RAPInfo.PublicID[j]:= rxbuf[i+j]; inc(i, $14); end; $14: //Root Hash begin // BAF3A9C3DBFA8454937DB77F2B8852B1 inc(i); for j:=0 to $0F do RAPInfo.ROOT_KEY_HASH[j]:= rxbuf[i+j]; inc(i, $0F); end else inc(i, KeyLen); end;//End Of Case end; { Application.ProcessMessages; PacketLen :=rxbuf[0];//длина принятого пакета данных BlockCount :=rxbuf[1];//количество блоков i:=2;//текущий байт в пакете данных j:=0;//текущий номер блока while (i No RootKeyHash Asic CMT. (IMEI DAMAGED?) Unable to continue flashing'); exit; end; Application.ProcessMessages; // Form1._msg('RAP_BOOT: '+ BufToHexStr(@RAPInfo.BootID[0], Length(RAPInfo.BootID))); Form1._msg('RAP_PUB: '+ BufToHexStr(@RAPInfo.PublicID[0], Length(RAPInfo.PublicID))); Form1._msg('CMT_ROOT: '+ BufToHexStr(@RAPInfo.ROOT_KEY_HASH[0], Length(RAPInfo.ROOT_KEY_HASH))); // Form1._msg('RAP_PAPUB: '+ BufToHexStr(@RAPInfo.PAPUBKEYSID[0], Length(RAPInfo.PAPUBKEYSID))); Application.ProcessMessages; //Извлечение RAW-Block RAWBlock:=TmemoryStream.Create; BB5_ExtractBlockOfRAWLoader(core, RAWBlock, b); if Not b then begin Form1.setready; Form1._msg('Error extracting RAW-loader'); RAWBlock.Free; StuffFlashReset; exit; end; // RAWBlock.SaveToFile('C:\Extract_RAW_Loader_from_'+ExtractFileName(core)+'.bin'); //Извлечение и патчинг RAW-loader'a RAWLoader:=TmemoryStream.Create; BB5_ExtractRAWLoader(RAWBlock, RAWLoader, b); if Not b then begin Form1.setready; Form1._msg('Error Patching RAW-loader'); RAWLoader.Free; RAWBlock.Free; StuffFlashReset; exit; end; Form1._msg('PatchRAWLoader: Patched OK'); //RAWLoader.SaveToFile('C:\RAW_Cert_Patch.bin'); //RAWLoader.Clear; //Извлечение Апдейт Агента UAgent:=TmemoryStream.Create; BB5_ExtractCertData(core, 'UPDAPP', UAgent, b, false); if Not b then begin Form1.pb1.Progress:=0; Form1._msg('Error Extracting UAgent ... ((('); Form1.setready; UAgent.Free; RAWLoader.Free; RAWBlock.Free; StuffFlashReset; exit; end; //UAgent.SaveToFile('C:\Extract_UA_from_'+ExtractFileName(core)+'.bin'); //Извлечение PASUB-серта PASUB:=TmemoryStream.Create; BB5_ExtractCertData(core, 'PASUBTOC', PASUB, b, false); if Not b then begin Form1.setready; Form1._msg('Error extracting PASUB sert'); PASUB.Free; UAgent.Free; RAWLoader.Free; RAWBlock.Free; exit; end; //PASUB.SaveToFile('C:\Extract_PASUBTOC_from_'+ExtractFileName(core)+'.bin'); //ms:=TMemoryStream.Create; Form1.statusbar.Panels[4].Text:='Sending Boot'; msgid:=$10; {================================== SEND RAW LOADER ===================================} Application.processmessages; RAWLoader.Seek(0, sofrombeginning); b:=true; PktLen:=$1000; k:=1; txBuf[0]:=$40; txBuf[1]:=$57; txBuf[2]:=$01; txBuf[3]:=$00; txBuf[4]:=$00; txBuf[5]:=$00; Form1.pb1.Progress:=0; Form1.pb1.MaxValue:=100; Form1._msg('Processing RAWLOADER...'); while (RAWLoader.position Error while send data to phone!'); Form1._msg(' Check battery, connection. Try again'); result:=False; PASUB.Free; UAgent.Free; RAWLoader.Free; RAWBlock.Free; StuffFlashReset; Exit; end; Application.ProcessMessages; Form1.pb1.Progress:=(RAWLoader.Position*100) div RAWLoader.Size; end; {================================== SEND UA ===========================================} Application.processmessages; UAgent.Seek(0, sofrombeginning); b:=true; PktLen:=$1000; k:=1; txBuf[0]:=$40; txBuf[1]:=$5c; txBuf[2]:=$01; txBuf[3]:=$00; txBuf[4]:=$00; txBuf[5]:=$00; Form1.pb1.Progress:=0; Form1.pb1.MaxValue:=100; Form1._msg('Processing UPDAPP...'); while (UAgent.position Error while send data to phone!'); Form1._msg(' Check battery, connection. Try again'); result:=False; PASUB.Free; UAgent.Free; RAWLoader.Free; RAWBlock.Free; StuffFlashReset; Exit; end; Application.ProcessMessages; Form1.pb1.Progress:=(UAgent.Position*100) div UAgent.Size; end; {================================== SEND PASUBTOC = ===================================} Application.processmessages; PASUB.Seek(0, sofrombeginning); b:=true; PktLen:=$1000; k:=1; txBuf[0]:=$40; txBuf[1]:=$5D; txBuf[2]:=$01; txBuf[3]:=$00; txBuf[4]:=$00; txBuf[5]:=$00; Form1.pb1.Progress:=0; Form1.pb1.MaxValue:=100; Form1._msg('Processing PASUBTOC...'); while (PASUB.position Error while send data to phone!'); Form1._msg(' Check battery, connection. Try again'); result:=False; PASUB.Free; UAgent.Free; RAWLoader.Free; RAWBlock.Free; StuffFlashReset; Exit; end; Application.ProcessMessages; Form1.pb1.Progress:=(PASUB.Position*100) div PASUB.Size; end; {======================================================================================} PASUB.Free; UAgent.Free; RAWLoader.Free; RAWBlock.Free; Application.ProcessMessages; form1.pb1.progress:=0; Application.ProcessMessages; endtimecount; form1._msg('TIME : Boot time : '+showtime(tmsres)); Application.ProcessMessages; i:=0; repeat begin Sleep(100); Inc(i); Application.ProcessMessages; end; until (DevPresent=False) or (i=150) or (catchdevice=$02); case mode of 0: begin if i=150 then b:=false else b:=BB5_Flashing; Form1.statusbar.Panels[4].Text:=''; Application.ProcessMessages; Result:=b; end; 1: begin if i=150 then b:=false else b:=true; Form1.statusbar.Panels[4].Text:=''; Application.ProcessMessages; result:=b; end; end; end;//End of Dead Mode function BB5_EraseFile(core: string):boolean; var fs : TFileStream; buf : array[0..$FFFF] of byte; n,j : Integer; HdrLen : Integer; HdrPos : LongInt; CurrSeem : Byte; CurrSeemLen,CurrEraseLen, CurSeemcount : Integer; EraseStart, EraseStop : array[0..$FF] of LongInt; EraseCnt : Integer; FlashCFG,Byte1,Byte2,Byte3 : Byte; streamlen, ms : TMemoryStream; loaderlen : DWORD; partitionlen, pcfg : Byte; fullerase : Integer; partLen : integer; erase : Boolean; b : Byte; begin Result:=false; partition:=false; partLen:=0; erase:=False; Form1.pb1.Progress:=0; Form1.pbsm1.Progress:=0; Form1._msg('Erase : Processing '+ExtractFileName(core)); Application.processmessages; Form1.statusbar.Panels[1].text:=''; Form1.pb1.ForeColor:=clYellow; Form1.pb1.progress:=0; Application.ProcessMessages; fs:=TFileStream.Create(core,fmOpenRead); fs.Seek(0, sofromBeginning); fs.Read(b,1); if b<>$B2 then begin Form1._msg('Erase: Invalid Image File'); USBClosePort; fs.Free; exit; end; fs.ReadBuffer(buf[0], 4);//Длина Flash Header HdrLen := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2)); fs.Seek(4,soFromCurrent); Application.ProcessMessages; starttime; Application.ProcessMessages; try while fs.Position<(HdrLen) do begin fs.ReadBuffer(CurrSeem, 1); case CurrSeem of $E4: begin // Form1._msg('SEEM: E4'); fs.ReadBuffer(buf[0], 2); CurrSeemLen:=(buf[0]*$100)+buf[1]; fs.Seek(CurrSeemLen, sofromCurrent); end; $E5: begin // Form1._msg('SEEM: E5'); fs.ReadBuffer(buf[0], 2); CurrSeemLen:=(buf[0]*$100)+buf[1]; fs.Seek(CurrSeemLen, sofromCurrent); end; $EA: begin // Form1._msg('SEEM: EA'); fs.ReadBuffer(buf[0], 2); CurrSeemLen:=(buf[0]*$100)+buf[1]; fs.Seek(CurrSeemLen, sofromCurrent); end; $EE: begin partition:=True; partitionstream:=TmemoryStream.Create; // Form1._msg('SEEM: EE'); fs.ReadBuffer(buf[0], 2); CurrSeemLen:=(buf[0]*$100)+buf[1]; partLen:=currseemlen; //fs.Seek(CurrSeemLen, sofromCurrent); partitionstream.copyFrom(fs,CurrSeemlen); /// ms.SaveToFile('C:\partition.bin'); Application.ProcessMessages; end; $F3: begin // Form1._msg('SEEM: F3'); fs.ReadBuffer(buf[0], 2); CurrSeemLen:=(buf[0]*$100)+buf[1]; fs.Seek(CurrSeemLen, sofromCurrent); end; $FA: begin // Form1._msg('SEEM: FA'); streamlen:=TmemoryStream.Create; streamlen.CopyFrom(fs,$E); // создавал поток, потому что иначе пока не умею streamlen.Seek(1, sofromBeginning); // пропускаем один байт streamlen.ReadBuffer(loaderlen,4); // читаем длину - это длина всего адресного пространства блока FA, которое занимает апдейт апп, сразу после блока длины. dwordswap(@loaderlen); // разворачиваем fs.seek(loaderlen-9,sofromcurrent); // меняем позицию - после идут старые добрые С8 Application.ProcessMessages; streamlen.Free; end; $C8: begin erase:=True; fs.ReadBuffer(buf[0], 1); CurrSeemLen:=buf[0]; fs.ReadBuffer(CurSeemcount, 1); //Form1._msg(''); // Form1._msg('Found '+IntToStr(CurrSeemLen)+' flash chips to erase'); for n:=1 to CurSeemcount do begin //form1._msg(IntToStr(fs.Position)); fs.ReadBuffer(currseem,1); case currseem of $12: begin FlashCfg:=$12; fs.ReadBuffer(CurrEraseLen, 1); Dec(CurrEraseLen, 3); fs.ReadBuffer(Byte1, 1); fs.ReadBuffer(Byte2, 1); fs.ReadBuffer(Byte3, 1); EraseCnt:=CurrEraseLen div 8; Form1._msg('Found '+IntToStr(EraseCnt)+' areas to erase'); fs.ReadBuffer(buf[0], CurrEraseLen); if byte2=$00 then begin Application.ProcessMessages; fullerase:=0; for j:=0 to EraseCnt-1 do begin EraseStart[n] := HexToInt(IntToHex(buf[j*8], 2)+IntToHex(buf[j*8+1], 2)+IntToHex(buf[j*8+2], 2)+IntToHex(buf[j*8+3], 2)); EraseStop[n] := HexToInt(IntToHex(buf[j*8+4], 2)+IntToHex(buf[j*8+5], 2)+IntToHex(buf[j*8+6], 2)+IntToHex(buf[j*8+7], 2)); fullErase:=fullerase+(EraseStop[n]-EraseStart[n]); end; Form1.pb1.MaxValue:=fullerase div $54000; Application.ProcessMessages; end; for j:=0 to EraseCnt-1 do begin Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[1].Text:=''; EraseStart[n] := HexToInt(IntToHex(buf[j*8], 2)+IntToHex(buf[j*8+1], 2)+IntToHex(buf[j*8+2], 2)+IntToHex(buf[j*8+3], 2)); EraseStop[n] := HexToInt(IntToHex(buf[j*8+4], 2)+IntToHex(buf[j*8+5], 2)+IntToHex(buf[j*8+6], 2)+IntToHex(buf[j*8+7], 2)); Form1.statusbar.Panels[0].Text:='Erase Area: '+ IntToStr(j+1); // Form1._msg('Erase Area: '+ IntToStr(j+1) + ' EraseStart: ' + inttohex(EraseStart[n],8) + ' EraseStop: ' + inttohex(EraseStop[n], 8)); //if not BB5_EraseSegment(EraseStart[n], EraseStop[n], FlashCfg, Byte1, Byte2, Byte3) then //raise E.Create('Erasure error, Area: '+IntToStr(n)); case byte2 of $00: begin if not BB5_EraseAreaSmallBlock(EraseStart[n], EraseStop[n], FlashCfg, Byte1, Byte2, Byte3) then raise E.Create('Erasure error, Area: '+IntToStr(n)); end; $01: begin if not BB5_EraseArea(EraseStart[n], EraseStop[n], FlashCfg, Byte1, Byte2, Byte3) then raise E.Create('Erasure error, Area: '+IntToStr(n)); Form1.pb1.progress:=Form1.pb1.progress+10; end; $03: begin if not BB5_EraseArea(EraseStart[n], EraseStop[n], FlashCfg, Byte1, Byte2, Byte3) then raise E.Create('Erasure error, Area: '+IntToStr(n)); Form1.pb1.progress:=Form1.pb1.progress+10; end; end; Application.ProcessMessages; end; Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[1].Text:=''; // Form1._msg(''); end; $19: begin fs.ReadBuffer(partitionlen,1); fs.readbuffer(pcfg,1); ////1B 00 10 6F 00 2E 00 14 06 92 txBuf[0]:=$1B; txBuf[1]:=$00; txBuf[2]:=$10; txBuf[3]:=$6F; txBuf[4]:=$00; txBuf[5]:=partitionlen-1; txBuf[6]:=$00; txBuf[7]:=$15; txBuf[8]:=ISIHeaderTransId; txBuf[9]:=$92; fs.ReadBuffer(txBuf[10], partitionlen-4); case adlmode of $80: begin Form1._msg('Erase partition 0x'+byte2str(txbuf[23])); //Form1._msg(BufToHexStr(@txbuf[0],partitionlen+5)); usbbulkWriteport(@txbuf[0], partitionlen+5); if usbbulkreadport($ffff) then begin //form1._msg(buftohexstr(@rxbuf[0], length(rxbuf))); if (rxBuf[9]=$93) and (rxBuf[10]=0) and (rxBuf[11]=0 ) then begin Form1._msg('Partition erase Ok'); end else begin if rxBuf[10]=$22 then Form1._msg('Partition erase [Ok]') else Form1._msg('Partition erase [Minor]') end; end else Form1._msg('Partition erase [Failed]'); end; $06: begin Form1._msg('Partition erase not allowed by loader'); Application.ProcessMessages; end; end; Application.ProcessMessages; fs.ReadBuffer(txBuf[0],3); // form1._msg('afPos : '+IntToStr(fs.Position)); end; end; end; if partition=True then begin RebuildPartition(partitionstream,partLen); partitionstream.Free; partition:=false; Application.ProcessMessages; end; Result:=True; Application.ProcessMessages; endtimecount; Form1._msg('TIME : Erase time : '+showtime(tmsres)); Application.ProcessMessages; Form1.pbsm1.Progress:=0; fs.Free; exit; // fs.Seek(HdrLen, sofromBeginning); end else begin //Form1._msg('SEEM : '+byte2str(currseem)); fs.ReadBuffer(buf[0], 1); CurrSeemLen:=buf[0]; fs.readbuffer(buf[0],CurrSeemLen); // form1._msg(buftohexstr(@buf[0], currseemlen)); // if CurrSeemLen<1 then fs.ReadBuffer(CurrSeemLen, 1); application.ProcessMessages; end; end; end; if erase=False then begin result:=True; Form1._msg('Erase : No any region, skip erase'); end; fs.Free; except on E:Exception do begin fs.Free; Form1._msg('EraseFile: Error: '+E.Message); end; end; Application.ProcessMessages; endtimecount; Form1._msg('TIME : Erase time : '+showtime(tmsres)); Application.ProcessMessages; fullerase:=0; Form1.pb1.MaxValue:=100; Form1.pb1.Progress:=0; end; function BB5_EraseArea(Start, arStop: LongInt; FlashCfg,Byte1,Byte2,Byte3:byte):boolean; var n : Integer; FlashType, Subsystem : String; begin Result:=False; case Byte1 of $00: Subsystem:='CMT'; $01: Subsystem:='APE'; else Subsystem:='Unknown ('+IntToStr(Byte1)+')'; end; case Byte2 of $00: FlashType:='NOR'; $03: FlashType:='NAND'; $01: FlashType:='NAND'; else FlashType:='Unknown ('+IntToStr(Byte2)+')'; end; case byte1 of 0: begin //Transanc.Id Erase[3] := $6F; Erase[7] := msgid; Erase[8] := ISIHeaderTransId; Erase[9] := $42; //Config Erase[10] := Byte1; Erase[11] := $01; Erase[12] := FlashCFG; Erase[13] := $0c; Erase[14] := Byte2; Erase[15] := Byte3; end; 1: begin //APE try Erase[3] := $21; Erase[7] := msgid; Erase[8] := ISIHeaderTransId; Erase[9] := $42; //Config Erase[10] := $00; Erase[11] := $01; Erase[12] := FlashCFG; Erase[13] := $0c; Erase[14] := Byte2; Erase[15] := Byte3; end; end; //Begin Block Erase[16] := Start div $1000000; Erase[17] := Start div $10000; Erase[18] := Start div $100; Erase[19] := Start mod $100; //End Block Erase[20] := arStop div $1000000; Erase[21] := arStop div $10000; Erase[22] := arStop div $100; Erase[23] := arStop mod $100; /// if stop=True then begin dostop('ERASE'); result:=false; Exit; end; /// Form1._msg('Erasing area 0x'+IntToHex(Start,8)+' - 0x'+IntToHex(arStop, 8)+ ', '+FlashType+', '+Subsystem); Application.processmessages; n:=USBBulkWritePort(@Erase[0], Length(Erase)); if n<>24 then begin Form1._msg('Erase : ERR1 : connection lost or data missmatch'); exit; end; if Not USBBulkReadPort(16) or (Length(rxBuf)<16) then begin Form1._msg('Erase : ERR1 : connection lost or data missmatch'); exit; end; Application.processmessages; if rxBuf[8]<>Erase[8] then exit; //целостность транзанкций if Word((@rxBuf[14])^)=$00 then Form1._msg('Result: '+IntToHex(Word((@rxBuf[14])^), 4)); Result:=True; end; function BB5_EraseAreaSmallBlock(Start, arStop: LongInt; FlashCfg,Byte1,Byte2,Byte3:byte):boolean; var n, PktLen : Integer; FlashType, Subsystem : String; b, k : Boolean; begin Result:=False; b:=true; k:=true; PktLen:=$54000; case Byte1 of $00: Subsystem:='CMT'; $01: Subsystem:='APE'; else Subsystem:='Unknown ('+IntToStr(Byte1)+')'; end; case Byte2 of $00: FlashType:='NOR'; $03: FlashType:='NAND'; $01: FlashType:='NAND'; else FlashType:='Unknown ('+IntToStr(Byte2)+')'; end; case byte1 of 0: begin //Transanc.Id Erase[3] := $6F; Erase[7] := msgid; Erase[8] := ISIHeaderTransId; Erase[9] := $42; //Config Erase[10] := Byte1; Erase[11] := $01; Erase[12] := FlashCFG; Erase[13] := $0c; Erase[14] := Byte2; Erase[15] := Byte3; end; 1: begin //APE try Erase[3] := $21; Erase[7] := msgid; Erase[8] := ISIHeaderTransId; Erase[9] := $42; //Config Erase[10] := $00; Erase[11] := $01; Erase[12] := FlashCFG; Erase[13] := $0c; Erase[14] := Byte2; Erase[15] := Byte3; end; end; Form1._msg('Erasing area 0x'+IntToHex(Start,8)+' - 0x'+IntToHex(arStop, 8)+ ', '+FlashType+', '+Subsystem); while (Start24 then begin Form1._msg('Erase : ERR1 : connection lost or data missmatch'); exit; end; if Not USBBulkReadPort(16) or (Length(rxBuf)<16) then begin Form1._msg('Erase : ERR1 : connection lost or data missmatch'); exit; end; Application.processmessages; if rxBuf[8]<>Erase[8] then exit; //целостность транзанкций if Word((@rxBuf[14])^)<>$00 then begin k:=false; b:=false; continue; end; Application.ProcessMessages; Form1.pb1.Progress:=Form1.pb1.progress+1; Start:=Start+PktLen; end; if k then Form1._msg('Result: '+IntToHex(Word((@rxBuf[14])^), 4)) else Form1._msg('Error Eraising Area: 0x'+IntToHex(Start, 4)+' - 0x'+IntToHex(arStop, 4)); Result:=k; end; function BB5_EraseSegment(startSegment, stopSegment: LongInt; FlashCfg,Byte1,Byte2,Byte3:byte):boolean; var SectorsToErase,i : integer; CurrentSector : LongInt; CurrEraseSize : LongInt; FlashType,Subsystem : string; begin Result:=False; SectorsToErase:=(StopSegment-StartSegment) div BB5_EraseSectorSize; if ((StopSegment-StartSegment) mod BB5_EraseSectorSize) > 0 then inc(SectorsToErase); case Byte1 of $00: Subsystem:='CMT'; $01: Subsystem:='APE'; else Subsystem:='Unknown ('+IntToStr(Byte1)+')'; end; case Byte2 of $00: FlashType:='NOR'; $03: FlashType:='NAND'; $01: FlashType:='NAND'; else FlashType:='Unknown ('+IntToStr(Byte2)+')'; end; //Form1._msg('Erasing area 0x'+IntToHex(StartSegment,8)+' - 0x'+IntToHex(StopSegment,8)+', Type: '+FlashType+', Subsystem: '+Subsystem); Application.processmessages; StopSegment :=StopSegment+1; CurrentSector :=StartSegment; CurrEraseSize :=BB5_EraseSectorSize; for i:=0 to SectorsToErase-1 do begin if ((i=SectorsToErase-1) and (((StopSegment-StartSegment) mod BB5_EraseSectorSize) > 0)) then CurrEraseSize:=((StopSegment-StartSegment) mod BB5_EraseSectorSize); if not BB5_EraseSector(CurrentSector, CurrEraseSize, FlashCfg, Byte1, Byte2, Byte3) then exit; CurrentSector:=CurrentSector+CurrEraseSize; Application.ProcessMessages; end; Result:=True; end; function BB5_EraseSector(startSector,EraseSectorSize:LongInt; FlashCfg,Byte1,Byte2,Byte3:byte):boolean; var n: integer; str:string; begin Result:=False; Application.ProcessMessages; {Erase : array[0..23] of Byte = ($1B, $00, $10, $6F, $00, $12, $00, $16, $00, $42, $00, $01, $00, $0C, $00, $00, $00, $00, $00, $C0, $00, $00, $00, $00);} case byte1 of 0: begin //Transanc.Id Erase[3] := $6F; Erase[7] := msgid; Erase[8] := ISIHeaderTransId; Erase[9] := $42; //Config Erase[10] := Byte1; Erase[11] := $01; Erase[12] := FlashCFG; Erase[13] := $0c; Erase[14] := Byte2; Erase[15] := Byte3; end; 1: begin //APE try Erase[3] := $21; Erase[7] := msgid; Erase[8] := ISIHeaderTransId; Erase[9] := $42; //Config Erase[10] := $00; Erase[11] := $01; Erase[12] := FlashCFG; Erase[13] := $0c; Erase[14] := Byte2; Erase[15] := Byte3; end; end; //Begin Block Erase[16] := StartSector div $1000000; Erase[17] := StartSector div $10000; Erase[18] := StartSector div $100; Erase[19] := StartSector mod $100; StartSector:=StartSector+(EraseSectorSize-1); //End Block Erase[20] := StartSector div $1000000; Erase[21] := StartSector div $10000; Erase[22] := StartSector div $100; Erase[23] := StartSector mod $100; n:=USBBulkWritePort(@Erase[0], Length(Erase)); if n<>24 then begin Form1._msg('Erase : ERR1 : connection lost or data missmatch'); exit; end; if Not USBBulkReadPort(16) or (Length(rxBuf)<16) then begin Form1._msg('Erase : ERR1 : connection lost or data missmatch'); exit; end; if rxBuf[8]<>txBuf[8] then exit; //целостность транзанкций if rxBuf[15]<>$00 then exit; str:=BufToHex_Str(@Erase, Length(Erase)); Form1._msg(str); Result:=True; end; function BB5_WriteFile(core: string):boolean; const Write_Split : word = $FDE8; var buf :array[0..$3FFFF] of byte; EntryPoint, DataLen, TargetOffset, CRCTmp : LongInt; i, n, Blocks, Packets,icl, CurrPacketSize : Integer; cf1,cf2,cf3,apeb : byte; good : Integer; CertName,AsicType : String; PAPUB_Already, APE_PAPUB : boolean; fs : TFileStream; writen : Dword; cmtcount,cmtdin,apedin, apecount,TokenType, unk : integer; partitionbuf : boolean; partitioncheck : Boolean; begin Result:=False; Form1._msg('Write : Processing '+ExtractFileName(core)); fs:=TFileStream.Create(core,fmOpenRead); fs.Seek(0, sofromBeginning); Blocks:=0; cmtcount:=0; cmtdin:=0; apecount:=0; apedin:=0; unk:=0; Form1.pb1.ForeColor:=clGreen; Form1.pb1.progress:=0; Application.ProcessMessages; partitionbuf:=false; //if pos('_blank_504KB_pmm_10.fpsx',core)<>0 then partitioncheck:=false else partitioncheck:=true; //Application.ProcessMessages; //if partitioncheck=false then form1._msg('Blank_PMM detected, blank flashing enabled...'); Application.ProcessMessages; try fs.Read(i,1); if i<>$B2 then raise E.Create('Write : Bad image file'); fs.ReadBuffer(buf[0], 4);//Длина Flash Header DataLen := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2)); fs.Seek(DataLen,soFromCurrent); EntryPoint := fs.Position; //Form1._msg('Counting data+cert blocks...'); starttime; Application.ProcessMessages; while fs.Position$54) and (buf[0]<>$5D) then raise E.Create('Write : Bad image file, Corrupted Data/Cert blocks!' ); case buf[0] of $54://Phoenix-token begin fs.ReadBuffer(buf[0], $3); case buf[1] of $17 : begin fs.ReadBuffer(buf[0], buf[2]+1); DataLen := HexToInt(IntToHex(buf[6], 2)+IntToHex(buf[7], 2)+IntToHex(buf[8], 2)+IntToHex(buf[9], 2)); TokenType := buf[0]; case tokentype of 0:Inc(cmtcount); 1:Inc(apecount); else inc(unk); end; //Form1._msg(inttohex(buf[0],2)+inttohex(buf[1],2)); fs.Seek(DataLen,soFromCurrent); inc(blocks); continue; end; $2E : begin fs.ReadBuffer(buf[0], buf[2]+1); DataLen := HexToInt(IntToHex(buf[17], 2)+IntToHex(buf[18], 2)+IntToHex(buf[19], 2)+IntToHex(buf[20], 2)); TokenType := buf[0]; case tokentype of 0:Inc(cmtcount); 1:Inc(apecount); else inc(unk); end; // Form1._msg(inttohex(buf[0],2)+inttohex(buf[1],2)); fs.Seek(DataLen,soFromCurrent); inc(blocks); continue; end; $30 : begin Application.ProcessMessages; fs.ReadBuffer(buf[0], buf[2]+1); DataLen := HexToInt(IntToHex(buf[13], 2)+IntToHex(buf[14], 2)+IntToHex(buf[15], 2)+IntToHex(buf[16], 2)); TokenType := buf[0]; case tokentype of 0:Inc(cmtcount); 1:Inc(apecount); else inc(unk); end; // Form1._msg(inttohex(buf[0],2)+inttohex(buf[1],2)); fs.Seek(DataLen,soFromCurrent); inc(blocks); continue; end; else begin fs.ReadBuffer(buf[0], buf[2]+1); DataLen := HexToInt(IntToHex(buf[6], 2)+IntToHex(buf[7], 2)+IntToHex(buf[8], 2)+IntToHex(buf[9], 2)); fs.Seek(DataLen,soFromCurrent); inc(blocks); continue; end; end; end; $5D://Phoenix-segment begin fs.ReadBuffer(buf[0], $3); fs.ReadBuffer(buf[0], buf[2]+1); DataLen := HexToInt(IntToHex(buf[37], 2)+IntToHex(buf[38], 2)+IntToHex(buf[39], 2)+IntToHex(buf[40], 2)); TokenType := buf[32]; case tokentype of 0:Inc(cmtcount); 1:Inc(apecount); else inc(unk); end; //Form1._msg(inttohex(buf[32],2)+inttohex(buf[33],2)); //Form1._msg(inttohex(buf[32],2)+inttohex(buf[33],2)+inttohex(buf[34],2)+inttohex(buf[35],2)); fs.Seek(DataLen,soFromCurrent); inc(blocks); continue; end; end; end; writen:=0; if Blocks=0 then begin Form1._msg('No any data for write, skip write'); fs.Free; result:=True; Exit; end; Form1._msg('Total '+IntToStr(blocks)+' ['+inttostr(cmtcount)+'/'+inttostr(apecount)+'/'+inttostr(unk)+'] blocks to write, writing... '); Application.ProcessMessages; Form1.statusbar.Panels[0].text:='Write Data....'; //Form1.statusbar.panels[1].text:='Time : '+inttostr(blocks div 10)+' sec...'; Form1.pb1.progress:=0; Form1.pb1.MaxValue:=Blocks; fs.Seek(EntryPoint, soFromBeginning); Application.ProcessMessages; Form1.statusbar.Panels[1].text:='0/'+inttostr(cmtcount); while fs.Position$54) and (buf[0]<>$5D) then raise E.Create('Bad image file! Write terminated!'); case buf[0] of $54://Phoenix-token begin fs.ReadBuffer(buf[0], $3); case buf[1] of $17: begin partitionbuf:=false; fs.ReadBuffer(buf[0], buf[2]+1); DataLen := HexToInt(IntToHex(buf[6], 2)+IntToHex(buf[7], 2)+IntToHex(buf[8], 2)+IntToHex(buf[9], 2)); TargetOffset := HexToInt(IntToHex(buf[10], 2)+IntToHex(buf[11], 2)+IntToHex(buf[12], 2)+IntToHex(buf[13], 2)); Application.ProcessMessages; WriteData[6] := buf[0]; WriteData[7] := msgid; WriteData[8] := ISIHeaderTransId; WriteData[9] := $4C; WriteData[10] := buf[1]; WriteData[11] := buf[2]; cf1:=buf[0]; cf2:=buf[1]; cf3:=buf[2]; apeb:=buf[0]; WriteData[12] := buf[6]; WriteData[13] := buf[7]; WriteData[14] := buf[8]; WriteData[15] := buf[9]; WriteData[16] := buf[10]; WriteData[17] := buf[11]; WriteData[18] := buf[12]; WriteData[19] := buf[13]; case apeb of 0: begin WriteData[3]:=$6F; WriteData[6]:=$00; cmtdin:=cmtdin+1; Form1.statusbar.Panels[1].text:='CMT : '+inttostr(cmtdin)+'/'+inttostr(cmtcount); Application.ProcessMessages; end; 1: begin WriteData[3]:=$21; WriteData[6]:=$00; apedin:=apedin+1; Form1.statusbar.Panels[1].text:='APE : '+inttostr(apedin)+'/'+inttostr(apecount); Application.ProcessMessages; end; else begin WriteData[3]:=$6F; WriteData[6]:=$00; end; end; {=============================================================================================================================================================} n:=USBBulkWritePort(@WriteData, 36); if n<>36 then raise E.Create('Write Failed, ERR1 : Data missmatch, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); if Not USBBulkReadPort(12) or (Length(rxBuf)<12) then raise E.Create('Write Failed, ERR0 : Connection lost, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); if rxBuf[8]<>WriteData[8] then raise E.Create('Write Failed, ERR5 : Transaction error, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8));//целостность транзанкций if rxBuf[11]<>$00 then raise E.Create('Write Failed, ERR3 : Data not accepted, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); {--------------------------------------------------------------------------------------------------------------------------------------------------------------} //Form1._msg('Send : '+BufToHex_Str(@WriteData, 36)); //Form1._msg('Receiv: '+BufToHex_Str(@rxBuf, n)); {=============================================================================================================================================================} Application.ProcessMessages; end; $2E: begin partitionbuf:=false; fs.ReadBuffer(buf[0], buf[2]+1); DataLen := HexToInt(IntToHex(buf[17], 2)+IntToHex(buf[18], 2)+IntToHex(buf[19], 2)+IntToHex(buf[20], 2)); TargetOffset := HexToInt(IntToHex(buf[21], 2)+IntToHex(buf[22], 2)+IntToHex(buf[23], 2)+IntToHex(buf[24], 2)); //form1._msg(byte2str(buf[21])+byte2str(buf[22])+byte2str(buf[23])+byte2str(buf[24])); Application.ProcessMessages; WriteData[6] := buf[0]; WriteData[7] := msgid; WriteData[8] := ISIHeaderTransId; WriteData[9] := $4C; WriteData[10] := buf[1]; WriteData[11] := buf[2]; cf1:=buf[0]; cf2:=buf[1]; cf3:=buf[2]; apeb:=buf[0]; dword((@writedata[12])^):=datalen; dwordswap(@writedata[12]); WriteData[16] := buf[21]; WriteData[17] := buf[22]; WriteData[18] := buf[23]; WriteData[19] := buf[24]; WriteData[20] := buf[5]; WriteData[21] := buf[6]; WriteData[22] := buf[7]; WriteData[23] := buf[8]; WriteData[24] := buf[9]; WriteData[25] := buf[10]; WriteData[26] := buf[11]; WriteData[27] := buf[12]; WriteData[28] := buf[13]; WriteData[29] := buf[14]; WriteData[30] := buf[15]; WriteData[31] := buf[16]; case apeb of 0: begin WriteData[3]:=$6F; WriteData[6]:=$00; cmtdin:=cmtdin+1; Form1.statusbar.Panels[1].text:='CMT : '+inttostr(cmtdin)+'/'+inttostr(cmtcount); Application.ProcessMessages; end; 1: begin WriteData[3]:=$21; WriteData[6]:=$00; apedin:=apedin+1; Form1.statusbar.Panels[1].text:='APE : '+inttostr(apedin)+'/'+inttostr(apecount); Application.ProcessMessages; end; else begin WriteData[3]:=$6F; WriteData[6]:=$00; end; end; {=============================================================================================================================================================} n:=USBBulkWritePort(@WriteData, 36); if n<>36 then raise E.Create('Write Failed, ERR1 : Data missmatch, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); if Not USBBulkReadPort(12) or (Length(rxBuf)<12) then raise E.Create('Write Failed, ERR0 : Connection lost, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); if rxBuf[8]<>WriteData[8] then raise E.Create('Write Failed, ERR5 : Transaction error, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8));//целостность транзанкций if rxBuf[11]<>$00 then raise E.Create('Write Failed, ERR3 : Data not accepted, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); {--------------------------------------------------------------------------------------------------------------------------------------------------------------} //Form1._msg('Send : '+BufToHex_Str(@WriteData, 36)); //Form1._msg('Receiv: '+BufToHex_Str(@rxBuf, n)); {=============================================================================================================================================================} for icl:=20 to 31 do WriteData[icl]:=$00; Application.ProcessMessages; end; $30 : Begin partitionbuf:=true; fs.ReadBuffer(buf[0], buf[2]+1); DataLen := HexToInt(IntToHex(buf[13], 2)+IntToHex(buf[14], 2)+IntToHex(buf[15], 2)+IntToHex(buf[16], 2)); TargetOffset := HexToInt(IntToHex(buf[17], 2)+IntToHex(buf[18], 2)+IntToHex(buf[19], 2)+IntToHex(buf[20], 2)); Application.ProcessMessages; partitonwrite[6] := buf[0]; partitonwrite[7] := msgid; partitonwrite[8] := ISIHeaderTransId; partitonwrite[9] := $88; partitonwrite[10] := buf[1]; partitonwrite[11] := buf[2]; cf1:=buf[0]; cf2:=buf[1]; cf3:=buf[2]; apeb:=buf[0]; partitonwrite[12] := buf[5]; partitonwrite[13] := buf[6]; partitonwrite[14] := buf[7]; partitonwrite[15] := buf[8]; partitonwrite[16] := buf[13]; partitonwrite[17] := buf[14]; partitonwrite[18] := buf[15]; partitonwrite[19] := buf[16]; partitonwrite[20] := buf[17]; partitonwrite[21] := buf[18]; partitonwrite[22] := buf[19]; partitonwrite[23] := buf[20]; case apeb of 0: begin partitonwrite[3]:=$6F; partitonwrite[6]:=$00; cmtdin:=cmtdin+1; Application.ProcessMessages; //Form1._msg('CMT : Write partition 0x'+byte2str(buf[8])); Application.ProcessMessages; Form1.statusbar.Panels[1].text:='CMT : partition 0x'+byte2str(buf[8])+' '+inttostr(cmtdin)+'/'+inttostr(cmtcount); Application.ProcessMessages; end; 1: begin WriteData[3]:=$21; WriteData[6]:=$00; apedin:=apedin+1; Application.ProcessMessages; //Form1._msg('APE : Write partition 0x'+byte2str(buf[8])); Application.ProcessMessages; Form1.statusbar.Panels[1].text:='APE : partition 0x'+byte2str(buf[8])+' '+inttostr(apedin)+'/'+inttostr(apecount); Application.ProcessMessages; end; else begin WriteData[3]:=$6F; WriteData[6]:=$00; end; end; {=============================================================================================================================================================} n:=USBBulkWritePort(@partitonwrite, 24); if n<>24 then raise E.Create('Write Failed, err1, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); if Not USBBulkReadPort(12) or (Length(rxBuf)<12) then raise E.Create('Write Failed, ERR0 :Connection lost, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); if rxBuf[8]<>partitonwrite[8] then raise E.Create('Write Failed, ERR5 : Transaction error, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8));//целостность транзанкций // if rxBuf[10]<>$00 then raise E.Create('Write Failed, err5, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); {--------------------------------------------------------------------------------------------------------------------------------------------------------------} //Form1._msg('Send : '+BufToHex_Str(@WriteData, 36)); //Form1._msg('Receiv: '+BufToHex_Str(@rxBuf, n)); {=============================================================================================================================================================} Application.ProcessMessages; end; else begin partitionbuf:=false; fs.ReadBuffer(buf[0], buf[2]+1); DataLen := HexToInt(IntToHex(buf[6], 2)+IntToHex(buf[7], 2)+IntToHex(buf[8], 2)+IntToHex(buf[9], 2)); TargetOffset := HexToInt(IntToHex(buf[10], 2)+IntToHex(buf[11], 2)+IntToHex(buf[12], 2)+IntToHex(buf[13], 2)); WriteData[6] := buf[0]; WriteData[7] := msgid; WriteData[8] := ISIHeaderTransId; WriteData[9] := $4C; WriteData[10] := buf[1]; WriteData[11] := buf[2]; cf1:=buf[0]; cf2:=buf[1]; cf3:=buf[2]; apeb:=buf[0]; WriteData[12] := buf[6]; WriteData[13] := buf[7]; WriteData[14] := buf[8]; WriteData[15] := buf[9]; WriteData[16] := buf[10]; WriteData[17] := buf[11]; WriteData[18] := buf[12]; WriteData[19] := buf[13]; case apeb of 0: begin WriteData[3]:=$6F; WriteData[6]:=$00; cmtdin:=cmtdin+1; Form1.statusbar.Panels[1].text:='CMT : '+inttostr(cmtdin)+'/'+inttostr(cmtcount); Application.ProcessMessages; end; 1: begin WriteData[3]:=$21; WriteData[6]:=$00; apedin:=apedin+1; Form1.statusbar.Panels[1].text:='APE : '+inttostr(apedin)+'/'+inttostr(apecount); Application.ProcessMessages; end; else begin WriteData[3]:=$6F; WriteData[6]:=$00; end; end; {=============================================================================================================================================================} n:=USBBulkWritePort(@WriteData, 36); if n<>36 then raise E.Create('Write Failed, err1, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); if Not USBBulkReadPort(12) or (Length(rxBuf)<12) then raise E.Create('Write Failed, ERR0 : Connection lost, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); if rxBuf[8]<>WriteData[8] then raise E.Create('Write Failed, ERR5 : Transaction error, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8));//целостность транзанкций if rxBuf[11]<>$00 then raise E.Create('Write Failed, ERR3 : Data not accepted, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); {--------------------------------------------------------------------------------------------------------------------------------------------------------------} //Form1._msg('Send : '+BufToHex_Str(@WriteData, 36)); //Form1._msg('Receiv: '+BufToHex_Str(@rxBuf, n)); {=============================================================================================================================================================} Application.ProcessMessages; end; end; Application.ProcessMessages; Form1.pb1.progress:=Form1.pb1.progress+1; // Header written... now Rock'n'Roll! fs.ReadBuffer(buf[0], DataLen); Packets:=1; CurrPacketSize:=DataLen; case partitionbuf of false : begin if DataLen>Write_Split then begin Packets:=DataLen div Write_Split; if (DataLen mod Write_Split) > 0 then inc(Packets); CurrPacketSize:=Write_Split; end; for i:=0 to Packets-1 do begin if (i=Packets-1) and (Packets>1) then begin if (DataLen mod Write_Split)>0 then CurrPacketSize:=(DataLen mod Write_Split) else CurrPacketSize:=Write_Split; end; txBuf[0] := $1B; txBuf[1] := $00; txBuf[2] := $10; txBuf[3] := $6F; txBuf[4] := ((CurrPacketSize+8) div $100); txBuf[5] := ((CurrPacketSize+8) mod $100); txBuf[6] := cf1; txBuf[7] := msgid; txBuf[8] := ISIHeaderTransId; txBuf[9] := $4B; txBuf[10] := (CurrPacketSize div $100); txBuf[11] := (CurrPacketSize mod $100); txBuf[12] := $00; txBuf[13] := $00; for n:=0 to CurrPacketSize-1 do begin txBuf[14+n] := buf[(i*Write_Split)+n]; end; CrcTmp:=$0000; for n:=0 to CurrPacketSize-1 do begin if (n mod 2)=0 then CrcTmp:=CrcTmp xor ( (txBuf[14+n]*$100) + (txBuf[14+n+1])); end; CrcTmp := CrcTmp AND $FFFF; txBuf[12] := CrcTmp div $100; txBuf[13] := CrcTmp mod $100; case apeb of 0: begin txbuf[3]:=$6F; txbuf[6]:=$00; end; 1: begin txbuf[3]:=$21; txbuf[6]:=$00; end; else begin txbuf[3]:=$6F; txbuf[6]:=$00; end; end; {=============================================================================================================================================================} n:=USBBulkWritePort(@txBuf, 14+CurrPacketSize); if n<>14+CurrPacketSize then raise E.Create('Write Failed, ERR1 : Data missmatch, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); if Not USBBulkReadPort(16) or (Length(rxBuf)<16) then raise E.Create('Write Failed, ERR0 : Connecttion lost, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); if rxBuf[8]<>txBuf[8] then raise E.Create('Write Failed, ERR5 : Transaction error, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8));//целостность транзанкций if rxBuf[15]<>$00 then raise E.Create('Write Failed, ERR3 : Data not accepted, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); {--------------------------------------------------------------------------------------------------------------------------------------------------------------} //Form1._msg('Send : '+BufToHex_Str(@WriteData, 36)); //Form1._msg('Receiv: '+BufToHex_Str(@rxBuf, n)); {=============================================================================================================================================================} end; end; true: begin if DataLen>$8000 then begin Packets:=DataLen div $8000; if (DataLen mod $8000) > 0 then inc(Packets); CurrPacketSize:=$8000; end; for i:=0 to Packets-1 do begin if (i=Packets-1) and (Packets>1) then begin if (DataLen mod $8000)>0 then CurrPacketSize:=(DataLen mod $8000) else CurrPacketSize:=$8000; end; txBuf[0] := $1B; txBuf[1] := $00; txBuf[2] := $10; txBuf[3] := $6F; txBuf[4] := ((CurrPacketSize+6) div $100); txBuf[5] := ((CurrPacketSize+6) mod $100); txBuf[6] := $00; txBuf[7] := msgid; txBuf[8] := ISIHeaderTransId; txBuf[9] := $90; txBuf[10] := (CurrPacketSize div $100); txBuf[11] := (CurrPacketSize mod $100); for n:=0 to CurrPacketSize-1 do begin txBuf[12+n] := buf[(i*$8000)+n]; end; case apeb of 0: begin txbuf[3]:=$6F; txbuf[6]:=$00; end; 1: begin txbuf[3]:=$21; txbuf[6]:=$00; end; else begin txbuf[3]:=$6F; txbuf[6]:=$00; end; end; {=============================================================================================================================================================} n:=USBBulkWritePort(@txBuf, 12+CurrPacketSize); if n<>12+CurrPacketSize then raise E.Create('Write Failed, ERR1 : Data missmatch, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); if Not USBBulkReadPort(12) or (Length(rxBuf)<12) then raise E.Create('Write Failed, ERR0 : Connection lost, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); if rxBuf[8]<>txBuf[8] then raise E.Create('Write Failed,ERR5 : Transaction failed, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8));//целостность транзанкций if (rxBuf[9]<>$91) and (rxBuf[10]<>$00) then raise E.Create('Write Failed, ERR3 : Partition not accepted, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); {--------------------------------------------------------------------------------------------------------------------------------------------------------------} //Form1._msg('Send : '+BufToHex_Str(@WriteData, 36)); //Form1._msg('Receiv: '+BufToHex_Str(@rxBuf, n)); {=============================================================================================================================================================} end; end; end; continue; end;//end of case $54 - write Data $5D://Phoenix-segment begin fillmemory(@txbuf[0],36,$00); fs.ReadBuffer(buf[0], 3); fs.ReadBuffer(buf[0], buf[2]+1); DataLen := HexToInt(IntToHex(buf[37], 2)+IntToHex(buf[38], 2)+IntToHex(buf[39], 2)+IntToHex(buf[40], 2)); TargetOffset := HexToInt(IntToHex(buf[41], 2)+IntToHex(buf[42], 2)+IntToHex(buf[43], 2)+IntToHex(buf[44], 2)); apeb:=buf[32]; //form1._msg(byte2str(buf[32])); Application.ProcessMessages; case apeb of 0: begin good:=0; for i:=$0 to $0F do if RAPInfo.Root_Key_Hash[i]=buf[i] then inc(good); if good<$10 then begin form1.pb1.progress:=form1.pb1.progress+1; cmtdin:=cmtdin+1; Form1.statusbar.Panels[1].text:='CMT : '+inttostr(cmtdin)+'/'+inttostr(cmtcount); Application.ProcessMessages; fs.Seek(DataLen, sofromCurrent); continue; end; AsicType:='CMT : '; end; 1: begin good:=0; for i:=$0 to $0F do if RAPInfo.APErootkey[i]=buf[i] then inc(good); if good<$10 then begin form1.pb1.progress:=form1.pb1.progress+1; apedin:=apedin+1; Form1.statusbar.Panels[1].text:='APE : '+inttostr(apedin)+'/'+inttostr(apecount); Application.ProcessMessages; fs.Seek(DataLen, sofromCurrent); continue; end; AsicType:='APE : '; end; else begin good:=0; for i:=$0 to $0F do if RAPInfo.Root_Key_Hash[i]=buf[i] then inc(good); if good<$10 then begin form1.pb1.progress:=form1.pb1.progress+1; Form1.statusbar.Panels[1].text:='UNK : -/-'; Application.ProcessMessages; fs.Seek(DataLen, sofromCurrent); continue; end; AsicType:='CMT : '; end; end; CertName:=''; for i:=20 to 31 do if buf[i]=$00 then break else CertName:=CertName+Chr(buf[i]); Form1._msg(AsicType+'Writing Hash CERT ['+CertName+']'); Application.ProcessMessages; txBuf[0] := $1B; txBuf[1] := $00; txBuf[2] := $10; txBuf[3] := $6F; txBuf[4] := $00; txBuf[5] := $1E; txBuf[6] := $00; txBuf[7] := msgid; txBuf[8] := ISIHeaderTransId; txBuf[9] := $4C; txBuf[10] := buf[33]; txBuf[11] := buf[34]; cf1:=buf[32]; cf2:=buf[33]; cf3:=buf[34]; txBuf[12] := buf[37]; txBuf[13] := buf[38]; txBuf[14] := buf[39]; txBuf[15] := buf[40]; txBuf[16] := buf[41]; txBuf[17] := buf[42]; txBuf[18] := buf[43]; txBuf[19] := buf[44]; for i:=20 to 35 do txBuf[i]:=$00; case apeb of 0: begin if CertName='PAPUBKEYS' then begin if not PAPUB_Already then begin //Form1._msg('CMT : Patch '+CertName); txBuf[16] := $00; txBuf[17] := $00; txBuf[18] := $00; txBuf[19] := $00; for i:=20 to 31 do txBuf[i]:=buf[i]; PAPUB_Already:=True; end else begin Form1._msg('CMT : PAPUBKEYS skip, already sent'); end; end; if CertName='SOS*ENO' then begin if BufToHexStr(@buf[41],4)='FFFFFFFF' then begin txBuf[16] := $00; txBuf[17] := $00; txBuf[18] := $00; txBuf[19] := $00; for i:=20 to 31 do txBuf[i]:=buf[i]; end; end; if CertName='NPC' then begin if BufToHexStr(@buf[41],4)='FFFFFFFF' then begin txBuf[16] := $00; txBuf[17] := $00; txBuf[18] := $00; txBuf[19] := $00; for i:=20 to 31 do txBuf[i]:=buf[i]; end; end; end; 1: begin if CertName='PAPUBKEYS' then begin if not APE_PAPUB then begin // Form1._msg('APE : Patch '+CertName); txBuf[16] := $00; txBuf[17] := $00; txBuf[18] := $00; txBuf[19] := $00; for i:=20 to 31 do txBuf[i]:=buf[i]; APE_PAPUB:=True; end else begin Form1._msg('APE : PAPUBKEYS skip, already sent'); end; end; end; end; case apeb of 0: begin txbuf[3]:=$6F; cmtdin:=cmtdin+1; Form1.statusbar.Panels[1].text:='CMT : '+inttostr(cmtdin)+'/'+inttostr(cmtcount); Application.ProcessMessages; end; 1: begin txbuf[3]:=$21; apedin:=apedin+1; Form1.statusbar.Panels[1].text:='APE : '+inttostr(apedin)+'/'+inttostr(apecount); Application.ProcessMessages; end; else begin txbuf[3]:=$6F; end; end; // form1._msg(BufToHexStr(@txbuf[1],36)); // Form1._msg(''); Application.ProcessMessages; {=============================================================================================================================================================} n:=USBBulkWritePort(@txBuf, 36); if n<>36 then raise E.Create('Write CERT Failed, ERR1 : Data missmatch, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); if Not USBBulkReadPort(12) or (Length(rxBuf)<12) then raise E.Create('Write CERT Failed, ERR0 : Connection lost, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); if rxBuf[8]<>txBuf[8] then raise E.Create('Write CERT Failed, ERR5 : Transaction failed, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8));//целостность транзанкций if rxBuf[11]<>$00 then raise E.Create('Write CERT Failed, ERR2 : Cert not accepted, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); {--------------------------------------------------------------------------------------------------------------------------------------------------------------} //Form1._msg('SendPrologiSert: '+BufToHex_Str(@txBuf, 36)); //Form1._msg('RecPrologiSert : '+BufToHex_Str(@rxBuf, n)); {=============================================================================================================================================================} // Шапка записана - Зажигаем! =) fs.ReadBuffer(buf[0], DataLen); Packets:=1; CurrPacketSize:=DataLen; if DataLen>Write_Split then begin Packets:=DataLen div Write_Split; if (DataLen mod Write_Split) > 0 then inc(Packets); CurrPacketSize:=Write_Split; end; for i:=0 to Packets-1 do begin if (i=Packets-1) and (Packets>1) then begin if (DataLen mod Write_Split)>0 then CurrPacketSize:=(DataLen mod Write_Split) else CurrPacketSize:=Write_Split; end; txBuf[0] := $1B; txBuf[1] := $00; txBuf[2] := $10; case ApeB of 0:txBuf[3] := $6F; 1:txBuf[3] := $21; else txBuf[3]:= $6F; end; txBuf[4] := ((CurrPacketSize+8) div $100); txBuf[5] := ((CurrPacketSize+8) mod $100); txBuf[6] := $00; txBuf[7] := msgid; txBuf[8] := ISIHeaderTransId; txBuf[9] := $4B; txBuf[10] := (CurrPacketSize div $100); txBuf[11] := (CurrPacketSize mod $100); for n:=0 to CurrPacketSize-1 do begin txBuf[14+n] := buf[(i*Write_Split)+n]; end; CrcTmp:=$0000; for n:=0 to CurrPacketSize-1 do begin if (n mod 2)=0 then CrcTmp:=CrcTmp xor ( (txBuf[14+n]*$100) + (txBuf[14+n+1])); end; CrcTmp := CrcTmp AND $FFFF; txBuf[12] := CrcTmp div $100; txBuf[13] := CrcTmp mod $100; {=============================================================================================================================================================} n:=USBBulkWritePort(@txBuf, 14+CurrPacketSize); if n<>14+CurrPacketSize then raise E.Create('Write CERT Failed, ERR1 : Data missamtch, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); if Not USBBulkReadPort(16) or (Length(rxBuf)<16) then raise E.Create('Write CERT Failed, ERR0 : Connection losted , at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); if rxBuf[8]<>txBuf[8] then raise E.Create('Write CERT Failed, ERR5 : Transaction failed, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8));//целостность транзанкций if rxBuf[11]<>$00 then raise E.Create('Write CERT Failed, ERR2 : Cert not accepted, at '+IntToHex(TargetOffset, 8)+':'+IntToHex(DataLen,8)); {--------------------------------------------------------------------------------------------------------------------------------------------------------------} //Form1._msg(BufToHex_Str(@txBuf, 14+CurrPacketSize)); //Form1._msg(BufToHex_Str(@rxBuf, n); {=============================================================================================================================================================} end; continue; form1.pb1.progress:=form1.pb1.progress+1; Application.ProcessMessages; end;//end of case $5D - write Sert end; end; Result:=True; fs.Free; endtimecount; form1._msg('TIME : Write time : '+showtime(tmsres)); except on E:Exception do begin fs.Free; Form1._msg('Error: '+E.Message); Form1.pb1.Progress:=0; USBClosePort; endtimecount; exit; end; end; Form1.pb1.Progress:=0; end; function USBControlPacket(_Class: LongWord; Length: longword; Expected:Integer):Boolean; var i : integer; Count : LongWord; Buffer : array[0..$FFFE] of byte; begin Result:=False; rxBuf:=nil; SetLength(rxBuf, 1); if hDevice = INVALID_HANDLE_VALUE then exit; if not DeviceIOControl(hDevice, _Class, @txBuf, Length, @Buffer, Expected, Count, nil) then exit; SetLength(rxBuf, Count); for i := 0 to Count - 1 do rxBuf[i]:=Buffer[i]; if Expected>0 then result:=False else result:=True; end; function BB5_USB_BootRom_GetFirstBlock:integer; begin Result:=0; txBuf[0]:=$40; txBuf[1]:=$59; txBuf[2]:=$00; txBuf[3]:=$00; txBuf[4]:=$00; txBuf[5]:=$00; txBuf[6]:=$00; txBuf[7]:=$00; try if USBControlPacket($222040, $8, 0) then begin Application.ProcessMessages; Form1._msg('[BB5 FLASH]: Bootrom Ok!'); end else begin Form1._msg('[BB5 FLASH]: Can'+#39+'t verify Bootrom :( Try again...'); USBClosePort; exit; end; Application.ProcessMessages; txBuf[0]:=$C0; txBuf[1]:=$56; txBuf[2]:=$00; txBuf[3]:=$00; txBuf[4]:=$00; txBuf[5]:=$00; txBuf[6]:=$00; txBuf[7]:=$03; USBControlPacket($222040, $8, $300); //Form1._msg('rxbuf: '+BufToHexStr(@rxBuf[0], Length(rxBuf))); if rxBuf[0]<1 then begin Application.ProcessMessages; Form1._msg('[BB5 FLASH]: GetFirstBlock Failed, Aborting'); USBClosePort; exit; end; Result:=rxBuf[0]; except Result:=0; end; end; function BB5_ADL_RestartMCU(mode: byte):boolean; var n: integer; begin Application.ProcessMessages; case mode of $04: begin Result:=False; txBuf[0] := $1B; txBuf[1] := $00; txBuf[2] := $10; txBuf[3] := $6f; txBuf[4] := $00; txBuf[5] := $06; txBuf[6] := $00; txBuf[7] := msgid; txBuf[8] := ISIHeaderTransId; txBuf[9] := $04; txBuf[10] := $00; txBuf[11] := $00; n:=USBBulkWritePort(@txBuf, 12); if n<>12 then exit; txBuf[0] := $1B; txBuf[1] := $00; txBuf[2] := $10; txBuf[3] := $6f; txBuf[4] := $00; txBuf[5] := $06; txBuf[6] := $00; txBuf[7] := msgid; txBuf[8] := ISIHeaderTransId; txBuf[9] := $00; txBuf[10] := $00; txBuf[11] := $00; n:=USBBulkWritePort(@txBuf, 12); if n<>12 then exit; Result:=True; end; $80: begin result:=False; txBuf[0] := $1B; txBuf[1] := $00; txBuf[2] := $10; txBuf[3] := $6f; txBuf[4] := $00; txBuf[5] := $06; txBuf[6] := $00; txBuf[7] := msgid; txBuf[8] := ISIHeaderTransId; txBuf[9] := $09; txBuf[10] := $02; txBuf[11] := $00; n:=USBBulkWritePort(@txBuf, 12); USBBulkReadPort($FF); if n<>12 then exit; txBuf[0] := $1B; txBuf[1] := $00; txBuf[2] := $10; txBuf[3] := $6f; txBuf[4] := $00; txBuf[5] := $06; txBuf[6] := $00; txBuf[7] := msgid; txBuf[8] := ISIHeaderTransId; txBuf[9] := $04; txBuf[10] := $02; txBuf[11] := $00; n:=USBBulkWritePort(@txBuf, 12); if n<>12 then exit; Result:=True; end else result:=False; end; end; function BB5restart2ndproto():boolean; var n:integer; begin //1B 00 10 6F 00 06 00 18 7D 09 02 00 //1B 00 10 6F 00 06 00 18 2E 09 02 00 //1B 00 10 6F 00 06 00 18 2F 04 02 00 end; function s4080Final():Boolean; begin //1st recheck adl80checkst[7]:=msgid; adl80checkst[8]:=ISIHeaderTransId; USBBulkWritePort(@adl80checkst, Length(adl80checkst)); UsbBulkReadport($FFFF); adl80checkst[3]:=$21; USBBulkWritePort(@adl80checkst, Length(adl80checkst)); adl80checkst[3]:=$6F; //2nd - repeat check adl, send bytes adl80precheck[7]:=msgid; adl80precheck[8]:=ISIHeaderTransID; USBBulkWritePort(@adl80precheck, Length(adl80precheck)); UsbBulkReadport($FFFF); adl80checkst[7]:=msgid; adl80checkst[8]:=ISIHeaderTransId; USBBulkWritePort(@adl80checkst, Length(adl80checkst)); UsbBulkReadport($FFFF); adl80checkst[3]:=$21; USBBulkWritePort(@adl80checkst, Length(adl80checkst)); adl80checkst[3]:=$6F; //3rd - getroot adl80getroot[7]:=msgid; adl80getroot[8]:=ISIHeaderTransId; USBBulkWritePort(@adl80getroot, Length(adl80getroot)); UsbBulkReadport($FFFF); //Select ASIC adl80preasic[7]:=msgid; adl80preasic[8]:=ISIHeaderTransId; USBBulkWritePort(@adl80preasic, Length(adl80preasic)); UsbBulkReadport($FFFF); adl80selASIC[7]:=msgid; adl80selASIC[8]:=ISIHeaderTransId; USBBulkWritePort(@adl80selASIC, Length(adl80selASIC)); UsbBulkReadport($FFFF); if rxbuf[10]=$00 then result:=True else result:=False; end; function CheckADLLoader:boolean; var n: integer; begin Result:=False; n:=USBBulkWritePort(@CheckADLUpload[0], Length(CheckADLUpload)); if n<>12 then exit; n:=ReadUBUSData; if n<6 then exit; if rxBuf[5]<>$04 then begin Form1._msg('ADL Server not confirmed flashmode!'); USBClosePort; exit; end else begin Form1._msg('ADL Server has confirmed its flashmode'); Result:=True; end; end; //Функция расчета CHK UPDAPP function GetLoaderCRC(Buf:Pointer; BufLen: integer): Word; begin Result:=0; while BufLen > 0 do begin Result:=Result+Byte(Buf^); inc(Integer(Buf)); dec(BufLen); end; Result:=Result xor $FFFF; end; function s40prep04 ():Boolean; var i:integer; begin CheckADLUpload[7]:=msgid; CheckADLUpload[8]:=ISIHeaderTransId; CheckADLUpload[9]:=$00; i:=USBBulkWritePort(@CheckADLUpload, Length(CheckADLUpload)); if i<>12 then exit; USBBulkReadPort(12); if rxBuf[11]<>$04 then result:=false else begin case oldsmart of false: begin; //GetRoot GetRoot[7]:=msgid; GetRoot[8]:=ISIHeaderTransId; GETRoot[9]:=$07; USBBulkWritePort(@GetRoot, Length(GetRoot)); USBBulkReadPort($FFFF); GetRoot[7]:=msgid; GetRoot[8]:=ISIHeaderTransId; GETRoot[9]:=$01; //USBBulkWritePort(@GetRoot, Length(GetRoot)); Application.ProcessMessages; sleep(100); Application.ProcessMessages; USBBulkWritePort(@oldsmGetRoot, Length(oldsmGetRoot)); USBBulkReadPort($FFFF); selectAsicCMT[3]:=$6F; selectAsicCMT[8]:=ISIHeaderTransId; //USBBulkWritePort(@selectAsicCMT, Length(selectAsicCMT)); Application.ProcessMessages; sleep(100); Application.ProcessMessages; //PreErase PreErase[7]:=msgid; PreErase[8]:=ISIHeaderTransId; PreErase[12]:=csbyte1; PreErase[13]:=csbyte2; PreErase[14]:=$00; PreErase[15]:=$00; USBBulkWritePort(@PreErase, Length(PreErase)); result:=True; end; true: begin //oldsmgetroot USBBulkWritePort(@oldsmGetRoot, Length(oldsmGetRoot)); USBBulkReadPort($FFFF); selectAsicCMT[3]:=$6F; selectAsicCMT[8]:=ISIHeaderTransId; USBBulkWritePort(@selectAsicCMT, Length(selectAsicCMT)); if USBBulkReadPort($FFFF) then begin if rxbuf[10]=$00 then begin result:=True; Form1._msg('ADL : ASIC CMT select Ok'); end else begin result:=False; Form1._msg('ADL : Select CMT failed'); end; end; Application.ProcessMessages; end; end; end; end; function s40prep80():Boolean; begin //1st recheck adl80checkst[7]:=msgid; adl80checkst[8]:=ISIHeaderTransId; USBBulkWritePort(@adl80checkst, Length(adl80checkst)); UsbBulkReadport($FFFF); adl80checkst[3]:=$21; USBBulkWritePort(@adl80checkst, Length(adl80checkst)); adl80checkst[3]:=$6F; //2nd - repeat check adl, send bytes adl80precheck[7]:=msgid; adl80precheck[8]:=ISIHeaderTransID; USBBulkWritePort(@adl80precheck, Length(adl80precheck)); UsbBulkReadport($FFFF); adl80checkst[7]:=msgid; adl80checkst[8]:=ISIHeaderTransId; USBBulkWritePort(@adl80checkst, Length(adl80checkst)); UsbBulkReadport($FFFF); adl80checkst[3]:=$21; USBBulkWritePort(@adl80checkst, Length(adl80checkst)); adl80checkst[3]:=$6F; //3rd - getroot adl80getroot[7]:=msgid; adl80getroot[8]:=ISIHeaderTransId; USBBulkWritePort(@adl80getroot, Length(adl80getroot)); UsbBulkReadport($FFFF); //PRECRTDATA if form1.chkMCUen.checked=true then S40BuildCertBody(core); //Select ASIC adl80preasic[7]:=msgid; adl80preasic[8]:=ISIHeaderTransId; USBBulkWritePort(@adl80preasic, Length(adl80preasic)); UsbBulkReadport($FFFF); adl80selASIC[7]:=msgid; adl80selASIC[8]:=ISIHeaderTransId; USBBulkWritePort(@adl80selASIC, Length(adl80selASIC)); UsbBulkReadport($FFFF); if rxbuf[10]=$00 then begin result:=True; Form1._msg('ADL : ASIC CMT select Ok'); end else begin result:=False; Form1._msg('ADL : Select CMT failed'); end; end; function Extractloader(core:string ; mode : integer):Boolean; var fs : TfileStream; currcert, currtoken, streamlen : TMemoryStream; data : string; hdrlen,seemcount, CurrSeemLen,i : Integer; currseem : Byte; a : string; blklen,loaderlen : DWORD; dcr : Boolean; RootInBlock : array[0..$F] of byte; j,good,i2 : Integer; n,k,l,m,PktLen : integer; ms, RAWBlock, RAWLoader : TmemoryStream; s, needSert : String; Key, KeyLen : Byte; PacketLen : Byte; BlockCount : Byte; CurrBlock : Byte; CurrBlockLen : Word; b, proto : Boolean; begin if mode=1 then begin Form1._msg('Dead Mode is Selected'); Form1._msg('Waiting for USB device...'); Form1._msg('--- Press phone'+#39+'s power button or insert cable & charger! ---'); Application.ProcessMessages; end; //Nokia USB ROM b:=false; i:=0; repeat if (i=2500) and (b=false) then begin Form1._msg('-> Phone not found.. :('); result:=False; Form1.SetReady; Exit; end; Application.ProcessMessages; if stop=True then begin // Stopping operation dostop('BOOT'); result:=false; Form1.pb1.progress:=0; i:=2499; b:=false; end; if catchdevice=$02 then begin b:=true; Form1._msg('Connection opened successfully'); end; Application.ProcessMessages; Sleep(10); inc(i); Form1.statusbar.Panels[0].Text:='Wait for phone '+inttostr(2500-i); Application.ProcessMessages; until b ; Form1.statusbar.Panels[0].Text:=''; Application.ProcessMessages; Form1._msg('Waiting for communication response...'); Application.ProcessMessages; if BB5_USB_BootRom_GetFirstBlock<2 then begin Form1.setready; Form1._msg('-> Error answer from BootRom'); Form1._msg('-> 1. Try make battery charge'); Form1._msg('-> 2. Try insert charger, without pressing poweron'); Form1._msg('-> 3. Try change USB port, if driver hang - restart PC'); result:=False; exit; end; Application.ProcessMessages; Form1.statusbar.Panels[3].Text:='Connected'; starttime; Application.ProcessMessages; // Root Hash Application.ProcessMessages; FillMemory(@RAPInfo.ROOT_KEY_HASH,$10,$00); FillMemory(@RAPInfo.APErootkey,$10,$00); FillMemory(@RAPInfo.FlashID,$A,$00); FillMemory(@RAPInfo.APEFlashID,$A,$00); FillMemory(@RAPInfo.PublicID,$14,$00); FillMemory(@RAPInfo.BootID,$8,$00); Application.ProcessMessages; Application.ProcessMessages; PacketLen :=rxbuf[0]; BlockCount :=rxbuf[1]; i:=2; j:=0; m:=0; while (i No ROOTKEY HASH Asic CMT. (IMEI DAMAGED?) Unable to continue flashing'); exit; end; Form1._msg('ROOT KEY HASH: '+ BufToHexStr(@RAPInfo.ROOT_KEY_HASH[0], Length(RAPInfo.ROOT_KEY_HASH))); end; $15://ROM_ID //4B9B75103E691FF8 begin for k:=0 to CurrBlockLen-1 do RAPInfo.ROM_ID[k]:= rxbuf[i+k]; Form1._msg('ROM ID: '+ BufToHexStr(@RAPInfo.ROM_ID[0], Length(RAPInfo.ROM_ID))); inc(i, CurrBlockLen); inc(j); end else begin inc(i, CurrBlockLen); inc(j); end; end;//End Of Case end; Application.ProcessMessages; //Извлечение RAW-Block RAWBlock:=TmemoryStream.Create; BB5_ExtractBlockOfRAWLoader(core, RAWBlock, b); if Not b then begin Form1.setready; Form1._msg('Error extracting RAW-loader'); RAWBlock.Free; exit; end; // RAWBlock.SaveToFile('C:\Extract_RAW_Loader_from_'+ExtractFileName(core)+'.bin'); //Извлечение и патчинг RAW-loader'a RAWLoader:=TmemoryStream.Create; BB5_ExtractRAWLoader(RAWBlock, RAWLoader, b); if Not b then begin Form1.setready; Form1._msg('Error Patching RAW-loader'); RAWLoader.Free; RAWBlock.Free; exit; end; Form1._msg('PatchRAWLoader: Patched OK'); //RAWLoader.SaveToFile('C:\RAW_Cert_Patch.bin'); //RAWLoader.Clear; {================================== SEND RAW LOADER ===================================} Application.processmessages; RAWLoader.Seek(0, sofrombeginning); b:=true; PktLen:=$1000; k:=1; txBuf[0]:=$40; txBuf[1]:=$57; txBuf[2]:=$01; txBuf[3]:=$00; txBuf[4]:=$00; txBuf[5]:=$00; Form1._msg('Processing RAWLOADER...'); while (RAWLoader.position$B2 then //Заголовок / идентификатор begin Form1.lst1.items.add('File damaged or Unknow format... :('); fs.Free; exit; end; fs.ReadBuffer(buf[0], 4);//Длина Flash-header'a HdrLen := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2)); //form1._msg('HeaderLen: '+inttostr(HdrLen)); fs.ReadBuffer(buf[0], 4);//Кол-во блоков в Flash-заголовке SeemCount := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2)); //form1._msg('BlockCount: '+inttostr(SeemCount)); Application.ProcessMessages; dcr:=false; currcert:=TMemoryStream.Create; currtoken:=TmemoryStream.Create; streamlen:=TMemoryStream.Create; good:=0; i2:=0; loaderlen:=0; try Form1.statusbar.Panels[4].Text:='Sending Boot'; while (fs.Position Boot error - device not ready - check battery/connection/HW'); currtoken.free; currcert.free; fs.Free; Exit; end; Application.ProcessMessages; end; /////// currtoken.clear; result:=True; Form1.pb1.progress:=Form1.pb1.progress+2; Application.processmessages; end; end; end; else begin fs.ReadBuffer(buf[0], 1); CurrSeemLen:=buf[0]; fs.Seek(CurrSeemLen, sofromcurrent); end; end; end; Form1.pb1.progress:=0; Form1.pb1.maxvalue:=100; if Result= True then form1._msg('Boot Done! :)') else begin result:=False; Form1.pb1.progress:=0; Form1.pb1.maxvalue:=100; form1._msg('-> Boot error... :('); currtoken.free; currcert.free; Fs.free; end; Form1.statusbar.Panels[4].Text:=''; currtoken.free; currcert.free; Fs.free; Application.ProcessMessages; i:=0; repeat begin Application.ProcessMessages; Inc(i); Form1.statusbar.Panels[0].Text:='Wait for phone '+inttostr(2000-i); Application.ProcessMessages; end; until (DevPresent=False) or (i=2000); Form1.statusbar.Panels[0].Text:=''; if i=2000 then begin result:=false; form1._msg('-> Boot error... Phone can'+#39+'t reboot'); exit; end; endtimecount; Form1._msg('TIME : Boot time : '+showtime(tmsres)); Application.ProcessMessages; except result:=False; Form1.pb1.progress:=0; Form1.pb1.maxvalue:=100; form1._msg('-> Boot error... :('); currtoken.free; currcert.free; Fs.free; end; end; function BB5_FlashingXSR15():boolean; var b, proto : Boolean; i : integer; rb : Byte; ms : TMemoryStream; begin Form1._msg('Reopening the connection...'); Application.ProcessMessages; Sleep(500); Application.ProcessMessages; adlmode:=$00; i:=30; while i>0 do begin Form1._msg('Waiting for response: '+inttostr(i)); Application.ProcessMessages; if catchdevice<>$02 then begin Application.ProcessMessages; sleep (1000); if stop=True then begin // Stopping operation dostop('FLASH'); i:=0; Form1.pb1.progress:=0; StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; end else i:=0; dec(i); end; if not DevPresent then begin Form1._msg('Phone not found... :('); Form1.SetBuzy; Form1.StatusBar.Panels[4].Text:=''; result:=False; USBClosePort; exit; end; fltime:=0; //Phone in Flash Mode??? CheckADLUpload[7]:=msgid; CheckADLUpload[8]:=ISIHeaderTransId; CheckADLUpload[9]:=$00; i:=USBBulkWritePort(@CheckADLUpload, Length(CheckADLUpload)); if i<>12 then exit; USBBulkReadPort(12); if rxBuf[11]<>$06 then begin if rxBuf[11]<>$80 then begin Form1._msg('ADL Server not confirmed flashmode!'); Form1._msg('ADL ReqPh : '+byte2str(rxbuf[11])); Form1.SetReady; result:=False; USBClosePort; exit; end else begin Form1._msg('ADL -> [2nd] changing...'); rb:=rxBuf[11]; end; end else rb:=rxBuf[11]; adlmode:=rb; Form1._msg('ADL Server confirm flashmode!'); case rb of $06: ADL06auth; // 6120, n76........ $80: ADL80auth; // 5800, n86........ end; selectAsicCMT[3]:=$6F; selectAsicCMT[8]:=ISIHeaderTransId; USBBulkWritePort(@selectAsicCMT, Length(selectAsicCMT)); if USBBulkReadPort($FFFF) then if rxBuf[10]=$00 then Form1._msg('ADL : ASIC CMT select Ok') else Form1._msg('ADL : Select CMT failed, try continue...'); Application.ProcessMessages; //Добавил для удобства кастом-прошивки Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[1].Text:=''; Form1.statusbar.Panels[2].Text:=''; Form1.statusbar.Panels[4].Text:='FLASHING'; Form1.statusbar.Panels[3].Text:='Connected'; Form1.TimConChk.Interval:=100; Application.ProcessMessages; if Form1.chkMCUen.Checked=true then begin Form1.chkMCUen.Enabled:=False; Form1._msg(' ===Flashing [MCU]==='); if not BB5_EraseFile(core) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not BB5_WriteFile(core) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('MCU Write done'); end; Application.ProcessMessages; if Form1.chkPPMe.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1._msg(' ===Flashing [PPM]==='); if not BB5_EraseFile(ppm) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not BB5_WriteFile(ppm) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('PPM Write done'); end; Application.ProcessMessages; if Form1.chkPPM1e.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1.chkPPM1e.Enabled:=False; Form1._msg(' ===Flashing [PPM2]==='); if not BB5_EraseFile(ppm1) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not BB5_WriteFile(ppm1) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('PPM Write done'); end; Application.ProcessMessages; if Form1.chkCNTe.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1.chkPPM1e.Enabled:=False; Form1.chkCNTe.Enabled:=False; Form1._msg(' ===Flashing [CNT]==='); if not BB5_EraseFile(image) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not BB5_WriteFile(image) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('CNT Write done'); end; Application.ProcessMessages; if Form1.chkAPEe.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1.chkPPM1e.Enabled:=False; Form1.chkCNTe.Enabled:=False; Form1.chkAPEe.Enabled:=False; Form1._msg(' ===Flashing [APE]==='); if not BB5_EraseFile(ape) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not BB5_WriteFile(ape) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('APE Write done'); end; Application.ProcessMessages; if Form1.chkcnt3.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1.chkPPM1e.Enabled:=False; Form1.chkCNTe.Enabled:=False; Form1.chkAPEe.Enabled:=False; Form1.chkcnt3.Enabled:=False; Form1._msg(' ===Flashing [CNT3]==='); if not BB5_EraseFile(cnt3) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not BB5_WriteFile(cnt3) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('CNT Write done'); end; Application.ProcessMessages; // режим рестарта AdlRestart06(rb); Application.ProcessMessages; Form1._msg(''); Form1._msg('Flashing done!'); Form1._msg('Total flash time : '+showtime(fltime)); Form1._msg('Reboot phone now...'); Form1._msg(''); Application.ProcessMessages; fltime:=0; Form1.statusbar.Panels[0].Text:=''; Form1.pb1.ForeColor:=clNavy; Form1.pbsm1.ForeColor:=clNavy; Form1.pb1.MaxValue:=100; Form1.pb1.progress:=0; Form1.statusbar.Panels[1].Text:=''; Form1.TimConChk.Interval:=2000; Form1.pb1.color:=clActiveBorder; if affenabled then Form1.afterFlashdo; Application.ProcessMessages; Sleep(200); Form1.SetReady; Form1.TimConChk.Enabled:=true; Form1._msg('Done!'); Form1.chkPPMe.Enabled:=True; Form1.chkMCUen.Enabled:=True; Form1.chkPPM1e.Enabled:=True; Form1.chkCNTe.Enabled:=True; Form1.chkAPEe.Enabled:=True; Form1.chkcnt3.Enabled:=True; Result:=true; end;//End of Normal Mode Flashing function RebuildPartition(F:TMemoryStream; PLen: integer):boolean; var Outstream:TmemoryStream; i:Integer; buf1:array [0..3] of Byte ; buf2:array [0..2] of Byte; cf : byte; len : Int64; blkcnt:DWORD; begin blkcnt:=0; len:=0; case PLen of // creating partition header, before tokens $22: Begin buf2[0]:=$01; buf2[1]:=$06; buf2[2]:=$00; end; $32: begin buf2[0]:=$02; buf2[1]:=$06; buf2[2]:=$00; end; $42: begin buf2[0]:=$03; buf2[1]:=$06; buf2[2]:=$00; end; $52: begin buf2[0]:=$04; buf2[1]:=$06; buf2[2]:=$00; end; $62: begin buf2[0]:=$05; buf2[1]:=$06; buf2[2]:=$00; end; $72: begin buf2[0]:=$06; buf2[1]:=$06; buf2[2]:=$00; end; end; ////////=////////// buf1[0]:=$06; // partiton tokens buf1[1]:=$14; buf1[2]:=$00; buf1[3]:=$00; Outstream:=TmemoryStream.Create; F.Seek(3, soFromBeginning); F.readbuffer(cf,1); F.Seek(3, soFromBeginning); Outstream.copyFrom(F,3); Outstream.Writebuffer(buf2[0],3); Outstream.copyfrom(F,8); F.ReadBuffer(blkcnt,4); DWordSwap(@blkcnt); for i:=1 to blkcnt do begin Outstream.Writebuffer(buf1[0],4); Outstream.copyfrom(F,16); end; ////1B 00 10 6F 00 62 00 15 75 10 ////1B 00 10 21 00 4E 00 12 11 10 ////build frame txBuf[0]:=$1B; txBuf[1]:=$00; txBuf[2]:=$10; case cf of // maybee ape exist? 0:txBuf[3]:=$6F; //cmt 1:txBuf[3]:=$21; // ape else txBuf[3]:=$6F; // anyway, if not detected - will be CMT end; txBuf[6]:=$00; txBuf[7]:=$0F; txBuf[8]:=ISIHeaderTransId; txBuf[9]:=$10; len:=Outstream.size; outstream.seek(0,soFromBeginning); outstream.ReadBuffer(txBuf[10], len); txBuf[4]:=(len+4) div $100; // build framelen txBuf[5]:=(len+4) mod $100; //form1._msg('buf : '+buftohexstr(@txbuf[0],len+$0A)); USBBulkWritePort(@txbuf[0],len+$A); // send data if USBBulkReadPort($FFFF) then begin if (rxBuf[10]=0) and (rxBuf[11]=0 ) then begin // Check buffer for answer - should be 00 00 Form1._msg('Partitioning : Ok ['+inttostr(blkcnt+1)+']'); result:=true; end else begin Form1._msg('Partitioning : Error :('); result:=False; end; end; Application.ProcessMessages; //Outstream.SaveToFile('C:\Data.bin'); Outstream.Free; end; function s60checkadl():Byte; begin ///1B 10 00 6F 00 06 17 37 08 20 00 07 ///1B 00 10 6F 00 06 00 17 08 00 00 00 AdlCheckst[8]:=ISIHeaderTransId; USBBulkWritePort(@AdlCheckst[0], Length(AdlCheckst)); If USBBulkReadPort($FFFF) then begin result:=rxbuf[11]; end; end; function ADLBootInFlash():Boolean; var n:Integer; begin ///1B 00 10 6F 00 06 00 14 09 04 00 00 - reboot in flash mode Application.ProcessMessages; ADLReboot[8]:=ISIHeaderTransId; n:=USBBulkWritePort(@AdlReboot[0], Length(ADLReboot)); if n<>12 then begin result:=False; Exit; end; n:=200; repeat begin Sleep(50); Application.ProcessMessages; dec(n); end; until (DevPresent=False) or (n=0); if n=0 then result:=False else result:=True; end; function ADL06auth ():Boolean; var len:Byte; begin USBBulkWritePort(@GetRootAsic, Length(GetRootAsic)); if USBBulkReadPort($FFFF) then //form1._msg(BufToHexStr(@rxBuf[0], Length(rxBuf))); len:=rxBuf[10]; if len>0 then begin bufcopy(@rxBuf[14],@txbuf[10],len); //1B00106F002E000F0406 txbuf[0]:=$1B; txbuf[1]:=$00; txbuf[2]:=$10; txbuf[3]:=$6F; txbuf[4]:=$00; txbuf[5]:=len+4; txbuf[6]:=$00; txbuf[7]:=$0F; txbuf[8]:=$04; txbuf[9]:=$06; USBBulkWritePort(@txbuf[0], len+$A); if USBBulkReadPort($FFF) then begin if rxBuf[10]<>0 then result:=true else result:=false; end; end else begin form1._msg('Get req info : empty'); end; end; function AdlRestart06 (rb:byte):Boolean; var i:integer; begin result:=false; case rb of $80: begin Form1._msg(' ================='); Form1._msg('ADL : End flashing'); AdlPreBootReq[8]:=ISIHeaderTransId; USBBulkWritePort(@AdlPreBootReq, Length(AdlPreBootReq)); if USBBulkReadPort($FFF) then begin if rxBuf[9]=$29 then Form1._msg('ADL : Finalize...'); i:=USBBulkWritePort(@adlrestersxr15, Length(adlrestersxr15)); if i<>12 then form1._msg('Error while rebooting :('); Application.ProcessMessages; end; end; $06: begin Form1._msg(' ================='); Form1._msg('ADL : End flashing'); AdlPreBootReq[8]:=ISIHeaderTransId; USBBulkWritePort(@AdlPreBootReq, Length(AdlPreBootReq)); if USBBulkReadPort($FFF) then begin if rxBuf[9]=$29 then Form1._msg('ADL : Finalize...'); i:=USBBulkWritePort(@adlrestersxr15, Length(adlrestersxr15)); if i<>12 then form1._msg('Error while rebooting :('); Application.ProcessMessages; end; end; end; end; function ADL80auth ():Boolean; var len:Byte; begin result:=False; ReqAdl80[8]:=ISIHeaderTransId; USBBulkWritePort(@ReqAdl80, Length(ReqAdl80)); if USBBulkReadPort($FFF) then begin if rxbuf[11]<>$01 then exit; ADL80RootReq[8]:=ISIHeaderTransId; USBBulkWritePort(@ADL80RootReq, Length(ADL80RootReq)); if USBBulkReadPort($FFF) then begin Application.ProcessMessages; end; Flastartreq[8]:=ISIHeaderTransId; USBBulkWritePort(@Flastartreq, Length(Flastartreq)); if USBBulkReadPort($FFF) then begin if rxbuf[10]<>$01 then Exit; Application.ProcessMessages; end; result:=True; form1._msg('ADL : Auth done...'); end; end; function OMAP2420boot () : boolean; var CMTadl, APEadl:TMemoryStream; b :Boolean; tmp :array of Byte; CHK, pktlen :Word; k :Integer; i :Word; begin // mdstart adlstartmode[8]:=ISIHeaderTransId; adlstartmode[7]:= $14; USBBulkWritePort(@adlstartmode, Length(adlstartmode)); If USBBulkReadPort($FFFF) then begin Application.ProcessMessages; //Form1._msg(BufToHexStr(@rxBuf[0], Length(rxBuf))); end; CMTadl:=TMemoryStream.Create; BB5_ExtractCertData(core,'UPDAPP', CMTAdl, b, false); ///CMTAdl.SaveToFile('C:\ADL.bin'); CMTAdl.Seek(0, soFromBeginning); SetLength(tmp, CMTAdl.Size); if CMTAdl.size=0 then begin result:=False; Exit; end; CMTAdl.ReadBuffer(tmp[0], CMTAdl.Size); CHK:=GetLoaderCRC(@tmp[0], CMTAdl.Size); Form1._msg('CMT Loader len: '+inttostr(CMTAdl.Size)+', CHK: '+inttohex(CHK, 4)); Application.ProcessMessages; Form1._msg('Sending CMT boot....'); // sending CRC and len of loader Sendomapcrcadl[7]:= $14; Sendomapcrcadl[8]:=ISIHeaderTransId; Sendomapcrcadl[12]:=CMTAdl.Size div $1000000; Sendomapcrcadl[13]:=CMTAdl.Size div $10000; Sendomapcrcadl[14]:=CMTAdl.Size div $100; Sendomapcrcadl[15]:=CMTAdl.Size mod $100; Sendomapcrcadl[16]:=CHK div $100; Sendomapcrcadl[17]:=CHK mod $100; USBBulkWritePort(@sendomapcrcadl, Length(Sendomapcrcadl)); If USBBulkReadPort($FFFF) then begin //Form1._msg(buftohexstr(@rxBuf[0],Length(rxBuf))); if rxBuf[11]<>0 then Form1._msg('Accept error, skip'); end; //Отправка агента по кусочкам b:=true; i:=1;//номер сообщения MsgBody:=2;//номер сообщения PktLen:=$0780;//длина отправляемого кусочка лоадера (длина как в Фениксе) Form1.pb1.Progress:=0; //ms:=TMemoryStream.Create;//для теста и сохранения текущего отправленного кусочка BufCopy(@Sendomapadl[0], @txBuf[0], Length(Sendomapadl)); //SendADL : array[0..15] of Byte = //($1B, $00, $10, $6F, $07, $8A, $00, $15, $56, $03, $00, $01, $00, $00, $07, $80); txBuf[8] := ISIHeaderTransId; CMTAdl.Seek(0, sofromBeginning); Application.ProcessMessages; while (CMTAdl.Position+PktLen)<=CMTAdl.Size do begin CMTAdl.ReadBuffer(txBuf[16], PktLen); Word((@txBuf[4])^):=Swap(PktLen+$0A); txBuf[3] :=$6F; txBuf[7] := $14; txBuf[8] := ISIHeaderTransId; Word((@txBuf[10])^):=Swap(i); Word((@txBuf[14])^):=Swap(PktLen); //Только для сохранения отправляемых кусочков агента {ms.Seek(0, soFromBeginning); ms.WriteBuffer(txBuf[0], 16); ms.WriteBuffer(txBuf[16], PktLen); ms.SaveToFile('C:\ADL_Send\'+Int2Digs(i,4)+'.bin'); ms.Clear;} k:=USBBulkWritePort(@txbuf[0], (PktLen+$10)); if k<>(PktLen+$10) then begin Form1.pb1.progress:=0; Form1._msg('Error while boot... :('); Form1._msg(''); USBClosePort; exit; end; USBBulkReadPort(16); if ((CMTAdl.Size-CMTAdl.position)0 then Form1._msg('Accept error, skip'); end; Application.ProcessMessages; Form1._msg('Sending APE boot....'); //Отправка агента по кусочкам b:=true; i:=1;//номер сообщения MsgBody:=2;//номер сообщения PktLen:=$0780;//длина отправляемого кусочка лоадера (длина как в Фениксе) Form1.pb1.Progress:=0; //ms:=TMemoryStream.Create;//для теста и сохранения текущего отправленного кусочка BufCopy(@Sendomapadl[0], @txBuf[0], Length(Sendomapadl)); //SendADL : array[0..15] of Byte = //($1B, $00, $10, $6F, $07, $8A, $00, $15, $56, $03, $00, $01, $00, $00, $07, $80); txBuf[8] := ISIHeaderTransId; APEAdl.Seek(0, sofromBeginning); Application.ProcessMessages; while (APEAdl.Position+PktLen)<=APEAdl.Size do begin APEAdl.ReadBuffer(txBuf[16], PktLen); Word((@txBuf[4])^):=Swap(PktLen+$0A); txBuf[3] := $21; txBuf[7] := $14; txBuf[8] := ISIHeaderTransId; Word((@txBuf[10])^):=Swap(i); Word((@txBuf[14])^):=Swap(PktLen); k:=USBBulkWritePort(@txbuf[0], (PktLen+$10)); if k<>(PktLen+$10) then begin Form1.pb1.progress:=0; Form1._msg('Error while boot... :('); Form1._msg(''); USBClosePort; exit; end; USBBulkReadPort(16); if ((APEAdl.Size-APEAdl.position)0 then Form1._msg('Accept error, skip'); end; //Отправка агента по кусочкам b:=true; i:=1;//номер сообщения MsgBody:=2;//номер сообщения PktLen:=$0780;//длина отправляемого кусочка лоадера (длина как в Фениксе) Form1.pb1.Progress:=0; //ms:=TMemoryStream.Create;//для теста и сохранения текущего отправленного кусочка BufCopy(@Sendomapadl[0], @txBuf[0], Length(Sendomapadl)); //SendADL : array[0..15] of Byte = //($1B, $00, $10, $6F, $07, $8A, $00, $15, $56, $03, $00, $01, $00, $00, $07, $80); txBuf[8] := ISIHeaderTransId; CMTAdl.Seek(0, sofromBeginning); Application.ProcessMessages; while (CMTAdl.Position+PktLen)<=CMTAdl.Size do begin CMTAdl.ReadBuffer(txBuf[16], PktLen); Word((@txBuf[4])^):=Swap(PktLen+$0A); txBuf[3] :=$6F; txBuf[7] := $18; txBuf[8] := ISIHeaderTransId; Word((@txBuf[10])^):=Swap(i); Word((@txBuf[14])^):=Swap(PktLen); //Только для сохранения отправляемых кусочков агента {ms.Seek(0, soFromBeginning); ms.WriteBuffer(txBuf[0], 16); ms.WriteBuffer(txBuf[16], PktLen); ms.SaveToFile('C:\ADL_Send\'+Int2Digs(i,4)+'.bin'); ms.Clear;} k:=USBBulkWritePort(@txbuf[0], (PktLen+$10)); if k<>(PktLen+$10) then begin USBClosePort; Form1._msg('Error while boot... :('); Form1._msg(''); exit; end; USBBulkReadPort(16); if ((CMTAdl.Size-CMTAdl.position)0 then Form1._msg('Accept error, skip'); end; Application.ProcessMessages; Form1._msg('Sending APE boot....'); //Отправка агента по кусочкам b:=true; i:=1;//номер сообщения MsgBody:=2;//номер сообщения PktLen:=$0780;//длина отправляемого кусочка лоадера (длина как в Фениксе) Form1.pb1.Progress:=0; //ms:=TMemoryStream.Create;//для теста и сохранения текущего отправленного кусочка BufCopy(@Sendomapadl[0], @txBuf[0], Length(Sendomapadl)); //SendADL : array[0..15] of Byte = //($1B, $00, $10, $6F, $07, $8A, $00, $15, $56, $03, $00, $01, $00, $00, $07, $80); txBuf[8] := ISIHeaderTransId; APEAdl.Seek(0, sofromBeginning); Application.ProcessMessages; while (APEAdl.Position+PktLen)<=APEAdl.Size do begin APEAdl.ReadBuffer(txBuf[16], PktLen); Word((@txBuf[4])^):=Swap(PktLen+$0A); txBuf[3] := $21; txBuf[7] := $18; txBuf[8] := ISIHeaderTransId; Word((@txBuf[10])^):=Swap(i); Word((@txBuf[14])^):=Swap(PktLen); k:=USBBulkWritePort(@txbuf[0], (PktLen+$10)); if k<>(PktLen+$10) then begin USBClosePort; Form1._msg('Error while boot... :('); Form1._msg(''); exit; end; USBBulkReadPort(16); if ((APEAdl.Size-APEAdl.position)0 then Form1._msg('Accept error, skip'); end; //Отправка агента по кусочкам b:=true; i:=1;//номер сообщения MsgBody:=2;//номер сообщения PktLen:=$0780;//длина отправляемого кусочка лоадера (длина как в Фениксе) Form1.pb1.Progress:=0; //ms:=TMemoryStream.Create;//для теста и сохранения текущего отправленного кусочка BufCopy(@Sendomapadl[0], @txBuf[0], Length(Sendomapadl)); //SendADL : array[0..15] of Byte = //($1B, $00, $10, $6F, $07, $8A, $00, $15, $56, $03, $00, $01, $00, $00, $07, $80); txBuf[8] := ISIHeaderTransId; CMTAdl.Seek(0, sofromBeginning); Application.ProcessMessages; while (CMTAdl.Position+PktLen)<=CMTAdl.Size do begin CMTAdl.ReadBuffer(txBuf[16], PktLen); Word((@txBuf[4])^):=Swap(PktLen+$0A); txBuf[3] :=$6F; txBuf[7] := $18; txBuf[8] := ISIHeaderTransId; Word((@txBuf[10])^):=Swap(i); Word((@txBuf[14])^):=Swap(PktLen); //Только для сохранения отправляемых кусочков агента {ms.Seek(0, soFromBeginning); ms.WriteBuffer(txBuf[0], 16); ms.WriteBuffer(txBuf[16], PktLen); ms.SaveToFile('C:\ADL_Send\'+Int2Digs(i,4)+'.bin'); ms.Clear;} k:=USBBulkWritePort(@txbuf[0], (PktLen+$10)); if k<>(PktLen+$10) then begin USBClosePort; Form1._msg('Error while boot... :('); Form1._msg(''); exit; end; USBBulkReadPort(16); if ((CMTAdl.Size-CMTAdl.position)0 then Form1._msg('Accept error, skip'); end; Application.ProcessMessages; Form1._msg('Sending APE boot....'); //Отправка агента по кусочкам b:=true; i:=1;//номер сообщения MsgBody:=2;//номер сообщения PktLen:=$0780;//длина отправляемого кусочка лоадера (длина как в Фениксе) Form1.pb1.Progress:=0; //ms:=TMemoryStream.Create;//для теста и сохранения текущего отправленного кусочка BufCopy(@Sendomapadl[0], @txBuf[0], Length(Sendomapadl)); //SendADL : array[0..15] of Byte = //($1B, $00, $10, $6F, $07, $8A, $00, $15, $56, $03, $00, $01, $00, $00, $07, $80); txBuf[8] := ISIHeaderTransId; APEAdl.Seek(0, sofromBeginning); Application.ProcessMessages; while (APEAdl.Position+PktLen)<=APEAdl.Size do begin APEAdl.ReadBuffer(txBuf[16], PktLen); Word((@txBuf[4])^):=Swap(PktLen+$0A); txBuf[3] := $21; txBuf[7] := $18; txBuf[8] := ISIHeaderTransId; Word((@txBuf[10])^):=Swap(i); Word((@txBuf[14])^):=Swap(PktLen); k:=USBBulkWritePort(@txbuf[0], (PktLen+$10)); if k<>(PktLen+$10) then begin USBClosePort; Form1._msg('Error while boot... :('); Form1._msg(''); exit; end; USBBulkReadPort(16); if ((APEAdl.Size-APEAdl.position)0 do begin Form1._msg('Waiting for response: '+inttostr(i)); Application.ProcessMessages; if catchdevice<>$02 then begin Application.ProcessMessages; sleep (1500); Application.ProcessMessages; if stop=True then begin // Stopping operation dostop('BOOT'); Form1.pb1.progress:=0; i:=0; end; sleep (1500); Application.ProcessMessages; end else i:=0; dec(i); end; if not DevPresent then begin Form1._msg('Phone not found... :('); Form1.SetBuzy; Form1.StatusBar.Panels[4].Text:=''; result:=False; USBClosePort; exit; end; fltime:=0; //Phone in Flash Mode??? CheckADLUpload[3]:=$6F; CheckADLUpload[7]:=msgid; CheckADLUpload[8]:=ISIHeaderTransId; CheckADLUpload[9]:=$00; i:=USBBulkWritePort(@CheckADLUpload, Length(CheckADLUpload)); if i<>12 then exit; USBBulkReadPort(12); if rxBuf[11]<>$03 then begin if rxBuf[11]<>$80 then begin Form1._msg('ADL Server (CMT) not confirmed flashmode!'); Form1._msg('ADL ReqPh : '+byte2str(rxbuf[11])); Form1.SetReady; result:=False; USBClosePort; exit; end else begin //1B 00 10 6F 00 06 00 14 A9 80 00 00 end; end; //Phone in Flash Mode??? CheckADLUpload[3]:=$21; CheckADLUpload[7]:=msgid; CheckADLUpload[8]:=ISIHeaderTransId; CheckADLUpload[9]:=$00; i:=USBBulkWritePort(@CheckADLUpload, Length(CheckADLUpload)); if i<>12 then exit; USBBulkReadPort(12); CheckADLUpload[3]:=$6F; // чистим, на всякий if rxBuf[11]<>$03 then begin if rxBuf[11]<>$80 then begin Form1._msg('ADL Server (APE) not confirmed flashmode!'); Form1._msg('ADL ReqPh : '+byte2str(rxbuf[11])); Form1.SetReady; result:=False; USBClosePort; exit; end; end; rb:=rxbuf[11]; Form1._msg('ADL Server confirm flashmode!'); case rb of $80 : begin get2420root[8]:=ISIHeaderTransID; UsbBulkWriteport(@get2420root, Length(get2420root)); if usbbulkreadport($FFFF) then begin form1._msg('ADL : Auth Ok'); Application.ProcessMessages; end; end; $03 : begin Application.Processmessages; form1._msg('ADL : Auth skip'); //sentroot+pc+hash-> conf APE //send crc& end; end; if stop=True then begin // Stopping operation dostop('FLASH'); Form1.pb1.progress:=0; Form1._msg(' Flashing failed...'); Form1.SetReady; Form1.enableFLtab; StuffFlashReset; result:=False; Exit; Form1._msg(''); exit; end; selectAsicCMT[3]:=$6F; selectAsicCMT[8]:=ISIHeaderTransId; USBBulkWritePort(@selectAsicCMT, Length(selectAsicCMT)); if USBBulkReadPort($FFFF) then begin if rxbuf[10]<>$00 then begin Form1._msg('ADL : Select CMT failed!'); Exit; end; Form1._msg('ADL : ASIC CMT select Ok'); Application.ProcessMessages; end; selectAsicCMT[3]:=$21; SelectAsicCMT[8]:=ISIHeaderTransId; USBBulkWritePort(@selectAsicCMT, Length(selectAsicCMT)); if USBBulkReadPort($FFFF) then begin if rxbuf[10]<>$00 then begin Form1._msg('ADL : Select APE failed!'); Exit; end; Form1._msg('ADL : ASIC APE select Ok'); selectAsicCMT[3]:=$6F; Application.ProcessMessages; end; //Добавил для удобства кастом-прошивки Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[1].Text:=''; Form1.statusbar.Panels[2].Text:=''; Form1.statusbar.Panels[4].Text:='FLASHING'; Form1.statusbar.Panels[3].Text:='Connected'; Form1.TimConChk.Interval:=100; Application.ProcessMessages; Form1.chkMCUen.checked:=true; Form1.chkPPMe.checked:=true; Form1.chkMCUen.Enabled:=False; Form1.chkPPMe.Enabled:=False; if Form1.chkMCUen.Checked=true then begin Form1._msg(' ===Flashing [MCU]==='); if not BB5_EraseFile(core) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not BB5_WriteFile(core) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('MCU Write done'); end; Application.ProcessMessages; if Form1.chkPPMe.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1._msg(' ===Flashing [PPM]==='); if not BB5_EraseFile(ppm) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not BB5_WriteFile(ppm) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('PPM Write done'); end; Application.ProcessMessages; if Form1.chkPPM1e.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1.chkPPM1e.Enabled:=False; Form1._msg(' ===Flashing [PPM2]==='); if not BB5_EraseFile(ppm1) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not BB5_WriteFile(ppm1) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('PPM Write done'); end; Application.ProcessMessages; if Form1.chkCNTe.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1.chkPPM1e.Enabled:=False; Form1.chkCNTe.Enabled:=False; Form1._msg(' ===Flashing [CNT]==='); if not BB5_EraseFile(image) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not BB5_WriteFile(image) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('CNT Write done'); end; Application.ProcessMessages; if Form1.chkAPEe.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1.chkPPM1e.Enabled:=False; Form1.chkCNTe.Enabled:=False; Form1.chkAPEe.Enabled:=False; Form1._msg(' ===Flashing [APE]==='); if not BB5_EraseFile(ape) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not BB5_WriteFile(ape) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('APE Write done'); end; Application.ProcessMessages; if Form1.chkcnt3.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1.chkPPM1e.Enabled:=False; Form1.chkCNTe.Enabled:=False; Form1.chkAPEe.Enabled:=False; Form1.chkcnt3.Enabled:=False; Form1._msg(' ===Flashing [CNT3]==='); if not BB5_EraseFile(cnt3) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not BB5_WriteFile(cnt3) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('CNT Write done'); end; if not ADLAPErestart(rb) then begin Application.ProcessMessages; Sleep(200); Form1.SetReady; Form1.TimConChk.Enabled:=true; Form1._msg('-> Flashing Failed! :( Maybee HW error, or Downgrade try???!'); Form1._msg(''); Form1.DisconnectFill; Result:=false; exit; end; Application.ProcessMessages; Form1._msg(''); Form1._msg('Flashing done!'); Form1._msg('Total flash time : '+showtime(fltime)); Form1._msg('Reboot phone now...'); Form1._msg(''); Application.ProcessMessages; fltime:=0; Form1.statusbar.Panels[0].Text:=''; Form1.pb1.ForeColor:=clNavy; Form1.pbsm1.ForeColor:=clNavy; Form1.pb1.MaxValue:=100; Form1.pb1.progress:=0; Form1.statusbar.Panels[1].Text:=''; Form1.TimConChk.Interval:=2000; Form1.pb1.color:=clActiveBorder; if affenabled then Form1.afterFlashdo; Application.ProcessMessages; Sleep(200); Form1.TimConChk.Enabled:=true; Form1._msg('Done!'); Form1.chkPPMe.Enabled:=True; Form1.chkMCUen.Enabled:=True; Form1.chkPPM1e.Enabled:=True; Form1.chkCNTe.Enabled:=True; Form1.chkAPEe.Enabled:=True; Form1.chkcnt3.Enabled:=true; Result:=true; end; function Omap1610extrboot(ASIC:string):boolean; var fs,resstream :TMemoryStream; data :string; hdrlen,seemcount, CurrSeemLen,i :Integer; currseem :Byte; loaderlen :DWORD; copysize :int64; begin result:=False; try fs:=TMemoryStream.Create; if ASIC='CMT' then fs.LoadFromFile(ExtractFilePath(Application.ExeName)+'\Flash\ADLREVC00.adl') else fs.LoadFromFile(ExtractFilePath(Application.ExeName)+'\Flash\ADLREVA00.adl'); fs.Read(buf[0] ,1); if buf[0]<>$B3 then //Заголовок / идентификатор begin Form1.lst1.items.add('-> File damaged or Unknow format... :('); fs.Free; exit; end; fs.ReadBuffer(buf[0], 4);//Длина Flash-header'a HdrLen := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2)); fs.ReadBuffer(buf[0], 4);//Кол-во блоков в Flash-заголовке SeemCount := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2)); Application.ProcessMessages; while (fs.Position$00 then begin Form1._msg('-> ADL : Close CMT session failed :('); result:=false; Exit; end; Form1._msg('ADL : Close CMT session Ok'); Application.ProcessMessages; end; CMTfinish[3]:=$21; CMTfinish[8]:=ISIHeaderTransId; USBBulkWritePort(@CMTfinish, Length(CMTfinish)); if USBBulkReadPort($FFFF) then begin if rxbuf[10]<>$00 then begin Form1._msg('-> ADL : Close APE session failed :('); result:=False; Exit; end; Form1._msg('ADL : Close APE session Ok'); Application.ProcessMessages; end; EndOmapFlash[3]:=$6F; EndOmapFlash[8]:=ISIHeaderTransId; USBBulkWritePort(@EndOmapFlash, Length(EndOmapFlash)); EndOmapFlash[3]:=$21; EndOmapFlash[8]:=ISIHeaderTransId; USBBulkWritePort(@EndOmapFlash, Length(EndOmapFlash)); EndOmapFlash[3]:=$6F; EndOmapFlash[8]:=ISIHeaderTransId; USBBulkWritePort(@EndOmapFlash, Length(EndOmapFlash)); result:=True; end; $80: begin Form1._msg(' ================='); Form1._msg('ADL : End flashing'); CMTfinish[3]:=$6F; CMTfinish[8]:=ISIHeaderTransId; CMTfinish[10]:=$02; USBBulkWritePort(@CMTfinish, Length(CMTfinish)); if USBBulkReadPort($FFFF) then begin if rxbuf[10]<>$00 then begin Form1._msg('-> ADL : Close CMT session failed :('); result:=false; Exit; end; Form1._msg('ADL : Close CMT session Ok'); Application.ProcessMessages; end; CMTfinish[3]:=$21; CMTfinish[8]:=ISIHeaderTransId; CMTfinish[10]:=$00; USBBulkWritePort(@CMTfinish, Length(CMTfinish)); if USBBulkReadPort($FFFF) then begin if rxbuf[10]<>$00 then begin Form1._msg('-> ADL : Close APE session failed :('); result:=false; Exit; end; Form1._msg('ADL : Close APE session Ok'); Application.ProcessMessages; end; EndOmapFlash[3]:=$6F; EndOmapFlash[8]:=ISIHeaderTransId; EndOmapFlash[10]:=$02; USBBulkWritePort(@EndOmapFlash, Length(EndOmapFlash)); EndOmapFlash[3]:=$21; EndOmapFlash[8]:=ISIHeaderTransId; EndOmapFlash[10]:=$00; USBBulkWritePort(@EndOmapFlash, Length(EndOmapFlash)); EndOmapFlash[3]:=$6F; EndOmapFlash[10]:=$00; result:=True; end; end; end; function S40BuildCertBody(core:string):Boolean; var buf :array[0..$3FFFF] of byte; EntryPoint, DataLen, TargetOffset, CRCTmp : LongInt; i, n, Blocks, Packets,icl : Integer; good : Integer; fs : TFileStream; certname : string; begin fs:=TFileStream.Create(core,fmOpenRead); fs.Seek(0, sofromBeginning); Application.ProcessMessages; S40adl80CRTdata[7]:=msgid; S40adl80CRTdata[8]:=ISIHEaderTransID; S40adl80CRTdata[28]:=csbyte1; S40adl80CRTdata[29]:=csbyte2; S40adl80CRTdata[30]:=csbyte3; //31 - DSP S40adl80CRTdata[48]:=csbyte1; S40adl80CRTdata[49]:=csbyte2; S40adl80CRTdata[50]:=csbyte3; //51 - MCUSW S40adl80CRTdata[68]:=csbyte1; S40adl80CRTdata[69]:=csbyte2; S40adl80CRTdata[70]:=csbyte3; //71 - NOLO S40adl80CRTdata[88]:=csbyte1; S40adl80CRTdata[89]:=csbyte2; S40adl80CRTdata[90]:=csbyte3; //91 - UPDAPP try fs.Read(i,1); if i<>$B2 then raise E.Create('CRTBuild : Bad image file'); fs.ReadBuffer(buf[0], 4);//Длина Flash Header DataLen := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2)); fs.Seek(DataLen,soFromCurrent); EntryPoint := fs.Position; Form1._msg('ADL : Check data'); while fs.Position$54) and (buf[0]<>$5D) then raise E.Create('CRTBuild : Bad image file, Corrupted blocks!' ); case buf[0] of $54://Phoenix-token begin fs.ReadBuffer(buf[0], $3); case buf[1] of $17 : begin fs.ReadBuffer(buf[0], buf[2]+1); DataLen := HexToInt(IntToHex(buf[6], 2)+IntToHex(buf[7], 2)+IntToHex(buf[8], 2)+IntToHex(buf[9], 2)); //Form1._msg(inttohex(buf[0],2)+inttohex(buf[1],2)); fs.Seek(DataLen,soFromCurrent); continue; end; $2E : begin fs.ReadBuffer(buf[0], buf[2]+1); DataLen := HexToInt(IntToHex(buf[17], 2)+IntToHex(buf[18], 2)+IntToHex(buf[19], 2)+IntToHex(buf[20], 2)); // Form1._msg(inttohex(buf[0],2)+inttohex(buf[1],2)); fs.Seek(DataLen,soFromCurrent); continue; end; else begin fs.ReadBuffer(buf[0], buf[2]+1); DataLen := HexToInt(IntToHex(buf[6], 2)+IntToHex(buf[7], 2)+IntToHex(buf[8], 2)+IntToHex(buf[9], 2)); fs.Seek(DataLen,soFromCurrent); inc(blocks); continue; end; end; end; $5D://Phoenix-segment begin fs.ReadBuffer(buf[0], $3); fs.ReadBuffer(buf[0], buf[2]+1); DataLen := HexToInt(IntToHex(buf[37], 2)+IntToHex(buf[38], 2)+IntToHex(buf[39], 2)+IntToHex(buf[40], 2)); good:=0; for i:=$0 to $0F do if RAPInfo.Root_Key_Hash[i]=buf[i] then inc(good); if good<$10 then begin fs.Seek(DataLen, sofromCurrent); continue; end; CertName:=''; for i:=20 to 31 do if buf[i]=$00 then break else CertName:=CertName+Chr(buf[i]); if certname='NOLO' then begin //Form1._msg('Hash CERT ['+CertName+']'); fs.readbuffer(buf[0],$D); csbyte4:=buf[12]; S40adl80CRTdata[71]:=csbyte4; fs.Seek(DataLen-$D,soFromCurrent); continue; end else if certname='DSP0' then begin //Form1._msg('Hash CERT ['+CertName+']'); fs.readbuffer(buf[0],$D); csbyte4:=buf[12]; S40adl80CRTdata[31]:=csbyte4; fs.Seek(DataLen-$D,soFromCurrent); continue; end else if certname='MCUSW' then begin //Form1._msg('Hash CERT ['+CertName+']'); fs.readbuffer(buf[0],$D); csbyte4:=buf[12]; S40adl80CRTdata[51]:=csbyte4; fs.Seek(DataLen-$D,soFromCurrent); continue; end else if certname='UPDAPP' then begin //Form1._msg('Hash CERT ['+CertName+']'); fs.readbuffer(buf[0],$D); csbyte4:=buf[12]; S40adl80CRTdata[91]:=csbyte4; fs.Seek(DataLen-$D,soFromCurrent); continue; end else begin Application.ProcessMessages; fs.Seek(DataLen,soFromCurrent); continue; end; end; end; end; //form1._msg(buftohexstr(@S40adl80CRTdata[0],length(S40adl80CRTdata))); UsbBulkWritePort(@S40adl80CRTdata[0],length(S40adl80CRTdata)); UsbBulkReadPort($FFFF); if rxbuf[10]<>$00 then form1._msg('ADL : Data NOT accepted by phone, continue at user risk') else if rxbuf[11]=$FF then form1._msg('ADL : Data accepted') else form1._msg('ADL : Data accepted as update'); fs.Free; except Fs.free; form1._msg('ADL : Build check data failed!'); end; end; function ExtractloaderXSRRap3Gv4(mode:integer):Boolean; var fs : TfileStream; currcert, currtoken, streamlen : TMemoryStream; data : string; hdrlen,seemcount, CurrSeemLen,i : Integer; fblen :Byte; currseem : Byte; a : string; blklen,loaderlen : DWORD; dcr : Boolean; RootInBlock : array[0..$F] of byte; j,good,i2 : Integer; n,k,l,m,PktLen : integer; ms, RAWBlock, RAWLoader : TmemoryStream; s, needSert : String; Key, KeyLen : Byte; PacketLen : Byte; BlockCount : Byte; CurrBlock : Byte; CurrBlockLen : Word; b, proto : Boolean; ASIC : string; rapmode : Integer; loaderinfo : string; begin if mode=1 then begin Form1._msg('Dead Mode is Selected'); Form1._msg('Waiting for USB device...'); Form1._msg('--- Insert cable and charger or press phone'+#39+'s power button! ---'); Application.ProcessMessages; end; loaderinfo:=''; //Nokia USB ROM b:=false; i:=0; repeat if (i=2500) and (b=false) then begin Form1._msg('-> Phone not found.. :('); result:=False; Form1.statusbar.Panels[0].Text:=''; Form1.SetReady; Exit; end; Application.ProcessMessages; if stop=True then begin // Stopping operation dostop('BOOT'); Form1.pb1.progress:=0; i:=2499; b:=false; end; if catchdevice=$02 then begin b:=true; Form1._msg('Connection opened successfully'); end; Application.ProcessMessages; Sleep(10); inc(i); Form1.statusbar.Panels[0].Text:='Wait for phone '+inttostr(2500-i); Application.ProcessMessages; until b ; Form1.statusbar.Panels[0].Text:=''; ASIC:=''; //rapmode:=1; // rapmode=0 - rapu, rapmode=1 rap3gv4 Application.ProcessMessages; Form1._msg('Waiting for communication response...'); Application.ProcessMessages; if BB5_USB_BootRom_GetFirstBlock<2 then begin Form1.setready; Form1._msg('-> Error answer from BootRom'); result:=False; exit; end; Application.ProcessMessages; Form1.statusbar.Panels[3].Text:='Connected'; Application.ProcessMessages; starttime; Application.ProcessMessages; // Root Hash Application.ProcessMessages; FillMemory(@RAPInfo.ROOT_KEY_HASH,$10,$00); FillMemory(@RAPInfo.APErootkey,$10,$00); FillMemory(@RAPInfo.FlashID,$A,$00); FillMemory(@RAPInfo.APEFlashID,$A,$00); FillMemory(@RAPInfo.PublicID,$14,$00); FillMemory(@RAPInfo.BootID,$8,$00); FillMemory(@RapInfo.Algo,$F,$00); Application.ProcessMessages; //form1._msg('rxBuf : '+buftohexstr(@rxBuf[0], Length(rxBuf))); //Application.ProcessMessages; PacketLen :=rxbuf[0]; BlockCount :=rxbuf[1]; i:=2; j:=0; m:=0; while (i No ROOTKEY HASH Asic CMT. (IMEI DAMAGED?) Unable to continue flashing'); exit; end; Form1._msg('ROOT KEY HASH: '+ BufToHexStr(@RAPInfo.ROOT_KEY_HASH[0], Length(RAPInfo.ROOT_KEY_HASH))); end; $15://ROM_ID //4B9B75103E691FF8 begin for k:=0 to CurrBlockLen-1 do RAPInfo.ROM_ID[k]:= rxbuf[i+k]; Form1._msg('ROM ID: '+ BufToHexStr(@RAPInfo.ROM_ID[0], Length(RAPInfo.ROM_ID))); inc(i, CurrBlockLen); inc(j); end else begin inc(i, CurrBlockLen); inc(j); end; end;//End Of Case end; Application.ProcessMessages; if (ASIC<>'') and (ASIC<>'0000000000000000') then SelLoaders(asic) else begin result:=False; Form1._msg('Error finding bootdata or ASIC not supported!'); Form1._msg(''); Form1.SetReady; Exit; end; if (ExtractFileName(Floader))='' then begin result:=False; Form1._msg('Error finding bootdata or ASIC not supported!'); Form1._msg(''); Form1.SetReady; Exit; end; if (ExtractFileName(Floader)='RAP3Gv40_2nd.fg') or (Pos('BCM',ExtractFileName(Floader))<>0) then rapmode:=1 else rapmode:=0; try loaderinfo:=getversion(Floader); fs:=TFileStream.Create(floader,fmOpenRead); except Form1._msg('Can'+#39+'t open file '+ ExtractFileName(floader)); result:=false; exit; end; Form1._msg('Use '+ExtractFileName(Floader)+' '+loaderinfo); RAWLoader:=TmemoryStream.Create; RAWBlock:=TmemoryStream.Create; RAWblock.LoadFromstream(fs); Application.ProcessMessages; if Pos('BCM',ExtractFileName(Floader))<>0 then BB5_ExtractRAWLoader(RAWblock, RAWLoader, b) else RAWLoader:=PrepareRAWloader(RAWblock) ; fs.Free; {================================== SEND RAW LOADER ===================================} Application.processmessages; //RAWLoader.Seek(0, sofrombeginning); //RAWLoader.savetofile('C:\raw.bin'); RAWLoader.Seek(0, sofrombeginning); b:=true; PktLen:=$1000; k:=1; txBuf[0]:=$40; txBuf[1]:=$57; txBuf[2]:=$01; txBuf[3]:=$00; txBuf[4]:=$00; txBuf[5]:=$00; Form1._msg('Processing RAWLOADER...'); while (RAWLoader.position0 then Application.ProcessMessages else checkbootcode; end; end; CheckCMTboot; // проверяем верность загрузки равки loaderinfo:=''; try loaderinfo:=getversion(sloader); fs:=TFileStream.Create(sloader,fmOpenRead); except Form1._msg('Can'+#39+'t open file '+ ExtractFileName(sloader)); result:=false; exit; end; Form1._msg('Use '+ExtractFileName(sloader)+' '+loaderinfo); fs.Read(buf[0] ,1); if buf[0]<>$B1 then //Заголовок / идентификатор begin Form1.lst1.items.add('File damaged or Unknow format... :('); fs.Free; exit; end; fs.ReadBuffer(buf[0], 4);//Длина Flash-header'a HdrLen := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2)); //form1._msg('HeaderLen: '+inttostr(HdrLen)); fs.ReadBuffer(buf[0], 4);//Кол-во блоков в Flash-заголовке SeemCount := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2)); //form1._msg('BlockCount: '+inttostr(SeemCount)); Application.ProcessMessages; dcr:=false; currcert:=TMemoryStream.Create; currtoken:=TmemoryStream.Create; streamlen:=TMemoryStream.Create; good:=0; i2:=0; loaderlen:=0; try Form1.statusbar.Panels[4].Text:='Sending Boot'; while (fs.Position<>(fs.size)) do begin fs.ReadBuffer(CurrSeem, 1); case CurrSeem of//Перебор всех блоков, поиск блока со структурой RAW-loader'а $56: begin //Form1._msg('Cert Token found, processing...'); Application.ProcessMessages; fs.ReadBuffer(buf[0], 3); case Buf[1] of $17: // UPDAPP body ( 1st block - precrt ) begin //form1._msg('UpdAPP Body processing'); Application.ProcessMessages; CurrSeemLen :=buf[2]+1; //fs.ReadBuffer(buf[0], currseemlen); fs.Seek(fs.Position-4, sofromBeginning); currtoken.CopyFrom(fs,currseemlen+4); //currtoken.SaveToFile('C:\token'+inttostr(i2)+'.bin'); // send token's header Application.processmessages; currtoken.Seek(0, sofrombeginning); b:=true; PktLen:=$100; k:=1; txBuf[0]:=$40; txBuf[1]:=$60; txBuf[2]:=$00; txBuf[3]:=$00; txBuf[4]:=$00; txBuf[5]:=$00; k:=0; while (currtoken.position0) and (k=(currcert.Size div $1000)) then txbuf[2]:=$01; USBControlPacket($222040, $8+PktLen, 0); //Form1._msg('Cert K : '+inttostr(k)+' / '+inttostr(currcert.size div $1000)+' / byte '+byte2str(txbuf[2])); Form1.pb1.progress:=Form1.pb1.progress+1; Application.ProcessMessages; end; Application.ProcessMessages; currcert.clear; currtoken.Clear; end; $27: // UPDAPP CERT begin Application.ProcessMessages; good:=0; CurrSeemLen :=buf[2]+1; fs.Seek(fs.Position-4, sofromBeginning); currtoken.CopyFrom(fs,currseemlen+4); currtoken.seek(4,soFromBeginning); currtoken.ReadBuffer(RootInBlock[0], $10); //form1._msg('UPDAPP: '+buftohexstr(@rootinBlock[0], $10)); Application.ProcessMessages; for j:=0 to $0f do if RootInBlock[j]=RAPInfo.Root_Key_Hash[j] then inc(good); if good=$10 then begin //currtoken.SaveToFile('C:\token_upd_cert'+inttostr(i2)+'.bin'); //form1._msg('Processing UPDAPP...'); //Form1._msg('Flashing header UpdAPP'); // send token's header Application.processmessages; currtoken.Seek(0, sofrombeginning); b:=true; PktLen:=$100; k:=1; txBuf[0]:=$40; txBuf[1]:=$60; txBuf[2]:=$00; txBuf[3]:=$00; txBuf[4]:=$00; txBuf[5]:=$00; while (currtoken.position Boot error - device not ready - check battery/connection/HW'); currtoken.free; currcert.free; fs.Free; Exit; end; } USBControlPacket($222040, $8+PktLen, 0); Application.ProcessMessages; end; /////// currtoken.clear; result:=True; Form1.pb1.progress:=Form1.pb1.progress+2; Application.processmessages; end; end; end; else begin fs.ReadBuffer(buf[0], 1); CurrSeemLen:=buf[0]; fs.Seek(CurrSeemLen, sofromcurrent); end; end; end; if RAPUFinalizeboot(rapmode) then result:=True else result:=False; // финализируем Form1.pb1.progress:=0; Form1.pb1.maxvalue:=100; if Result= True then form1._msg('Boot Done! :)') else begin result:=False; Form1.pb1.progress:=0; Form1.pb1.maxvalue:=100; form1._msg('-> Boot error... :('); currtoken.free; currcert.free; Fs.free; Exit; end; Form1.statusbar.Panels[4].Text:=''; currtoken.free; currcert.free; Fs.free; Application.ProcessMessages; i:=0; repeat begin Sleep(100); Application.ProcessMessages; Inc(i); Form1.statusbar.Panels[0].Text:='Wait for phone '+inttostr(300-i); end; until (DevPresent=False) or (i=300); Form1.statusbar.Panels[0].Text:=''; if i=300 then begin result:=false; form1._msg('-> Boot error... Phone can'+#39+'t reboot'); exit; end; except result:=False; Form1.pb1.progress:=0; Form1.pb1.maxvalue:=100; form1._msg('-> Boot error... :('); currtoken.free; currcert.free; Fs.free; end; Application.ProcessMessages; endtimecount; form1._msg('TIME : Boot time : '+showtime(tmsres)+' '); Application.ProcessMessages; end; function PrepareRAWloader(loader:TMemoryStream):TMemoryStream; var b : Boolean; ULO : array[0..3] of Byte; MEDia : array[0..10] of Byte; RAWLoader : TMemoryStream; begin ULO[0]:=$55;ULO[1]:=$4C;ULO[2]:=$4F;ULO[3]:=$00; MEDia[0]:=$42;MEDia[1]:=$4F;MEDia[2]:=$4F;MEDia[3]:=$54; MEDia[4]:=$5F;MEDia[5]:=$4D;MEDia[6]:=$45;MEDia[7]:=$44; MEDia[8]:=$49;MEDia[9]:=$41;MEDia[10]:=$31; try //Извлечение и патчинг RAW-loader'a RAWLoader:=TmemoryStream.Create; BB5_ExtractRAWLoader(loader, RAWLoader, b); //Подготовка патчинга равки RAWloader.Seek(20,soFromBeginning); RAWloader.readbuffer(Buf[0],4); if buf[0]<>$4B then begin // Если не равно - начит позиция смещена на $32 вперед RAWloader.Seek(20,soFromBeginning); //RAP3GV4 SILO RAWloader.writebuffer(ulo[0],4); end else begin RAWloader.Seek(52,soFromBeginning); //RAPUx SILO RAWloader.writebuffer(ulo[0],4); end; RAWloader.Seek(148,soFromBeginning); RAWloader.readbuffer(Buf[0],$B); RAWloader.Seek(148,soFromBeginning); if (buf[0]=$42) and (buf[1]=$4F) then RAWloader.WriteBuffer(Media[0],$B) else result:=nil; //RAWloader.SaveToFile('C:\RAW_RAPNEW_patch.bin'); Result:=RAWloader; except Result:=nil; end; end; function checkbootcode():Boolean; begin result:=False; Sleep(50); Application.ProcessMessages; /// Check Upload Bootcode txBuf[0]:=$C0; txBuf[1]:=$61; txBuf[2]:=$00; txBuf[3]:=$00; txBuf[4]:=$00; txBuf[5]:=$00; txBuf[6]:=$00; txBuf[7]:=$10; USBControlPacket($222040, $8, $1000); //Form1._msg('rxbuf: '+BufToHexStr(@rxBuf[0], Length(rxBuf))); Application.ProcessMessages; sleep(50); /// Check Upload Bootcode txBuf[0]:=$C0; txBuf[1]:=$61; txBuf[2]:=$00; txBuf[3]:=$00; txBuf[4]:=$00; txBuf[5]:=$00; txBuf[6]:=$00; txBuf[7]:=$10; USBControlPacket($222040, $8, $1000); //Form1._msg('rxbuf: '+BufToHexStr(@rxBuf[0], Length(rxBuf))); // result:=True; end; function CheckCMTboot():Boolean; var BlockCount : Integer; j,k,i : Integer; currblock, currblocklen : Byte; devasic : Byte; begin bufcopy(@VenCHeckUpl[0],@txbuf[0], Length(VenCHeckUpl)); USBControlPacket($222040, Length(VenCHeckUpl), 0); Sleep(50); Application.ProcessMessages; /// Check Preboot txBuf[0]:=$C0; txBuf[1]:=$61; txBuf[2]:=$00; txBuf[3]:=$00; txBuf[4]:=$00; txBuf[5]:=$00; txBuf[6]:=$00; txBuf[7]:=$10; USBControlPacket($222040, $8, $1000); //Form1._msg('rxbuf: '+BufToHexStr(@rxBuf[0], Length(rxBuf))); if (rxbuf[0]=$C3) and (rxbuf[1]=$00) and (rxbuf[2]=$FF) then application.ProcessMessages else form1._msg('2nd boot not accepted... Alive Request not done :('); Application.ProcessMessages; bufcopy(@VenCheckFlic[0],@txbuf[0], Length(VenCheckFlic)); USBControlPacket($222040, Length(VenCheckFlic), 0); Sleep(50); Application.ProcessMessages; /// Check FLic txBuf[0]:=$C0; txBuf[1]:=$61; txBuf[2]:=$00; txBuf[3]:=$00; txBuf[4]:=$00; txBuf[5]:=$00; txBuf[6]:=$00; txBuf[7]:=$10; USBControlPacket($222040, $8, $1000); //Form1._msg('rxbuf: '+BufToHexStr(@rxBuf[0], Length(rxBuf))); if rxBuf[0]=$C1 then begin BlockCount :=rxbuf[1]; i:=2; j:=0; while j0 then begin bufcopy(@algsend3[0],@txbuf[0], Length(algsend3)); //Broadcomm USBControlPacket($222040, Length(algsend2), 0); // BroadComm end else begin bufcopy(@algsend2[0],@txbuf[0], Length(algsend2)); //RAP3Gv4 USBControlPacket($222040, Length(algsend2), 0); // Rap3Gv4 Sleep(50); txBuf[0]:=$C0; txBuf[1]:=$61; txBuf[2]:=$00; txBuf[3]:=$00; txBuf[4]:=$00; txBuf[5]:=$00; txBuf[6]:=$00; txBuf[7]:=$10; USBControlPacket($222040, $8, $1000); // Application.ProcessMessages; end; end; end; bufcopy(@VenCHeckUpl[0],@txbuf[0], Length(VenCHeckUpl)); USBControlPacket($222040, Length(VenCHeckUpl), 0); /// Check updboot txBuf[0]:=$C0; txBuf[1]:=$61; txBuf[2]:=$00; txBuf[3]:=$00; txBuf[4]:=$00; txBuf[5]:=$00; txBuf[6]:=$00; txBuf[7]:=$10; USBControlPacket($222040, $8, $1000); //Form1._msg('rxbuf: '+BufToHexStr(@rxBuf[0], Length(rxBuf))); Application.ProcessMessages; bufcopy(@bootflash[0],@txbuf[0], Length(bootflash)); USBControlPacket($222040, Length(bootflash), 0); /// Check updboot txBuf[0]:=$C0; txBuf[1]:=$61; txBuf[2]:=$00; txBuf[3]:=$00; txBuf[4]:=$00; txBuf[5]:=$00; txBuf[6]:=$00; txBuf[7]:=$10; USBControlPacket($222040, $8, $1000); //Form1._msg('rxbuf: '+BufToHexStr(@rxBuf[0], Length(rxBuf))); if (rxbuf[0]=$C3) and (rxbuf[1]=$00) and (rxbuf[2]=$FF) then result:=true else form1._msg('Transmission type request fail ['+byte2str(rxbuf[0])+byte2str(rxbuf[1])+byte2str(rxbuf[2])+']'); Application.ProcessMessages; end; function RAPnewChkADL ():Boolean; begin form1._msg('ADL: Check mode'); USBBulkWritePort(@rapuchkadl[0], Length(rapuchkadl)); if USBBulkReadPort($FFFF) then //form1._msg('rxbuf: '+buftohexstr(@rxBuf[0], Length(rxBuf))); if cmtreadreq then application.ProcessMessages else begin Form1._msg('ADL: flash mode confirm error...'); result:=false; exit; end; //form1._msg('ADL: Select ASIC'); UsbBulkWriteport(@rapuselAsic[0], length(rapuselAsic)); if USBBulkReadPort($FFFF) then //form1._msg('rxbuf: '+buftohexstr(@rxBuf[0], Length(rxBuf))); if (rxBuf[8]=$00) and (rxBuf[9]=$00) then Application.ProcessMessages else Form1._msg('Select ASIC ['+byte2str(rxBuf[8])+byte2str(rxBuf[9])+']'); //form1._msg('ADL: PAPUBKEYS_REQ'); UsbBulkWriteport(@rapugetroot[0], length(rapugetroot)); if USBBulkReadPort($FFFF) then Application.ProcessMessages; //form1._msg('rxbuf: '+buftohexstr(@rxBuf[0], Length(rxBuf))); //form1._msg('ADL: CRTCHK_REQ'); UsbBulkWriteport(@rapucrtchkreq[0], length(rapucrtchkreq)); if USBBulkReadPort($FFFF) then //form1._msg('rxbuf: '+buftohexstr(@rxBuf[0], Length(rxBuf))); if cmtreadreq then application.ProcessMessages else Form1._msg('CRT store return bad status...'); result:=true; end; function RAPnewChkADLWCRT ():Boolean; begin form1._msg('ADL: Check mode'); USBBulkWritePort(@rapuchkadl[0], Length(rapuchkadl)); if USBBulkReadPort($FFFF) then //form1._msg('rxbuf: '+buftohexstr(@rxBuf[0], Length(rxBuf))); if cmtreadreq then application.ProcessMessages else begin Form1._msg('ADL: flash mode confirm error...'); result:=false; exit; end; //form1._msg('ADL: Select ASIC'); UsbBulkWriteport(@rapuselAsic[0], length(rapuselAsic)); if USBBulkReadPort($FFFF) then //form1._msg('rxbuf: '+buftohexstr(@rxBuf[0], Length(rxBuf))); if (rxBuf[8]=$00) and (rxBuf[9]=$00) then Application.ProcessMessages else Form1._msg('Select ASIC ['+byte2str(rxBuf[8])+byte2str(rxBuf[9])+']'); //form1._msg('ADL: PAPUBKEYS_REQ'); UsbBulkWriteport(@rapugetroot[0], length(rapugetroot)); if USBBulkReadPort($FFFF) then Application.ProcessMessages; //form1._msg('rxbuf: '+buftohexstr(@rxBuf[0], Length(rxBuf))); result:=true; end; function RAPnewChkADL2 ():Boolean; begin form1._msg('ADL: Request programm status'); UsbBulkWriteport(@rapucloseASIC[0], length(rapucloseASIC)); if USBBulkReadPort($FFFF) then contentexplore; //form1._msg('ADL: PAPUBKEYS_REQ'); UsbBulkWriteport(@rapugetroot[0], length(rapugetroot)); if USBBulkReadPort($FFFF) then Application.ProcessMessages; //form1._msg('rxbuf: '+buftohexstr(@rxBuf[0], Length(rxBuf))); end; function RapNewFinish():boolean; begin form1._msg('ADL: Close_Session'); UsbBulkWriteport(@rapucloseASIC[0], length(rapucloseASIC)); if USBBulkReadPort($FFFF) then form1._msg('Content: '+buftohexstr(@rxBuf[12], $0F)); form1._msg('ADL: Reboot'); Application.ProcessMessages; Sleep(10); UsbBulkWriteport(@rapureboot[0], length(rapureboot)); Sleep(50); {if catchdevice<>$02 then Application.ProcessMessages else begin UsbBulkWriteport(@rapureboot[0], length(rapureboot)); } if USBBulkReadPort($FFFF) then //form1._msg('rxbuf: '+buftohexstr(@rxBuf[0], Length(rxBuf))); if ((rxBuf[0]=$80) and (rxBuf[1]=$0F) and (rxBuf[2]=$70)) or ((rxBuf[0]=$80) and (rxBuf[1]=$F0) and (rxBuf[2]=$8F)) then application.ProcessMessages else Form1._msg('Reboot req not accepted...'); end; function RapNewFinishLocal():boolean; begin form1._msg('ADL: Close_Session'); UsbBulkWriteport(@rapucloseASIC[0], length(rapucloseASIC)); if USBBulkReadPort($FFFF) then form1._msg('Content: '+buftohexstr(@rxBuf[12], $0F)); form1._msg('ADL: Reboot'); Application.ProcessMessages; Sleep(10); UsbBulkWriteport(@rapurebootlocal[0], length(rapurebootlocal)); Sleep(50); {if catchdevice<>$02 then Application.ProcessMessages else begin UsbBulkWriteport(@rapureboot[0], length(rapureboot)); } if USBBulkReadPort($FFFF) then //form1._msg('rxbuf: '+buftohexstr(@rxBuf[0], Length(rxBuf))); if ((rxBuf[0]=$80) and (rxBuf[1]=$0F) and (rxBuf[2]=$70)) or ((rxBuf[0]=$80) and (rxBuf[1]=$F0) and (rxBuf[2]=$8F)) then application.ProcessMessages else Form1._msg('Reboot req not accepted...'); end; function frameCrc(Buf:Pointer; buflen:Integer):Byte; begin Result:=0; while BufLen > 0 do begin Result:=Result+Byte(Buf^); inc(Integer(Buf)); dec(BufLen); end; Result:=Result xor $FF; end; function RapuYamaErase(core:string):Boolean; var fs : TFileStream; buf : array[0..$FFFF] of byte; n,j,buflen : Integer; HdrLen : Integer; HdrPos : LongInt; CurrSeem : Byte; CurrSeemLen, CurSeemcount : Integer; ms : TMemoryStream; loaderlen : DWORD; erase : Boolean; framelen : DWORD; begin Result:=false; partition:=false; erase:=False; Form1._msg('Erase : Processing '+ExtractFileName(core)); Application.processmessages; Form1.statusbar.Panels[1].text:=''; Application.ProcessMessages; fs:=TFileStream.Create(core,fmOpenRead); fs.Seek(0, sofromBeginning); fs.Read(buf[0],1); if buf[0]<>$B2 then begin fs.free; raise E.Create('Erase : Bad image file'); Exit; end; Application.ProcessMessages; starttime; Application.ProcessMessages; fs.ReadBuffer(buf[0], 4);//Длина Flash Header HdrLen := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2)); fs.Seek(4,soFromCurrent); try while fs.Position<(HdrLen) do begin fs.ReadBuffer(CurrSeem, 1); case CurrSeem of $EE: begin Application.ProcessMessages; form1._msg('Partitioning....'); partition:=True; partitionstream:=TmemoryStream.Create; fs.ReadBuffer(buf[0], 2); CurrSeemLen:=(buf[0]*$100)+buf[1]; partitionstream.copyFrom(fs,CurrSeemlen); partitionstream.Seek(0,soFromBeginning); Application.ProcessMessages; if partition=True then begin Application.ProcessMessages; framelen:=CurrSeemLen+10; DWord((@txBuf[0])^):=framelen; DWordSwap(@txbuf[0]); txBuf[4]:=$01; txBuf[5]:=$10; txBuf[6]:=$00; txBuf[7]:=frameCrc(@txbuf[0],7); txBuf[8]:=$64; partitionstream.ReadBuffer(txBuf[9], CurrSeemLen); txBuf[framelen-1]:=frameCrc(@txbuf[9],CurrSeemLen); //Form1._msg('txbuf : '+BufToHexStr(@txbuf[0],framelen)); USBBulkWritePort(@txbuf[0],framelen); delay(200); Application.ProcessMessages; USBBulkReadPort($FFFF); //Form1._msg('RxBuf : '+buftohexstr(@rxBuf[0],Length(rxBuf))); try if cmtreadreq then form1._msg('Partitioning Ok...') else begin Form1._msg('Partitioning error : '+buftohexstr(@rxBuf[0],4)); form1._msg('Partitioning failed! :('); result:=false; end; except Form1._msg('Partitioning error! Phone Not respond!'); Application.ProcessMessages; end; delay(300); Application.ProcessMessages; partitionstream.free; end; end; $C8: begin if stop=True then begin // Stopping operation dostop('ERASE'); Form1.pb1.progress:=0; Application.ProcessMessages; fs.Free; ms.free; exit; end; form1._msg('Erasing....'); erase:=True; Application.ProcessMessages; fs.ReadBuffer(buf[0], 1); CurrSeemLen:=buf[0]; ms:=TmemoryStream.Create; ms.copyFrom(fs,CurrSeemlen); ms.Seek(0,soFromBeginning); framelen:=CurrSeemLen+10; DWord((@txBuf[0])^):=framelen; DWordSwap(@txbuf[0]); txBuf[4]:=$01; txBuf[5]:=$10; txBuf[6]:=$00; txBuf[7]:=frameCrc(@txbuf[0],7); txBuf[8]:=$50; ms.ReadBuffer(txBuf[9], CurrSeemLen); txBuf[framelen-1]:=frameCrc(@txbuf[9],CurrSeemLen); //Form1._msg('txbuf : '+BufToHexStr(@txbuf[0],framelen)); USBBulkWritePort(@txbuf[0],framelen); delay(200); Application.ProcessMessages; USBBulkReadPort($FFFF); //Form1._msg('RxBuf : '+buftohexstr(@rxBuf[0],Length(rxBuf))); try if cmtreadreq then begin form1._msg('Erasing Ok...'); Result:=True; end else begin Form1._msg('Erase error : '+buftohexstr(@rxBuf[0],4)); form1._msg('Erasing failed! :('); form1._msg(''); result:=false; end; except Form1._msg('Erase error : Connection lost => HW error or Cable problem...'); form1._msg('Erasing failed! :('); form1._msg(''); fs.Free; ms.free; exit; end; delay(300); Application.ProcessMessages; endtimecount; Form1._msg('TIME : Erase time : '+showtime(tmsres)+' '); Application.ProcessMessages; Form1.pbsm1.Progress:=0; fs.Free; ms.free; exit; end else begin // Form1._msg('SEEM : '+byte2str(currseem)); fs.ReadBuffer(buf[0], 1); CurrSeemLen:=buf[0]; fs.readbuffer(buf[0],CurrSeemLen); application.ProcessMessages; end; end; end; if erase=False then begin result:=True; Form1._msg('Erase : No any region, skip erase'); end; fs.Free; except on E:Exception do begin fs.Free; Form1._msg('EraseFile: Error: '+E.Message); end; end; Application.ProcessMessages; endtimecount; Form1._msg('TIME : Erase time : '+showtime(tmsres)+' '); Application.ProcessMessages; end; function RapuYamaWriteFile(core:string):Boolean; const maxlen : dWORD = $4FFFF ; var buf :array[0..$4FFFF] of byte; HdrLen, CurrBlockLen : Cardinal; EntryPoint, DataLen, TargetOffset, CRCTmp : LongInt; i, n, Blocks, Packets,icl, CurrPacketSize, TokenHdrLen : Integer; good : Integer; CertName,AsicType : String; PAPUB_Already, APE_PAPUB : boolean; fs : TFileStream; ms : TMemoryStream; writen,framelen : Dword; cmtcount,cmtdin, TokenSubType, unk : integer; nopbyte : byte; nopword : word; ttxbuf : array[0..$4FFFF] of byte; begin Result:=False; Form1._msg('Write : Processing '+ExtractFileName(core)); fs:=TFileStream.Create(core,fmOpenRead); fs.Seek(0, sofromBeginning); Blocks:=0; cmtcount:=0; cmtdin:=0; unk:=0; Form1.pb1.ForeColor:=clGreen; Form1.pb1.progress:=0; Application.ProcessMessages; try fs.Read(ttxbuf[0],1); if ttxbuf[0]<>$B2 then begin fs.free; raise E.Create('Write : Bad image file'); end; Application.ProcessMessages; starttime; Application.ProcessMessages; fs.ReadBuffer(ttxbuf[0], 4);//Длина Flash-header'a HdrLen := HexToInt(IntToHex(ttxbuf[0], 2)+IntToHex(ttxbuf[1], 2)+ IntToHex(ttxbuf[2], 2)+IntToHex(ttxbuf[3], 2)); fs.Seek(HdrLen, sofromcurrent);//К началу первого Flash-токена {ms:=TMemoryStream.Create;} form1.pb1.maxvalue:=(fs.size-hdrlen); form1.statusbar.Panels.Items[0].Text:='Writing...'; while fs.Position HW error or Cable problem...'); form1._msg('Write CMT failed on block '+inttostr(Blocks)+' :('); form1._msg(''); fs.Free; exit; end; Application.ProcessMessages; inc(blocks); form1.statusbar.Panels[1].Text:='CMT : '+inttostr(Blocks); end;//End of Case $54 $5D://Phoenix-segment begin //5D 0127 2D 25B977A055BE9B5DEC0C38A2A279C695 8594B99841444100000000000000000000030077E7 00000400 000A0800 BB // Len RootKey Hash Len Flash CRC //5D 0128 43 25B977A055BE9B5DEC0C38A2A279C695 8594B99850415055424B4559530000000003 00A70900 00060000 11F000397DCE210733C335E84BAD369EC893FCA06D1BC3 0100 A5 // Len RootKey Hash Len Flash CRC fs.ReadBuffer(ttxbuf[$09], $3);//Чтение значения подтипа токена и длины его заголовка TokenHdrLen:=ttxbuf[$0B];//Длина заголовка токена TokenSubType:=TokenHdrLen; fs.Seek(fs.position-4, sofrombeginning);//смещение на начало токена inc(TokenHdrLen, 5);//Увеличим длину до общей длины токена с его CRC fs.ReadBuffer(ttxbuf[8], TokenHdrLen);//Чтение значений токена с его CRC case TokenSubType of $2D: //Длина текущего блока между токенами CurrBlockLen := HexToInt(IntToHex(ttxbuf[TokenHdrLen-1], 2)+ IntToHex(ttxbuf[TokenHdrLen], 2)+ IntToHex(ttxbuf[TokenHdrLen+1], 2)+ IntToHex(ttxbuf[TokenHdrLen+2], 2)); $43: //Длина текущего блока между токенами CurrBlockLen := HexToInt(IntToHex(ttxbuf[TokenHdrLen-$17], 2)+ IntToHex(ttxbuf[TokenHdrLen-$16], 2)+ IntToHex(ttxbuf[TokenHdrLen-$15], 2)+ IntToHex(ttxbuf[TokenHdrLen-$14], 2)); else begin fs.Free; E.Create('Write : Bad image file'); end; end;//End of Case //Сравнение RootKey Hash телефона и RootKey Hash блока сертов good:=0; for i:=$0 to $0F do if RAPInfo.Root_Key_Hash[i]=ttxbuf[i+$0C] then inc(good); if good<$10 then begin//RootKey Hash не совпал, пропускаем fs.Seek(CurrBlockLen, soFromCurrent);//Пропускаем токен и его данные continue; end else begin//RootKey Hash серта совпал, копируем case TokenSubType of $2D: begin DWord((@ttxBuf[$8+TokenHdrLen])^):=$0000;//Добавление слова-разделителя $0000 fs.ReadBuffer(ttxBuf[$0A+TokenHdrLen],CurrBlockLen);//Копирование данных Application.ProcessMessages; CertName:=''; for i:=32 to 45 do if ttxbuf[i]=$00 then break else CertName:=CertName+Chr(ttxbuf[i]); Form1._msg('CMT: Writing Hash CERT ['+CertName+']'); Application.ProcessMessages; framelen:=CurrBlockLen+TokenHdrLen+$0A;//Состоит из 8 байт команды, токена, слова-разделителя, //Расчет длины фрейма // данных пакета DWord((@ttxBuf[0])^):=framelen; DWordSwap(@ttxbuf[0]); //form1._msg('Cert Len : '+IntToStr(framelen)); ttxBuf[4]:=$01; ttxBuf[5]:=$10; ttxBuf[6]:=$00; //Расчет первой crc (crc шапки команды) ttxBuf[7]:=frameCrc(@ttxbuf[0],7); //Form1._msg('txbuf : '+BufToHexStr(@txbuf[0],framelen)); USBBulkWritePort(@ttxbuf[0],framelen); USBBulkReadPort($FFFF); //Form1._msg('RxBuf : '+buftohexstr(@rxBuf[0],Length(rxBuf))); try if cmtreadreq then Application.ProcessMessages else begin Form1._msg('Write cert error : '+buftohexstr(@rxBuf[0],4)); form1._msg('Write cert failed! :('); form1._msg(''); result:=false; fs.free; exit; end; except Form1._msg('Write cert error : Connection lost => HW error or Cable problem...'); form1._msg('Write cert failed! :('); form1._msg(''); result:=false; fs.free; exit; end; Application.ProcessMessages; inc(blocks); Application.ProcessMessages; form1.statusbar.Panels[1].Text:='CMT : '+inttostr(Blocks); end; $43: begin fs.ReadBuffer(ttxBuf[$08+TokenHdrLen],CurrBlockLen);//Копирование данных Form1._msg('CMT: Writing Hash CERT [PAPUBKEYS]'); Application.ProcessMessages; framelen:=CurrBlockLen+TokenHdrLen+$08;//Состоит из 8 байт команды, токена, слова-разделителя, //Расчет длины фрейма // данных пакета DWord((@ttxBuf[0])^):=framelen; DWordSwap(@ttxbuf[0]); //form1._msg('Cert Len : '+IntToStr(framelen)); ttxBuf[4]:=$01; ttxBuf[5]:=$10; ttxBuf[6]:=$00; //Расчет первой crc (crc шапки команды) ttxBuf[7]:=frameCrc(@ttxbuf[0],7); //Form1._msg('txbuf : '+BufToHexStr(@txbuf[0],framelen)); USBBulkWritePort(@ttxbuf[0],framelen); USBBulkReadPort($FFFF); //Form1._msg('RxBuf : '+buftohexstr(@rxBuf[0],Length(rxBuf))); try if cmtreadreq then Application.ProcessMessages else begin Form1._msg('Write PAPUBKEYS error : '+buftohexstr(@rxBuf[0],4)); form1._msg('Write PAPUBKEYS failed! :('); form1._msg(''); result:=false; fs.free; exit; end; except Form1._msg('Write PAPUBKEYS error : Connection lost => HW error or Cable problem...'); form1._msg('Write PAPUBKEYS failed! :('); form1._msg(''); result:=false; fs.free; exit; end; Application.ProcessMessages; inc(blocks); Application.ProcessMessages; form1.statusbar.Panels[1].Text:='CMT : '+inttostr(Blocks); end; end; end; end//End of Case $5D else begin//Unknow Tokens or Bad File fs.free; E.Create('Write : Bad image file'); end; end;//End of Case form1.pb1.progress:=fs.Position; end;//End of While fs.free; Form1._msg('Total writen '+inttostr(blocks)+' blocks'); form1.statusbar.Panels[1].Text:=''; Application.ProcessMessages; endtimecount; Form1._msg('TIME : Write time : '+showtime(tmsres)+' '); result:=True; //form1._msg('Errors : '+inttostr(GetLastError)); Exit; {writen:=0; if Blocks=0 then begin Form1._msg('No any data for write, skip write'); ms.Free; result:=True; Exit; end;} //54 0117 0E 000300 4D9C 01 00000400 00000000 E8 {fs.ReadBuffer(buf[0], $3);//Чтение значения подтипа токена и длины его заголовка TokenHdrLen:=buf[2];//Длина заголовка токена fs.Seek(fs.position-4, sofrombeginning);//смещение на начало токена inc(TokenHdrLen, 5);//Увеличим длину до общей длины токена с его CRC fs.ReadBuffer(buf[0], TokenHdrLen);//Чтение значений токена с его CRC /Длина текущего блока между токенами CurrBlockLen := HexToInt(IntToHex(txbuf[TokenHdrLen-9], 2)+ IntToHex(txbuf[TokenHdrLen-8], 2)+ IntToHex(txbuf[TokenHdrLen-7], 2)+ IntToHex(txbuf[TokenHdrLen-6], 2)); Application.ProcessMessages; ms.WriteBuffer(buf[0], TokenHdrLen);//Копирование текущего токена buf[0]:=0; ms.WriteBuffer(buf[0], 1);//Добавление байта-разделителя $00 ms.CopyFrom(fs, CurrBlockLen);//Копирование данных Application.ProcessMessages; inc(blocks); end;//End of Case $54 $5D://Phoenix-segment begin //5D 0127 2D 25B977A055BE9B5DEC0C38A2A279C695 8594B99841444100000000000000000000030077E7 00000400 000A0800 BB // Len RootKey Hash Len Flash CRC //5D 0128 43 25B977A055BE9B5DEC0C38A2A279C695 8594B99850415055424B4559530000000003 00A70900 00060000 11F000397DCE210733C335E84BAD369EC893FCA06D1BC3 0100 A5 // Len RootKey Hash Len Flash CRC fs.ReadBuffer(buf[0], $3);//Чтение значения подтипа токена и длины его заголовка TokenHdrLen:=buf[2];//Длина заголовка токена TokenSubType:=TokenHdrLen; fs.Seek(fs.position-4, sofrombeginning);//смещение на начало токена inc(TokenHdrLen, 5);//Увеличим длину до общей длины токена с его CRC fs.ReadBuffer(buf[0], TokenHdrLen);//Чтение значений токена с его CRC case TokenSubType of $2D: //Длина текущего блока между токенами CurrBlockLen := HexToInt(IntToHex(buf[TokenHdrLen-9], 2)+ IntToHex(buf[TokenHdrLen-8], 2)+ IntToHex(buf[TokenHdrLen-7], 2)+ IntToHex(buf[TokenHdrLen-6], 2)); $43: //Длина текущего блока между токенами CurrBlockLen := HexToInt(IntToHex(buf[TokenHdrLen-$1F], 2)+ IntToHex(buf[TokenHdrLen-$1E], 2)+ IntToHex(buf[TokenHdrLen-$1D], 2)+ IntToHex(buf[TokenHdrLen-$1C], 2)); else begin ms.Free; E.Create('Write : Bad image file'); end; end;//End of Case //Сравнение RootKey Hash телефона и RootKey Hash блока сертов good:=0; for i:=$0 to $0F do if RAPInfo.Root_Key_Hash[i]=buf[i+4] then inc(good); Application.ProcessMessages; if good<$10 then begin//RootKey Hash не совпал, пропускаем fs.Seek(CurrBlockLen, soFromCurrent);//Пропускаем токен и его данные continue; end else begin//RootKey Hash серта совпал, копируем ms.WriteBuffer(buf[0], TokenHdrLen);//Копирование текущего токена buf[0]:=0; buf[1]:=0; ms.WriteBuffer(buf[0], 2);//Добавление слова-разделителя $0000 Application.ProcessMessages; ms.CopyFrom(fs, CurrBlockLen);//Копирование данных Application.ProcessMessages; inc(blocks); end; end//End of Case $5D} {ms.Seek(0, sofrombeginning); ms.SaveToFile('C:\1.bin'); ms.Seek(0, sofrombeginning); Form1._msg('Total '+IntToStr(blocks)+' ['+inttostr(cmtcount)+'/'+inttostr(unk)+'] blocks to write, writing... '); Application.ProcessMessages; Form1.statusbar.Panels[0].text:='Write Data....'; //Form1.statusbar.panels[1].text:='Time : '+inttostr(blocks div 10)+' sec...'; Form1.pb1.progress:=0; Form1.pb1.MaxValue:=Blocks; Application.ProcessMessages; Form1.statusbar.Panels[1].text:='0/'+inttostr(cmtcount); while ms.Position0 do begin Form1._msg('Waiting for response: '+inttostr(i)); Application.ProcessMessages; if catchdevice<>$02 then begin Application.ProcessMessages; sleep (1000); if stop=true then begin dostop('BOOT'); Application.ProcessMessages; i:=0; end; Application.ProcessMessages; end else i:=0; dec(i); end; if not DevPresent then begin Form1._msg('Phone not found... :('); Form1.SetBuzy; Form1.StatusBar.Panels[4].Text:=''; result:=False; USBClosePort; exit; end; RAPnewChkADL; Form1._msg('ADL: phone is in flash mode'); //Добавил для удобства кастом-прошивки Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[1].Text:=''; Form1.statusbar.Panels[2].Text:=''; Form1.statusbar.Panels[4].Text:='FLASHING'; Form1.statusbar.Panels[3].Text:='Connected'; Form1.TimConChk.Interval:=100; Application.ProcessMessages; if Form1.chkBackup.Checked=True then begin try Form1._msg(''); form1._msg('Backup enabled, will read all certificates...'); grabrpl(0); Form1.writeRpl(imei_global); finally Application.ProcessMessages; end; Application.ProcessMessages; end; delay(1000); if Form1.chkMCUen.Checked=true then begin Form1.chkMCUen.Enabled:=False; Form1._msg(' ===Flashing [MCU]==='); if not RapuYamaErase(core) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not RapuYamaWriteFile(core) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('MCU Write done'); Application.ProcessMessages; RAPnewChkADL2; Application.ProcessMessages; end; delay(1000); Application.ProcessMessages; if Form1.chkPPMe.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1._msg(' ===Flashing [PPM]==='); if not RapuYamaErase(ppm) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not RapuYamaWriteFile(ppm) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('PPM Write done'); Application.ProcessMessages; RAPnewChkADL2; Application.ProcessMessages; end; delay(1000); Application.ProcessMessages; if Form1.chkPPM1e.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1.chkPPM1e.Enabled:=False; Form1._msg(' ===Flashing [PPM2]==='); if not RapuYamaErase(ppm1) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not RapuYamaWriteFile(ppm1) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('PPM Write done'); Application.ProcessMessages; RAPnewChkADL2; Application.ProcessMessages; end; delay(1000); Application.ProcessMessages; if Form1.chkCNTe.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1.chkPPM1e.Enabled:=False; Form1.chkCNTe.Enabled:=False; Form1._msg(' ===Flashing [CNT]==='); if not RapuYamaErase(image) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not RapuYamaWriteFile(image) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('CNT Write done'); Application.ProcessMessages; RAPnewChkADL2; Application.ProcessMessages; end; delay(1000); Application.ProcessMessages; if Form1.chkAPEe.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1.chkPPM1e.Enabled:=False; Form1.chkCNTe.Enabled:=False; Form1.chkAPEe.Enabled:=False; Form1._msg(' ===Flashing [APE]==='); if not RapuYamaErase(ape) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not RapuYamaWriteFile(ape) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('APE Write done'); Application.ProcessMessages; RAPnewChkADL2; Application.ProcessMessages; end; delay(1000); Application.ProcessMessages; if Form1.chkcnt3.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1.chkPPM1e.Enabled:=False; Form1.chkCNTe.Enabled:=False; Form1.chkAPEe.Enabled:=False; Form1.chkcnt3.Enabled:=False; Form1._msg(' ===Flashing [CNT3]==='); if not RapuYamaErase(cnt3) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not RapuYamaWriteFile(cnt3) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('CNT Write done'); Application.ProcessMessages; RAPnewChkADL2; Application.ProcessMessages; end; Application.ProcessMessages; RapNewFinish; // режим рестарта Application.ProcessMessages; Form1._msg(''); Form1._msg('Flashing done!'); Form1._msg('Total flash time : '+showtime(fltime)); Form1._msg('Reboot phone now...'); Form1._msg(''); Application.ProcessMessages; fltime:=0; Form1.statusbar.Panels[0].Text:=''; Form1.pb1.ForeColor:=clNavy; Form1.pbsm1.ForeColor:=clNavy; Form1.pb1.MaxValue:=100; Form1.pb1.progress:=0; Form1.statusbar.Panels[1].Text:=''; Form1.TimConChk.Interval:=2000; Form1.pb1.color:=clActiveBorder; if affenabled then Form1.afterFlashdo; Application.ProcessMessages; delay(300); Form1.SetReady; Form1.TimConChk.Enabled:=true; Form1._msg('Done!'); Form1.chkPPMe.Enabled:=True; Form1.chkMCUen.Enabled:=True; Form1.chkPPM1e.Enabled:=True; Form1.chkCNTe.Enabled:=True; Form1.chkAPEe.Enabled:=True; Form1.chkcnt3.Enabled:=True; Result:=true; end;//End of Normal Mode Flashing function NomandicRawextract():Boolean; var i,k,j,m,blockcount,l :Integer; CurrBlock : Byte; CurrBlockLen : integer; fs : TFileStream; Rawloader,Rawblock : TmemoryStream; rawsize : Int64; bulkread : integer; loaderinfo : string; begin result:=false; Form1._msg('Req CMT info'); DWord((@txBuf[0])^):=$0B; DWordSwap(@txbuf[0]); UsbBulkWriteport(@txbuf[0],4); Application.ProcessMessages; UsbBulkWriteport(@NomSelAPE, Length(NomSelAPe)); repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; // Root Hash Application.ProcessMessages; FillMemory(@RAPInfo.ROOT_KEY_HASH,$10,$00); //FillMemory(@RAPInfo.APErootkey,$10,$00); FillMemory(@RAPInfo.FlashID,$A,$00); FillMemory(@RAPInfo.APEFlashID,$A,$00); FillMemory(@RAPInfo.PublicID,$14,$00); FillMemory(@RAPInfo.BootID,$8,$00); Application.ProcessMessages; Application.ProcessMessages; BlockCount :=rxbuf[20]; i:=21; j:=0; m:=0; while j No ROOTKEY HASH Asic CMT. (IMEI DAMAGED?) Unable to continue flashing'); exit; end; Form1._msg('ROOT KEY HASH: '+ BufToHexStr(@RAPInfo.ROOT_KEY_HASH[0], Length(RAPInfo.ROOT_KEY_HASH))); end; $15://ROM_ID //4B9B75103E691FF8 begin inc(i); CurrBlockLen:=CurrBlockLen-1; for k:=0 to CurrBlockLen-1 do RAPInfo.ROM_ID[k]:= rxbuf[i+k]; Form1._msg('ROM ID: '+ BufToHexStr(@RAPInfo.ROM_ID[0], Length(RAPInfo.ROM_ID))); inc(i, CurrBlockLen); inc(j); end else begin inc(i, CurrBlockLen); inc(j); end; end;//End Of Case end; Application.ProcessMessages; Form1._msg('Send CMT loader...'); loaderinfo:=''; try loaderinfo:=getversion(ExtractFilePath(Application.ExeName)+'\Flash\RAPIDOv11_2nd.fg'); fs:=TFileStream.Create(ExtractFilePath(Application.ExeName)+'\Flash\RAPIDOv11_2nd.fg',fmOpenRead); except Form1._msg('Error on prepare - loader not found or damaged!'); exit; end; Form1._msg('Use '+ExtractFileName(ExtractFilePath(Application.ExeName)+'\Flash\RAPIDOv11_2nd.fg')+' '+loaderinfo); RAWLoader:=TmemoryStream.Create; RAWBlock:=TmemoryStream.Create; RAWblock.LoadFromstream(fs); RAWLoader:=PrepareCMTNomandicloader(RAWblock); fs.Free; //Sendloader if Rawloader<>nil then begin Application.ProcessMessages; DWord((@txbuf[0])^):=Rawloader.Size+52; DWordSwap(@txbuf[0]); USBBulkWritePort(@txbuf[0], 4); DWord((@txbuf[0])^):=Rawloader.Size+52; DWordSwap(@txbuf[0]); txBuf[4]:=$01; txbuf[5]:=$20; txBuf[6]:=$00; txBuf[7]:=frameCrc(@txbuf[0],7); txBuf[8]:=$5B; txBuf[9]:=$01; txBuf[10]:=$24; txBuf[11]:=$04; DWord((@txbuf[12])^):=Rawloader.Size+32; DWordSwap(@txbuf[12]); txBuf[16]:=frameCrc(@txbuf[0],16); txBuf[17]:=$00; txBuf[18]:=$00; txBuf[19]:=$00; RAWLoader.Seek(0,soFromBeginning); Rawloader.ReadBuffer(txBuf[20], Rawloader.size); rawsize:=Rawloader.size+20; for i:=rawsize to rawsize+32 do txBuf[i]:=$00; USBBulkWritePort(@txbuf[0], Rawloader.size+52); repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; if apereadreq then begin result:=True; Form1._msg('CMT loader sent') end else result:=false; Application.ProcessMessages; RAWLoader.free; RAWBlock.free; //Form1._msg('Req CMT info'); DWord((@txBuf[0])^):=$0B; DWordSwap(@txbuf[0]); UsbBulkWriteport(@txbuf[0],4); Application.ProcessMessages; UsbBulkWriteport(@NomSelectFlCmt, Length(NomSelectFlCmt)); repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; if rxBuf[8]<>$C1 then Form1._msg('Error while reading initial info, boot not accepted') else Form1._msg('CMT FLID : '+buftohexstr(@rxBuf[43],2)+buftohexstr(@rxBuf[41],2)+' , NOR , CMT'); end else begin result:=false; RAWLoader.free; RAWBlock.free; end; Application.ProcessMessages; end; function NomandicSendBoot():Boolean; var fs : TfileStream; currcert, currtoken, streamlen : TMemoryStream; data : string; hdrlen,seemcount, CurrSeemLen,i : Integer; fblen : Byte; currseem : Byte; blklen,loaderlen : DWORD; RootInBlock : array[0..$F] of byte; j,good : Integer; n,k,l,m : integer; ms : TmemoryStream; BlockCount : Byte; CurrBlock : Byte; CurrBlockLen : Word; b : Boolean; bulkread : integer; loaderinfo : string; begin result:=false; loaderinfo:=''; try loaderinfo:=getversion(ExtractFilePath(Application.ExeName)+'\Flash\RAPIDOv11_XSR15_alg.fg'); fs:=TFileStream.Create(ExtractFilePath(Application.ExeName)+'\Flash\RAPIDOv11_XSR15_alg.fg',fmOpenRead); except Form1._msg('Error on prepare - loader not found or damaged!'); exit; end; Form1._msg('Use '+ExtractFileName(ExtractFilePath(Application.ExeName)+'\Flash\RAPIDOv11_XSR15_alg.fg')+' '+loaderinfo); fs.Read(buf[0] ,1); if buf[0]<>$B1 then //Заголовок / идентификатор begin Form1.lst1.items.add('File damaged or Unknow format... :('); fs.Free; exit; end; fs.ReadBuffer(buf[0], 4);//Длина Flash-header'a HdrLen := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2)); //form1._msg('HeaderLen: '+inttostr(HdrLen)); fs.ReadBuffer(buf[0], 4);//Кол-во блоков в Flash-заголовке SeemCount := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2)); //form1._msg('BlockCount: '+inttostr(SeemCount)); Application.ProcessMessages; currcert:=TMemoryStream.Create; currtoken:=TmemoryStream.Create; streamlen:=TMemoryStream.Create; good:=0; loaderlen:=0; form1.pb1.MaxValue:=fs.Size; try Form1.statusbar.Panels[4].Text:='Sending Boot'; while (fs.Position<>(fs.size)) do begin fs.ReadBuffer(CurrSeem, 1); case CurrSeem of//Перебор всех блоков, поиск блока со структурой RAW-loader'а $56: begin //Form1._msg('Cert Token found, processing...'); Application.ProcessMessages; fs.ReadBuffer(buf[0], 3); case Buf[1] of $17: // UPDAPP body ( 1st block - precrt ) begin //form1._msg('UpdAPP Body processing'); Application.ProcessMessages; CurrSeemLen :=buf[2]+1; //fs.ReadBuffer(buf[0], currseemlen); fs.Seek(fs.Position-4, sofromBeginning); currtoken.CopyFrom(fs,currseemlen+4); currtoken.Seek(0,soFromBeginning); currtoken.ReadBuffer(txBuf[8],currtoken.size); // send token's header Application.processmessages; currtoken.Seek(10,sofromBeginning); currtoken.ReadBuffer(blklen,4); DWordSwap(@blklen); currcert.CopyFrom(fs,blklen); Application.processmessages; currcert.Seek(0, sofrombeginning); //Form1._msg('CERT SIZE : '+inttostr(currcert.Size)); dword((@txbuf[0])^):=currcert.size+9+currtoken.size; dwordswap(@txbuf[0]); UsbBulkWritePort(@txbuf[0],4); txBuf[4]:=$01; txbuf[5]:=$10; txBuf[6]:=$00; txbuf[7]:=frameCrc(@txbuf[0],7); txBuf[8+(Currtoken.size)]:=$00; currcert.readbuffer(txbuf[8+(Currtoken.size+1)],currcert.size); UsbBulkWritePort(@txbuf[0],currcert.size+(9+Currtoken.size)); repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; Application.ProcessMessages; currcert.clear; currtoken.Clear; end; $27: // UPDAPP CERT begin Application.ProcessMessages; good:=0; CurrSeemLen :=buf[2]+1; fs.Seek(fs.Position-4, sofromBeginning); currtoken.CopyFrom(fs,currseemlen+4); currtoken.seek(4,soFromBeginning); currtoken.ReadBuffer(RootInBlock[0], $10); //form1._msg('UPDAPP: '+buftohexstr(@rootinBlock[0], $10)); Application.ProcessMessages; for j:=0 to $0f do if RootInBlock[j]=RAPInfo.Root_Key_Hash[j] then inc(good); if good=$10 then begin // send token's header Application.processmessages; currtoken.Seek(41,sofromBeginning); currtoken.ReadBuffer(blklen,4); DWordSwap(@blklen); currcert.CopyFrom(fs,blklen); Application.processmessages; currcert.Seek(0, sofrombeginning); dword((@txbuf[0])^):=currcert.size+10+currtoken.size; dwordswap(@txbuf[0]); UsbBulkWriteport(@txBuf[0],4); txBuf[4]:=$01; txbuf[5]:=$10; txBuf[6]:=$00; txbuf[7]:=frameCrc(@txbuf[0],7); currtoken.Seek(0,sofromBeginning); currtoken.ReadBuffer(txBuf[8],currtoken.size); word((@txBuf[currtoken.size+9])^):=$0000; currcert.readbuffer(txbuf[8+(currtoken.size+2)],currcert.size); UsbBulkWritePort(@txbuf[0],currcert.size+(10+currtoken.size)); repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; Application.ProcessMessages; end else begin currtoken.Seek(41,sofromBeginning); currtoken.ReadBuffer(blklen,4); DWordSwap(@blklen); currcert.CopyFrom(fs,blklen); Application.ProcessMessages; end; Application.ProcessMessages; currcert.clear; currtoken.Clear; end; end; end; else begin fs.ReadBuffer(buf[0], 1); CurrSeemLen:=buf[0]; fs.Seek(CurrSeemLen, sofromcurrent); end; end; form1.pb1.Progress:=fs.Position; Application.ProcessMessages; end; except fs.free; result:=false; Form1.pb1.progress:=0; Form1.pb1.MaxValue:=100; Application.ProcessMessages; exit; end; dword((@txbuf[0])^):=$1F; dwordswap(@txbuf[0]); UsbBulkWritePort(@txbuf[0],4); UsbBulkWritePort(@fincmtbootrapido15, length(fincmtbootrapido15)); repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; if apereadreq then begin dword((@txbuf[0])^):=$12; dwordswap(@txbuf[0]); UsbBulkWritePort(@txbuf[0],4); UsbBulkWriteport(@cmtrunnomadic,length(cmtrunnomadic)); repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; if cmtreadreq then begin result:=true; form1._msg('CMT algo sent'); end else result:=false; end else result:=False; fs.Free; Form1.pb1.progress:=0; Form1.pb1.MaxValue:=100; Application.ProcessMessages; end; function NomandicAPErawextract():Boolean; var fs : TFileStream; Rawloader,Rawblock : TmemoryStream; rawsize : Int64; bulkread : Integer; loaderinfo : string; begin result:=false; loaderinfo:=''; try loaderinfo:=getversion(ExtractFilePath(Application.ExeName)+'\Flash\STn8815_2nd.fg'); fs:=TFileStream.Create(ExtractFilePath(Application.ExeName)+'\Flash\STn8815_2nd.fg',fmOpenRead); except Form1._msg('Error on prepare - loader not found or damaged!'); exit; end; Form1._msg('Use '+ExtractFileName(ExtractFilePath(Application.ExeName)+'\Flash\STn8815_2nd.fg')+' '+loaderinfo); RAWLoader:=TmemoryStream.Create; RAWBlock:=TmemoryStream.Create; RAWblock.LoadFromstream(fs); RAWLoader:=PrepareApeNomandicloader(RAWblock); fs.Free; //Sendloader Application.ProcessMessages; if Rawloader<>nil then begin rawsize:=Rawloader.size; DWord((@txBuf[0])^):=Rawsize; //Form1._msg(BufToHexStr(@txbuf[0], 4)); UsbBulkWriteport(@txbuf[0],4); Rawloader.Seek(0,soFromBeginning); RAWLoader.ReadBuffer(txBuf[0], rawsize); UsbBulkWriteport(@txbuf[0],rawsize); repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; if (rxbuf[0]=$37) and (rxbuf[1]=$78) and (rxbuf[2]=$62) and (rxbuf[3]=$00) then begin form1._msg('APE loader sent'); Application.ProcessMessages; end else begin form1._msg('Minor error, try skip'); end; RAWLoader.free; RAWBlock.free; DWord((@txBuf[0])^):=4; DWordSwap(@txbuf[0]); UsbBulkWriteport(@txbuf[0],4); Application.ProcessMessages; txBuf[0]:=$66; txBuf[1]:=$00; txBuf[2]:=$FF; txBuf[3]:=$00; UsbBulkWriteport(@txbuf[0],4); repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; if rxBuf[0]<>$C1 then begin result:=False; Form1._msg('Error while reading initial info, boot not accepted'); end else begin Form1._msg('APE FLID : '+buftohexstr(@rxBuf[36],2)+buftohexstr(@rxBuf[34],2)+' , NAND , APE'); result:=true; end; Application.ProcessMessages; end else begin result:=false; RAWLoader.free; RAWBlock.free; end; end; function PrepareApeNomandicloader(loader:Tmemorystream):TMemoryStream; var b : Boolean; ULO : array[0..3] of Byte; MEDia : array[0..10] of Byte; RAWLoader : TMemoryStream; begin ULO[0]:=$32;ULO[1]:=$4E;ULO[2]:=$44;ULO[3]:=$00; MEDia[0]:=$42;MEDia[1]:=$4F;MEDia[2]:=$4F;MEDia[3]:=$54; MEDia[4]:=$5F;MEDia[5]:=$4D;MEDia[6]:=$45;MEDia[7]:=$44; MEDia[8]:=$49;MEDia[9]:=$41;MEDia[10]:=$31; try //Извлечение и патчинг RAW-loader'a RAWLoader:=TmemoryStream.Create; BB5_ExtractAPERAWLoader(loader, RAWLoader, b); //RAWloader.SaveToFile('C:\RAW_Nomandic_patch.bin'); //Подготовка патчинга равки RAWloader.Seek(20,soFromBeginning); RAWloader.readbuffer(Buf[0],4); if buf[0]<>$53 then begin Form1._msg('Prepare loader failed'); result:=nil; end else begin RAWloader.Seek(20,soFromBeginning); //RAPUx SILO RAWloader.writebuffer(ulo[0],4); end; RAWloader.Seek(148,soFromBeginning); RAWloader.readbuffer(Buf[0],$B); RAWloader.Seek(148,soFromBeginning); if (buf[0]=$42) and (buf[1]=$4F) then RAWloader.WriteBuffer(Media[0],$B) else result:=nil; //RAWloader.SaveToFile('C:\RAW_RAPNEW_patch.bin'); Result:=RAWloader; except Result:=nil; end; end; function PrepareCMTNomandicloader(loader:Tmemorystream):TMemoryStream; var b : Boolean; ULO : array[0..3] of Byte; MEDia : array[0..10] of Byte; RAWLoader : TMemoryStream; begin MEDia[0]:=$42;MEDia[1]:=$4F;MEDia[2]:=$4F;MEDia[3]:=$54; MEDia[4]:=$5F;MEDia[5]:=$4D;MEDia[6]:=$45;MEDia[7]:=$44; MEDia[8]:=$49;MEDia[9]:=$41;MEDia[10]:=$32; try //Извлечение и патчинг RAW-loader'a RAWLoader:=TmemoryStream.Create; BB5_ExtractRAWLoader(loader, RAWLoader, b); //RAWloader.SaveToFile('C:\RAW_Nomandic_patch.bin'); //Подготовка патчинга равки RAWloader.Seek(148,soFromBeginning); RAWloader.readbuffer(Buf[0],$B); RAWloader.Seek(148,soFromBeginning); if (buf[0]=$42) and (buf[1]=$4F) then RAWloader.WriteBuffer(Media[0],$B) else result:=nil; //RAWloader.SaveToFile('C:\RAW_CMT_RAPNEW_patch.bin'); Result:=RAWloader; except Result:=nil; end; end; function NomandicAPESendBoot():Boolean; var fs : TfileStream; currcert, currtoken, streamlen : TMemoryStream; data : string; hdrlen,seemcount, CurrSeemLen,i : Integer; fblen :Byte; currseem : Byte; blklen,loaderlen : DWORD; RootInBlock : array[0..$F] of byte; j,good : Integer; n,k,l,m : integer; ms : TmemoryStream; BlockCount : Byte; CurrBlock : Byte; CurrBlockLen : Word; b : Boolean; bulkread : integer; loaderinfo : string; begin result:=false; loaderinfo:=''; try loaderinfo:=getversion(ExtractFilePath(Application.ExeName)+'\Flash\STn8815_STNFMS_alg.fg'); fs:=TFileStream.Create(ExtractFilePath(Application.ExeName)+'\Flash\STn8815_STNFMS_alg.fg',fmOpenRead); except Form1._msg('Error on prepare - loader not found or damaged!'); exit; end; Form1._msg('Use '+ExtractFileName(ExtractFilePath(Application.ExeName)+'\Flash\STn8815_STNFMS_alg.fg')+' '+loaderinfo); fs.Read(buf[0] ,1); if buf[0]<>$B1 then //Заголовок / идентификатор begin Form1.lst1.items.add('File damaged or Unknow format... :('); fs.Free; exit; end; fs.ReadBuffer(buf[0], 4);//Длина Flash-header'a HdrLen := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2)); //form1._msg('HeaderLen: '+inttostr(HdrLen)); fs.ReadBuffer(buf[0], 4);//Кол-во блоков в Flash-заголовке SeemCount := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2)); //form1._msg('BlockCount: '+inttostr(SeemCount)); Application.ProcessMessages; currcert:=TMemoryStream.Create; currtoken:=TmemoryStream.Create; streamlen:=TMemoryStream.Create; good:=0; loaderlen:=0; form1.pb1.MaxValue:=fs.Size; try Form1.statusbar.Panels[4].Text:='Sending Boot'; while (fs.Position<>(fs.size)) do begin fs.ReadBuffer(CurrSeem, 1); case CurrSeem of//Перебор всех блоков, поиск блока со структурой RAW-loader'а $56: begin //Form1._msg('Cert Token found, processing...'); Application.ProcessMessages; fs.ReadBuffer(buf[0], 3); case Buf[1] of $17: // UPDAPP body ( 1st block - precrt ) begin //form1._msg('UpdAPP Body processing'); Application.ProcessMessages; CurrSeemLen :=buf[2]+1; //fs.ReadBuffer(buf[0], currseemlen); fs.Seek(fs.Position-4, sofromBeginning); currtoken.CopyFrom(fs,currseemlen+4); //currtoken.SaveToFile('C:\token'+inttostr(i2)+'.bin'); // send token's header Application.processmessages; currtoken.Seek(0, sofrombeginning); dword((@txbuf[0])^):=currtoken.size; dwordswap(@txbuf[0]); UsbBulkWritePort(@txbuf[0],4); currtoken.readbuffer(txbuf[0],currtoken.size); UsbBulkWritePort(@txbuf[0],currtoken.size); //send cert body currtoken.Seek(10,sofromBeginning); currtoken.ReadBuffer(blklen,4); DWordSwap(@blklen); currcert.CopyFrom(fs,blklen); Application.processmessages; currcert.Seek(0, sofrombeginning); //Form1._msg('CERT SIZE : '+inttostr(currcert.Size)); dword((@txbuf[0])^):=currcert.size; dwordswap(@txbuf[0]); UsbBulkWritePort(@txbuf[0],4); currcert.readbuffer(txbuf[0],currcert.size); UsbBulkWritePort(@txbuf[0],currcert.size); Application.ProcessMessages; currcert.clear; currtoken.Clear; end; $27: // UPDAPP CERT begin Application.ProcessMessages; good:=0; CurrSeemLen :=buf[2]+1; fs.Seek(fs.Position-4, sofromBeginning); currtoken.CopyFrom(fs,currseemlen+4); currtoken.seek(4,soFromBeginning); currtoken.ReadBuffer(RootInBlock[0], $10); //form1._msg('UPDAPP: '+buftohexstr(@rootinBlock[0], $10)); Application.ProcessMessages; for j:=0 to $0f do if RootInBlock[j]=RAPInfo.Aperootkey[j] then inc(good); if good=$10 then begin // send token's header Application.processmessages; currtoken.Seek(0, sofrombeginning); dword((@txbuf[0])^):=currtoken.size; dwordswap(@txbuf[0]); UsbBulkWritePort(@txbuf[0],4); currtoken.readbuffer(txbuf[0],currtoken.size); UsbBulkWritePort(@txbuf[0],currtoken.size); currtoken.Seek(41,sofromBeginning); currtoken.ReadBuffer(blklen,4); DWordSwap(@blklen); currcert.CopyFrom(fs,blklen); Application.processmessages; currcert.Seek(0, sofrombeginning); //Form1._msg('ROOTCERT SIZE : '+inttostr(currcert.Size)); dword((@txbuf[0])^):=currcert.size; dwordswap(@txbuf[0]); UsbBulkWritePort(@txbuf[0],4); currcert.readbuffer(txbuf[0],currcert.size); UsbBulkWritePort(@txbuf[0],currcert.size); Application.ProcessMessages; end else begin currtoken.Seek(41,sofromBeginning); currtoken.ReadBuffer(blklen,4); DWordSwap(@blklen); currcert.CopyFrom(fs,blklen); Application.ProcessMessages; end; Application.ProcessMessages; currcert.clear; currtoken.Clear; end; end; end; else begin fs.ReadBuffer(buf[0], 1); CurrSeemLen:=buf[0]; fs.Seek(CurrSeemLen, sofromcurrent); end; end; Form1.pb1.progress:=fs.Position; Application.ProcessMessages; end; except fs.free; result:=false; Form1.pb1.progress:=0; Form1.pb1.MaxValue:=100; exit; end; dword((@txbuf[0])^):=$17; dwordswap(@txbuf[0]); UsbBulkWritePort(@txbuf[0],4); UsbBulkWritePort(@NomandicAPeend, length(NomandicAPeend)); repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; if rxBuf[0]=$37 then begin result:=true; form1._msg('APE algo sent'); end else result:=False; fs.Free; Form1.pb1.progress:=0; Form1.pb1.MaxValue:=100; Application.ProcessMessages; end; function nomandicIniUpdServer():Boolean; var i : Integer; bulkread : integer; begin result:=False; dword((@txbuf[0])^):=$12; dwordswap(@txbuf[0]); UsbBulkWritePort(@txbuf[0],4); i:=UsbBulkWritePort(@ApeNomUpl, Length(ApeNomUpl)); if i<>18 then Exit; repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; if apereadreq then application.ProcessMessages else form1._msg('Ape server init fail'); dword((@txbuf[0])^):=$12; dwordswap(@txbuf[0]); UsbBulkWritePort(@txbuf[0],4); i:=UsbBulkWritePort(@ApeNomUpl2, Length(ApeNomUpl2)); if i<>18 then Exit; repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; if apereadreq then result:=True; end; function NomandicBoot(mode:Integer):Boolean; var fs : TfileStream; currcert, currtoken, streamlen : TMemoryStream; data : string; hdrlen,seemcount, CurrSeemLen,i : Integer; fblen :Byte; currseem : Byte; a : string; blklen,loaderlen : DWORD; dcr : Boolean; RootInBlock : array[0..$F] of byte; j,good,i2 : Integer; n,k,l,m,PktLen : integer; ms, RAWBlock, RAWLoader : TmemoryStream; s, needSert : String; Key, KeyLen : Byte; PacketLen : Byte; BlockCount : Byte; CurrBlock : Byte; CurrBlockLen : Word; b, proto : Boolean; ASIC : string; rapmode : Integer; bulkread : Integer; begin if mode=1 then begin Form1._msg('Dead Mode is Selected'); Form1._msg('Waiting for USB device...'); Form1._msg('--- Press phone'+#39+'s power button or insert charger! ---'); Application.ProcessMessages; end; //Nokia USB ROM b:=false; i:=0; repeat if (i=2500) and (b=false) then begin Form1._msg('-> Phone not found.. :('); result:=False; Form1.SetReady; Exit; end; Application.ProcessMessages; if stop=true then begin dostop('BOOT'); i:=2499; b:=False; end; if catchdevice=$02 then begin b:=true; Form1._msg('Connection opened successfully'); end; Application.ProcessMessages; Sleep(10); inc(i); Form1.statusbar.Panels[0].Text:='Wait for phone '+inttostr(2500-i); Application.ProcessMessages; until b ; Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[3].Text:='Connected'; txBuf[0]:=$15; txBuf[1]:=$88; txBuf[2]:=$54; txBuf[3]:=$53; i:=USBBulkWritePort(@txbuf[0],4); if i<>4 then begin Form1._msg('-> Read initial data failed : phone not in flash mode.. :('); result:=False; Form1.SetReady; Exit; end; try Form1._msg('Req APE info'); repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; Application.ProcessMessages; // Root Hash Application.ProcessMessages; FillMemory(@RAPInfo.ROOT_KEY_HASH,$10,$00); FillMemory(@RAPInfo.APErootkey,$10,$00); FillMemory(@RAPInfo.FlashID,$A,$00); FillMemory(@RAPInfo.APEFlashID,$A,$00); FillMemory(@RAPInfo.PublicID,$14,$00); FillMemory(@RAPInfo.BootID,$8,$00); Application.ProcessMessages; Application.ProcessMessages; BlockCount :=rxbuf[0]; i:=1; j:=0; m:=0; while j No ROOTKEY HASH Asic APE. (IMEI DAMAGED?) Unable to continue flashing'); exit; end; Form1._msg('ROOT KEY HASH: '+ BufToHexStr(@RAPInfo.Aperootkey[0], Length(RAPInfo.Aperootkey))); end; $15://ROM_ID //4B9B75103E691FF8 begin inc(i); CurrBlockLen:=CurrBlockLen-1; for k:=0 to CurrBlockLen-1 do RAPInfo.ROM_ID[k]:= rxbuf[i+k]; Form1._msg('ROM ID: '+ BufToHexStr(@RAPInfo.ROM_ID[0], Length(RAPInfo.ROM_ID))); inc(i, CurrBlockLen); inc(j); end else begin inc(i, CurrBlockLen); inc(j); end; end;//End Of Case end; Application.ProcessMessages; //02 00 03 F0 txBuf[0]:=$02; txBuf[1]:=$00; txBuf[2]:=$03; txBuf[3]:=$F0; i:=USBBulkWritePort(@txbuf[0],4); if i<>4 then begin Form1._msg('-> Setup initial data failed : phone not in flash mode.. :('); result:=False; Form1.SetReady; Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[4].Text:=''; Exit; end; except form1._msg('Error on initialization stage'); result:=false; Exit; end; Application.ProcessMessages; //Prepare and send RAWloader Form1.statusbar.Panels[0].Text:='Boot stage #1'; Form1._msg('Send APE loader...'); try if not NomandicAPErawextract then begin form1._msg('Error on boot stage #1'); result:=false; Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[4].Text:=''; exit; end; except form1._msg('Error on boot stage #1'); result:=false; Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[4].Text:=''; exit; end; Application.ProcessMessages; //Prepare and send algo Form1.statusbar.Panels[0].Text:='Boot stage #2'; Form1._msg('Send APE algo...'); try if not NomandicAPESendBoot then begin form1._msg('Error on boot stage #2'); result:=false; Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[4].Text:=''; exit; end; except form1._msg('Error on boot stage #2'); result:=false; Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[4].Text:=''; exit; end; Application.ProcessMessages; //initialize updServer Form1.statusbar.Panels[0].Text:='UpdateServer initialize'; Form1._msg('Initialize UpdateServer...'); try if not nomandicIniUpdServer then begin form1._msg('Error initialize UpdateServer'); result:=false; Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[4].Text:=''; exit; end; except form1._msg('Error initialize UpdateServer'); result:=false; Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[4].Text:=''; exit; end; Form1._msg('UpdateServer initialized'); Application.ProcessMessages; form1._msg('Processing Slave part'); //SendCMTrawloader Form1.statusbar.Panels[0].Text:='Boot stage #3'; try if not NomandicRawextract then begin form1._msg('Error on boot stage #3'); result:=false; Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[4].Text:=''; exit; end; except form1._msg('Error on boot stage #3'); result:=false; Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[4].Text:=''; exit; end; Application.ProcessMessages; //SendCMT algo Form1.statusbar.Panels[0].Text:='Boot stage #4'; Form1._msg('Send CMT algo...'); try if not NomandicSendBoot then begin form1._msg('Error on boot stage #4'); result:=false; Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[4].Text:=''; exit; end; except form1._msg('Error on boot stage #4'); result:=false; Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[4].Text:=''; exit; end; Application.ProcessMessages; Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[4].Text:=''; try if not NomandicFlprepare then begin form1._msg('Error on flash prepare'); result:=false; Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[4].Text:=''; exit; end; except form1._msg('Error on flash prepare'); result:=false; Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[4].Text:=''; exit; end; Form1._msg('Flash prepare done'); result:=True; end; function NomandicFlprepare():Boolean; var i : Integer; bulkread : Integer; begin result:=false; Application.ProcessMessages; //confirm cmtselect USBBulkWritePort(@nomselcmt[0],4); i:=USBBulkWritePort(@nomselcmt,Length(nomselcmt)); if i<>11 then Exit; repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; if (rxBuf[7]=$E5) and (rxBuf[8]=$00) then Form1._msg('ADL : CMT select Ok') else Form1._msg('ADL : CMT select : already on adl'); //get cmt papub Application.ProcessMessages; USBBulkWritePort(@nomgetcmtpapub[0],4); i:=USBBulkWritePort(@nomgetcmtpapub,Length(nomgetcmtpapub)); if i<>14 then Exit; repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; if rxBuf[11]=$15 then Form1._msg('ADL : CMT PapubKeys req Ok') else Form1._msg('ADL : CMT PapubKeys req : blank/erased'); // check CRT req Application.ProcessMessages; USBBulkWritePort(@nomcmreqcert[0],4); i:=USBBulkWritePort(@nomcmreqcert,Length(nomcmreqcert)); if i<>71 then Exit; repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; if cmtreadreq then Form1._msg('ADL : CMT CRT check Ok') else Form1._msg('ADL : CMT CRT check failed'); // cmt fl req Application.ProcessMessages; USBBulkWritePort(@nomselcmtfl[0],4); i:=USBBulkWritePort(@nomselcmtfl,Length(nomselcmtfl)); if i<>11 then Exit; repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; //get ape papub Application.ProcessMessages; USBBulkWritePort(@nomgetapepapub[0],4); i:=USBBulkWritePort(@nomgetapepapub,Length(nomgetapepapub)); if i<>14 then exit; repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; if rxBuf[11]=$15 then Form1._msg('ADL : APE PapubKeys req Ok') else Form1._msg('ADL : APE PapubKeys req : blank/erased'); // check CRT ape req Application.ProcessMessages; USBBulkWritePort(@nomapereqcert[0],4); i:=USBBulkWritePort(@nomapereqcert,Length(nomapereqcert)); if i<>71 then Exit; repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; if apereadreq then Form1._msg('ADL : APE CRT check Ok') else Form1._msg('ADL : APE CRT check failed'); result:=True; end; function NomandicEraseFile(core:string):Boolean; var fs : TFileStream; buf1 : array[0..$FFFF] of byte; n,j,buflen,i : Integer; HdrLen : Integer; HdrPos : LongInt; CurrSeem : Byte; CurrSeemLen, CurSeemcount : Integer; ms : TMemoryStream; loaderlen : DWORD; erase : Boolean; framelen : DWORD; cmt,ape : Boolean; bulkread : integer; begin Result:=false; partition:=false; erase:=False; cmt:=false; ape:=false; Form1._msg('Erase : Processing '+ExtractFileName(core)); Application.processmessages; Form1.statusbar.Panels[1].text:=''; Application.ProcessMessages; fs:=TFileStream.Create(core,fmOpenRead); fs.Seek(0, sofromBeginning); fs.Read(buf1[0],1); if buf1[0]<>$B2 then begin fs.free; raise E.Create('Erase : Bad image file'); Exit; end; Application.ProcessMessages; starttime; Application.ProcessMessages; fs.ReadBuffer(buf1[0], 4);//Длина Flash Header HdrLen := HexToInt(IntToHex(buf1[0], 2)+IntToHex(buf1[1], 2)+IntToHex(buf1[2], 2)+IntToHex(buf1[3], 2)); fs.Seek(4,soFromCurrent); try while fs.Position<(HdrLen) do begin if stop=true then begin dostop('ERASE'); Application.ProcessMessages; fs.free; result:=False; Exit; end; fs.ReadBuffer(CurrSeem, 1); case CurrSeem of $EE: begin Application.ProcessMessages; Form1.statusbar.Panels[0].Text:='Partitioning, Wait'; Application.ProcessMessages; cmt:=false; ape:=false; form1._msg('Partitioning....'); partition:=True; partitionstream:=TmemoryStream.Create; fs.ReadBuffer(buf1[0], 2); CurrSeemLen:=(buf1[0]*$100)+buf1[1]; partitionstream.copyFrom(fs,CurrSeemlen); Application.ProcessMessages; if partition=True then begin partitionstream.Seek(0,soFromBeginning); partitionstream.ReadBuffer(buf1[0],1); n:=buf1[0]; for i:=1 to n do begin partitionstream.ReadBuffer(buf1[0],2); buflen:=buf1[1]; partitionstream.ReadBuffer(buf1[0],buflen); case buf1[1] of $01 : ape:=True; $00 : cmt:=True; end; end; if cmt=True then begin partitionstream.Seek(0,soFromBeginning); framelen:=CurrSeemLen+10; DWord((@txBuf[0])^):=framelen; DWordSwap(@txbuf[0]); txBuf[4]:=$01; txBuf[5]:=$10; txBuf[6]:=$00; txBuf[7]:=frameCrc(@txbuf[0],7); txBuf[8]:=$64; partitionstream.ReadBuffer(txBuf[9], CurrSeemLen); txBuf[framelen-1]:=frameCrc(@txbuf[9],CurrSeemLen); //Form1._msg('CMT txbuf : '+BufToHexStr(@txbuf[0],framelen)); USBBulkWritePort(@txbuf[0],4); i:=USBBulkWritePort(@txbuf[0],framelen); if i<>framelen then begin result:=False; Form1._msg('Error sending CMT partition req, partition operation fail'); fs.free; ms.free; Exit; end; repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; //Form1._msg('RxBuf : '+buftohexstr(@rxBuf[0],Length(rxBuf))); if cmtreadreq then form1._msg('Partitioning CMT Ok...') else begin form1._msg('Partitioning CMT failed! :('); result:=false; end; end; if ape=True then begin partitionstream.Seek(0,soFromBeginning); framelen:=CurrSeemLen+10; DWord((@txBuf[0])^):=framelen; DWordSwap(@txbuf[0]); txBuf[4]:=$01; txBuf[5]:=$20; txBuf[6]:=$00; txBuf[7]:=frameCrc(@txbuf[0],7); txBuf[8]:=$64; partitionstream.ReadBuffer(txBuf[9], CurrSeemLen); txBuf[framelen-1]:=frameCrc(@txbuf[9],CurrSeemLen); //Form1._msg('APE txbuf : '+BufToHexStr(@txbuf[0],framelen)); USBBulkWritePort(@txbuf[0],4); i:=USBBulkWritePort(@txbuf[0],framelen); if i<>framelen then begin result:=False; Form1._msg('Error sending APE partition req, partition operation fail'); fs.free; ms.free; Exit; end; repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; //Form1._msg('RxBuf : '+buftohexstr(@rxBuf[0],Length(rxBuf))); if apereadreq then form1._msg('Partitioning APE Ok...') else begin form1._msg('Partitioning APE failed! :('); result:=false; end; end; Application.ProcessMessages; partitionstream.free; end; end; $C8: begin Application.ProcessMessages; Form1.statusbar.Panels[0].Text:='Erasing, Wait'; Application.ProcessMessages; ape:=false; cmt:=false; form1._msg('Erasing....'); erase:=True; fs.ReadBuffer(buf1[0], 1); CurrSeemLen:=buf1[0]; ms:=TmemoryStream.Create; ms.copyFrom(fs,CurrSeemlen); ms.Seek(0,soFromBeginning); ms.readbuffer(buf1[0],1); n:=buf1[0]; for i:=1 to n do begin ms.ReadBuffer(buf1[0],2); buflen:=buf1[1]; ms.ReadBuffer(buf1[0],buflen); case buf1[1] of $01 : ape:=True; $00 : cmt:=True; end; end; if cmt=true then begin Application.ProcessMessages; Form1.statusbar.Panels[0].Text:='Erasing CMT, Wait'; Application.ProcessMessages; ms.Seek(0,soFromBeginning); framelen:=CurrSeemLen+10; DWord((@txBuf[0])^):=framelen; DWordSwap(@txbuf[0]); txBuf[4]:=$01; txBuf[5]:=$10; txBuf[6]:=$00; txBuf[7]:=frameCrc(@txbuf[0],7); txBuf[8]:=$50; ms.ReadBuffer(txBuf[9], CurrSeemLen); txBuf[framelen-1]:=frameCrc(@txbuf[9],CurrSeemLen); //Form1._msg('CMT txbuf : '+BufToHexStr(@txbuf[0],framelen)); USBBulkWritePort(@txbuf[0],4); i:=USBBulkWritePort(@txbuf[0],framelen); if i<>framelen then begin result:=False; Form1._msg('Error sending CMT erase req, erase fail'); fs.free; ms.free; Exit; end; repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; //Form1._msg('RxBuf : '+buftohexstr(@rxBuf[0],Length(rxBuf))); if cmtreadreq then begin form1._msg('Erasing CMT Ok...'); Result:=True; end else begin form1._msg('Erasing CMT failed! :('); result:=false; end; Application.ProcessMessages; end; if ape=True then begin Application.ProcessMessages; Form1.statusbar.Panels[0].Text:='Erasing APE, Wait'; Application.ProcessMessages; ms.Seek(0,soFromBeginning); framelen:=CurrSeemLen+10; DWord((@txBuf[0])^):=framelen; DWordSwap(@txbuf[0]); txBuf[4]:=$01; txBuf[5]:=$20; txBuf[6]:=$00; txBuf[7]:=frameCrc(@txbuf[0],7); txBuf[8]:=$50; ms.ReadBuffer(txBuf[9], CurrSeemLen); txBuf[framelen-1]:=frameCrc(@txbuf[9],CurrSeemLen); //Form1._msg('APE txbuf : '+BufToHexStr(@txbuf[0],framelen)); USBBulkWritePort(@txbuf[0],4); i:=USBBulkWritePort(@txbuf[0],framelen); if i<>framelen then begin result:=False; Form1._msg('Error sending APE erase req, erase fail'); fs.free; ms.free; Exit; end; repeat bulkread:=usbbulkreadportint($FFFF) until bulkread<>0; //Form1._msg('RxBuf : '+buftohexstr(@rxBuf[0],Length(rxBuf))); if apereadreq then begin form1._msg('Erasing APE Ok...'); Result:=True; end else begin form1._msg('Erasing APE failed! :('); result:=false; end; Application.ProcessMessages; end; Application.ProcessMessages; endtimecount; Form1._msg('TIME : Erase time : '+showtime(tmsres)+' '); Application.ProcessMessages; Form1.pbsm1.Progress:=0; fs.Free; ms.free; Form1.statusbar.Panels[0].Text:=''; exit; end else begin // Form1._msg('SEEM : '+byte2str(currseem)); fs.ReadBuffer(buf[0], 1); CurrSeemLen:=buf[0]; fs.readbuffer(buf[0],CurrSeemLen); application.ProcessMessages; end; end; end; if erase=False then begin result:=True; Form1._msg('Erase : No any region, skip erase'); end; fs.Free; except on E:Exception do begin fs.Free; Form1._msg('EraseFile: Error: '+E.Message); result:=False; Application.ProcessMessages; Form1.statusbar.Panels[0].Text:=''; end; end; Form1.statusbar.Panels[0].Text:=''; Application.ProcessMessages; endtimecount; Form1._msg('TIME : Erase time : '+showtime(tmsres)+' '); end; function NomandicWriteFile(core:string):Boolean; const maxlen : dWORD = $4FFFF ; var buf :array[0..$4FFFF] of byte; HdrLen, CurrBlockLen : Cardinal; EntryPoint, DataLen, TargetOffset, CRCTmp : LongInt; i, n, Blocks, Packets,icl, CurrPacketSize, TokenHdrLen : Integer; good : Integer; CertName,AsicType : String; PAPUB_Already, APE_PAPUB : boolean; fs : TFileStream; ms : TMemoryStream; writen,framelen : Dword; cmtcount,cmtdin, TokenSubType, unk : integer; nopbyte : byte; nopword : word; ttxbuf : array[0..$4FFFF] of byte; ape,cmt : Boolean; apebyte : Byte; bulkread : integer; begin Result:=False; Form1._msg('Write : Processing '+ExtractFileName(core)); fs:=TFileStream.Create(core,fmOpenRead); fs.Seek(0, sofromBeginning); Blocks:=0; cmtcount:=0; cmtdin:=0; unk:=0; Form1.pb1.ForeColor:=clGreen; Form1.pb1.progress:=0; Application.ProcessMessages; try fs.Read(ttxbuf[0],1); if ttxbuf[0]<>$B2 then begin fs.free; raise E.Create('Write : Bad image file'); end; Application.ProcessMessages; starttime; Application.ProcessMessages; fs.ReadBuffer(ttxbuf[0], 4);//Длина Flash-header'a HdrLen := HexToInt(IntToHex(ttxbuf[0], 2)+IntToHex(ttxbuf[1], 2)+ IntToHex(ttxbuf[2], 2)+IntToHex(ttxbuf[3], 2)); fs.Seek(HdrLen, sofromcurrent);//К началу первого Flash-токена {ms:=TMemoryStream.Create;} form1.pb1.maxvalue:=(fs.size-hdrlen); form1.statusbar.Panels.Items[0].Text:='Writing...'; while fs.Position0; //Form1._msg('RxBuf : '+buftohexstr(@rxBuf[0],Length(rxBuf))); if cmtreadreq then Application.ProcessMessages else begin form1._msg('Write CMT failed on block '+inttostr(Blocks)+' :('); result:=false; fs.free; exit; end; end; $01: begin USBBulkWritePort(@ttxbuf[0],4); USBBulkWritePort(@ttxbuf[0],framelen); repeat bulkread:=USBBulkReadPortInt($FFFF); until bulkread<>0; //Form1._msg('RxBuf : '+buftohexstr(@rxBuf[0],Length(rxBuf))); if apereadreq then Application.ProcessMessages else begin form1._msg('Write APE failed on block '+inttostr(Blocks)+' :('); result:=false; fs.free; exit; end; end; end; Application.ProcessMessages; inc(blocks); case apebyte of $00:form1.statusbar.Panels[1].Text:='CMT : '+inttostr(Blocks); $01:form1.statusbar.Panels[1].Text:='APE : '+inttostr(Blocks); end; end;//End of Case $54 $5D://Phoenix-segment begin //5D 0127 2D 25B977A055BE9B5DEC0C38A2A279C695 8594B99841444100000000000000000000030077E7 00000400 000A0800 BB // Len RootKey Hash Len Flash CRC //5D 0128 43 25B977A055BE9B5DEC0C38A2A279C695 8594B99850415055424B4559530000000003 00A70900 00060000 11F000397DCE210733C335E84BAD369EC893FCA06D1BC3 0100 A5 // Len RootKey Hash Len Flash CRC fs.ReadBuffer(ttxbuf[$09], $3);//Чтение значения подтипа токена и длины его заголовка TokenHdrLen:=ttxbuf[$0B];//Длина заголовка токена TokenSubType:=TokenHdrLen; fs.Seek(fs.position-4, sofrombeginning);//смещение на начало токена inc(TokenHdrLen, 5);//Увеличим длину до общей длины токена с его CRC fs.ReadBuffer(ttxbuf[8], TokenHdrLen);//Чтение значений токена с его CRC apebyte:=ttxbuf[44]; case TokenSubType of $2D: //Длина текущего блока между токенами CurrBlockLen := HexToInt(IntToHex(ttxbuf[TokenHdrLen-1], 2)+ IntToHex(ttxbuf[TokenHdrLen], 2)+ IntToHex(ttxbuf[TokenHdrLen+1], 2)+ IntToHex(ttxbuf[TokenHdrLen+2], 2)); $43: //Длина текущего блока между токенами CurrBlockLen := HexToInt(IntToHex(ttxbuf[TokenHdrLen-$17], 2)+ IntToHex(ttxbuf[TokenHdrLen-$16], 2)+ IntToHex(ttxbuf[TokenHdrLen-$15], 2)+ IntToHex(ttxbuf[TokenHdrLen-$14], 2)); else begin fs.Free; E.Create('Write : Bad image file'); end; end;//End of Case //Сравнение RootKey Hash телефона и RootKey Hash блока сертов good:=0; case apebyte of $00: begin for i:=$0 to $0F do if RAPInfo.Root_Key_Hash[i]=ttxbuf[i+$0C] then inc(good); end; $01: begin for i:=$0 to $0F do if RAPInfo.APErootkey[i]=ttxbuf[i+$0C] then inc(good); end; end; if good<$10 then begin//RootKey Hash не совпал, пропускаем fs.Seek(CurrBlockLen, soFromCurrent);//Пропускаем токен и его данные continue; end else begin//RootKey Hash серта совпал, копируем case TokenSubType of $2D: begin DWord((@ttxBuf[$8+TokenHdrLen])^):=$0000;//Добавление слова-разделителя $0000 fs.ReadBuffer(ttxBuf[$0A+TokenHdrLen],CurrBlockLen);//Копирование данных Application.ProcessMessages; CertName:=''; for i:=32 to 45 do if ttxbuf[i]=$00 then break else CertName:=CertName+Chr(ttxbuf[i]); case apebyte of $00:Form1._msg('CMT: Writing Hash CERT ['+CertName+']'); $01:Form1._msg('APE: Writing Hash CERT ['+CertName+']'); end; Application.ProcessMessages; framelen:=CurrBlockLen+TokenHdrLen+$0A;//Состоит из 8 байт команды, токена, слова-разделителя, //Расчет длины фрейма // данных пакета DWord((@ttxBuf[0])^):=framelen; DWordSwap(@ttxbuf[0]); //form1._msg('Cert Len : '+IntToStr(framelen)); ttxBuf[4]:=$01; case apebyte of $01:ttxBuf[5]:=$20; $00:ttxBuf[5]:=$10; end; ttxBuf[6]:=$00; //Расчет первой crc (crc шапки команды) ttxBuf[7]:=frameCrc(@ttxbuf[0],7); //Form1._msg('txbuf : '+BufToHexStr(@txbuf[0],framelen)); Application.ProcessMessages; case apebyte of $00:begin USBBulkWritePort(@ttxbuf[0],4); USBBulkWritePort(@ttxbuf[0],framelen); repeat bulkread:=USBBulkReadPortInt($FFFF); until bulkread<>0; //Form1._msg('RxBuf : '+buftohexstr(@rxBuf[0],Length(rxBuf))); if cmtreadreq then Application.ProcessMessages else begin form1._msg('Write CMT cert failed! :('); result:=false; fs.free; exit; end; end; $01: begin USBBulkWritePort(@ttxbuf[0],4); USBBulkWritePort(@ttxbuf[0],framelen); repeat bulkread:=USBBulkReadPortInt($FFFF); until bulkread<>0; //Form1._msg('RxBuf : '+buftohexstr(@rxBuf[0],Length(rxBuf))); if apereadreq then Application.ProcessMessages else begin form1._msg('Write APE cert failed! :('); result:=false; fs.free; exit; end; end; end; Application.ProcessMessages; inc(blocks); Application.ProcessMessages; case apebyte of $00:form1.statusbar.Panels[1].Text:='CMT : '+inttostr(Blocks); $01:form1.statusbar.Panels[1].Text:='APE : '+inttostr(Blocks); end; end; $43: begin fs.ReadBuffer(ttxBuf[$08+TokenHdrLen],CurrBlockLen);//Копирование данных case apebyte of $00:Form1._msg('CMT: Writing Hash CERT [PAPUBKEYS]'); $01:Form1._msg('APE: Writing Hash CERT [PAPUBKEYS]'); end; Application.ProcessMessages; framelen:=CurrBlockLen+TokenHdrLen+$08;//Состоит из 8 байт команды, токена, слова-разделителя, //Расчет длины фрейма // данных пакета DWord((@ttxBuf[0])^):=framelen; DWordSwap(@ttxbuf[0]); //form1._msg('Cert Len : '+IntToStr(framelen)); ttxBuf[4]:=$01; case apebyte of $01:ttxBuf[5]:=$20; $00:ttxBuf[5]:=$10; end; ttxBuf[6]:=$00; //Расчет первой crc (crc шапки команды) ttxBuf[7]:=frameCrc(@ttxbuf[0],7); //Form1._msg('txbuf : '+BufToHexStr(@txbuf[0],framelen)); Application.ProcessMessages; case apebyte of $00:begin USBBulkWritePort(@ttxbuf[0],4); USBBulkWritePort(@ttxbuf[0],framelen); repeat bulkread:=USBBulkReadPortInt($FFFF); until bulkread<>0; //Form1._msg('RxBuf : '+buftohexstr(@rxBuf[0],Length(rxBuf))); if cmtreadreq then Application.ProcessMessages else begin form1._msg('Write CMT cert failed! :('); result:=false; fs.free; exit; end; end; $01: begin USBBulkWritePort(@ttxbuf[0],4); USBBulkWritePort(@ttxbuf[0],framelen); repeat bulkread:=USBBulkReadPortInt($FFFF); until bulkread<>0; //Form1._msg('RxBuf : '+buftohexstr(@rxBuf[0],Length(rxBuf))); if apereadreq then Application.ProcessMessages else begin form1._msg('Write APE cert failed! :('); result:=false; fs.free; exit; end; end; end; Application.ProcessMessages; inc(blocks); Application.ProcessMessages; case apebyte of $01:form1.statusbar.Panels[1].Text:='APE : '+inttostr(Blocks); $00:form1.statusbar.Panels[1].Text:='CMT : '+inttostr(Blocks); end; end; end; end; end//End of Case $5D else begin//Unknow Tokens or Bad File fs.free; E.Create('Write : Bad image file'); end; end;//End of Case form1.pb1.progress:=fs.Position; Application.ProcessMessages; end;//End of While fs.free; Form1._msg('Total writen '+inttostr(blocks)+' blocks'); Application.ProcessMessages; endtimecount; Form1._msg('TIME : Write time : '+showtime(tmsres)+' '); form1.statusbar.Panels[1].Text:=''; form1.statusbar.Panels[0].Text:=''; result:=True; //form1._msg('Errors : '+inttostr(GetLastError)); form1.pb1.maxvalue:=100; form1.pb1.progress:=0; Application.ProcessMessages; except on E:Exception do begin Form1._msg('Error: '+E.Message); Form1.pb1.Progress:=0; USBClosePort; exit; end; end; Form1.pb1.Progress:=0; end; function nomandicEndflash():Boolean; var i,bulkread:Integer; begin result:=False; //nomclosecmt form1._msg('ADL : Close CMT session'); USBBulkWritePort(@nomclosecmt,4); i:=UsbBulkWriteport(@nomclosecmt, Length(nomclosecmt)); if i<>11 then Exit; repeat bulkread:=USBBulkReadPortInt($FFFF); until bulkread<>0; //Form1._msg(buftohexstr(@rxBuf[0], Length(rxBuf))); Application.ProcessMessages; //nomcloseape form1._msg('ADL : Close APE session'); USBBulkWritePort(@nomcloseape,4); i:=UsbBulkWriteport(@nomcloseape, Length(nomcloseape)); if i<>11 then Exit; repeat bulkread:=USBBulkReadPortInt($FFFF); until bulkread<>0; Form1._msg('Content : '+buftohexstr(@rxBuf[14], 12)); Application.ProcessMessages; //nomrebootreq form1._msg('ADL : Reboot'); USBBulkWritePort(@nomrebootreq,4); i:=UsbBulkWriteport(@nomrebootreq, Length(nomrebootreq)); if i<>14 then Exit; //if USBBulkReadPortInt($FFFF)=0 then USBBulkReadPort($FFFF); //Form1._msg(buftohexstr(@rxBuf[0], Length(rxBuf))); Application.ProcessMessages; result:=true; end; function BB5_FlashingNomadic():boolean; var b, proto : Boolean; i : integer; rb : Byte; ms : TMemoryStream; begin Application.ProcessMessages; Sleep(500); Application.ProcessMessages; fltime:=0; if not DevPresent then begin Form1._msg('Phone not found... :('); Form1.SetBuzy; Form1.StatusBar.Panels[4].Text:=''; result:=False; USBClosePort; exit; end; Form1._msg('ADL : phone is in flash mode'); //Добавил для удобства кастом-прошивки Form1.statusbar.Panels[0].Text:=''; Form1.statusbar.Panels[1].Text:=''; Form1.statusbar.Panels[2].Text:=''; Form1.statusbar.Panels[4].Text:='FLASHING'; Form1.statusbar.Panels[3].Text:='Connected'; Form1.TimConChk.Interval:=100; Application.ProcessMessages; if Form1.chkMCUen.Checked=true then begin Form1.chkMCUen.Enabled:=False; Form1._msg(' ===Flashing [MCU]==='); if not NomandicEraseFile(core) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not NomandicWriteFile(core) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('MCU Write done'); Application.ProcessMessages; end; Application.ProcessMessages; if Form1.chkPPMe.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1._msg(' ===Flashing [PPM]==='); if not NomandicEraseFile(ppm) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not NomandicWriteFile(ppm) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('PPM Write done'); Application.ProcessMessages; end; Application.ProcessMessages; if Form1.chkPPM1e.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1.chkPPM1e.Enabled:=False; Form1._msg(' ===Flashing [PPM2]==='); if not NomandicEraseFile(ppm1) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not NomandicWriteFile(ppm1) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('PPM Write done'); Application.ProcessMessages; end; Application.ProcessMessages; if Form1.chkCNTe.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1.chkPPM1e.Enabled:=False; Form1.chkCNTe.Enabled:=False; Form1._msg(' ===Flashing [CNT]==='); if not NomandicEraseFile(image) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not NomandicWriteFile(image) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('CNT Write done'); Application.ProcessMessages; end; Application.ProcessMessages; if Form1.chkAPEe.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1.chkPPM1e.Enabled:=False; Form1.chkCNTe.Enabled:=False; Form1.chkAPEe.Enabled:=False; Form1._msg(' ===Flashing [APE]==='); if not NomandicEraseFile(ape) then begin StuffFlashReset; result:=False; Exit; end; Form1._msg('Erase taken : '+showtime(tmsres)+' s'); Application.ProcessMessages; if not NomandicWriteFile(ape) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('APE Write done'); Application.ProcessMessages; end; Application.ProcessMessages; if Form1.chkcnt3.Checked=true then begin Form1.chkPPMe.Enabled:=False; Form1.chkMCUen.Enabled:=False; Form1.chkPPM1e.Enabled:=False; Form1.chkCNTe.Enabled:=False; Form1.chkAPEe.Enabled:=False; Form1.chkcnt3.Enabled:=False; Form1._msg(' ===Flashing [CNT3]==='); if not NomandicEraseFile(cnt3) then begin StuffFlashReset; result:=False; Exit; end; Application.ProcessMessages; if not NomandicWriteFile(cnt3) then begin StuffFlashReset; result:=False; Exit; end; form1._msg('CNT Write done'); Application.ProcessMessages; end; Application.ProcessMessages; if not nomandicEndflash then Form1._msg('Flash finalization fail!'); // режим рестарта Application.ProcessMessages; Application.ProcessMessages; Form1._msg(''); Form1._msg('Flashing done!'); Form1._msg('Total flash time : '+showtime(fltime)); Form1._msg('Reboot phone now...'); Form1._msg(''); Application.ProcessMessages; fltime:=0; Form1.statusbar.Panels[0].Text:=''; Form1.pb1.ForeColor:=clNavy; Form1.pbsm1.ForeColor:=clNavy; Form1.pb1.MaxValue:=100; Form1.pb1.progress:=0; Form1.statusbar.Panels[1].Text:=''; Form1.TimConChk.Interval:=2000; Form1.pb1.color:=clActiveBorder; if affenabled then Form1.afterFlashdo; Application.ProcessMessages; Sleep(200); //form1._msg(Form1.SetReady); Form1.TimConChk.Enabled:=true; Form1._msg('Done!'); Form1.chkPPMe.Enabled:=True; Form1.chkMCUen.Enabled:=True; Form1.chkPPM1e.Enabled:=True; Form1.chkCNTe.Enabled:=True; Form1.chkAPEe.Enabled:=True; Form1.chkcnt3.Enabled:=True; Result:=true; end;//End of Normal Mode Flashing function cmtreadreq():Boolean; begin try if (rxbuf[0]=$80) and (rxbuf[1]=$01) and (rxbuf[2]=$7E) and (rxbuf[3]=$00) then result:=True else begin if (rxbuf[0]=$80) and (rxbuf[1]=$10) and (rxbuf[2]=$6F) and (rxbuf[3]=$00) then result:=True else end; except result:=false; end; end; function apereadreq():Boolean; begin try if (rxbuf[0]=$80) and (rxbuf[1]=$02) and (rxbuf[2]=$7D) and (rxbuf[3]=$00) then result:=True else begin if (rxbuf[0]=$80) and (rxbuf[1]=$20) and (rxbuf[2]=$5F) and (rxbuf[3]=$00) then result:=true else result:=False; end; except result:=false; end; end; function readcertrequsb(CERT : string):string; var framelen : dword; i : Integer; blkcnt : Integer; Blen : Integer; certstr : string; startblk : Integer; begin result:=''; startblk:=11; for i:=12 to 25 do rednpcreq[i]:=$00; Form1._msg('Reading '+CERT+' certificate...'); framelen:=Length(rednpcreq); DWord((@rednpcreq[0])^):=framelen; DWordSwap(@rednpcreq[0]); rednpcreq[7]:=frameCrc(@rednpcreq[0],7); for i:=0 to Length(CERT) do rednpcreq[i+12]:=Ord(CERT[i+1]); rednpcreq[framelen-1]:=frameCrc(@rednpcreq[9],Length(rednpcreq)-9); USBBulkWritePort(@rednpcreq[0], Length(rednpcreq)); If USBBulkReadPort($FFFF) then begin blkcnt:=rxbuf[9]; if blkcnt=0 then Exit; for i:=0 to blkcnt-1 do begin Blen:=rxbuf[startblk]; certstr:=certstr+buftohexstr(@rxBuf[startblk+1],Blen); startblk:=startblk+blen+2; end; //Form1._msg(CERT+' : '+certstr); result:=certstr; end; end; function buildxsr16cert(DataStream : widestring; cert : string ): Boolean; var i, framelen : Integer; tmp : array of Byte; chk : word; x : Integer; begin result:=False; // prepare and clear start buffer CopyMemory(@txbuf[0],@CRTwriteBuf[0],32); for i:=32 to 43 do txbuf[i]:=$00; for i:=0 to Length(CERT) do txbuf[i+32]:=Ord(CERT[i+1]); txBuf[44]:=$00; txBuf[45]:=$03; txBuf[46]:=$00; SetLength(tmp, length(DataStream) div 2); x:=StrToBufHex(DataStream,@tmp[0]); CHK:=FbusGetChk(@tmp[0], x); Word((@txBuf[47])^):=chk; DWord((@txBuf[49])^):=x; DWordSwap(@txbuf[49]); txBuf[53]:=$FF; txBuf[54]:=$FF; txBuf[55]:=$FF; txBuf[56]:=$FF; txBuf[57]:=framecrc(@txbuf[9],46); txBuf[58]:=$00; txBuf[59]:=$00; StrToBufHex(DataStream,@txbuf[60]); framelen:=x+60; DWord((@txBuf[0])^):=framelen; DWordSwap(@txbuf[0]); txBuf[7]:=framecrc(@txbuf[0],7); //Form1._msg(BufToHexStr(@txbuf[0],framelen)); USBBulkWritePort(@txbuf[0],framelen); if USBBulkReadPort($FFFF) then if cmtreadreq=true then result:=true else exit else exit; end; function CertErase(CERT : string):Boolean; begin result:=buildxsr16cert(Zerobyte, CERT); end; function contentExplore():Boolean; var i:Integer; s,asic,cnt1,cnt2,cnt3:string; begin Application.ProcessMessages; if rxbuf[11]=$0F then begin case rxBuf[13] of $03:asic:='NAND'; $01:asic:='NAND'; $00:asic:='NOR'; else asic:='Unknow' end; cnt1:=BufToHexStr(@rxBuf[15],4); cnt2:=BufToHexStr(@rxBuf[19],4); cnt3:=BufToHexStr(@rxBuf[23],4); Application.ProcessMessages; Form1._msg(asic +' status : '+cnt1+' / '+cnt2+' / '+cnt3); end else Form1._msg('Status : '+buftohexstr(@rxBuf[12],$0F)); form1._msg(''); Application.ProcessMessages; result:=true; end; function cntrel():Boolean; var cmtflash : Dword; phsec : integer; b : Boolean; begin TransId:=$5E; MsgBody:=$0A; Application.ProcessMessages; GetRoot[7]:=msgid; GetRoot[8]:=ISIHeaderTransId; GetRAPInfo; Application.ProcessMessages; Form1._msg('Checking CNT sector PN<>FL'); cmtflash:=Swap(Word((@rxBuf[20])^)); cmtflash:=cmtflash Shl 16; cmtflash:=cmtflash+Swap(Word((@rxBuf[18])^)); phsec:=getcntsize(cmtflash); Form1._msg('PN CNT sector : '+inttostr(phsec)+' kb'); if phsec=64 then Begin Application.ProcessMessages ; Form1._msg('No need convertion, continue flashing...'); end else begin if FileExists(image+'_128') then Form1._msg('Converted data exist') else begin b:=convertimages40(image); if b=True then image:=image+'_128'; end; end; end; function s40flashprepare2ndstage():Boolean; var b : Boolean; Uagent : TMemoryStream; i,i2 : integer; rb : Byte; cmtflash : DWord; begin if not BB5_PerFlashing then exit; rb:=$04; Application.ProcessMessages; Form1._msg('Reset connection...'); Application.ProcessMessages; Sleep(2000); Application.ProcessMessages; i:=30; while i>0 do begin Form1.StatusBar.Panels[0].Text:='Wait '+inttostr(i); Application.ProcessMessages; if catchdevice<>$02 then begin Application.ProcessMessages; sleep (1000); Application.ProcessMessages; sleep (1000); Application.ProcessMessages; end else i:=0; dec(i); end; if not DevPresent then begin Form1._msg('-> Phone not found... :('); Form1.StatusBar.Panels[0].Text:=''; USBClosePort; exit; end; Form1.StatusBar.Panels[0].Text:=''; //Phone in Flash Mode??? CheckADLUpload[7]:=msgid; CheckADLUpload[8]:=ISIHeaderTransId; CheckADLUpload[9]:=$00; i:=USBBulkWritePort(@CheckADLUpload, Length(CheckADLUpload)); if i<>12 then begin Sleep(200); Application.ProcessMessages; Form1._msg('Wait for device bootup...'); i:=0; repeat begin Sleep(100); Application.ProcessMessages; Inc(i); if catchdevice=$02 then i2:=USBBulkWritePort(@CheckADLUpload, Length(CheckADLUpload)); Form1.statusbar.Panels[0].Text:='Wait phone '+IntToStr(100-i); end; until (i2=12) or (i=100); if i2<>12 then begin Form1._msg('-> Bootcode start in CMT fail ! Need flash via programming device :('); Form1.TimConChk.Interval:=2000; result:=False; Form1.statusbar.Panels[0].Text:=''; exit; end; Form1.statusbar.Panels[0].Text:=''; Application.ProcessMessages; end; USBBulkReadPort(12); if rxBuf[11]<>$04 then begin if rxBuf[11]<>$80 then begin //Form1._msg('ADL Server not confirmed flashmode!'); Form1.SetReady; USBClosePort; exit; end else begin //Form1._msg('ADL -> [2nd] changing...'); rb:=rxBuf[11]; end; end else rb:=rxBuf[11]; // Form1._msg(Byte2Str(rb)); Application.ProcessMessages; case rb of $04: begin s40prep04; end; $80: begin s40prep80; end; else begin Form1._msg('-> Error while prepare!'); Exit; end; end; //Добавил для удобства кастом-прошивки Form1.statusbar.Panels[4].Text:='FLASHING'; Form1.statusbar.Panels[3].Text:='Connected'; Form1.TimConChk.Interval:=100; Application.ProcessMessages; result:=True; end; function BB5_EraseCustomArea_USB(area:string):boolean; var b,proto : Boolean; i,i2 : integer; rb : Byte; cntx : integer; n2way : Boolean; mcufl : Boolean; cntfl : Boolean; erasestart, erasestop : LongInt; begin result:=false; erasestart:=Hextoint(Copy(area,1,8)); erasestop:=Hextoint(Copy(area,9,8)); if (erasestart=0) or (erasestop=0) then Exit; starttime; rb:=$04; n2way:=false; mcufl:=false; cntfl:=false; Application.ProcessMessages; Form1._msg('Reopening the connection...'); Application.ProcessMessages; Sleep(2000); Application.ProcessMessages; i:=30; while i>0 do begin Form1._msg('Waiting for response: '+inttostr(i)); Application.ProcessMessages; if catchdevice<>$02 then begin Application.ProcessMessages; sleep (1000); Application.ProcessMessages; sleep (1000); Application.ProcessMessages; end else i:=0; dec(i); end; if not DevPresent then begin Form1._msg('-> Phone not found... :('); Form1.SetBuzy; Form1.StatusBar.Panels[4].Text:=''; USBClosePort; endtimecount; exit; end; fltime:=0; //Phone in Flash Mode??? CheckADLUpload[7]:=msgid; CheckADLUpload[8]:=ISIHeaderTransId; CheckADLUpload[9]:=$00; i:=USBBulkWritePort(@CheckADLUpload, Length(CheckADLUpload)); if i<>12 then begin Sleep(200); Application.ProcessMessages; Form1._msg('Wait for device bootup'); i:=0; repeat begin Sleep(100); Application.ProcessMessages; Inc(i); if catchdevice=$02 then i2:=USBBulkWritePort(@CheckADLUpload, Length(CheckADLUpload)); Form1.statusbar.Panels[0].Text:='Wait phone '+IntToStr(100-i); end; until (i2=12) or (i=100); if i2<>12 then begin Form1._msg('-> Bootcode start in CMT fail ! Need flash via programming device :('); Form1.TimConChk.Interval:=2000; result:=False; Form1.statusbar.Panels[0].Text:=''; endtimecount; exit; end; Form1.statusbar.Panels[0].Text:=''; Application.ProcessMessages; end; USBBulkReadPort(12); if rxBuf[11]<>$04 then begin if rxBuf[11]<>$80 then begin Form1._msg('ADL Server not confirmed flashmode!'); Form1.SetReady; USBClosePort; endtimecount; exit; end else begin Form1._msg('ADL -> [2nd] changing...'); rb:=rxBuf[11]; end; end else rb:=rxBuf[11]; // Form1._msg(Byte2Str(rb)); Form1._msg('ADL Server confirm flashmode!'); Application.ProcessMessages; case rb of $04: begin s40prep04; end; $80: begin s40prep80; end; else begin Form1._msg('-> Error while prepare!'); Form1.setready; endtimecount; Exit; end; end; //Добавил для удобства кастом-прошивки Form1.statusbar.Panels[4].Text:='FLASHING'; Form1.statusbar.Panels[3].Text:='Connected'; Form1.TimConChk.Interval:=100; Application.ProcessMessages; form1._msg('Starting Erase Custom Block'); if not BB5_EraseAreaSmallBlock(EraseStart, EraseStop, $12, $00, $00, $00) then begin Form1._msg('Error Erase Area! Check Model, setting'); Form1.SetReady; result:=False; Form1._msg(''); exit; end; endtimecount; Application.ProcessMessages; Form1._msg('ADL : End Erasing'); Form1._msg(''); Form1._msg('Erase done!'); Form1._msg('Total time : '+showtime(fltime)); Form1._msg('Try Reboot phone now...'); Form1._msg(''); Application.ProcessMessages; fltime:=0; Form1.statusbar.Panels[0].Text:=''; Form1.pb1.ForeColor:=clNavy; Form1.pbsm1.ForeColor:=clNavy; Form1.pb1.MaxValue:=100; Form1.pb1.progress:=0; Form1.statusbar.Panels[1].Text:=''; Form1.TimConChk.Interval:=2000; case rb of $80: begin BB5_ADL_RestartMCU(rb); i:=0; repeat Sleep(500); Application.ProcessMessages; i:=i+1; until (catchdevice=$02) or (i=10); if i<>10 then begin s4080Final; BB5_ADL_RestartMCU(rb); end; end; $04: begin BB5_ADL_RestartMCU(rb); i:=0; repeat Sleep(500); Application.ProcessMessages; i:=i+1; until (catchdevice=$02) or (i=10); if i<>10 then begin BB5_ADL_RestartMCU(rb); end; Application.ProcessMessages; Sleep(500); Application.ProcessMessages; i:=0; repeat Application.ProcessMessages; Sleep(200); Inc(i); Form1.statusbar.Panels[0].Text:=IntToStr(100-i); Application.ProcessMessages; if catchdevice=$01 then i:=100 else BB5_ADL_RestartMCU(rb); until (i=100) or (catchdevice=$01); Form1.statusbar.Panels[0].Text:=''; Application.ProcessMessages; if (i=100) and (catchdevice=$02) then begin Form1._msg('Custom mode fail!'); Form1._msg('Need reflash mcu only in DEAD mode'); StuffFlashReset; result:=False; Exit; end; end; end; Form1.pb1.color:=clActiveBorder; //if affenabled then Form1.afterFlashdo; Application.ProcessMessages; Sleep(200); Form1.TimConChk.Enabled:=true; Form1._msg('Done!'); Result:=true; end; function getversion(algfile:string):string; var fs : TfileStream; bcount : Integer; jblkbuf : array[0..$1FFFF] of Byte; i,i2 : Integer; data, a : string; CurrSeemLen, Currblocklen, hdrlen, SeemCount : Integer; CurrSeem : Byte; rev, vers : string; loaderlen : DWORD; begin result:=''; try fs:=TFileStream.Create(algfile,fmOpenRead); fs.seek(0,sofrombeginning); fs.Read(jblkbuf[0] ,1); if (jblkbuf[0]<>$B0) and (jblkbuf[0]<>$B1) then //Caaieiaie / eaaioeoeeaoi? begin fs.Free; exit; end; fs.Readbuffer(jblkbuf[0], 4);//Aeeia Flash-header'a HdrLen := HexToInt(IntToHex(jblkbuf[0], 2)+IntToHex(jblkbuf[1], 2)+IntToHex(jblkbuf[2], 2)+IntToHex(jblkbuf[3], 2)); //form1._msg('HeaderLen: '+inttostr(HdrLen)); fs.Readbuffer(jblkbuf[0], 4);//Eie-ai aeieia a Flash-caaieiaea SeemCount := HexToInt(IntToHex(jblkbuf[0], 2)+IntToHex(jblkbuf[1], 2)+IntToHex(jblkbuf[2], 2)+IntToHex(jblkbuf[3], 2)); //form1._msg('BlockCount: '+inttostr(SeemCount)); Application.ProcessMessages; while (fs.Position1) and (CurrBlockLen<3) then begin Rev:=inttostr(jblkbuf[0])+'.'+ inttostr(jblkbuf[1]); result:=result+' Rev : '+rev+' '; end else Rev:=''; inc(i); end; $DB://Version begin fs.Readbuffer(CurrBlockLen, 1); //Form1._msg('Found Block '+inttohex(CurrBlock, 1)+': Len: '+inttohex(CurrBlockLen, 2)); fs.Readbuffer(jblkbuf[0], CurrBlockLen); if (CurrBlockLen>1) and (CurrBlockLen<4) then begin Vers:=inttostr(jblkbuf[0])+'.'+ inttostr(jblkbuf[1])+'.'+ inttostr(jblkbuf[2]); result:=result+' Ver : '+vers+' '; end else Vers:=''; inc(i); end; else begin fs.Readbuffer(jblkbuf[0], 1); CurrSeemLen:=jblkbuf[0]; fs.Seek(CurrSeemLen, sofromcurrent); end; end; end; Fs.free; except result:=''; end; end; end.