PTPカメラとの私の戦い、または最小の逆転についての魅力的な物語

ほぼすべての高度な一眼レフカメラといくつかの正しい石鹸箱を使用すると、コンピューターから自分自身を制御できます。 カメラのソフトウェア制御は、たとえば、 タイムラプスビデオの撮影、カメラと顕微鏡のペアリング、コンピュータービジョンの分野での実験など、興味深い機会を提供します。 カメラを制御するために、ベンダーは独自のSDKを提供します。これは通常、Windowsでのみ動作し、特定の行内でのみカメラをサポートします(たとえば、Canonには最大4つの非互換SDKがあります)。 まともなオープンオルタナティブ-gphotoプロジェクトが存在することは何と恵まれていますか。



Gphotoは現在1598台のカメラモデルをサポートしており、リストは常に増え続けています。 このプロジェクトは、LinuxやMac OS Xを含むすべてのUNIXライクなオペレーティングシステム用に構築されています。撮影は、コマンドラインユーティリティを使用して、またはlibgphotoライブラリを使用して独自のプログラムから制御できます。 バインディングは、 node.jsを含むさまざまな言語プラットフォームで使用できます。



最新のオペレーティングシステムには、デジタルカメラを操作するための組み込みツールがあります。原則として、「作業」とは、カメラから写真をアップロードすることを意味します。 これらの組み込みメカニズムは、USBデバイスを排他モードでキャプチャするため、gphotoの動作を妨げます。 この点で特に興味深いのは、Mac OS Xの場合です。OSは無効化のための通常の機能を提供しませんが、デジタルカメラのサポートシステムはリバースエンジニアリングに簡単に対応できます。



githubでのPTPCameraの起動をブロックするスクリプト



PTPカメラ

インターネットでは、通常のgphoto操作のためにカメラを接続した後、 killall -9 PTPCamera



を実行する(PTPCameraプロセスをkillall -9 PTPCamera



する)ことをお勧めします。 これは本当に役立ちますが、カメラを接続するたびに、手順をもう一度繰り返す必要があります。 もちろん、PTPCameraプログラムは簡単に削除できますが、それほど急進的な解決策はありません。



一般に、PTPCameraの起動メカニズムを理解し、この機能を可能な限り正しく無効にする必要がありました。



Mac OS Xでの画像のキャプチャについて

利用可能なソース[ 1、2 ]によると、Mac OS Xの画像キャプチャインフラストラクチャは次のように構成されています。







スタックの一番上には、ユーザーが直接操作するアプリケーションがあります(例:iPhoto)。



最下部には、デバイスを管理するためのアプリケーションがあり、後者にはPTPCameraが含まれます。 デバイス管理アプリケーション( MassStorageCamera.app



PTPCamera.app



TWAINBridge.app



など)は、システムフォルダー/System/Library/Image Capture/Devices



および/Library/Image Capture/Devices



ます。



中央には、上位レベルと下位レベルの間の接続を整理する通信レイヤーがあります。 複数のユーザーアプリケーションが同じデバイスを共有でき、ローカルネットワーク上のデバイスとの透過的な作業も可能です。



誰がPTPCameraを立ち上げましたか?

PTPCameraを起動するメカニズムを決定してみましょう。最初に親プロセスを定義します。

 $ pgrep PTPCamera 29045 $ ps -O ppid -p 29045 PID PPID TT STAT TIME COMMAND 29045 202 ?? S 0:00.10 /System/Library/Image Capture/Devices/PTPCamer $ ps -p 202 PID TTY TIME CMD 202 ?? 0:16.75 /sbin/launchd
      
      





したがって、PTPCameraはlaunchdプロセスによって起動されることがわかります。 Mac OS Xでは、launchdはシステムおよびユーザーデーモン用のユニバーサルランチャーです。 システムは、アクティブなユーザーごとにlaunchdのインスタンスを実行します。 ルートlaunchdは、従来のUNIXシステムのinitと同じ機能を実行します。



 $ ps -A -O user | grep /sbin/launchd 1 root ?? Ss 3:06.80 /sbin/launchd 172 _windowserver ?? Ss 0:00.06 /sbin/launchd 202 nickz ?? Ss 0:16.76 /sbin/launchd 206 _spotlight ?? Ss 0:00.27 /sbin/launchd 28919 _cvmsroot ?? Ss 0:00.01 /sbin/launchd 28937 _securityagent ?? Ss 0:00.01 /sbin/launchd
      
      





デーモンに加えて、laucnhdは他のプログラムからのコマンドでグラフィカルアプリケーションも起動します。 launchdのタスクIDからわかるように、PTPCameraは最後のケースです。[prefix]はこれを示しています。



 $ launchctl list | grep PTPCamera 29045 - [0x0-0x457457].com.apple.PTPCamera
      
      





したがって、PTPCameraは、一部のアプリケーションXのコマンドで、launchdプロセスによって起動されたことがわかります。



launchdロギング( launchctl log level debug



)をオンにし、PTPCameraをトリガーして再起動します。



デフォルトでは、システム内のプロセスごとに1秒あたり500ログエントリのクォータが割り当てられます。 制限内にないメッセージは破棄されます。 デバッグメッセージの別のアセンブリを設定して、制限をバイパスします。



/etc/syslog.conf



ファイルに行を追加します
 *.debug /var/log/debug.log
      
      





設定を再読み込みする必要があることをsyslogd



デーモンに通知します
 sudo killall -HUP syslogd
      
      





結果のdebug.log



ファイルを分析します。 私たちは望ましいものを見つけます:
 ([0x0-0x2d92d9].com.apple.PTPCamera[24472]): Spawned by PID 240: com.apple.SystemUIServer.agent
      
      





com.apple.SystemUIServer.agent



に関する情報をlaunchd



要求します。

 $ launchctl list com.apple.SystemUIServer.agent { "Program" = "/System/Library/CoreServices/SystemUIServer.app/Contents/MacOS/SystemUIServer"; };
      
      





PTPCamera



を起動する「犯人」はPTPCamera



SystemUIServer







SystemUIServerを突く

必要な機能がSystemUIServer



自体ではなく、リンクされたフレームワークの1つにあるという疑いがあります。

 $ otool -L /System/Library/CoreServices/SystemUIServer.app/Contents/MacOS/SystemUIServer /System/Library/CoreServices/SystemUIServer.app/Contents/MacOS/SystemUIServer: /System/Library/PrivateFrameworks/CoreUI.framework/Versions/A/CoreUI /System/Library/PrivateFrameworks/Admin.framework/Versions/A/Admin /System/Library/Frameworks/Carbon.framework/Versions/A/Carbon /System/Library/PrivateFrameworks/SystemUIPlugin.framework/Versions/A/SystemUIPlugin /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit /System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit /System/Library/Frameworks/Security.framework/Versions/A/Security /System/Library/PrivateFrameworks/ICANotifications.framework/Versions/A/ICANotifications /System/Library/PrivateFrameworks/iPod.framework/Versions/A/iPod ...
      
      





このリストの主な容疑者はICANotifications.framework



です。 ICA



画像キャプチャの略で、同じ頭字語は画像をキャプチャするためのパブリックフレームワークで使用されます。



ICANotifications.frameworkの学習

叙情的な余談。 実行可能ファイルは、コードと不変の静的データ(異なる定数、テーブルなど)で構成されています。文字列定数は特に重要です。 strings



コマンドを使用してそれらを抽出できstrings







strings /System/Library/PrivateFrameworks/ICANotifications.framework/Versions/A/ICANotifications



実行し、結果を楽しみます。

 ... /Library/Caches/com.apple.ImageCaptureNotifications.DeviceDiscoveryDatabase.%d ... CREATE TABLE DBVersion (ID integer primary key not null, typeID integer, value integer) CREATE TABLE SourceFile (ID integer primary key not null, typeID integer, bundleID varchar(256), bundleVersion integer, bundlePath varchar(256), deviceDiscoveryPath varchar(256), deviceDiscoveryModDate varchar(20), readDate varchar(20), iTWAINDS integer) CREATE TABLE IOUSBDevice (ID integer primary key not null, typeID integer, idVendor integer, idProduct integer) CREATE TABLE IOUSBInterface (ID integer primary key not null, typeID integer, bInterfaceClass integer, bInterfaceSubClass integer, bInterfaceProtocol integer) ...
      
      





これがSQLです!



したがって、動作する仮説は、ライブラリがSQLiteデータベースで動作するということです。ほとんどの場合、 /Library/Caches



あるファイルcom.apple.ImageCaptureNotifications.DeviceDiscoveryDatabase



です。



 $ ls /Library/Caches/com.apple.ImageCaptureNotifications.DeviceDiscoveryDatabase.* /Library/Caches/com.apple.ImageCaptureNotifications.DeviceDiscoveryDatabase.501 $ sqlite3 /Library/Caches/com.apple.ImageCaptureNotifications.DeviceDiscoveryDatabase.501 sqlite> .schema CREATE TABLE DBVersion (ID integer primary key not null, typeID integer, value integer); CREATE TABLE IOUSBDevice (ID integer primary key not null, typeID integer, idVendor integer, idProduct integer); CREATE TABLE IOUSBInterface (ID integer primary key not null, typeID integer, bInterfaceClass integer, bInterfaceSubClass integer, bInterfaceProtocol integer); ...
      
      





そうです!



ユーザーIDが名前の最後( com.apple.ImageCaptureNotifications.DeviceDiscoveryDatabase.501



)に追加され、各ユーザーが独自のファイルを持っていることがcom.apple.ImageCaptureNotifications.DeviceDiscoveryDatabase.501



ます。 内容から、ベースがデバイスクラスとデバイスが検出されたときに実行する必要がある制御プログラムの対応のリストを設定することが明らかです。



データベースを編集し、選択したユーザーに対してPTPCamera



の起動を無効にします。 これは間違いなく成功です!



必要に応じて、すべてを戻すか、変更をロールバックするか、単にデータベースファイルを削除します(フォルダー/Library/Caches



の名前は、必要に応じてOSがコンテンツを再生成できることを示しています)



さらに技術の問題です。



オプション素材

  1. Amit Singh Mac OS X内部:システムズアプローチ[ アマゾン ]
  2. プロジェクトリポジトリ



All Articles