PythonからWindowsAPIを触る

私は環境に依存しない開発やツールが好きです。
理想だとは分かっていますけどWindowsで作ったものをLinuxで実行させたいしOSXでも使いたい。またその逆もやりたいというよくばりなのですがWindowsに特化したサービスを利用したいときもやっぱりあります。
そんなときはCやC#で書くことがよさそうです。
でも面倒なんです・・・
開発環境そのものを準備するところからすでに身がまえちゃいます(おおげさ)。

そこで、今回はどんなWindowsにも入ってる(うそ)Pythonを活用してみます。
Pythonは世界を変えたくなっちゃう環境であるAnaconda
利用して簡単に世界を変えちゃうことにします。

Windowsのインタフェースを用いる

太古の昔からWindowsAPIといえばwindows.hで定義されているとおりCの呼び出し規約が基本のようです。
そのため、Pythonから呼び出すにはではctypeモジュールの利用が必要となりますね。
http://docs.python.jp/3/library/ctypes.html

またWindows固有のデータ型を利用しますのでctypes.wintypesも(通常)importします。
これでWindowsならではのDWORDなども扱えるようになります。

from ctypes import *
from ctypes.wintypes import MSG
from ctypes.wintypes import DWORD

こんなコード利用でuser32.dllやkernel32.dllの関数が利用できます。
かーんたん!(な気分になります)

user32 = windll.user32
kernel32 = windll.kernel32

また、Windowsプログラムで避けて通れないでコールバックは
CFUNCTYPE()が利用できますので問題ありませんね!

メッセージフック

Windowsのプログラムはメッセージで動作してるのでメッセージをフックしてみます。
MSDNによるとCではこんな感じに書けばよさそうですね。

HHOOK SetWindowsHookEx(
    int idHook, // フックタイプ
    HOOKPROC lpfn, // フックプロシージャ
    HINSTANCE hMod, // アプリケーションインスタンスのハンドル
    DWORD dwThreadId // スレッドの識別子
);

特定のイベントタイプを監視するにはこれを呼べば実現できますね。
ここではキーボードをフックしたいのでフックタイプとしてはWH_KEYBOARD_LLを利用することにします。

コード

決まり文句みたいなものでインストールとアンインストールを含めればよいです。

class Hoge:
  def __init__(self):
    self.lUser32 = user32

  def installHookProc(self, pointer):
    self.hooked = self.lUser32.SetWindowsHookExA(
        WH_KEYBOARD_LL,
        pointer,
        kernel32.GetModuleHandleW(None),
        0
    )

  def uninstallHookProc(self):
    self.lUser32.UnhookWindowsHookEx(self.hooked)
    self.hooked = None

これをデコレートしていけば立派なキーロガー^H^H^H^H^Hソフトウエアが作成できますね(悪用しないように)
Python-keylogger _15_2015-11-19_15-29-40

それではよいWindowsAPIライフを!

投稿者プロフィール

えんじにあん
インフラ系のエンジニアです。
運用系のスクリプトを書いたり、オートメーションな世界に向かって日々精進しています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

Time limit is exhausted. Please reload CAPTCHA.

ABOUTこの記事をかいた人

インフラ系のエンジニアです。 運用系のスクリプトを書いたり、オートメーションな世界に向かって日々精進しています。