質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.82%

  • Windows

    1299questions

    Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

  • Python 2.7

    1139questions

    Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

  • Win32 API

    195questions

    Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

PythonとWindowsAPI

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 276

psycho

score 1

Pythonに噛まれました

Windows APIを利用し,デバッガを作成しています.
言語はPython(2.7)です.

現在,手動で電卓を開き,プロセスIDを取得し,
電卓のプロセスを停止するプログラムを作成しています.
プログラムのコンパイルは無事に通るのですが,
アタッチに失敗します.
なぜなのかと解決策を質問したいです.

また以前,
PROCESS_ALL_ACCESSが定義されていないと
コンパイルが通らなかったことがあります.
定義を行って修正しましたが
問題がないかもお願いいたします.

実行例

実行例(PID:1620):

Enter the PID of the process to attach to:1620
[*] Unable to attach to the process.
There was an error

my_debugger_defines

from ctypes import *

WORD    = c_ushort
DWORD   = c_ulong
LPBYTE  = POINTER(c_ubyte)
LPTSTR  = POINTER(c_char)
HANDLE  = c_void_p

DEBUG_PROCESS = 0x00000001
CREATE_NEW_CONSOLE = 0x00000010

class STARTUPINFO(Structure):
    _fields_ = [
        ("cb",              DWORD),
        ("lpReserved",      LPTSTR),
        ("lpDesktop",       LPTSTR),
        ("lpTitle",         LPTSTR),
        ("dwX",             DWORD),
        ("dwY",             DWORD),
        ("dwXSize",         DWORD),
        ("dwYSize",         DWORD),
        ("dwXCountChars",   DWORD),
        ("dwYCountChars",   DWORD),
        ("dwFillAttribute", DWORD),
        ("dwFlags",         DWORD),
        ("wShowWindow",     WORD),
        ("cbReserved2",     WORD),
        ("lpReserved2",     LPBYTE),
        ("hStdInput",       HANDLE),
        ("hStdOutput",      HANDLE),
        ("hStdError",       HANDLE),
    ]

class PROCESS_INFORMATION(Structure):
    _fields_ = [
        ("hProcess",        HANDLE),
        ("hThread",         HANDLE),
        ("dwProcessId",     DWORD),
        ("dwThreadId",      DWORD),
    ]

my_debuggera

from ctypes import *
from my_debugger_defines import *

kernel32 = windll.kernel32
#PROCESS_ALL_ACCESS = 2035711
PROCESS_ALL_ACCESS = (0x000F0000L | 0x00100000L | 0xFFF)

class debugger():
    def __init__(self):
        self.h_process  =   None
        self.pid    =   None
        self.debugger_active    =   False

    def load(self,path_to_exe):
        creation_flags = DEBUG_PROCESS

        startupinfo         = STARTUPINFO()
        process_information = PROCESS_INFORMATION()

        startupinfo.dwFlags = 0x1
        startupinfo.wShowWindow = 0x0

        startupinfo.cb = sizeof(startupinfo)

        if kernel32.CreateProcessA(path_to_exe,
                                   None,
                                   None,
                                   None,
                                   None,
                                   creation_flags,
                                   None,
                                   None,
                                   byref(startupinfo),
                                   byref(process_information)):
            print "[*] We have successfully lauched the process!"
            print "[*] PID: %d" % process_information.dwProcessId
            self.h_process = self.open_process(process_information.dwProcessId)

        else:
            print "Error: 0x%08x." % kernel32.GetLastError()

    def open_process(self,pid):

        h_process = kernel32.OpenProcess(PROCESS_ALL_ACCESS,False,pid)
        return h_process

    def attach(self,pid):

        self.h_process = self.open_process(pid)

        if kernel32.DebugActiveProcess(pid):
            self.debugger_active = True
            self.pid = int(pid)
        else:
            print "[*] Unable to attach to the process."

    def run(self):
        while self.debugger_active == True:
            self.get_debug_event()

    def get_debug_event(self):

        debug_event = DEBUG_EVENT()
        continue_status = DBG_CONTINUE

        if kernel32.WaitForDebugEvent(byref(debug_event),INFINITE):

            raw_input("Press a key to continue...")
            self.debugger_active = False
            kernel32.ContinueDebugEvent(
                debug_event.dwProcessId,
                debug_event.dwThreadId,
                continue_status )

    def datach(self):

        if kernel32.DebugActiveProcessStop(self.pid):
            print "[*] Finished debugging. Exiting..."
            return True
        else:
            print "There was an error"
            return False

実行ファイル

import my_debuggera

debugger = my_debuggera.debugger()

pid = raw_input("Enter the PID of the process to attach to:")

debugger.attach(int(pid))
debugger.run()
debugger.datach()

再定義

PROCESS_ALL_ACCESS

補足情報

Python2.7
Windows7

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • 退会済みユーザー

    2017/12/18 09:54

    複数のユーザーから「意図的に内容が抹消された質問」という意見がありました
    解決後に編集機能を用いて質問内容を改変し関係のない内容にしたり、内容を削除する行為は禁止しています。
    投稿していただいた質問は、後に他の誰かが困ったときに助けになる情報資産になると考えるからです。
    「質問を編集する」ボタンから編集を行い、他のユーザにも質問内容が見えるように修正してください。

回答 2

checkベストアンサー

+2

この本で扱われている内容ですね。

https://www.google.co.jp/amp/s/www.oreilly.co.jp//books/9784873114484/mobile.html

多分アタッチ対象のプロセスへの権限が足りなくてアタッチできない状況だと推測しますが、なかなかややこしい箇所で本を全部そらんじるほどの理解もないので、「本を読んでみてください」とだけお伝えします。

 追記

Python 3.6ですが、以下のコードで電卓のPIDへアタッチ/デタッチしてみましたが、特別なことをしなくてもエラーにならなかったので、やっぱり権限関連の問題だと思います。

'''
Created on 2017/12/15

@author: sakurai
'''

from ctypes import windll
from ctypes import WinError
from ctypes import wintypes


def assertTrue(result, _, args):
    if not result:
        raise WinError()
    return args


DebugActiveProcess = windll.kernel32.DebugActiveProcess
DebugActiveProcess.restype = wintypes.BOOL
DebugActiveProcess.argtypes = (wintypes.DWORD, )
DebugActiveProcess.errcheck = assertTrue

DebugActiveProcessStop = windll.kernel32.DebugActiveProcessStop
DebugActiveProcessStop.restype = wintypes.BOOL
DebugActiveProcessStop.argtypes = (wintypes.DWORD, )
DebugActiveProcessStop.errcheck = assertTrue


if __name__ == "__main__":
    pid = int(input("PID: "))
    DebugActiveProcess(pid)
    DebugActiveProcessStop(pid)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/15 00:39

    御回答ありがとうございます。
    その通りです。
    本を通してPythonとWindowsプログラミングを学習しております。
    本に書いている内容だと関数の紹介のみで対処に困っている状況です。

    プロセス権限に関して検討していきたいと考えております。
    お忙しい中、回答ありがとうございました。

    キャンセル

  • 2017/12/16 03:55

    Windowsの64bitが動作環境であったため、ctypesによりWin32を扱う場合、Windows APIの構造体や共用体、グローバル変数を再定義しなければならなかったようです。

    sakurai様のソースコードで問題なく動作したため、気づくことができました。
    ありがとうございました。

    キャンセル

+2

(解決済になってるけど、新たに回答を追加することは可能だよね……)

Pythonが32bitでcalc.exeが64bitの場合はDebugActiveProcessが失敗するのではないかと思います。
Side Effects of Debugger から抜粋

DebugActiveProcess would fail if a 32bit debugger tried to attach to a 64bit target.

PROCESS_ALL_ACCESSの下4桁は、XP時代は0x0FFFだけどVista以降に特有の機能を使う場合は0xFFFFにするべきかもしれません。
Process Security and Access Rights
(PROCESS_ALL_ACCESSのところに書いてあるのは逆に、Vista以降向けの設定でコンパイルした物をXPで動かしたら失敗するよ、という内容ですが。)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/16 03:50

    御回答ありがとうございます。
    Pythonは確認したところ64bitでした。

    グローバル変数に関しましては、その通りで、Windowsが32bitを想定したプログラムだったため動作を行わなかったようです。

    Windows APIに関する、構造体や共用体、グローバル変数を再定義することによって改善できました。

    お忙しい中ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.82%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Windows

    1299questions

    Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

  • Python 2.7

    1139questions

    Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

  • Win32 API

    195questions

    Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。