32

実際のデバイスで ios アプリケーションの起動をデバッグする必要があります...起動とは、OS が制御をアプリに渡すときに実行される最初の命令を意味します。「メイン」ではありません。また、このアプリケーションにはシンボルがありません (つまり、デバッグ情報はまだ利用できません)。CPU 命令レベルでデバッグする必要があるかどうかは気にしません。私はそれを行う方法を知っています (30 年以上それを行ってきました)。コントロールがアプリに転送されようとしているときにデバッガーを停止したい。Attach|by Name コマンドを使用して実行すると、「Finished running」とだけ表示されます。

ああ、このアプリケーションは XCode でビルドされていませんでした。ただし、これ私が作成、署名、プロビジョニングし、デバイスに移動したアプリケーションです。コンソール出力が表示されるので、アプリケーションは実行されます。私が誰かのアプリケーションをデバッグしようとしているハッカーだと思っている場合に備えて。

背の高い注文はどうですか?誰もこれに答えられないに違いない... XCodeで構築されたプロジェクトでこれを行う方法に関する情報を見つけることができませんでした。Appleの大君主によってそれが単に不可能または「許可」されているのだろうか?

スタックオーバーフローの神々、あなたは何と言いますか?

更新: 何かを明確にする必要があります。このアプリケーションは、市販またはオープンソースのツールを使用して構築されていません。コンパイラ、フレームワーク、および IDE を作成するツール ベンダーと協力しています。IOW、あなたはこのツールを手に入れることができません... まだ。新しいツール チェーンをブートストラップするプロセスでは、非常に低レベルの生のデバッグに定期的に頼らなければなりません。特に、ツールによって生成されたコードにバグがある場合。

4

3 に答える 3

23

解決策に出くわしたと思うので、私は自分の質問に答えるつもりです。これよりエレガントでシンプルなものがあれば、それも答えてください。手順に進みます:

生のモノリシック iOS 実行可能ファイル (バンドルされた .app ではなく、マシン コードである実際のバイナリ mach-o ファイル) から始めます。

  1. 同じ名前の新しい空の Xcode プロジェクトを作成します。デバイスでビルドして実行します。
  2. 出力バンドルの .app フォルダーを見つけます。
  3. 上記の未加工の iOS 実行可能ファイルを .app バンドルのフォルダーにある既存の実行可能ファイルにコピーします。
  4. アプリケーションの署名が無効になり、デプロイおよび実行できなくなります。
  5. アプリ バンドルに対して codesign を実行します (上記の Xcode プロジェクトで xcodebuild を実行すると、コマンド ラインを確認できます)。
  6. バンドルの .app フォルダーで、バイナリ イメージに対して otool -h -l を実行します。LC_UNIXTHREAD ロード コマンドを見つけて、「pc」レジスタに関連付けられている値を見つけます。これは、OS ローダーがアプリケーションにジャンプするアドレスです。このアドレスが奇数の場合、これらは Thumb 命令であり、それ以外の場合は ARM になります (そのように動作すると思います)。
  7. シンボリック ブレークポイントを追加し (私は LLDB の代わりに GDB を使用しました)、アドレスをシンボルとして「*0x00001234」と入力します。
  8. 製品|アクションの実行|ビルドせずに実行を選択します。

GDB がブレークポイント式を評価してブレークポイントを設定でき、[製品]、[ワークフローのデバッグ]、[デバッグ時に逆アセンブリを表示] を選択したと仮定すると、プロセスはアプリケーションで実行される最初の命令で中断するはずです。

命令をシングル ステップで実行し、GDB コンソールを使用してレジスタ値を取得/設定できるようになりました。

于 2012-05-28T23:50:54.210 に答える
2

あなたの質問は意味がありません-メインはアプリケーションへのエントリポイントです。これは、一部のクラスでinitialize()をオーバーライドしていない限り、最初に遭遇するコードです(ただし、それでも、実行前にmainがヒットすると思います)。

起動時にある種の奇妙なエラーが発生していて、それをキャッチするためにエントリにブレークポイントを設定したいと考えていると思いますが、起動時に問題を説明し、4000人のうちの1人に同じクラッシュを見て修正したことがあなたを助けます...

ただし、本当にGDBを使用して、シンボルのないアプリケーションでブレークしたい場合(ただし、XCodeから起動した場合)、次のようにアセンブリアドレスでGDBブレークを実行できます。

gdbの特定のアドレスでアセンブリ命令を中断するにはどうすればよいですか?

main(または他のメソッド)のアドレスを見つけるには、ツールまたはatosを使用できます。この質問のいくつかの例:

iOSクラッシュダンプのオフセットを分解されたバイナリに一致させる

添加:

何らかの理由でXCodeがデバッグ用にアプリケーションを起動できない場合は、ジェイルブレイクしてデバイス自体にGDBをインストールすることもできます。これにより、デバッグを完全に制御できます。XCodeがアプリケーションを起動できる場合、任意のメモリアドレスでブレークできることが、求める機能を提供しない理由はわかりません...

于 2012-05-27T21:13:18.003 に答える