問題タブ [objdump]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - 自己変更コード、ヒープでのコピー/ジャンプに失敗しました
まず、この投稿が長くなって申し訳ありませんが、問題を明確に説明したかったのです。
C で一種の小さな自己修正プログラムを作成しようとしていますが、いくつかの問題があり、その理由が正確にはわかりません。
プラットフォーム: Ubuntu/Linux 2.6.32-40 x86_64、prog は x86 arch でビルド、gcc (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3、GNU ld (Ubuntu の GNU Binutils) 2.20.1-system.20100303
プログラムの目的は、 ( memalign(3)およびmprotect(2)を使用して) メモリの読み取り/書き込み/実行のチャンクを作成し、このメモリのチャンクで (セグメントで定義された)呼び出された小さな関数をコピーしてから、ポインターを介して関数をコピーしました。この関数は、 を使用してメッセージを表示するだけです。p()
.text
p()
printf(puts)
のコードの開始アドレスと終了アドレスを取得するp()
(コピーする) ために、関数自体のアドレスと in の直後に作成される関数のアドレスを使用しdummy()
ます。p()
.text
チャンク メモリの作成とコピーは正常に行われますが、チャンク内のコードが実行されると segfault が発生します。これを使用gdb
すると、チャンクのコード (コピーされた関数の本体) に入力することは明らかですが、printf の呼び出しは失敗しました。関数とチャンク内のコードを逆アセンブルするp()
と、「呼び出し」で使用されるアドレスが同じではないことがわかります。
そして、なぜアドレスが間違っているのかわかりません。コードをコピーすると、それが表示され、p()
関数を逆アセンブルしたときに objdump (または gdb) が私に与えたものと同じです。
の再配置プロセスに関する-static
潜在的な問題を回避するために、バイナリは で作成されます。コピーされた関数の先頭が実行されるため、でコードを実行しても問題はないようです( で確認してください)。got/plt
ld.so
heap
gdb
プログラムの簡略化された src :
p()
によって逆アセンブルされた関数objdump(1)
:
プログラムを gdb(1) で実行すると、コピーされたコードは上記の objdump(1) と同じ (16 進値) になります。
main を見ると、次に chunk に入ります:
しかし、p() とチャンクが逆アセンブルされると、p() 関数の like のcall 0x80d2c90
代わりにメモリ チャンクに がありますか? call 0x8048f50 <puts>
そのため、表示されるアドレスは同じではありません。
メモリをチェックすると、コードは同一のようです。この時点で、何が起こっているのか理解できません。何が問題なのですか? gdb の解釈に失敗しました。コードのコピーか何か?
ブレークポイントが設定されている場合、メモリ チャンクで実行が続行されます。
したがって、この時点で、プログラムがそのように実行されてセグメンテーション違反が発生するか、$eip が変更されてプログラムがエラーなしで終了します。
何が起こっているのか、何が失敗したのかわかりません。コードのコピーは問題ないように見えます。メモリ チャンクへのジャンプも同様です。では、なぜ (呼び出しの) アドレスが適切ではないのでしょうか?
あなたの答えとあなたの時間をありがとう
arrays - デバッグ情報から変数の型を取得する
検討 :
データ セクションの objdump を実行すると、開始アドレスとサイズ (4*3) バイトの変数 x が取得されます。x が配列であり、どのタイプであったかという情報を取得する簡単な方法はありますか?
dwarfdump -i a.out を使用してこれを実行し、結果を解析して同じことを達成できることはわかっていますが、もっと簡単にできることはありますか? それが配列で、どのタイプのものかを確認する必要がありますか?
よろしく、
パンカジ
linux - objdump が intel 構文を出力する方法
objdump
デフォルトの AT&T 構文ではなく、Intel 構文でアセンブリを出力するように指示するにはどうすればよいですか?
c++ - ソースをC++プログラムのアセンブリリストと相関させる
リテールビルドでコアダンプを分析するには、多くobjdump
の場合、特定のモジュールとソースを相互に関連付ける必要があります。通常、関数が非常に複雑な場合、アセンブリダンプをソースと関連付けるのは面倒です。assembly listing
今日、私は1つの特定のモジュール(コンパイルオプションを使用)を作成しようとしましたが-S
、アセンブリまたは何らかの相関関係を持つインターリーブソースが表示されることを期待していました。残念ながら、リストは相互に関連付けるのに十分なほど友好的ではなかったので、私は疑問に思っていました
- クラッシュの場所を特定できるコアダンプが与えられた
objdump
失敗したモジュールのアセンブリリストを再コンパイルして-S
オプション付きモジュール。
ソースと1対1で対応することは可能ですか?
例として、アセンブリリストは次のように表示されます。
.LVL2123
しかし、のようなラベルとのようなディレクティブを解釈する方法を理解できませんでした.loc 2 4863 0
注
示されている回答のように、アセンブリソースを読み、シンボル(関数呼び出し、分岐、returnステートメントなど)に基づいてパターンを直感的に判断することが、私が一般的に行っていることです。私はそれが機能しないことを否定していませんが、関数がかなり関与している場合、アセンブリリストのページを読むのは苦痛であり、関数がインライン化されるかオプティマイザが単に投げられたために、ほとんど一致しないリストになってしまうことがよくあります好きなようにコード。どれだけ効率的に見えるかValgrind
最適化されたバイナリを処理し、Windows WinDBGで最適化されたバイナリを処理する方法について、私が見逃していることがあります。だから私はコンパイラの出力から始めて、それを使って相関させます。私のコンパイラがバイナリのマングリングを担当している場合、ソースとの相関方法を言うのが最善の人ですが、残念ながらそれはあまり役に立たず、.loc
本当に誤解を招く恐れがあります。残念ながら、私はさまざまなプラットフォーム間で再現不可能なダンプを読み通さなければならないことが多く、WinDBGを介したWindowsミニダンプのデバッグとLinuxコアダンプのデバッグに費やす時間が最も少なくなっています。私はそれが私が物事を正しくやっていないかもしれないけれども、私はこの質問を思いついた。
linux - objdumpとudis86は、/ proc/kcoreを逆アセンブルするときに異なる出力を生成します
Linuxでファイルを逆アセンブルする必要があり、後で配置する/proc/kcore
ためにいくつかの特別な命令の仮想アドレスを取得する必要があります。このドキュメントkprobes
によると、物理メモリのイメージですが、この質問では、誰かがそれがカーネルの仮想メモリ(まさに私が探しているもの)であると答えました。 /proc/kcore
ツールを使用objdump
して分解すると、アドレスは。のようf7c0b000
になりますが、udis86は0x0(およびまったく異なる命令)で始まります。grep
特定の指示をしようとすると、たとえばmov 0xf7c1d60c,%edx
、次のようになります。
objdump
udis86
udis86
との間のオフセットのように見えますが、objdump
常に0xbffff000
です。なぜそんなに奇妙なオフセット?特定の命令の仮想アドレスを取得するにはどうすればよいですか?私が読んだどこかで、そのカーネルは仮想アドレス0xc0000000+0x100000に静的にマッピングされています。が本当に物理的なイメージである場合/proc/kcore
、によって返されるアドレスに0x100000を追加するだけで正しいのobjdump
でしょうか?仮想アドレスを取得しますか?
c++ - Objdump ユーティリティから vptr (仮想テーブル別名 VTABLE へのポインタ) を取得していますか?
objdump ユーティリティと逆アセンブルされたコードを使用して、 VTABLE (対応する vptr)のアドレスを知るにはどうすればよいでしょうか。vptr は通常、オブジェクトの最初のバイトに格納されます (これを修正/編集してください)。仮想関数を使用したこの単純なコードがあります。
以下はコードの出力です:
以下は main 関数の一部です - コードの逆アセンブル:
ここでは、_ZN4baseC1Ev がベース オブジェクトのアドレスであり、_ZN3derC1Ev が派生オブジェクトのアドレスであることを示しています。
_ZN4baseC1Ev で
objdump -S exeファイルの出力へのリンクは次のとおりです
また、objdump -t virtualfunctionsize | grep vtable はこれを与えます:
私が知りたかったのは、VTABLEアドレスとそれに対応する仮想関数がそれによって示されていることです。
Vptr のアドレスは = 0x7fff86a78fe0 です。これは何を表していますか - VTABLE の場所?
Vptr の値 = 0x400c30 - これは何を表していますか? 基本クラスの最初の仮想関数?
派生クラスの仮想関数の後続のアドレスを見つけるにはどうすればよいですか?
Rgds、ソフト
global-variables - objdump 出力ファイルでグローバル変数のデータ型を抽出する方法は?
objdump 逆アセンブラー ツールを使用して逆アセンブルするバイナリ ファイルがあります。objdump 出力ファイルに存在するグローバル変数のデータ型を抽出する方法を教えてください。
windows - デバッグ情報を表示するための Windows での objdump
.out ファイル内の変数のアドレスとメンバー名を取得する必要があります。基本的にgccを使用してLinuxでacプログラムをコンパイルしましたが、ファイルの情報を見たいと思います。Linuxには多くの例がありますが、Windowsで行う必要があります。
編集
cygwin をインストールしましたが、何らかの理由で objdump が機能しません:
cygwin - cygwin で objdump が見つからない
cygwin で objdump コマンドを使用したいと考えています。私は例外を受け取ります:
-bash: objdump: コマンドが見つかりません
cygwin が objdump を見つけられないのはなぜですか?
EDIT ---- http://cygwin.com/packages/で binutils を見ることができます 。binutils パッケージを見つけたら、それをクリックすると、ここに移動します。インストール方法を教えてください。そこに着いたらどうすればいいですか?
gcc - objdump/readelfは変数情報を取得します
コンパイルされたcプログラムからグローバル変数に関する情報を取得する必要があります。私はここで同様の質問をしました。
私が今抱えている問題は、変数情報を抽出しようとしているプログラムが非常に大きく、ツリーをテキストで取得するだけで4秒かかることです(readelf -w[i] file.out
)。次に、必要な場所に到達するために、前後にジャンプするツリーを解析する必要があります。たとえば、変数がタイプのconst unsigned char * volatile MyVariable
場合、ツリーの5つの異なるノードに移動する必要があり、プログラムに1000個の変数が含まれている場合、必要なものを取得するのに時間がかかります。
ですから、私の質問は、readelfコマンドをより有効に活用して必要なものを実現するにはどうすればよいかということです。このreadelf -w[i] file.out
コマンドは、必要な情報(すべての関数、サブルーチン、ローカル変数など)を提供します。たとえば、そのコマンドの出力を調べてグローバル変数を取得する代わりに、readelf -s --wide file.out
コマンドを使用して変数のみを取得します。そのコマンドは変数の名前を教えてくれるので、たとえば変数が整数であるかどうかを確認するためにツリーを調べる必要があります。
このリンクの237ページには、たとえばタイプに関する情報を取得する方法の例があると思います。ここに写真があります:
必要なものを解析するのに約15秒かかりますが、まだいくつかのバグがあります。車輪の再発明をしなくても、readelfコマンドをより有効に活用できれば便利です。