プログラムカウンタPC
の内容を出力するCプログラムを作成したいと思います。これはユーザー空間、アセンブリ、またはいくつかの特定のカーネルルーチンが使用されることができますか?Cのプログラムカウンタの正確な値を出力する方法
答えて
(ARMコンパイラは同じの多くをサポートしていますGCCとしての拡張)。 *これは、ARMの特定です:
int main() {
printf("%#x\n", __current_pc());
printf("%#x\n", __current_pc());
printf("%#x\n", __current_pc());
return 0;
}
* FrankHに感謝します。一般的に
__current_pc()
の存在を指摘するために、PCは、関数呼び出しのリターンアドレスとして保存されます。 ARM以外のlinuxシステムでGCCを使用している場合は、__builtin_return_address(0)
を呼び出して、現在の関数呼び出しコンテキストの戻りアドレスを取得できます。このようにプログラムカウンタを取得することは、関数呼び出しを追加するという不利益を被りますが、インラインアセンブルを回避するので、この手法はGCCでサポートされているシステムに移植可能です。
void * get_pc() { return __builtin_return_address(0); }
int main() {
printf("%p\n", get_pc());
printf("%p\n", get_pc());
printf("%p\n", get_pc());
return 0;
}
私は私のx86
システム上で上記のプログラムを実行すると、それは出力を生成します
0x8048432
0x8048447
0x804845c
gdb
に分解した場合:
Dump of assembler code for function main:
0x08048424 <+0>: push %ebp
0x08048425 <+1>: mov %esp,%ebp
0x08048427 <+3>: and $0xfffffff0,%esp
0x0804842a <+6>: sub $0x10,%esp
0x0804842d <+9>: call 0x804841c <get_pc>
0x08048432 <+14>: mov %eax,0x4(%esp)
0x08048436 <+18>: movl $0x8048510,(%esp)
0x0804843d <+25>: call 0x80482f0 <[email protected]>
0x08048442 <+30>: call 0x804841c <get_pc>
0x08048447 <+35>: mov %eax,0x4(%esp)
0x0804844b <+39>: movl $0x8048510,(%esp)
0x08048452 <+46>: call 0x80482f0 <[email protected]>
0x08048457 <+51>: call 0x804841c <get_pc>
0x0804845c <+56>: mov %eax,0x4(%esp)
0x08048460 <+60>: movl $0x8048510,(%esp)
0x08048467 <+67>: call 0x80482f0 <[email protected]>
0x0804846c <+72>: mov $0x0,%eax
0x08048471 <+77>: leave
0x08048472 <+78>: ret
End of assembler dump.
リターンアドレスとPC( 'EIP' /' RIP')は同じものではありません。 –
お詫び申し上げます。ARMでは、リターンアドレス( 'LR')と' PC'は同じものではありません。 –
さらに、あなたの作品がなぜ機能するかは、あなたが関数call_(あなたの関数内で 'LR'を呼び出しサイトの' PC 'にする)を強制するためです。これは不必要に非効率的です。 –
あなたはCコードの中にアセンブリブロックを挿入することで情報を得ることができると思います。これは、あなたのコンパイラとあなたのプラットフォームのレジスタセットに完全に依存します。 私はこのようにそれをやった:あなたはARMコンパイラツールチェーンで__current_pc()
intrinsicを使用してPCを決定することができるはず
int get_counter1()
{
__asm__ ("lea (%rip), %eax ") ;
}
int get_counter2()
{
int x = 0;
__asm__ ("lea (%rip), %eax") ;
}
int main()
{
printf("%x\n",get_counter1());
printf("%x\n",get_counter2());
return 0;
}
4004ce
4004e1
をARMで、使用することができます
static __inline__ void * get_pc(void) {
void *pc;
asm("mov %0, pc" : "=r"(pc));
return pc;
}
それともこの1つは同様に動作する必要があります。それはあなたが呼び出しサイトごとにPC
を取得保証しているため
static __inline__ void * get_pc(void) {
register void * pc __asm__("pc");
__asm__("" : "=r"(pc));
return pc;
}
強制インライン化は、ここで重要なのです。
編集:ちょうど覚えている__current_pc()
ARM intrinsic。 GCCもこれを持っているはずです。
- 1. 正確な出力方法
- 2. 不正確な出力C#
- 3. PIC18Fのスタックからプログラムカウンタの値を取得する方法
- 4. 不正確な出力
- 5. JSON出力の作成中に値を確認する方法
- 6. foobarのデバッグ方法プログラムカウンタ
- 7. IFステートメントの不正確な出力R
- 8. DOMDocument loadHtmlを使用して正確な入力値をロードする方法
- 9. std :: stodは正確な数値を出力しません
- 10. Javaプログラムのプログラムカウンタのレジスタ値
- 11. C++で1行に3つの異なる値を出力する方法
- 12. IDの正確な値を取得する方法
- 13. C#リストコレクションの要素の正確な数を知る方法
- 14. ランダムな値を出力するC++プログラム
- 15. Marko.jsで値を出力する正しい方法
- 16. Cを使用したARM Cortex Mシリーズのプログラムカウンタ値の取得
- 17. C++でfloat値を出力する方法は?
- 18. 値の正確なパーセンテージを見つける方法
- 19. C++:キャストint to charが正しい値を出力しない
- 20. Opencvのヒストグラムが不正確な出力に一致する
- 21. Matrix C++の値を出力
- 22. 入力フィールドの出力を正確に入力する方法を教えてください。
- 23. C++ Xcode-色を出力する方法
- 24. 負の値を出力するC++コード
- 25. c# - 無限の値を出力する
- 26. C#のオブジェクト[]。値を出力する
- 27. 変数の値を空白なしで出力する方法
- 28. Xcode出力コンソールにC++出力を表示する方法
- 29. C#デリゲート(出力に正しい値が表示されない)
- 30. 5つの異なるテーブルから正確な値を選択する方法
デバッガのコードがPCを制御/アクセスするので、インラインアセンブリを使用する方法があるはずです。 –
@GrijeshChauhan:プログラムカウンターのGCC拡張があると思いますか? –
はい私はあまりよく分かっていませんが、このノートを回避するには何らかの方法が必要だと感じています:コードに 'lable:'がある場合、 '&lable'を使ってそのアドレスを表示することができます)。非常に後方のコード(合法的)はこの種の命令を使用しますが、マルウェアコードで頻繁に使用します。 –