組み込みシステムで動作するLinuxシステムがあります。さまざまな理由でログインできず(そうでなければ解雇される可能性があります)、キーボードやSSHなどの一般的な手段を介してシステムに直接アクセスすることはできません。実行中のファイルを変更するのは邪悪なことです。しかし、私を信じてください。代替案があればそれを受け入れるでしょう。
ARM CPUに基づいて構築されたこのシステムには、純粋なARM機械語コード(C ++でコンパイルされた)である実行可能ファイルがあります。このコードでバグが見つかりました。 UXTB命令をUXTH命令に置き換えることで、このエラーを解決できることがわかりました。幸いなことに、これを行うにはopcodeバイトを0xEFから0xFFに変更する必要がありました。このパッチを実行するには、次のコマンドを実行します。
printf '\xff' | dd of=path/to/executable bs=1 seek=$((0x01ce22)) conv=notrunc
変更されたバイトは、組み込みシステムが特定のコマンドを受信したときにのみ呼び出される関数の一部です。このパッチを実行すると、このコマンドが送信されないことを絶対に保証できます。したがって、RAMとストレージに異なるバージョンのコードが発生するリスクはありません。
残念ながら、変更が必要なプログラム(やはりシステム起動時の起動)は、システムへのアクセスをほとんど許可しない私が依存するプログラムでもあります。したがって、アクセス権を失わないようにプロセスを終了することはできません。
実行可能ファイルのこのバイト、直接使用されないこの小さなバイトを変更することは可能ですか?
おそらく最善の解決策は、シェルスクリプトを使用して基本プロセスを終了し、バイトを変更してから再起動を有効にすることですか?理想的には、変更が成功したかどうかを確認できるように、システムはアクティブな状態を維持したいと思います。
SSHを介して直接アクセスできる同じシステムで実行されるテストケーススクリプトがあります。テストスクリプトは、単に0.1秒単位で1000回ファイルに値を出力するC ++スクリプトです。私はそれを分解し、上記のprintf |に似た定数値を保持するバイトを見つけました。 ddコマンドを使用して定数を変更できますが、プログラムが実行されていない場合にのみ可能です。私にとって理想的な解決策は、出力ファイルが500のC ++生の値と正しいバイトに入力された500の値を保持するように定数を動的に変更できることです。
提供できる助けやアドバイスに感謝します。
答え1
Linuxや他のほとんどのUnixオペレーティングシステムでは、実行バイナリを実際に変更することはできません。書き込み用にこれらのファイルを開こうとすると、ETXTBSY
エラー(テキストファイルが使用中)が発生します。これは、バイナリがメモリにマッピングされ、ファイルを変更すると、ほとんど確実に意図しない方法でバイナリが変更されるためです。カーネルがこの状況を適切に処理できない可能性があります。
ただし、ファイルを片側にコピーし、そこで変更してから呼び出しrename(2)
(またはそれと一緒に別のものを使用mv(1)
)して、新しいバイナリの名前を古いバイナリに変更できます。これは、以前のバイナリはまだディスクにありますが、どの名前でもファイルシステムを介してアクセスできず、最後のユーザーがそれを閉じるまで残ります。バイナリを再実行すると、新しいバージョンがダウンロードされます。