unit UnitUFS; interface Uses D2XXUnit,HexUtils, FBoots, Windows, Masks, Forms,sysutils, classes, boots, dialogs ; procedure readUID(); // внешняя функция для использования function readUIDstep1 ():Boolean; // Общая функция чтения function SendRawID(Asic:integer; Loader:string) : integer; // Сама функция чтения данных function Select2ndDie(idr:string):Boolean; // подбираем лоадеры implementation uses UnitE1, UnitPavel, unit1, FlashBoots, USBmain, unitmisc, Graphics, UnitUFS; function Select2ndDie(idr:string):Boolean; var s:string; begin result:=true; idr:=copy(idr,1,5); FbusFloader:=''; FbusSloader:=''; case Str2Byte(idr[1]+idr[2]) of $BA: begin FbusFloader:=StartDir+'Flash\UFS\Special\RAP3Gv3_BAF3A9C3DBFA8454937DB77F2B8852B1.bin'; FbusSloader:=StartDir+'Flash\UFS\Special\BootCustom_BAF3A9C3DBFA8454937DB77F2B8852B1.bin'; bof:=StartDir+'Flash\UFS\Special\RAP3Gv3_BO.bin'; end; $9D: begin FbusFloader:=StartDir+'Flash\UFS\Special\RAP3Gv3_9DDBFCFE6E73CED7D8C6268C8EB85723.bin'; FbusSloader:=StartDir+'Flash\UFS\Special\BootCustom_9DDBFCFE6E73CED7D8C6268C8EB85723.bin'; bof:=StartDir+'Flash\UFS\Special\RAP3Gv3_BO.bin'; end; $E9: begin FbusFloader:=StartDir+'Flash\UFS\Special\RAP3Gv2_E9EFF4BFAA5393217CA6B17755FC3E14.bin'; FbusSloader:=StartDir+'Flash\UFS\Special\BootCustom_E9EFF4BFAA5393217CA6B17755FC3E14.bin'; bof:=StartDir+'Flash\UFS\Special\RAP3Gv2_BO.bin'; end; $38: begin FbusFloader:=StartDir+'Flash\UFS\Special\RAP3Gv3_38F312750F686F9FC9B1B3778774A195.bin'; FbusSloader:=StartDir+'Flash\UFS\Special\BootCustom_38F312750F686F9FC9B1B3778774A195.bin'; bof:=StartDir+'Flash\UFS\Special\RAP3Gv3_BO.bin'; end; $A5: begin FbusFloader:=StartDir+'Flash\UFS\Special\RAP3Gv3_A5404AE83A594ECADEE532F0C236BFA6.bin'; FbusSloader:=StartDir+'Flash\UFS\Special\BootCustom_A5404AE83A594ECADEE532F0C236BFA6.bin'; bof:=StartDir+'Flash\UFS\Special\RAPIDO_BO.bin'; end; $9A: begin FbusFloader:=StartDir+'Flash\UFS\Special\RAPIDOv11_9A28E119033B91D14D22838C86D0D53C.bin'; FbusSloader:=StartDir+'Flash\UFS\Special\BootCustom_9A28E119033B91D14D22838C86D0D53C.bin'; bof:=StartDir+'Flash\UFS\Special\RAPIDO_BO.bin'; end; $CA: begin FbusFloader:=StartDir+'Flash\UFS\Special\RAPIDOv11_CAEEBB65D3C48E6DC73B49DC5063A2EE.bin'; FbusSloader:=StartDir+'Flash\UFS\Special\BootCustom_CAEEBB65D3C48E6DC73B49DC5063A2EE.bin'; bof:=StartDir+'Flash\UFS\Special\RAPIDO_BO.bin'; end; $F2: begin FbusFloader:=StartDir+'Flash\UFS\Special\RAPIDOv11_F2D76DFAFD66C7F195F278417DF05888.bin'; FbusSloader:=StartDir+'Flash\UFS\Special\BootCustom_F2D76DFAFD66C7F195F278417DF05888.bin'; bof:=StartDir+'Flash\UFS\Special\RAPIDO_BO.bin'; end; $F6: begin FbusFloader:=StartDir+'Flash\UFS\Special\RAPIDOv11_F682624FFB08F6D955DBE7D9C0485084.bin'; FbusSloader:=StartDir+'Flash\UFS\Special\BootCustom_F682624FFB08F6D955DBE7D9C0485084.bin'; bof:=StartDir+'Flash\UFS\Special\RAPIDO_BO.bin'; end; $FC: begin FbusFloader:=StartDir+'Flash\UFS\Special\RAPIDOv11_FCB5C510AF7F09F313D9BDE85A707CC0.bin'; FbusSloader:=StartDir+'Flash\UFS\Special\BootCustom_FCB5C510AF7F09F313D9BDE85A707CC0.bin'; bof:=StartDir+'Flash\UFS\Special\RAPIDO_BO.bin'; end; else result:=False; end; end; function readUIDstep1 ():Boolean; begin result:=false; form1._msg('Setting FlashMode'); if not SwitchBoxMode('FlashBus') then begin form1._msg('UFSx : FlashMode init fail! Reconnect box'); form1._msg(''); form1.SetReady; exit; end; Form1.statusbar.Panels[0].Text:='UFS : Booting phone...'; ufs_cmd(3500,@CMTread[0],2,@cmd_buf,200); //Form1._msg('BootData : '+BufToHexStr(@cmd_buf[0], $FF)); Application.ProcessMessages; if (FT_IN_BUFFER[1]>20) and (FT_IN_BUFFER[2]<>$72) and (FT_IN_BUFFER[2]<>$20) then FetchBootData else begin form1._msg('No answer from phone... :('); form1._msg('1. Check cable/connection, try again'); form1._msg('2. Maybe HW fault or bad cable'); form1._msg(''); form1.SetReady; Exit; end; if not Select2ndDie(ROOTKEY) then begin // выбор лоадера по необходимый руткейхэшь Form1._msg('Error finding required loader... :('); form1._msg(''); form1.SetReady; Exit; end; if SendRawId(0,FbusFloader)<>0 then exit; result:=True; end; function SendRawID(Asic:integer; Loader:string) : integer; var rawloader, rawblock : TMemoryStream; b : Boolean; chk : word; tmp : array of Byte; i : integer; flblk : integer; lb : Byte; filename : string; mmc : System.Text; id : string; begin result:=9; algo:=''; Form1.statusbar.Panels[0].Text:='UFS : CMT 2ND boot...'; // шлем бут Form1._msg('CMT : Sending 2nd loader...'); Application.ProcessMessages; RAWloader:=TMemoryStream.Create; rawloader.LoadFromFile(loader); rawloader.Seek(0,soFromBeginning); SetLength(tmp, rawloader.Size); if rawloader.size=0 then exit; result:=8; // RAwloader prepare error if (FLbyte=$F1) or (FLbyte=$F5) or (FLbyte=$F3) then begin ufs_cmd(50,@prerawcheck[0],3,@cmd_buf,1); Form1._msg('Set Data ['+Byte2Str(ft_in_buffer[0])+']'); //form1._msg('Set Data ['+Byte2Str(replyverify3)+']'); end; rawloader.ReadBuffer(tmp[0], rawloader.Size); RawLen[6]:=rawloader.Size mod $100; RawLen[5]:=rawloader.Size div $100; result:=7; // PrebootCheck error - raw len no accepted ufs_cmd(50,@Rawlen[0],7,@cmd_buf,2); Form1._msg('Set data ['+byte2str(FT_In_Buffer[0])+']'); devbyte:=FT_In_Buffer[0]; if FT_In_Buffer[1]<>$72 then Exit; Application.ProcessMessages; FT_Out_Buffer[0]:=$69; FT_Out_Buffer[1]:=$02; FT_Out_Buffer[2]:=$0A; FT_Out_Buffer[3]:=$00; FT_Out_Buffer[5]:=rawloader.Size mod $100; FT_Out_Buffer[4]:=rawloader.Size div $100; FT_Out_Buffer[6]:=$00; FT_Out_Buffer[7]:=$00; Application.ProcessMessages; for i:=0 to rawloader.size+7 do FT_Out_Buffer[i+8]:=TMP[i]; ufs_cmd(500,@FT_out_buffer,(rawloader.Size+8),@cmd_buf,7); result:=6; // rawloader not accepted by phone if ft_in_buffer[0]<>$00 then begin form1._msg('ERR: '+buftohexstr(@FT_in_buffer[0],7)); exit; end; //if ft_in_buffer[5]<>$F1 then exit; if ft_in_buffer[6]<>$72 then begin form1._msg('ERR: '+buftohexstr(@FT_in_buffer[0],7)); exit; end; Application.ProcessMessages; Form1._msg('CMT Loader sent, Boot Ok'); Form1.statusbar.Panels[0].Text:='UFS : 2ND Boot Ok, wait...'; // выполняем переполнение бута rawloader.Free; RAWloader:=TMemoryStream.Create; rawloader.LoadFromFile(bof); rawloader.Seek(0,soFromBeginning); SetLength(tmp, rawloader.Size); rawloader.ReadBuffer(tmp[0], rawloader.Size); Application.ProcessMessages; FT_Out_Buffer[0]:=$74; FT_Out_Buffer[1]:=$20; FT_Out_Buffer[2]:=$00; FT_Out_Buffer[3]:=$02; FT_Out_Buffer[4]:=$E4; for i:=0 to rawloader.size+4 do FT_Out_Buffer[i+5]:=TMP[i]; ufs_cmd(500,@FT_out_buffer,(rawloader.Size+5),@cmd_buf,2); rawloader.Free; if ft_in_buffer[1]<>$72 then exit; Application.ProcessMessages; ufs_cmd(500,@flow,Length(flow),@cmd_buf,2); Form1.statusbar.Panels[0].Text:='UFS : Exploit Ok, wait...'; // Переполнение прошло, шлем кастом-лоадер Application.ProcessMessages; Form1._msg('OWF : '+byte2str(ft_in_buffer[0])); if ft_in_buffer[1]<>$72 then exit; RAWloader:=TMemoryStream.Create; rawloader.LoadFromFile(FbusSloader); rawloader.Seek(0,soFromBeginning); SetLength(tmp, rawloader.Size); rawloader.ReadBuffer(tmp[0], rawloader.Size); Application.ProcessMessages; FT_Out_Buffer[0]:=$74; FT_Out_Buffer[1]:=$20; FT_Out_Buffer[2]:=$00; FT_Out_Buffer[4]:=rawloader.Size mod $100; FT_Out_Buffer[3]:=rawloader.Size div $100; for i:=0 to rawloader.size+4 do FT_Out_Buffer[i+5]:=TMP[i]; dwordswap(@FT_out_buffer[5]); ufs_cmd(500,@FT_out_buffer,(rawloader.Size+5),@cmd_buf,2); rawloader.free; if ft_in_buffer[1]<>$72 then exit; Application.ProcessMessages; ufs_cmd(500,@flow,Length(flow),@cmd_buf,2); Application.ProcessMessages; Form1._msg('OWF2 : '+byte2str(ft_in_buffer[0])); // Кастом-лоадер запущен, начинаем подготовливать стеки if ft_in_buffer[1]<>$72 then exit; Application.ProcessMessages; ufs_cmd(500,@overready , 9 ,@cmd_buf,11); Form1._msg('OWF3 : '+byte2str(ft_in_buffer[9])); //if ft_in_buffer[8]<>$72 then exit; Application.ProcessMessages; ufs_cmd(500,@readdieid , 6 ,@cmd_buf, $40); // читаем наши данные - 20 байт RAP_PUBLIC_ID+20 байт UNIQUEID Form1.statusbar.Panels[0].Text:='UFS : Fetching data, wait...'; id:=buftohexstr(@ft_in_buffer[0],$40); try FileName:=getcurrentdir+'\'+'Special'+'\'+buftohexstr(@RAPInfo.PUBLIC_ID,Length(RAPInfo.PUBLIC_ID))+'_fetch.best'; // сохраняем по значению рапайди except FileName:=getcurrentdir+'\Err_read_info_fetch.best'; end; if fileexists(filename) then filename:=getcurrentdir+'\'+'Special'+'\'+'rand'+'__fetch.best'; System.Assign (MMC ,FileName ) ; System.Rewrite ( MMC ); System.WriteLn (MMC,'[fetched]'); System.Writeln (MMC, 'RAPID='+buftohexstr(@RAPInfo.PUBLIC_ID,Length(RAPInfo.PUBLIC_ID))); System.Writeln (MMC, 'HASH='+buftohexstr(@RAPInfo.ROOT_KEY_HASH,Length(RAPInfo.ROOT_KEY_HASH))); System.Writeln (MMC, 'ROMID='+buftohexstr(@RAPInfo.ROM_ID,Length(RAPInfo.ROM_ID))); System.Writeln (MMC, 'id='+id); System.Close(mmc); Form1._msg('Saved to : '+filename); Form1.statusbar.Panels[0].Text:=''; result:=0; end; procedure readUID(); begin if not readUIDstep1 then form1._msg('Error fetching data... :(') else form1._msg('ID read done ;)'); end;