3

わかりましたので、Python に慣れることは良い考えだと思いました。(私はJava、php、perl、VBなどの経験があり、マスターではありませんが、中級の知識です)

そのため、ソケットからデータを取得して画面に変換するスクリプトを作成しようとしています。従うべき大まかな最初のコード:

私のコードはソケットからバイナリ情報を正しく読み取っているようですが、元の構造にアクセスできないため、解凍できません。

別のプログラムを使用したこのストリームの出力があります(これはひどく書かれているため、これに取り組んでいます)

recv を印刷すると、このようになります...

b'L\x00k\x07vQ\n\x01\xffh\x00\x04NGIN\x04MAIN6Product XX finished reprocessing cdc XXXXX at jesadr 0c\x00k\x07vQ\n\x01\xffF\x00\x06CSSPRD\x0cliab_checkerCCheckpointed to XXXXXXXXXXXXXXXX:XXXXXXX.XXX at jesadr 0 (serial 0)[\x00l\x07vQ\n\x00\xff\x01\x00\x05MLIFE\x06dayendBdayend 1 Copyright XXXX XXXXXXX XXXXXXX XXXXX XXX XXXXXX XXXXXXXX.

これを見て、それを他のプログラムの出力と比較すると、次のように分割する必要があると思います..

b'L\x00k\x07vQ\n\x01\xffh\x00\x04NGIN\x04MAIN6Product XX finished reprocessing cdc XXXXX at jesadr 0'

対応する情報で

04-23
00:00:43
10
1
NGIN
MAIN
255
104
Product XX finished reprocessing cdc XXXXX at jesadr 0

今、私の調査に基づいて、「構造体」を使用して展開する必要があるように見えますが、これの元の構造はわかりません。そこから入手できる情報しか知りません。正直に言うと、私はこれを理解するのにかなりの時間を費やしています。

私は Python インタープリターを使用して行の断片をアンパックしようとしましたが、それはフラストレーションの練習です。

誰かが少なくとも私が始めるのを手伝ってくれるなら、とても感謝しています。

ありがとう

4

4 に答える 4

2

わかった。中間の 16 ビット値についてはわかりませんが、なんとかデコードできたと思います。

この Python 2.7 コード...

from cStringIO import StringIO
import struct
import time

def decode(f):

    def read_le16(f):
        return struct.unpack('<h', f.read(2))[0]

    def read_timestamp(f):
        ts = struct.unpack('<l', f.read(4))[0]
        return time.ctime(ts)

    def read_byte(f):
        return ord(f.read(1))

    def read_pascal(f):
        l = ord(f.read(1))
        return f.read(l)

    result = []

    # Read total length
    result.append('Total message length is %d bytes' % read_le16(f))

    # Read timestamp
    result.append(read_timestamp(f))

    # Read 3 x byte
    result.append(read_byte(f))
    result.append(read_byte(f))
    result.append(read_byte(f))

    # Read 1 x LE16
    result.append(read_le16(f))

    # Read 3 x pascal string
    result.append(read_pascal(f))
    result.append(read_pascal(f))
    result.append(read_pascal(f))

    return result

s = 'L\x00k\x07vQ\n\x01\xffh\x00\x04NGIN\x04MAIN6Product XX finished reprocessing cdc XXXXX at jesadr 0c\x00k\x07vQ\n\x01\xffF\x00\x06CSSPRD\x0cliab_checkerCCheckpointed to XXXXXXXXXXXXXXXX:XXXXXXX.XXX at jesadr 0 (serial 0)[\x00l\x07vQ\n\x00\xff\x01\x00\x05MLIFE\x06dayendBdayend 1 Copyright XXXX XXXXXXX XXXXXXX XXXXX XXX XXXXXX XXXXXXXX.'

f = StringIO(s)
print decode(f)
print decode(f)
print decode(f)

...収量...

['Total message length is 76 bytes', 'Tue Apr 23 05:00:43 2013', 10, 1, 255, 104, 'NGIN', 'MAIN', 'Product XX finished reprocessing cdc XXXXX at jesadr 0']
['Total message length is 99 bytes', 'Tue Apr 23 05:00:43 2013', 10, 1, 255, 70, 'CSSPRD', 'liab_checker', 'Checkpointed to XXXXXXXXXXXXXXXX:XXXXXXX.XXX at jesadr 0 (serial 0)']
['Total message length is 91 bytes', 'Tue Apr 23 05:00:44 2013', 10, 0, 255, 1, 'MLIFE', 'dayend', 'dayend 1 Copyright XXXX XXXXXXX XXXXXXX XXXXX XXX XXXXXX XXXXXXXX.']

タイムスタンプが 5 時間ずれているので、タイムゾーンの問題だと思います。

于 2013-04-25T19:32:21.923 に答える
0

これまでのところ、バイナリ ストリームではなくコードをリバース エンジニアリングしただけなので、私はあなたの挑戦の専門家とは言えません。しかし、私はあなたの問題にどのように対処しようとするかについて私の考えを共有したいと思います. たぶん、誰かがそれが役に立つと思うかもしれません(私はいつか一人でいるかもしれません)。

TL;DR 関連の教育ビデオ: Harald Welte at 27C3

ロードマップ

1. 文脈

プログラム (プログラミング言語、既知のシリアライザー/シリアライゼーション形式、既知の癖など)、ドメイン、その領域の仕様などについて、できるだけ多くの情報を入手してください。

2. コレクション

ストリームの十分な長さの部分を収集するか、メッセージがどのように見えるか (メッセージの開始/メッセージの終わりのマーカー) がわかっている場合は、適切なメッセージの束を収集します。参照プログラムの対応する出力も収集します。

3. 簡単な成果

ワイヤ プロトコルと対応する出力の両方で簡単に見つけられる文字列と数字を特定するようにしてください。どの部分がよく理解されていないかを書き留めます。

4. 目を開けたままにする

ワイヤ プロトコルのメッセージ全体で繰り返しや違いを探して、知識を広げてください。それらの「興味深いスポット」を、記録された出力の繰り返しと違いに一致させるようにしてください。

5.仮説

知っていることに基づいて、ワイヤ形式に関する仮説を作成します。特に、何が起こっているのかを助ける可能性のあるステップ 1 の情報を考慮に入れてください。また、タイムスタンプ、シーケンス番号、チェックサム、メッセージ ヘッダー、メタデータなどについて考えてみてください。

6. 検証

仮説をコードに実装します。記録したデータ セットに対して実行し、期待どおりに動作することをテストします。次に、あなたの仮説を裏付けるために、新鮮なサンプルの (おそらくもっと長い) 束 (これまでに見たことがないもの) と比較します。何かが失敗した場合は、手順 5 に戻ります。

7. やり直す

必要なすべての情報を抽出できるまで、必要に応じて上記の手順を繰り返します。

閉会の辞

ワイヤ プロトコルの理解が正しいという確信を得るために、集中的にテストすることをお勧めします。これには、A) 新しい仮説のテスト中に壊れやすいコードで問題が発生していないことを確認するための単体テスト、および B) 検証ステップで述べたように、コードに新しいサンプルをスローし、期待どおりであることを確認することが含まれます。

しかし、それでも、あなたは間違っているかもしれません。徹底的なテストを行ったとしても、これは仮定が正しいことを保証するものではありません。非常に明確に見えたことが実際にはまったく異なることが判明する可能性があるため、常に新しい方法で考える準備をしてください。

必要に応じて、ワイヤ形式に隠されている可能性のあるものや、物事がどのように配置および/または関連しているかについて、熱狂的に考えてください。

私のこのおそらく役に立たないテキストの後に、動画で締めくくらせてください: Harald Welte at 27C3の実世界の RFID 支払いシステムのリバース エンジニアリングについて。

于 2013-04-25T20:40:11.553 に答える
0

構造体を使用するのは正しいと思いますが、構造体についてひどいのは、元の構造を常に知っておく必要があるということです。

たぶん、tcp の仕様と isos を読むことはすべてを助けるでしょうが、それでもそれを理解するのは大変な時間になるでしょう :/

于 2013-04-25T18:45:19.697 に答える