Siemens SGold:Javaを介したハッキン​​グ

まえがき



この記事では、少なくともいくつかのコードを実行できる単一の環境、つまりJavaマシンを介して、Siemens SGoldプラットフォーム電話のプロセッサのアドレス空間にアクセスする方法を開示します。

提案された方法は、BBプロセッサを搭載したSiemens電話のファームウェアを変更およびデバッグすることが不可能だった友人であるChaos(Dmitry Zakharov)によって発明されました。

SGoldLiteおよびSGold-2ファミリー。 そして、私はそれを拡張して体系化しました。



これは長期的に何をもたらすのでしょうか?



これはすべて、コンピューターとデータケーブルなしで携帯電話から直接ファームウェアを変更することを可能にしますが、これは現時点では見つからず、資金不足の可能性があります。 単純なユーザーの場合、これはハードウェア(プロセッサーのオーバークロック、生産性の向上、SDRAMのロック解除など)とソフトウェアの拡張です。

(ELF形式の伝説的なエグゼキューター、Javaヒープの増加など)可能性、そしてプログラマーのために-ARMプログラムの作成を練習するためすべての条件があります。 そして当然、これは興味を持ち好奇心が強い人、そのようなデバイスが横になっている人のためのものです。 興味がありますか?

だから彼に第二の人生を与えてください!



ソースコード



すべての作業は、個別のASpaceクラスのアドレス空間で設計しました。 さらにその詳細のいくつかを説明します。



初期化



さて、最後にメソッドに移りましょう。

ご想像のとおり、このアクションはJavaコード、そしてもちろんARMアセンブラーを介して行われます。 Siemens Javaマシンには、zipアーカイブを操作するための組み込みクラスがあります。 その時、「自慢のファシスト」が穴を開けたのは、つまり、ドイツの技術者が穴を見落としていたからです。 これは、既存のすべてのファームウェアに適用されます(残念ながらまたは喜びのために、新しいファームウェアは待つ必要はありません)。

実際にタイトルについては、コードを見てみましょう:



//    ZIP  public byte[] aspace_ziparray = {0,0,0,0}; //,   2,  public int[] mainarray = {0}; //   public static final int ASPACE_RET_SUCCESS = 1; public static final int ASPACE_RET_UNKNOWNERROR = 0; public static final int ASPACE_RET_NOZIPFILE = -1; public static final int ASPACE_RET_NOZIPENTRY = -2; public static final int ASPACE_RET_SIGNOFIND = -3; //     0xA8000000 (SDRAM)  0xB0000000 (Flash) private static final int ASPACE_OFFSET_SDRAM_TO_FLASH = 0x8000000; //    0x00000000 (  ) public static int mainarray_startindex = 0; /*     Flash */ //   ()   0xA0000030 private static final int[] aspace_sgold_flash_signature = { 0xA0000000, //0xA0000000 0x5FFFFFFF, //0x5FFFFFFF 0xA0000074, //0xA0000074 0x544B4A43 //CJKT Marker }; /*   ( ) */ public int ASpace_Init(String any_zipfile, String any_zipentryname) { try { //  ,       ZipFile zf = new ZipFile(any_zipfile); if (zf != null) { // ZipEntry      ZipEntry ze = zf.getEntry(any_zipentryname); if (ze != null) { //  InputStream zis = zf.getInputStream(ze); //   ,      , //     2 zis.read(aspace_ziparray, 4, 0x7FFFFFFF); // zip -  zf.close(); //    Flash //       //     0x0 int i = ASPACE_OFFSET_SDRAM_TO_FLASH/4; for (; i > 0; i--) { int j = 0; for (int k = 0; k < 4; k++) { if (mainarray[i + k] != aspace_sgold_flash_signature[k]) { j = 1; break; } } if (j == 0) { //    Flash mainarray_startindex = i - (aspace_sgold_flash_signature_offset/4); // ,    , .. 0x00 mainarray_startindex += ( 0x50000000/4 ); break; } } //,   if (i != 0) return ASPACE_RET_SUCCESS; //  else return ASPACE_RET_SIGNOFIND; //     } else return ASPACE_RET_NOZIPENTRY; //    } else return ASPACE_RET_NOZIPFILE; //  } catch (Exception e) { return ASPACE_RET_UNKNOWNERROR; } }
      
      







シーメンスのアドレス空間マップがどのようなものかを説明します。

0x00000000-0x00003FFF-内蔵SRAM#1(マイクロコントローラー内)

0x00080000-0x00097FFF-内蔵SRAM#2(マイクロコントローラー内)

0x00400000-0x0040FFFF-内部BootROM(マイクロコントローラー内)

0xA0000000-0xA7FFFFFF-外部フラッシュ(32 MB、64 MB、96 MB、128 MBの場合もあります)

0xA8000000-0xA9FFFFFF-外部SDRAM(8 MB、16 MB、32 MBが発生します)

0xB0000000-0xB7FFFFFF-書き込みアクセス可能なフラッシュミラー

0xF0000000-0xFFFFFFFF-I / Oポート、組み込みデバイスのレジスタ(ミクロン単位)



一番下の行は、aspace_ziparray配列の外側の0x7FFFFFFFメソッドバイトを読み取ることにより、メイン配列配列領域に分類されるため、Javaはその長さを2 GB(0x7FFFFFFF)に増やします。 すべてがルールの範囲内にあるため、配列を離れることに関する例外は表示されません。 そして、この配列の内容はアドレス空間です。

SDRAMのこのアレイの物理アドレスから始めます。



当然、これはJavaヒップのどこかにあります。

x65thモデルでは、これは0xA8000000-0xA8300000領域にあります。

x75thモデルでは、これは0xA8500000-0xA8700000領域にあります。



配列はintであるため、1つのセルは4バイトです。 インデックスを1移動すると、4バイト移動します。 配列はintですが、2 GBを超えないため、SDRAM、フラッシュミラー、I / Oポート、およびすべての内部メモリの半分を自由に使用できます。

残りは、いわば「舞台裏」です。 次に、インデックスをフラッシュミラーの領域に移動し、インデックスを先頭に移動して、途中でaspace_sgold_flash_signature署名を確認する必要があります。これは、フラッシュの先頭であることを示しています。 それを見つけたので、開始アドレスにジャンプし、アドレス0x00に対応するmainarray配列のインデックスを変数mainarray_startindexに書き込みます。

すべて、初期化が完了しました。



読み書き



mainarray配列を使用して、そのインデックスをmainarray_startindexに相対的に移動すると、SRAM / SDRAM / I / Oポートの読み取りと書き込みの両方ができます。

メソッドはこれに関係しています:



 //   32    public int ASpace_readword(int address); //   16    public int ASpace_readhwrd(int address); //    public int ASpace_readbyte(int address); //   32    public int ASpace_writeword(int address, int value); //   16    public int ASpace_writehwrd(int address, int value); //    public int ASpace_writebyte(int address, int value);
      
      







ARMコードの実行



実際、これはすべて良いことですが、ARMコードの実行はどうでしょうか?

プロセッサのマシンコードのエグゼキュータをインストールする方法があります。

電話機のSRAM / SDRAMには、定期的に呼び出される手順へのさまざまなポインター(わからない、C / C ++チュートリアルを読む)がたくさんあります。ファームウェア自体がそれを呼び出します。 しかし、システムが落ちないように、すべてを正しく行う必要があります。 たとえば、このメソッドのARMコードエグゼキューターは次のようになります。



  /* ARM Caller -  ARM - */ //    public final int aspace_sgold_armcaller_newpointer = 0x803F8; //    ARM Caller'a public final int aspace_sgold_armcaller_bodyaddress = 0x8E010; //       public final int aspace_sgold_workcode_bodyaddress = 0x8E100; //    private static final int ASPACE_ARMCALLER_STATE = 16; private static final int ASPACE_ARMCALLER_OLDPROC = 17; private static final int ASPACE_ARMCALLER_RUNPROC = 18; private static final int ASPACE_ARMCALLER_PARAM0 = 19; private static final int ASPACE_ARMCALLER_PARAM1 = 20; private static final int ASPACE_ARMCALLER_PARAM2 = 21; private static final int ASPACE_ARMCALLER_PARAM3 = 22; private static final int ASPACE_ARMCALLER_RETURN = 23; //  private static int aspace_armcaller_repaddress = 0; //   ARM Caller'a private static int aspace_armcaller_bodyaddress = 0; //     ARM  private static int[] aspace_armcaller = { 0xE92D401F, // ; STMFD SP!, {R0-R4,LR} 0xE59F0038, // ; LDR R0, =old_proc 0xE12FFF30, // ; BLX R0 0xE59F002C, // ; LDR R0, =state 0xE3500000, // ; CMP R0, #0 0x08BD801F, // ; LDMEQFD SP!, {R0-R4,PC} 0xE59F002C, // ; LDR R0, =param0 0xE59F102C, // ; LDR R1, =param1 0xE59F202C, // ; LDR R2, =param2 0xE59F302C, // ; LDR R3, =param3 0xE59F4018, // ; LDR R4, =run_proc 0xE12FFF34, // ; BLX R4 0xE58F0024, // ; STR R0, [PC,#0x24] ; ret 0xE3A00000, // ; MOV R0, #0 0xE58F0000, // ; STR R0, [PC,#0x00] ; state 0xE8BD801F, // ; LDMFD SP!, {R0-R4,PC} 0x00000000, // ; state 0x00000000, // ; old_proc 0x00000000, // ; run_proc 0x00000000, // ; param0 0x00000000, // ; param1 0x00000000, // ; param2 0x00000000, // ; param3 0x00000000 // ; ret };
      
      







プログラムの本体を変更して、パラメーターを設定し、1つのコマンドでコードが1回だけ呼び出されるようにします。 インストール後、ARMプロシージャを実行し、最大4つのパラメーターを設定して戻り値を取得できます。

パフォーマーに役立つメソッド:



  /*   / ARM Caller'a (   ) */ // ARM Caller'a public int ASpace_InstallArmCaller(int replace_address, int body_address); // ARM Caller'a public int ASpace_DeInstallArmCaller(); /*     */ public int ASpace_RunArmCode(int address, int arg0, int arg1, int arg2, int arg3);
      
      







追加の方法



さて、上記で与えられているのは、コア、基盤です。 しかし、クラスには他のメソッドがあります。

それらに基づいて組み立てられます。 一部はARMコードを使用します:



 /*    / ARM  Data Abort */ public void ASpace_DisableDataAbort(); public void ASpace_EnableDataAbort(); /*    SDRAM  0xB8000000 (  ARM Caller) */ public void ASpace_SDRAMRemap(); /*          */ public int ASpace_SearchFunction(int search_address, int search_size, int[] pattern, int offset); /*          */ public int ASpace_SearchFunctionByWords(int search_address, int search_size, int[] pattern, int offset);
      
      







おわりに



上記で、視点について言及しました。 彼女のアイデアの1つの既製の実装が既に存在し、

そして、もちろん、このクラスで作業する例です。

ここでソースと準備ができているミッドレットを見つけることができます:



シーメンスSGoldサービスツール



All Articles