2017-09-20 15 views
2

バイナリの問題を抱えてリモートサーバにSSHdしている。tty(SSH経由)のプログラムのstdinにASCII以外の文字を書き込む

ある時点で、私はテキストを入力するように求めます。私はfgets()を使ってstdinを読んでいることを知っていて、近くの変数にコピーされて上書きされている場所でオーバーフローする可能性があります。

問題は、私は私bashを使うことができたならば、私はecho -ne "\x84"だろうか、Cの六角配列を使用するなど、私が必要とするアドレス値を入力する方法を知っている\x84\x04ていないですが、私はそのようなものを行うことはできませんここのものの。

私は、16進数のASCIIコンバーターを使用し、バイナリ文字をコピーし、また期待値スクリプトを使ってバイナリ値を送信しようとしましたが、どちらも同じ問題があります。 x84は追加のcharを追加し、x04はまったく書き込まれません。

Unixのtty上でASCII文字で表現できない値をメモリに確実に書き込むための最良の方法はありますか?

+1

あなたの質問は混乱しています。ターミナルに制御文字を入力する方法や、Cプログラムがそれをメモリに書き込む方法を尋ねていますか? – Barmar

+0

バイナリデータを操作している場合は、 'fgets()'とフレンドを使うべきではありません。それはテキストデータを読むためのものです。 –

+0

申し訳ありません、私は今、私の電話にいます。おそらく前者。私がAAAAを書くと、私はx41x41x41x41などをメモリに入れます。私が\ x84を書くと、x78x38x34などが書かれます。私はfgetsがasciiとしてすべてを解釈し、エスケープシーケンスを許可していないように見せたい16進値を書くのに問題があります。 – GhostSparkles

答えて

3

高い文字の場合は、おそらくコピー/ペーストできます。

echo -ne "\x84" | xclip -iあなたのデスクトップがLinuxを実行している場合は、端末エミュレータで中クリックしてください。 (かどうかは、を参照してください)。またはecho ... | ssh [email protected]が動作する可能性があります。

他の端末エミュレータで

ssh -Tまたは同等また、「無効疑似端末割当て」に、オプションであるかもしれないので、リモート側のプログラムは、そのstdinがSSHDからパイプではなく、偽であるだろうターミナル、私は思う。これにより、^s^vのようなものは無効になります。

逆に、echo foo | ssh -ttは、sshに内容を配管していても、リモート側でttyを要求するよう強制します。SSH上で必ずバイナリデータを作るために


あまり侵入的な方法は、TTY層を介して、受信プログラムのstdinになっコントロール - v(16進数の0x16)ですべてのバイトの前にあります。

Barmarが指摘するように、それはリテラルの次の文字(のstty -a出力)です。 の前にそれを使用できます。ペイロードのすべてのバイト。通常の文字の前でさえ、受信機のTTYレイヤーによって取り除かれます。

# LANG=C sed to replace every byte with ^V byte 
# using bash $'' to put a literal control-V on sed's command line 
echo "hello" | LANG=C sed $'s/./\x16&/g' | hd 
     16 68 16 65 16 6c 16 6c 16 6f 0a     |.h.e.l.l.o.| 

あなたはhexdump -C(別名hd)に入力することで、ローカルにこのすべてをテストすることができます。ターミナルでそれを実行し、いくつかのものを入力または貼り付け、終了するまでcontrol-Dします。

$ echo -ne "\x01\xff\x99" | LANG=C sed $'s/./\x16&/g' | hd 
00000000 16 01 16 ff 16 99         |......| 
00000006 
     # yup, correct bytes from sed 
$ echo -ne "\x01\xff\x99" | LANG=C sed $'s/./\x16&/g' | xclip -i 
$ LANG=C hd 
^A��  (middle click, return, control-d) 
00000000 01 ef bf bd ef bf bd 0a       |........| 
    # nope, that munged my data :/ 

$ xclip -o | hd 
00000000 16 01 16 ff 16 99         |......| 

ので、Xの選択自体は正しいですが、それは私がペーストとしてkonsoleのいずれかによってマングド、またはkonsoleのからhexdumpへの道上のTTY層によって取得のか?後者はそう思わない。おそらくそれはペーストの問題です。 Konsoleの「エンコーディング」設定はUTF-8です。これは普通のASCII設定を持っていないようです。

LANG=C xtermなどで試してみるか、expectというスクリプトを正しく実行して、実際のバイナリデータをエスケープコードではなくsshに送信してください。

もちろんの

fgetsエスケープシーケンスを処理しない、任意のより多くstrcpyでしょう。一般に、C関数はそうではありません。 Cではコンパイラは、コンパイル時に文字列リテラルのエスケープシーケンスを処理します。

+1

'すべてのバイトの前にControl-v(16進数0x16)'が完璧に働いています。私は16進数を送信するためにpexpectスクリプトを使用しました。 Barmarの答えがうまく拡張されました。両方をアップした。 'これは受信者のTTYレイヤーによっても除去されています。通常の文字の前には非常に興味深い情報があります。ありがとうございます! – GhostSparkles

3

0x000x1fの範囲の文字をキーボードで制御文字を入力すると書き込むことができます。 コントロールキーを押しながら、このASCII Chartの3番目の列に文字を入力して、最初の列に対応するコードを取得します。

いくつかの制御文字は端末ドライバ(プロセスを殺すために、例えばCTL-C)に特別な意味を持っている、あなたはCTL-Vで、先行することにより、文字通り、それらを入力することができます。

そして、あなたは(これはバックスペースをlabeldかもしれない後退削除文字、あり、前方にはそれが別々のキーパッドであってもよく、削除しない)を削除CTL-Vを入力して0x7fを得ることができます。

これを超える文字を簡単に入力できるかどうかはわかりません。端末エミュレータの設定に応じて、対応するASCII文字を入力しながらAltキーを押して、ハイビットセットを取得できる場合があります。例えば。 Alt-A0xc10x80 | 0x41)を送信します。

+0

端末のUTF-8仮定を克服できれば、上位ビットがセットされたデータをコピー/ペーストすることもできます。 –

関連する問題