none
x64 での__readmsr apiについて。 RRS feed

  • 質問

  • はじめまして、 もしスレ違いでしたら、ご指摘下さい。

    (間違って、VC++スレに書き込んでしまいましたので、こちらに改めて書き込みます。)

    現在Windows7のドライバとして下記の様な関数を作成いたしました。 

    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    //    関数名:AccessReadMSR

    //    MSRReadを行う「rdmsr」の発行。

    //    ドライバ内は、デフォルトでRing0??

    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    NTSTATUS    AccessReadMSR(

                    ULONG   IoctlCode,       // IoControlCode

                    void    *lpInBuffer,     // 上位アプリからの入力データバッファ

                                             // rdmsrの読み出しを行うレジスタ値

                    ULONG   nInBufferSize,    // 上位アプリからの入力データの大きさ

                    void    *lpOutBuffer,     // 上位アプリへの出力データバッファ

                                             // rdmsrからの出力値

                    ULONG   nOutBufferSize,  // 上位アプリへの出力データの大きさ

                    ULONG_PTR* lpBytesReturned) // 転送完了バイト数を格納する

    {

        ULONGLONG data = 0;

        try{

            data = __readmsr(*(ULONG*)lpInBuffer); // MSR ReadAPI

            memcpy((PULONG)lpOutBuffer,&data,8);

            *lpBytesReturned = 8;

            return STATUS_SUCCESS;

        } except (EXCEPTION_EXECUTE_HANDLER) {

           *lpBytesReturned = 0;      // x64ではこちらに飛ぶ?。

           return STATUS_UNSUCCESSFUL;

        }

    }

    ///////////////////////////////////////////////////////////////////////////////////

    同じコードをx86(32Bit)で作成した物は、MSRの値を取得出来ていた様だったので

    そのままx64でビルドしてみたのですが、STATUS_UNSUCCESSFULが返ってきます。

    (例外が発生??)

    __readmsrは、x86/x64対応の様でしたが、x64では何らかの前処理(オマジナイ?)

    が必要なのでしょうか?

    利用DDK(WDK):7600.16385.1

    上位アプリ、DLLはVS(VC++) 2008 Sp1を利用。

    実行OSは、Windows7 Pro (x86(32Bitドライバ/アプリ時)/x64(64Bitドライバ/アプリ時))

     

    もし、なにか解決策などをご存知でしたら、大変お忙しいかと思いますが、

    ご教授いただけませんでしょうか??

    よろしくお願いいたします。

    • 移動 Mike Wang (MSCS) 2012年10月2日 12:54 (移動元:Windows デバイスドライバー開発)
    2012年3月7日 4:33

回答

  • 念のため… __readmsr() を呼び出さなかった場合、例えば memcpy( (PULONG)lpOutBuffer, (PULONG)lpInBuffer, 4); とかだけを実行した場合は STATUS_SUCCESS になりますか?
    • 回答の候補に設定 佐祐理 2012年3月7日 6:47
    • 回答としてマーク GFKBXFA4 2012年3月12日 1:38
    2012年3月7日 4:40
  • 投稿された質問のコード中で、以下の部分が気になったのですが。。。

    > ULONG   IoctlCode,       // IoControlCode

    これってもしかして、上位アプリから DeviceIoControl() でドライバに対して I/O 用のバッファを渡すような実装なんでしょうか?
    だとしたらその I/O Control Code は、独自に定義した Custom I/O Control Code だと思いますが、その Code の定義 (値) は大丈夫でしょか?
    I/O Control Code の中には、「User Mode から Kernel Mode に対して、どのような方法でバッファを渡すか。。。」の情報も含まれています。
    なので、Custom I/O Control Code に 0 とか 1 とか適当な値を指定してもバッファが適切に Kernel Mode 側に渡されないので、まともに動かないと思います。
    (Kernel Mode 側では User Mode 側で提供されている「メモリ保護」のような気の利いた機能はないので、アクセスさせ出来れば、他のドライバが使っている領域でもかまわずぶっ壊しちゃいます。)

    I/O Control Code は通常 CTL_CODE マクロを使って行いますので、そのマクロをご覧になれば、この Code の中にどのような情報が含まれているのかご理解いただけると思います。
    (ちなみに、バッファのやり取りに関する情報は下位2ビットになります。)

    ご参考になりましたら幸いです。

    • 回答としてマーク GFKBXFA4 2012年3月12日 1:37
    2012年3月7日 8:37
  • x86では動作しているとのことですから、ポインターサイズ絡みかなと予想してますが…。

    (ULONG*)とか(PULONG)とか平気でキャストして無意味にmemcpyしてる、その辺りからポインターについて無頓着に見えます。

    *reinterpret_cast<__int64*>(lpOutBuffer) = __readmsr( *reinterpret_cast<int*>(lpInBuffer) );

    • 編集済み 佐祐理 2012年3月8日 0:13
    • 回答としてマーク GFKBXFA4 2012年3月12日 1:37
    2012年3月7日 23:59
  • 1行目のみがコメントで、それ以降は蛇足だったのですが、誤解を与えてしまったようなので補足します。

    reinterpret_castは深い意味はありません。それよりも

    1. __readmsr()の引数はintです。しかしULONG*にキャストして読み出しています。
    2. __readmsr()の戻り値は__int64です。しかしその値をULONGLONGの変数に代入しています。
    3. memcpy()の第1引数はvoid*です。元々void*だった引数を無意味にもPULONGにキャストしています。
    4. 1.のULONG*と3.のPULONGの2つの表記が使われています。
    5. そもそも2.で直接代入できているのにわざわざmemcpy()を使っています。

    この辺りを踏まえて「ポインターについて無頓着」と表現しました。
    # 改めてまとめてみると、ポインターについてと言うよりデータ型についてですね…。

    • 回答としてマーク GFKBXFA4 2012年3月12日 1:37
    2012年3月8日 9:09
  • 関係無いのかもしれませんが、一応。。。

    前回の私の返信の意図は、以下の様に考えたからです。

    「上位アプリから DeviceIoControl() でターゲット ドライバに対し I/O バッファの受け渡しを行っているのであれば、User Mode - Kernel Mode 間で、そのバッファ ポインタの受け渡しが適切に行われていることが保証されない限り、__readmsr() や memcpy() コールでのポインタ指定を議論しても意味がない。」

    先の返信でも触れましたが、I/O Control Code にはバッファ受け渡し方法に関する情報が含まれています。
    GFKBXFA4さんのケースでは METHOD_BUFFERED を指定されているとのことですが、この場合 NT カーネル (I/O マネージャ) は、一旦 Kernel Mode 側での処理用に別途バッファを確保してから、その I/O Control Code をハンドリングするドライバに処理を渡し、ドライバから処理が戻されたタイミングで NT カーネルが DeviceIoControl() API の lpOutBuffer パラメータで指定されたバッファに結果をコピーする。。。という動作になると思います。
    つまり、User Mode 側のアプリで確保されたバッファ ポインタが、そのまま Kernel Mode 側のドライバに渡される訳ではない、ということになるので、まずはその部分が確実に期待通りの動きになっているかを確認することが重要だと考えています。

    私だったら、まず以下の様なコードでこの点を確認します。

    -------------------------------------------------
    #define IOCTL_CUSTOM_CONTROL_CODE   CTL_CODE(5000, 0x0980, METHOD_BUFFERED, FILE_ANY_ACCESS)

    ++++++++++++++++++++++++++++++++++++++++++++++
    <User Mode 側アプリ>

    ....
        BOOL    bResult;
        DWORD   dwInBuffer      = 0x12345678;
        DWORD   dwOutBuffer     = 0;
        DWORD   dwBytesReturned = 0;

        // DebugBreak();
        bResult = DeviceIoControl( hDevice,
                                    IOCTL_CUSTOM_CONTROL_CODE,
                                    &dwInBuffer,
                                    sizeof( DWORD ),
                                    &dwOutBuffer,
                                    sizeof( DWORD ),
                                    &dwBytesReturned,
                                    NULL );

        if ( bResult && (dwBytesReturned == sizeof( DWORD )) )
        {
            if ( dwOutBuffer == 0x98765432 )
            {
                // 成功!! <バッファの受け渡しに問題なし>
            }
            else
            {
                // 失敗... <バッファの受け渡しに問題がある可能性大>
            }
        }
        else
        {
            // 失敗... <バッファの受け渡し以前に、ドライバ側でIRP_MJ_DEVICE_CONTROL 処理に問題がある可能性大>
        }

    ....
    ++++++++++++++++++++++++++++++++++++++++++++++
    <Kernel Mode 側ドライバ>

    NTSTATUS AccessReadMSR
    (
        ULONG       IoctlCode,          // IoControlCode
        void       *lpInBuffer,         // 上位アプリからの入力データバッファ
        ULONG       nInBufferSize,      // 上位アプリからの入力データの大きさ
        void       *lpOutBuffer,        // 上位アプリへの出力データバッファ
        ULONG       nOutBufferSize,     // 上位アプリへの出力データの大きさ
        ULONG_PTR  *lpBytesReturned     // 転送完了バイト数を格納する
    )
    {
        NTSTATUS    ntStatus = STATUS_UNSUCCESSFUL;

        if ( IoctlCode == IOCTL_CUSTOM_CONTROL_CODE )
        {
            if ( lpInBuffer )
            {
                PULONG  inputData = (PULONG)lpInBuffer;

                if ( (nInBufferSize == sizeof( ULONG )) && (*inputData == 0x12345678) )
                {
                    if ( (lpOutBuffer) && (nOutBufferSize == sizeof( ULONG )) )
                    {
                        PULONG  outputData = (PULONG)lpOutBuffer;

                        *outputData = 0x98765432;
                        *lpBytesReturned = nOutBufferSize;

                        ntStatus = STATUS_SUCCESS;
                }
            }
        }

        return ntStatus;
    }
    ++++++++++++++++++++++++++++++++++++++++++++++
    -------------------------------------------------

    既に、上記部分に問題がないことをご確認されている場合はご容赦ください。

    なお蛇足ですが。。。
    I/O Control Code の CTL_CODE によるマクロ定義で METHOD_BUFFERED を指定した場合、ドライバに渡される lpInBuffer と lpOutBuffer のポインタは同じアドレスになるはずだったと思います。



    • 回答としてマーク GFKBXFA4 2012年3月12日 1:37
    • 編集済み お馬鹿 2012年3月12日 3:13
    2012年3月8日 9:31
  • 大変申し訳ございません。
    先の私の返信内容に誤りがありました。
    つきましては、下記の様に修正させていただきました。

    -----------------------------------------------
    [誤]
    // 失敗... <バッファの受け渡し以前に、ドライバ側での IRP_MJ_DIRECTORY_CONTROL 処理に問題がある可能性大>

    [正]
    // 失敗... <バッファの受け渡し以前に、ドライバ側での IRP_MJ_DEVICE_CONTROL 処理に問題がある可能性大>
    -----------------------------------------------

    なお上位アプリでの DeviceIoControl() API コールが FALSE になるとのことですので、まずはその デバイス I/O リクエストが GFKBXFA4 さんの作成されたドライバの、IRP_MJ_DEVICE_CONTROL ディスパッチ ルーチンおよび AccessReadMSR() に届いているかを確認された方が良いのかも。
    またカーネル デバッガの使用を躊躇されているようですが、上記確認は WinDBG を使えばすぐに判別できますので、ドライバ開発をされているのであれば、カーネル モード デバッグ環境を構築されておくことをお勧めいたします。
    (WinDBG のカーネル モード デバッグ環境を用意しておくと、サービスなどのユーザ モード側のデバッグもプロセス間の「壁」を超えてトレース出来るので、とっても便利です。)

    • 回答としてマーク GFKBXFA4 2012年3月12日 11:06
    2012年3月12日 3:12

すべての返信

  • 念のため… __readmsr() を呼び出さなかった場合、例えば memcpy( (PULONG)lpOutBuffer, (PULONG)lpInBuffer, 4); とかだけを実行した場合は STATUS_SUCCESS になりますか?
    • 回答の候補に設定 佐祐理 2012年3月7日 6:47
    • 回答としてマーク GFKBXFA4 2012年3月12日 1:38
    2012年3月7日 4:40
  • 佐祐理 様

    はじめまして、そして返信頂きありがとう御座います。

    --------------------------------------

    return STATUS_SUCCESS;

    --------------------------------------

    (try{} もコメントアウト)

    のみに変更したのですが、それでもエラー(false)が帰ってくる様で、

    x64ドライバについて、なにか根本的なミスが有るようです。

    (x86版に関しては、偶然?動作していた??)

    一度、x64ドライバについて再確認してみたいと思います。

    2012年3月7日 6:11
  • 投稿された質問のコード中で、以下の部分が気になったのですが。。。

    > ULONG   IoctlCode,       // IoControlCode

    これってもしかして、上位アプリから DeviceIoControl() でドライバに対して I/O 用のバッファを渡すような実装なんでしょうか?
    だとしたらその I/O Control Code は、独自に定義した Custom I/O Control Code だと思いますが、その Code の定義 (値) は大丈夫でしょか?
    I/O Control Code の中には、「User Mode から Kernel Mode に対して、どのような方法でバッファを渡すか。。。」の情報も含まれています。
    なので、Custom I/O Control Code に 0 とか 1 とか適当な値を指定してもバッファが適切に Kernel Mode 側に渡されないので、まともに動かないと思います。
    (Kernel Mode 側では User Mode 側で提供されている「メモリ保護」のような気の利いた機能はないので、アクセスさせ出来れば、他のドライバが使っている領域でもかまわずぶっ壊しちゃいます。)

    I/O Control Code は通常 CTL_CODE マクロを使って行いますので、そのマクロをご覧になれば、この Code の中にどのような情報が含まれているのかご理解いただけると思います。
    (ちなみに、バッファのやり取りに関する情報は下位2ビットになります。)

    ご参考になりましたら幸いです。

    • 回答としてマーク GFKBXFA4 2012年3月12日 1:37
    2012年3月7日 8:37
  • お馬鹿 様

    はじめまして、そして返信頂きありがとう御座います。

    ドライバでレベルでのメモリアクセスやI/Oアクセス(特にWrite)の危険性は承知しております。

    また、I/O Control Codeは、CTL_CODEマクロにて以下の様に設定しております。

     CTL_CODE(5000,0x0980,METHOD_BUFFERED,FILE_READ_ACCESS)

    ( CTL_CODE(5000,0x0980,METHOD_BUFFERED,FILE_WRITE_ACCESS) でもだめでした。)

    イロイロデバックにて試している最中ですが、どうやらアプリ-DLL-ドライバ間の何処かで、

    バッファのアドレスを壊している様ですので、デバックにて追いかけてみようと思っております。

    (VSのデバックに慣れてしまうと、カーネルデバッカの使い勝手が。。。)

    大変貴重なお時間をお掛けし、アドバイスを頂戴し感謝いたします。

    2012年3月7日 11:27
  • x86では動作しているとのことですから、ポインターサイズ絡みかなと予想してますが…。

    (ULONG*)とか(PULONG)とか平気でキャストして無意味にmemcpyしてる、その辺りからポインターについて無頓着に見えます。

    *reinterpret_cast<__int64*>(lpOutBuffer) = __readmsr( *reinterpret_cast<int*>(lpInBuffer) );

    • 編集済み 佐祐理 2012年3月8日 0:13
    • 回答としてマーク GFKBXFA4 2012年3月12日 1:37
    2012年3月7日 23:59
  • 佐祐理 様

    返信頂きありがとう御座います。

    ご指摘ありがとう御座います。確かに、キャストに関しては、ご指摘の通り、お恥ずかしい限りです。

    「reinterpret_cast」などでvoid を元の形に戻す方法は、ドライバレベルプログラム以外でも有用ですね。

    (「reinterpret_cast」、「static_cast 」はすっかり失念しておりました。。。)

    別件にて、今すぐ修正は出来ない状況ですが、後ほど試してみます。

    大変お手数をお掛けいたしました事を、お礼いたします。

    2012年3月8日 8:54
  • 1行目のみがコメントで、それ以降は蛇足だったのですが、誤解を与えてしまったようなので補足します。

    reinterpret_castは深い意味はありません。それよりも

    1. __readmsr()の引数はintです。しかしULONG*にキャストして読み出しています。
    2. __readmsr()の戻り値は__int64です。しかしその値をULONGLONGの変数に代入しています。
    3. memcpy()の第1引数はvoid*です。元々void*だった引数を無意味にもPULONGにキャストしています。
    4. 1.のULONG*と3.のPULONGの2つの表記が使われています。
    5. そもそも2.で直接代入できているのにわざわざmemcpy()を使っています。

    この辺りを踏まえて「ポインターについて無頓着」と表現しました。
    # 改めてまとめてみると、ポインターについてと言うよりデータ型についてですね…。

    • 回答としてマーク GFKBXFA4 2012年3月12日 1:37
    2012年3月8日 9:09
  • 関係無いのかもしれませんが、一応。。。

    前回の私の返信の意図は、以下の様に考えたからです。

    「上位アプリから DeviceIoControl() でターゲット ドライバに対し I/O バッファの受け渡しを行っているのであれば、User Mode - Kernel Mode 間で、そのバッファ ポインタの受け渡しが適切に行われていることが保証されない限り、__readmsr() や memcpy() コールでのポインタ指定を議論しても意味がない。」

    先の返信でも触れましたが、I/O Control Code にはバッファ受け渡し方法に関する情報が含まれています。
    GFKBXFA4さんのケースでは METHOD_BUFFERED を指定されているとのことですが、この場合 NT カーネル (I/O マネージャ) は、一旦 Kernel Mode 側での処理用に別途バッファを確保してから、その I/O Control Code をハンドリングするドライバに処理を渡し、ドライバから処理が戻されたタイミングで NT カーネルが DeviceIoControl() API の lpOutBuffer パラメータで指定されたバッファに結果をコピーする。。。という動作になると思います。
    つまり、User Mode 側のアプリで確保されたバッファ ポインタが、そのまま Kernel Mode 側のドライバに渡される訳ではない、ということになるので、まずはその部分が確実に期待通りの動きになっているかを確認することが重要だと考えています。

    私だったら、まず以下の様なコードでこの点を確認します。

    -------------------------------------------------
    #define IOCTL_CUSTOM_CONTROL_CODE   CTL_CODE(5000, 0x0980, METHOD_BUFFERED, FILE_ANY_ACCESS)

    ++++++++++++++++++++++++++++++++++++++++++++++
    <User Mode 側アプリ>

    ....
        BOOL    bResult;
        DWORD   dwInBuffer      = 0x12345678;
        DWORD   dwOutBuffer     = 0;
        DWORD   dwBytesReturned = 0;

        // DebugBreak();
        bResult = DeviceIoControl( hDevice,
                                    IOCTL_CUSTOM_CONTROL_CODE,
                                    &dwInBuffer,
                                    sizeof( DWORD ),
                                    &dwOutBuffer,
                                    sizeof( DWORD ),
                                    &dwBytesReturned,
                                    NULL );

        if ( bResult && (dwBytesReturned == sizeof( DWORD )) )
        {
            if ( dwOutBuffer == 0x98765432 )
            {
                // 成功!! <バッファの受け渡しに問題なし>
            }
            else
            {
                // 失敗... <バッファの受け渡しに問題がある可能性大>
            }
        }
        else
        {
            // 失敗... <バッファの受け渡し以前に、ドライバ側でIRP_MJ_DEVICE_CONTROL 処理に問題がある可能性大>
        }

    ....
    ++++++++++++++++++++++++++++++++++++++++++++++
    <Kernel Mode 側ドライバ>

    NTSTATUS AccessReadMSR
    (
        ULONG       IoctlCode,          // IoControlCode
        void       *lpInBuffer,         // 上位アプリからの入力データバッファ
        ULONG       nInBufferSize,      // 上位アプリからの入力データの大きさ
        void       *lpOutBuffer,        // 上位アプリへの出力データバッファ
        ULONG       nOutBufferSize,     // 上位アプリへの出力データの大きさ
        ULONG_PTR  *lpBytesReturned     // 転送完了バイト数を格納する
    )
    {
        NTSTATUS    ntStatus = STATUS_UNSUCCESSFUL;

        if ( IoctlCode == IOCTL_CUSTOM_CONTROL_CODE )
        {
            if ( lpInBuffer )
            {
                PULONG  inputData = (PULONG)lpInBuffer;

                if ( (nInBufferSize == sizeof( ULONG )) && (*inputData == 0x12345678) )
                {
                    if ( (lpOutBuffer) && (nOutBufferSize == sizeof( ULONG )) )
                    {
                        PULONG  outputData = (PULONG)lpOutBuffer;

                        *outputData = 0x98765432;
                        *lpBytesReturned = nOutBufferSize;

                        ntStatus = STATUS_SUCCESS;
                }
            }
        }

        return ntStatus;
    }
    ++++++++++++++++++++++++++++++++++++++++++++++
    -------------------------------------------------

    既に、上記部分に問題がないことをご確認されている場合はご容赦ください。

    なお蛇足ですが。。。
    I/O Control Code の CTL_CODE によるマクロ定義で METHOD_BUFFERED を指定した場合、ドライバに渡される lpInBuffer と lpOutBuffer のポインタは同じアドレスになるはずだったと思います。



    • 回答としてマーク GFKBXFA4 2012年3月12日 1:37
    • 編集済み お馬鹿 2012年3月12日 3:13
    2012年3月8日 9:31
  • 佐祐理 様

    返信頂きありがとう御座います。

    あらためて、ご指摘ありがとう御座います。

    たしかに、実際にはアセンブラ用のコードを半分くらい作成していて、後から”__readmsr()”をみつけて

    無理やり対応させるために無茶なキャストをしておりました。

    やはり、落ち着いて見直すと、結構ボロが出てきますね・・・・(反省)

    焦ってバグもちコードを書くよりか、一呼吸おいて落ち着いてから書き直した方が良さそうですね。

    大変お手数をお掛けいたしました事を、お礼いたします。

    2012年3月9日 13:05
  • お馬鹿 様

    返信頂きありがとう御座います。

    あらためて、ご指摘ありがとう御座います。

    試してみたところ、やはり下記の行に飛んできておりました。

    ++++++++++++++++++++++++++++++++++++++++++++++

    // 失敗... <バッファの受け渡し以前に、ドライバ側での IRP_MJ_DIRECTORY_CONTROL 処理に問題がある可能性大>

    ++++++++++++++++++++++++++++++++++++++++++++++

    やはりドライバとしての、もっと根本的な部分が間違っていたようです。

    あらためて、I/O Control Codeのコードや、ドライバのほかの部分を再度見直し、勉強して出直してみたいと思います。 

    大変お手数をお掛けいたしました事を、お礼いたします。

    2012年3月9日 13:09
  • 大変申し訳ございません。
    先の私の返信内容に誤りがありました。
    つきましては、下記の様に修正させていただきました。

    -----------------------------------------------
    [誤]
    // 失敗... <バッファの受け渡し以前に、ドライバ側での IRP_MJ_DIRECTORY_CONTROL 処理に問題がある可能性大>

    [正]
    // 失敗... <バッファの受け渡し以前に、ドライバ側での IRP_MJ_DEVICE_CONTROL 処理に問題がある可能性大>
    -----------------------------------------------

    なお上位アプリでの DeviceIoControl() API コールが FALSE になるとのことですので、まずはその デバイス I/O リクエストが GFKBXFA4 さんの作成されたドライバの、IRP_MJ_DEVICE_CONTROL ディスパッチ ルーチンおよび AccessReadMSR() に届いているかを確認された方が良いのかも。
    またカーネル デバッガの使用を躊躇されているようですが、上記確認は WinDBG を使えばすぐに判別できますので、ドライバ開発をされているのであれば、カーネル モード デバッグ環境を構築されておくことをお勧めいたします。
    (WinDBG のカーネル モード デバッグ環境を用意しておくと、サービスなどのユーザ モード側のデバッグもプロセス間の「壁」を超えてトレース出来るので、とっても便利です。)

    • 回答としてマーク GFKBXFA4 2012年3月12日 11:06
    2012年3月12日 3:12
  • 馬鹿 様

    返信頂きありがとう御座います。

    IRP_MJ_DIRECTORY_CONTROL >IRP_MJ_DEVICE_CONTROLは、ソースの方では

    正しくなっておりましたので、コードを追加時に補正していたようです。

    たしかに、WinDBGをキッチリ動作する環境を用意しておいた方が良さそうですね。

    最近のPCでは減りつつあるCOMやIEEE1394、専用?のUSBケーブル等での接続がネックですが、

    環境を整えたいと思います。(倉庫に行って、USB-COM変換を探してきます。)

    (どうせなら、LAN(クロスケーブル)にも対応していただけると便利なのですが。。>MSさん)

    2012年3月12日 11:15
  •  やっとで纏まった時間が出来まして、再挑戦いたしました。

     結果は・・・動いて居たようでした。

     どうやら、デバック用に未署名のドライバで確認していたつもりが、改造前の同名署名付きドライバ

     情報がレジストリに登録されている場合、そちらを優先して使われてしまう様です。

     (運用の都合でinfファイルなどを利用したインストールを行わず、実行ファイルのフォルダにドライバや

      DLLを置いていたので、同名の署名付きドライバが別フォルダにもあった。)

     そりゃ書名付きドライバ内では本関数は存在しないため、デバックをしていても変なアドレスに

     飛んで正しく動作しませんね。

     別途マッサラな環境を作成してみたら動作してましたので・・・なんでだろ?とイロイロ足掻いて

     ました。

     レジストリ内の書名付きの方のドライバエントリー情報を削除して、改めて実行した所取得

     できておりました。

     ドライバの改良などで複数のドライバで動作確認をする場合など、嵌りそうですね・・・・・

     まさか、この様な落とし穴に嵌っていたとは思っても居ませんでしたが・・・・汗

     (こちらも実行環境の詳細や経緯なども書くべきだったと反省しております。)

      佐祐理 様、お馬鹿 様 大変ありがとう御座いました。

      (特にお馬鹿さま、最後の返信にてお名前を間違えましたことをお詫び申し上げます。)

      また、この様な場を提供してくださるMSさんにも感謝いたします。

    2013年1月8日 2:39