3

ptrace他のプロセスの実行に影響を与えるために使用するガイドや例 (特に ARM のもの) またはライブラリはありますか? たとえば、あるデータがファイル ディスクリプタに表示されていると信じ込ませるには (つまり、select/poll をリリースして何らかの結果を出し、カーネルの前で次の read syscall に「応答」します)。PTRACE_SYSEMU に関連する何かが予想されます。

ポータブルな方法で行うことはできますか?libc-overriding LD_PRELOAD トリックのようなものが必要ですが、実行時にアタッチできます。

いくつかの gdb コマンドで実行できますか?

LD_PRELOAD を使用して実行する場合のように、syscall に簡単かつ移植可能にフックして、実際の呼び出しが行われる前または後に編集 (またはエミュレート) できるライブラリがあれば、理想的なバリアントになります。

@link PTRACE_SYSEMU の使用に関する適切なガイドはありますか?

4

1 に答える 1

1

PTRACE_SYSCALL リクエストを使用できます。これは子プロセスを再起動します (PTRACE_CONT と同様) が、システム コールへの次のエントリまたはシステム コールからの終了で停止するように調整します。例 (x86 用にビルドされたカーネルを想定):

#include <sys/ptrace.h>
#include <signal.h>
#include <linux/user.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc, char **argv)
{
    int status = 0, pid, r;
    struct user_regs_struct uregs;

    if ((pid = fork()) == 0) {
        printf("pid = %d, ppid = %d\n", getpid(), getppid());
        ptrace(PTRACE_TRACEME, 0, 0, 0);
        kill(getpid(), SIGINT);
        r = getpid();
        printf("%d\n", r);
    } else {
        wait(&status);
        ptrace(PTRACE_SYSCALL, pid, 0, 0);
        wait(&status);
        ptrace(PTRACE_GETREGS, pid, 0, &uregs);

        /* this prints the syscall number of getpid */
        printf("syscall nr: %d\n", uregs.orig_eax);
        /* 64 is syscall number of getppid */
        uregs.orig_eax = 64;
        ptrace(PTRACE_SETREGS, pid, 0, &uregs);
        ptrace(PTRACE_CONT, pid, 0, 0);
        wait(&status);
        if(WIFEXITED(status))
            printf("we're done\n");
    }
}

子はその PID を出力し、それ自体にシグナルを配信します。これに対する事前の呼び出しのため、ptrace()停止されます。

親はこれが発生するのを待ち、PTRACE_SYSCALL で子を再起動してから待ちます。次に、子がgetpidシステム コールを呼び出し、もう一度停止します。親プロセスは、PTRACE_GETREGS 呼び出しを使用しeaxて、システム コール番号を保持する子のレジスタを調べます。親はこれを のシステム コール番号に変更し、getppidもう一度子に続行を許可します。システム コールの呼び出しの前にシステム コール番号が変更されているため、子は のgetppid代わりに呼び出すようになりgetpidました。

この目的での使用ptraceは移植可能かもしれませんが、私はそれをテストしていません。gdb では、コマンドも使用できますcatch syscall

于 2012-11-17T01:15:55.567 に答える