2017-08-06 8 views
1

設定可能なメモリ領域への書き込みアクセスを行うと、プログラム自体はどのように信号を送ることができますか?メモリ範囲アクセス例外をトリガする方法は?

これは、一部のデバッガで検出されるデータブレークポイント機能に似ています。 POSIXの準拠は望ましいが、Linux上で動作する限り必須ではない。

#include <stdio.h> 
#include <stdlib.h> 
#include <signal.h> 

void configure_trap(void *FROM, void *TO){ 
    /* 
    Set a trap on write access to any memory location from 
    address FROM to address TO. 
    When the trap is triggered, send SIGTRAP to the process. 
    There is no need for an answer to have the full code, just 
    an indication on how to proceed. 
    */ 
} 

char *ptr; 

void trap_signal_handler(int signum){ 
    if(ptr[123] == 'x'){ 
    printf("Invalid value in ptr[123] !!!\n"); 
    /* 
    Print a backtrace using libunwind. (Not part of this question.) 
    */ 
    } 
} 

void some_function(){ 
    ptr[123] = 'x'; 
    /* 
    This write access could be performed directly in this function or 
    another function called directly or indirectly by this one and it 
    could reside in this program or in an external library or could even 
    be performed in a system call. 
    trap_signal_handler should be called at this point. 
    After the signal handler has been executed, program should resume 
    normal operation. 
    */ 
} 

int main(){ 
    struct sigaction sa = { .sa_handler = trap_signal_handler }; 
    sigaction(SIGTRAP, &sa, NULL); 
    ptr = malloc(1024); 
    configure_trap(&ptr[123], &ptr[123]); 
    some_function(); 
    return(0); 
} 

ありがとう:

は、ここで私が望むものの説明コードがあります!

答えて

2

最初に、mprotect()を使用してページを読み取り専用にします。それが書かれたら、SIGSEGVが上がります。このためにシグナルハンドラがインストールされており、sigactionを使用して完了した場合は、si_addrを調べることによって、どのアドレスにアクセスしたのかを知ることができます。 C SIGSEGV Handler & Mprotect

mprotect()は1ページの細分性があります。つまり、1バイトを保護しようとすると、実際には4 KB(ページサイズの場合)が保護されます。

+0

書き込みが実行された後、この方法を使用して 'trap_signal_handler'を呼び出すにはどうすればよいですか? – vicencb

+0

@vicencb:できません。 –

+1

実際には、ページはアクセス不可能とマークされているため、ページへのすべてのアクセスによってSIGSEGVが発生します。シグナルハンドラ*は命令*をエミュレートします。これは、単一の(初期)アクセス以上に確実に動作する唯一の方法です。シグナルハンドラは、別のシグナルを発生させたり、他のシグナルハンドラを直接呼び出すことができます(変更された 'siginfo_t'構造体で)。もちろん、これはハードウェア固有のものです。 –

1

https://github.com/vicencb/qdbpプロジェクトを使用してください。

  1. 最初にmprotectです。メモリページは読み取り専用です。
  2. SIGSEGVが呼び出されると、プログラムは1度に1命令ずつ、読み取り専用メモリへの書き込みを引き起こすまで1ステップずつ実行します。
  3. 次に、コールバックを呼び出します。
関連する問題