外部デバイス(usb / thunderbolt)をMacコンピューターに接続することで、再生成の問題なしに任意の実行可能ファイルまたはシェルスクリプトをトリガーするための詳細な手順とサンプルファイルを使用して、これに関するチュートリアルを作成しました。
著者のアプローチと同様に、デバイスの検出にはAppleのライブラリに依存しIOKit
、目的の実行可能ファイルを実行するにはデーモンに依存しています。デバイスの接続後にデーモンが繰り返しトリガーされないようにするには、@ fordによる投稿と彼のgithubリポジトリで説明されているように、特別なストリームハンドラー(xpc_set_event_stream_handler
)を使用してイベントを「消費」します。com.apple.iokit.matching
特に、チュートリアルでは、xpcストリームハンドラーをコンパイルする方法と、デーモンplistファイル内の実行可能ファイルと一緒にそれを参照する方法、および関連するすべてのファイルを正しいアクセス許可で配置する場所について説明します。
ファイルについては、こちらをご覧ください。完全を期すために、以下にそれらのコンテンツも貼り付けました。
Macでデバイス検出によってトリガーされたシェルスクリプトまたは実行可能ファイルを実行する
ここでは、イーサネットアダプタがMacに接続されているときにそのMACアドレスをスプーフィングする例を使用します。これは、任意の実行可能ファイルとデバイスに一般化できます。
シェルスクリプトまたは実行可能ファイルを配置します
シェルスクリプトを適応させるspoof-mac.sh
#!/bin/bash
ifconfig en12 ether 12:34:56:78:9A:BC
必要に応じて実行可能にします。
sudo chmod 755 spoof-mac.sh
次に、それを/usr/local/bin
、または他のディレクトリに移動します。
cp spoof-mac.sh /usr/local/bin/
ストリームハンドラーの構築
ストリームハンドラーxpc_set_event_stream_handler.m
// Created by Ford Parsons on 10/23/17.
// Copyright © 2017 Ford Parsons. All rights reserved.
//
#import <Foundation/Foundation.h>
#include <xpc/xpc.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
xpc_set_event_stream_handler("com.apple.iokit.matching", NULL, ^(xpc_object_t _Nonnull object) {
const char *event = xpc_dictionary_get_string(object, XPC_EVENT_KEY_NAME);
NSLog(@"%s", event);
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
if(argc >= 2) {
execv(argv[1], (char **)argv+1);
}
}
}
ユニバーサル(適応する必要はありません)であり、macコマンドライン(xcodeがインストールされている)で構築できます:
gcc -framework Foundation -o xpc_set_event_stream_handler xpc_set_event_stream_handler.m
/usr/local/bin
デーモンのメインの実行可能ファイルのように、に配置しましょう。
cp xpc_set_event_stream_handler /usr/local/bin/
デーモンをセットアップします
plistファイルcom.spoofmac.plist
には、デバイス接続トリガーで実行可能ファイルを実行するデーモンのプロパティが含まれています。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UserName</key>
<string>root</string>
<key>StandardErrorPath</key>
<string>/tmp/spoofmac.stderr</string>
<key>StandardOutPath</key>
<string>/tmp/spoofmac.stdout</string>
<key>Label</key>
<string>com.spoofmac.program</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/xpc_set_event_stream_handler</string>
<string>/usr/local/bin/spoofmac.sh</string>
</array>
<key>LaunchEvents</key>
<dict>
<key>com.apple.iokit.matching</key>
<dict>
<key>com.apple.device-attach</key>
<dict>
<key>idVendor</key>
<integer>32902</integer>
<key>idProduct</key>
<integer>5427</integer>
<key>IOProviderClass</key>
<string>IOPCIDevice</string>
<key>IOMatchLaunchStream</key>
<true/>
<key>IOMatchStream</key>
<true/>
</dict>
</dict>
</dict>
</dict>
</plist>
、、などidVendor
、トリガーのベースにするデバイスを識別するための情報が含まれています。これらは、Macのアプリで把握できます。idProduct
IOProviderClass
System Information
plistファイルに挿入する前に16進識別子を整数に変換します(たとえばint(0x8086)
、Pythonで使用します)。
IOProviderClass
IOPCIDevice
(Thunderbolt)またはIOUSBDevice
(USB)のいずれかである必要があります。
plistファイルの他の関連するエントリは、実行可能ファイルの場所xpc_set_event_stream_handler
と実行可能ファイルです。
その他のエントリには、標準出力(ログ)ファイルの場所と実行中のユーザーが含まれます。
MACスプーフィングにはroot権限が必要なため、次のように記述com.spoofmac.plist
し/Library/LaunchDaemons
ます。
cp com.spoofmac.plist /Library/LaunchDaemons/
LaunchAgents
フォルダには入れません。起動エージェントはUserName
引数を無視します。
ファイルの所有者が次のroot
とおりであることを確認してください。
sudo chown root:wheel /Library/LaunchDaemons/com.spoofmac.plist
デーモンを起動します
デーモンをアクティブ化します。
launchctl load /Library/LaunchDaemons/com.spoofmac.plist
そして、あなたは行ってもいいです。
アンロードはを使用して行われlaunchctl unload
ます。