実行中のアプリケーション情報の取得について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
se_user
記事: 5
登録日時: 13年前

実行中のアプリケーション情報の取得について

#1

投稿記事 by se_user » 13年前

実行中のアプリケーションの情報を取得したいんですが、具体的に申しますと
起動中アプリケーションが読み込んでいるスレッド等の情報をすべて表示させることは可能でしょうか?
最後に編集したユーザー se_user on 2012年4月15日(日) 14:17 [ 編集 1 回目 ]

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 実行中のアプリケーション情報の取得について

#2

投稿記事 by softya(ソフト屋) » 13年前

詳しくはないですが、processExplolerとかでは表示できているので取得する手段はあると思います。
というよりprocessExplolerではダメですか?

「Process Explorer」
http://technet.microsoft.com/en-us/sysi ... s/bb896653
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

se_user
記事: 5
登録日時: 13年前

Re: 実行中のアプリケーション情報の取得について

#3

投稿記事 by se_user » 13年前

softya(ソフト屋) さんが書きました:詳しくはないですが、processExplolerとかでは表示できているので取得する手段はあると思います。
というよりprocessExplolerではダメですか?

「Process Explorer」
http://technet.microsoft.com/en-us/sysi ... s/bb896653
返信ありがとうございます。
自作したいんですが、関数だけ抜き出したりできませんか・・・

http://processhacker.sourceforge.net/do ... ource.html

こちらのページにソースがありました。

プロジェクト化されているのですが、

コード:

    PhAddTreeNewColumn(hwnd, PHTHTLC_STARTADDRESS, TRUE, L"Start Address", 180, PH_ALIGN_LEFT, 3, 0);

コード:

  case PHTHTLC_STARTADDRESS:
                PhSwapReference(&node->StartAddressText, threadItem->StartAddressString);
                getCellText->Text = PhGetStringRef(node->StartAddressText);
この部分のみを利用したいのですが、可能でしょうか?
最後に編集したユーザー se_user on 2012年4月14日(土) 12:35 [ 編集 1 回目 ]

YuO
記事: 947
登録日時: 14年前
住所: 東京都世田谷区

Re: 実行中のアプリケーション情報の取得について

#4

投稿記事 by YuO » 13年前

プロセスやスレッドなどの列挙は,Tool Help Libraryを使うのが基本です。
ただし,スレッドの開始アドレスはこの方法では取得できないようです。

WMIを探すと,Win32_thread classがあって,ここにはStartAddressというメンバがあります。
ただし,型がint_ptrのような記述では無くuint32と書かれているため,x64環境で正しく取得できるのか疑問がありますが。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 実行中のアプリケーション情報の取得について

#5

投稿記事 by softya(ソフト屋) » 13年前

「Process Explorer」はオープンソースではないので参考に出来ませんね。
YuOさんの方法が参考になるのでは?

[追記]
あれ?オープンソースでした? → 別の似たようなツールですね。
ソースがあるのなら試してみれば良いのでは?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

se_user
記事: 5
登録日時: 13年前

Re: 実行中のアプリケーション情報の取得について

#6

投稿記事 by se_user » 13年前

YuO さんが書きました:プロセスやスレッドなどの列挙は,Tool Help Libraryを使うのが基本です。
ただし,スレッドの開始アドレスはこの方法では取得できないようです。

WMIを探すと,Win32_thread classがあって,ここにはStartAddressというメンバがあります。
ただし,型がint_ptrのような記述では無くuint32と書かれているため,x64環境で正しく取得できるのか疑問がありますが。
Win32_thread classの使用方法を教えてください。
識別子が見つからないので、おそらくなにらかのincludeが必要かと思われます。

コード:

Win32_Thread(
  string   Caption,
  string   CreationClassName,
  string   CSCreationClassName,
  string   CSName,
  string   Description,
  uint64   ElapsedTime,
  uint16   ExecutionState,
  string   Handle,
  datetime InstallDate,
  uint64   KernelModeTime,
  string   Name,
  string   OSCreationClassName,
  string   OSName,
  uint32   Priority,
  uint32   PriorityBase,
  string   ProcessCreationClassName,
  string   ProcessHandle,
  uint32   StartAddress,
  string   Status,
  uint32   ThreadState,
  uint32   ThreadWaitReason,
  uint64   UserModeTime);

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 実行中のアプリケーション情報の取得について

#7

投稿記事 by softya(ソフト屋) » 13年前

Win32_thread classが含まれるWMIはcom系なので次のような操作が必要です。

「C++ で WMI クラスを使う « re-Think things」
http://togarasi.wordpress.com/2009/12/2 ... %E3%81%86/
ATL のスマートポインタを使ってますが好きなスマートポインタに置き換えて下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

たろ

Re: 実行中のアプリケーション情報の取得について

#8

投稿記事 by たろ » 13年前

NtQuerySystemInformationで取得できたような・・と思ったのでやってみました。
自分の環境(WinXP Home SP3)でしか確認していませんが、ご参考までに。。
ただProcess Explorerが表示するStartAddressの内容は取れないようにも見えます。
スレッドIDやスレッドの数は合っているようですが。

コード:

#include <windows.h>
#include <stdio.h>
#include <tchar.h>

//--------------------------------------------------------------------------------------------------
//
//    NTDLL関数戻り値
//    NTSTATUS_SUCCESS=成功、NTSTATUS_XXX=エラー。ntstatus.hに定義。
//    必要なものを SDK/v6.0A/Include/ntstatus.hからコピー
//
#ifndef NTSTATUS
#define NTSTATUS LONG
#endif
#define STATUS_SUCCESS                ((NTSTATUS)0x00000000L) // ntsubauth
#define STATUS_INFO_LENGTH_MISMATCH   ((NTSTATUS)0xC0000004L)

typedef LONG KPRIORITY;

typedef struct {
    HANDLE    UniqueProcess;
    HANDLE    UniqueThread;
} CLIENT_ID, *PCLIENT_ID;

typedef enum {
    Executive           = 0,
    FreePage            = 1,
    PageIn              = 2,
    PoolAllocation      = 3,
    // 使わないので途中省略
    WrRundown           = 36,
    MaximumWaitReason   = 37
} KWAIT_REASON, *PKWAIT_REASON;

// SDK/v6.0A/Include/winternl.h
typedef struct {
    USHORT    Length;
    USHORT    MaximumLength;
    PWSTR     Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef struct {
    UINT64        KernelTime;
    UINT64        UserTime;
    UINT64        CreateTime;
    ULONG         WaitTime;
    PVOID         StartAddress;
    CLIENT_ID     ClientId;
    KPRIORITY     Priority;
    LONG          BasePriority;
    ULONG         ContextSwitches;
    ULONG         ThreadState;
    KWAIT_REASON  WaitReason;
} SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION;

//
//    SYSTEM_PROCESS_INFORMATION構造体は、最後のメンバSYSTEM_THREAD_INFORMATIONが可変長で、
//    NtQuerySystemInformationでは可変長のものがつながった配列を取得する。次の配列エントリ
//    はNextEntryOffsetメンバでわかる。
//    これ以外の構造体は Process Hacker 2.x ソースも参考・流用。
//
typedef struct {
    ULONG           NextEntryOffset;                // 次エントリオフセット
    BYTE            Reserved1[28];
    UINT64          CreateTime;
    UINT64          UserTime;                       // ユーザ時間(100ナノ秒単位)
    UINT64          KernelTime;                     // カーネル時間(100ナノ秒単位)
    UNICODE_STRING  ImageName;                      // プロセス名("notepad.exe"など)
    KPRIORITY       BasePriority;
    HANDLE          UniqueProcessId;                // プロセスID
    HANDLE          InheritedFromUniqueProcessId;   // 親プロセスID
    ULONG           HandleCount;                    // ハンドル数
    ULONG           SessionId;
    ULONG_PTR       PageDirectoryBase;
    SIZE_T          PeakVirtualSize;                // ピーク仮想メモリサイズ
    SIZE_T          VirtualSize;                    // 仮想メモリサイズ
    ULONG           PageFaultCount;
    SIZE_T          PeakWorkingSetSize;             // ピークワーキングセットサイズ
    SIZE_T          WorkingSetSize;                 // ワーキングセットサイズ
    SIZE_T          QuotaPeakPagedPoolUsage;
    SIZE_T          QuotaPagedPoolUsage;
    SIZE_T          QuotaPeakNonPagedPoolUsage;
    SIZE_T          QuotaNonPagedPoolUsage;
    SIZE_T          PagefileUsage;
    SIZE_T          PeakPagefileUsage;
    SIZE_T          PrivatePageCount;               // プライベートページ数
    UINT64          ReadOperationCount;             // I/O読み取り
    UINT64          WriteOperationCount;            // I/O書き込み
    UINT64          OtherOperationCount;            // I/Oその他
    UINT64          ReadTransferCount;              // I/O読み取りバイト数
    UINT64          WriteTransferCount;             // I/O書き込みバイト数
    UINT64          OtherTransferCount;             // I/Oその他バイト数
    SYSTEM_THREAD_INFORMATION Threads[1];           // スレッド情報(可変)
} SYSTEM_PROCESS_INFORMATION;

//
// SDK/v6.0A/Include/winternl.h
//
typedef enum _SYSTEM_INFORMATION_CLASS {
    SystemBasicInformation = 0,
    SystemPerformanceInformation = 2,
    SystemTimeOfDayInformation = 3,
    SystemProcessInformation = 5,
    SystemProcessorPerformanceInformation = 8,
    SystemInterruptInformation = 23,
    SystemExceptionInformation = 33,
    SystemRegistryQuotaInformation = 37,
    SystemLookasideInformation = 45
} SYSTEM_INFORMATION_CLASS;

//
//    NtQuerySystemInformation関数ポインタ型
//
typedef NTSYSAPI NTSTATUS (NTAPI *PNtQuerySystemInformation)
(
    IN   SYSTEM_INFORMATION_CLASS  SystemInformationClass,
    OUT  PVOID                     SystemInformation,
    IN   ULONG                     SystemInformationLength,
    OUT  PULONG                    ReturnLength OPTIONAL
);
//
//    SYSTEM_PROCESS_INFORMATION構造体配列で次の構造体ポインタを取得する関数マクロ
//
#define IS_LAST_PROCESS(p)            ( (p)->NextEntryOffset==0 )
#define PROCESS_INFORMATION_NEXT(p)   \
        (SYSTEM_PROCESS_INFORMATION*)(IS_LAST_PROCESS(p)? 0 : (((ULONG_PTR)(p)) + (p)->NextEntryOffset))


//
//  SYSTEM_PROCESS_INFORMATION構造体のスレッド数を返す
//
UINT32
ThreadCount( SYSTEM_PROCESS_INFORMATION* pi, ULONG_PTR limit )
{
    SYSTEM_THREAD_INFORMATION* thread = pi->Threads;
    UINT32 count = 0;

    while( (ULONG_PTR)thread < limit )
    {
        thread++;
        count++;
    }
    if( (ULONG_PTR)thread > limit )
    {
        // 最後の構造体がサイズ不足?
        count--;
    }
    return count;
}

int
_tmain( void )
{
    HINSTANCE ntdll = LoadLibrary( _T("ntdll.dll") );
    if( ntdll )
    {
        PNtQuerySystemInformation pNtSysInfo = (PNtQuerySystemInformation)GetProcAddress(ntdll,"NtQuerySystemInformation");
        if( pNtSysInfo )
        {
            SYSTEM_PROCESS_INFORMATION* spi = NULL;
            NTSTATUS status;
            ULONG size = 0;

         retry:
            status = pNtSysInfo( SystemProcessInformation, spi, size, &size );
            switch( status ) {
            case STATUS_SUCCESS:
            {
                // 成功
                SYSTEM_PROCESS_INFORMATION* pi = spi;
                while( pi )
                {
                    SYSTEM_PROCESS_INFORMATION* next = PROCESS_INFORMATION_NEXT( pi );
                    UINT32 count, n;

                    if( pi->ImageName.Buffer )
                        wprintf(L"%u %s\r\n", pi->UniqueProcessId, pi->ImageName.Buffer);
                    else
                        wprintf(L"%u %s\r\n", pi->UniqueProcessId, L"System Idle Process");

                    if( next )
                        count = ThreadCount( pi, (ULONG_PTR)next );
                    else
                        count = ThreadCount( pi, (ULONG_PTR)spi + size );

                    for( n=0; n<count; n++ )
                    {
                        SYSTEM_THREAD_INFORMATION* th = pi->Threads + n;
                        wprintf(L"   [%u] %p %u %u\r\n",
                                n+1, th->StartAddress, th->ClientId.UniqueProcess, th->ClientId.UniqueThread);
                    }
                    pi = next;
                }

                HeapFree( GetProcessHeap(), 0, spi );
                break;
            }
            case STATUS_INFO_LENGTH_MISMATCH:
                // バッファサイズ不足、再確保してリトライ
                if( spi ) HeapFree( GetProcessHeap(), 0, spi );
                spi = (SYSTEM_PROCESS_INFORMATION*)HeapAlloc( GetProcessHeap(), 0, size );
                if( !spi ) break;
                goto retry;

            default:
                // エラー
                if( spi ) HeapFree( GetProcessHeap(), 0, spi );
                spi = NULL;
                break;
            }
            pNtSysInfo = NULL;
        }
        FreeLibrary( ntdll );
        ntdll = NULL;
    }
    return 0;
}

se_user
記事: 5
登録日時: 13年前

Re: 実行中のアプリケーション情報の取得について

#9

投稿記事 by se_user » 13年前

返信ありがとうございます。


>ただProcess Explorerが表示するStartAddressの内容は取れないようにも見えます。
>スレッドIDやスレッドの数は合っているようですが。
Process Hacker のソースを参考にStart Addressまでは見れないですかね・・・・
thrdlist.cに書いてあると思うんですけど

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 実行中のアプリケーション情報の取得について

#10

投稿記事 by softya(ソフト屋) » 13年前

se_user さんが書きました:返信ありがとうございます。


>ただProcess Explorerが表示するStartAddressの内容は取れないようにも見えます。
>スレッドIDやスレッドの数は合っているようですが。
Process Hacker のソースを参考にStart Addressまでは見れないですかね・・・・
thrdlist.cに書いてあると思うんですけど
誰も使ったことがない機能だと思いますので、ご自分でまず試してみてはどうでしょうか?
それとも誰かに全部プログラムを組んで欲しいのでしょうか? それだと丸投げでフォーラムルール違反になりますが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

“C言語何でも質問掲示板” へ戻る