1

C++ コードを使用して、root 権限を持たずに実行中のプロセス (実行可能ファイル) のフル パスを取得したいと考えています。誰かがこれを達成する方法を提案できますか?

Linux プラットフォームでは、次の方法を使用して実行できます。

char exepath[1024] = {0};
char procid[1024] = {0};
char exelink[1024] = {0};

sprintf(procid, "%u", getpid());

strcpy(exelink, "/proc/");
strcat(exelink, procid);
strcat(exelink, "/exe");

readlink(exelink, exepath, sizeof(exepath));

ここで、exepath は実行可能ファイルのフル パスを示します。

同様に、ウィンドウの場合は、

GetModuleFileName(NULL, exepath, sizeof(exepath));  /* get fullpath of the service */

HP-UX には /proc ディレクトリがないため、HP-UX での実行方法を教えてください。

4

5 に答える 5

9

まず、Linuxソリューションについてコメントしたいと思います。必要な長さの約5倍であり、完全に不要な操作を多数実行し、1024マジックナンバーを使用しています。これはまったく間違っています。

$ grep PATH_MAX /usr/include/linux/limits.h 
#define PATH_MAX        4096    /* # chars in a path name */

正しい最小限の交換は次のとおりです。

#include <limits.h>
...
  char exepath[PATH_MAX] = {0};
  readlink("/proc/self/exe", exepath, sizeof(exepath));

次に、HP-UXでは、shl_get_r()ロードされているすべてのモジュールに関する情報を取得するために使用できます。インデックス0には、メインの実行可能ファイルに関する情報があります。は、そのdesc.filename時点での実行可能ファイルの名前を指しexecve(2)ます。

残念ながら、その名前は相対的なものであるため、検索する必要があり、アプリケーションが実行した場合、または元のexenameがegであり、それ以降にアプリケーションが実行された$PATH場合は失敗する可能性があります。putenv("PATH=some:new:path")./a.outchdir(2)

于 2008-11-09T07:24:41.120 に答える
1

UnixプログラミングFAQを参照した以前の回答は正しかった。Linux / procの回答でも問題は、exec()以降に実行可能ファイルへのパスが変更されている可能性があることです。実際、実行可能ファイルは削除されている可能性があります。リンク(シンボリックとハードの両方)を考慮すると、さらに複雑になります。同じ実行可能ファイルへのパスが複数ある場合があります。パスが残っていない可能性があり、パスがある場合は一意ではない可能性があるため、すべてのケースをカバーする一般的な答えはありません。

とは言うものの、以前にcjhuittによって提唱されたように、いくつかのロジックでargv [0]を使用すると、おそらく99.9%の時間で必要なことを実行できます。相対パスチェックを実行する前に、「/」を含むパスのチェックを追加します(cwd()を呼び出す前にチェックする必要があることに注意してください)。あなたの呼び出し側プログラムがいたずらを感じているなら、これを台無しにするためにfork()とexec()の間でできることがたくさんあることに注意してください。アプリケーションのセキュリティに影響を与える可能性のあるもの(構成ファイルの場所など)については、これに依存しないでください。

于 2008-10-14T16:20:45.147 に答える
1

実行可能パスはどのような目的で必要ですか? 以前の投稿で述べたように、実行可能ファイルへのパスが存在するという保証や、パスが一意であるという保証はないことに注意してください。

于 2008-10-17T19:25:07.957 に答える
0

私は以前、一般的なケースでこれを行いました。一般的な考え方は、argv [0]を取得し、それに対していくつかの処理を行うことです。

int main( int argc, char** argv )
{
  string full_prog_path = argv[0];
  if ( full_prog_path[0] == "/" )
  {   // It was specified absolutely; no processing necessary.
  }
  else
  {
    string check_cwd = getcwd();
    check_cwd += argv[0];
    if ( FileExists( check_cwd ) )
    { // It was specified relatively.
      full_prog_path = check_cwd;
    }
    else
    { // Check through the path to find it
      string path = getenv( "PATH" );
      list<string> paths = path.split( ":" );
      foreach( test_path, paths )
      {
        if ( FileExists( test_path + argv[0] ) )
        { // We found the first path entry with the program
          full_prog_path = test_path + argv[0];
          break;
        }
      }
    }
  }

  cout << "Program path: " << full_prog_path << endl;

  return 0;
}

明らかに、これにはある時点で破れる可能性のあるいくつかの仮定がありますが、ほとんどの場合は機能するはずです。

于 2008-10-14T13:54:23.663 に答える