4

私は最近 python を学ぼうとしていますが、それがどのように機能するかを正確に理解するのに苦労しているものに出くわしました。主にリストのデザインです。

問題のリストは、単純なファジングツールについて説明している次のセキュリティ記事からのものです。2 秒で.aspx

問題の実際のリストは次のとおりです。

#Negotiate Protocol Request
packet = [chr(int(a, 16)) for a in """
00 00 00 90
ff 53 4d 42 72 00 00 00 00 18 53 c8 00 00 00 00
00 00 00 00 00 00 00 00 ff ff ff fe 00 00 00 00
00 6d 00 02 50 43 20 4e 45 54 57 4f 52 4b 20 50
52 4f 47 52 41 4d 20 31 2e 30 00 02 4c 41 4e 4d
41 4e 31 2e 30 00 02 57 69 6e 64 6f 77 73 20 66
6f 72 20 57 6f 72 6b 67 72 6f 75 70 73 20 33 2e
31 61 00 02 4c 4d 31 2e 32 58 30 30 32 00 02 4c
41 4e 4d 41 4e 32 2e 31 00 02 4e 54 20 4c 4d 20
30 2e 31 32 00 02 53 4d 42 20 32 2e 30 30 32 00
""".split()]

彼は、次の行を使用して、そこから 1 バイト (だと思いますか?) を取り出します。

what = packet[:]
where = choice(range(len(packet)))
which = chr(choice(range(256)))
what[where] = which

私はこのように設計されたリストを見たことがありません。私を最も混乱させているのはpacket = [chr(int(a, 16)) for a in """、コメントブロックのように見えるものにすべてのものを収容している.split(). 0_o

これが漠然とした質問であることは承知していますが、誰かが私にこれを説明してくれるか、リスト作成のスタイルを説明するドキュメントの方向性を教えてくれたら、私は非常にうれしいです. これは、大量のバイトを格納/引き出すための非常に効率的な方法のようです。

4

5 に答える 5

10

これ

"""
00 00 00 90
ff 53 4d 42 72 00 00 00 00 18 53 c8 00 00 00 00
00 00 00 00 00 00 00 00 ff ff ff fe 00 00 00 00
00 6d 00 02 50 43 20 4e 45 54 57 4f 52 4b 20 50
52 4f 47 52 41 4d 20 31 2e 30 00 02 4c 41 4e 4d
41 4e 31 2e 30 00 02 57 69 6e 64 6f 77 73 20 66
6f 72 20 57 6f 72 6b 67 72 6f 75 70 73 20 33 2e
31 61 00 02 4c 4d 31 2e 32 58 30 30 32 00 02 4c
41 4e 4d 41 4e 32 2e 31 00 02 4e 54 20 4c 4d 20
30 2e 31 32 00 02 53 4d 42 20 32 2e 30 30 32 00
"""

単なる複数行の文字列です。

"""
00 00 00 90
ff 53 4d 42 72 00 00 00 00 18 53 c8 00 00 00 00
""".split()

上記の文字列のスペースで分割を生成します。

['00', '00', '00', '90', 'ff', '53', '4d', '42', '72', '00', '00', '00', '00', '18', '53', 'c8', '00', '00', '00', '00']

この:

[chr(int(a, 16)) for a in ['00', '00', '00', '90', 'ff', '53', '4d', '42', '72', '00', '00', '00', '00', '18', '53', 'c8', '00', '00', '00', '00']]

は、形成されたリストを調べて、 each に適用されるすべての値を変換するリスト内包表記です。chr(int(a,16))a

int(a,16)16 進数の文字列表現を含む文字列を に変換しますint

chrこの整数を char に変換します。

結果は次のとおりです。

>>> [chr(int(a, 16)) for a in ['00', '00', '00', '90', 'ff', '53', '4d', '42', '72', '00', '00', '00', '00', '18', '53', 'c8', '00', '00', '00', '00']]
['\x00', '\x00', '\x00', '\x90', '\xff', 'S', 'M', 'B', 'r', '\x00', '\x00', '\x00', '\x00', '\x18', 'S', '\xc8', '\x00', '\x00', '\x00', '\x00']
于 2012-05-14T19:44:42.107 に答える
2

それを分解して、読みやすくするために単純化してみましょう。

    bytes = """
            00 00 00 90
            ff 53 4d 42 72 00 00 00 00 18 53 c8 00 00 00 00
            00 00 00 00 00 00 00 00 ff ff ff fe 00 00 00 00
            00 6d 00 02 50 43 20 4e 45 54 57 4f 52 4b 20 50
            52 4f 47 52 41 4d 20 31 2e 30 00 02 4c 41 4e 4d
            41 4e 31 2e 30 00 02 57 69 6e 64 6f 77 73 20 66
            6f 72 20 57 6f 72 6b 67 72 6f 75 70 73 20 33 2e
            31 61 00 02 4c 4d 31 2e 32 58 30 30 32 00 02 4c
            41 4e 4d 41 4e 32 2e 31 00 02 4e 54 20 4c 4d 20
            30 2e 31 32 00 02 53 4d 42 20 32 2e 30 30 32 00
            """
    packet = [chr(int(a, 16)) for a in bytes.split()]

bytesは文字列であり、"""通常はPython docstringに使用されますが、コードで使用して非常に長い文字列を作成できます(ただし、コードに余分なスペースが含まれるため、文字列はやや面倒です。

bytes.split()空白で分割され、スペースで区切られた文字列の個々の部分のリストを返します。

print bytes.split()

['00', '00', '00', '90', 'ff', '53', '4d', '42', '72', 
 '00', '00', '00', '00', '18', '53', 'c8', '00', '00' ... ] # and more

だからこれ:

packet = [chr(int(a, 16)) for a in bytes.split()]

これはリスト内包表記です:

  • 上記のように分割bytesしてそのリストを取得します
  • リスト内の各要素(aここ)に対して実行int(a,16)します。これにより、基数16から10進数への変換を実行して整数値を取得します(つまりFF255)。
  • 次にchr、その値を実行します。これにより、そのバイトのASCII値が返されます。

したがってpacket、ASCII形式のバイトのリストになります。

print packet
['\x00', '\x00', '\x00', '\x90', '\xff', 'S', 'M', 'B', 'r', '\x00', '\x00', '\x00',
 '\x00', '\x18', 'S', '\xc8', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', 
 '\x00', '\x00', '\x00', '\x00', '\x00', '\xff', '\xff', '\xff', '\xfe', '\x00', 
 '\x00', '\x00', '\x00', '\x00', 'm', '\x00', '\x02', 'P', 'C', ' ', 'N', 'E', 'T', 
 'W', 'O', 'R', 'K', ' ', 'P', 'R', 'O', 'G', 'R', 'A', 'M', ' ', '1', '.', '0', 
 '\x00', '\x02', 'L', 'A', 'N', 'M', 'A', 'N', '1', '.', '0', '\x00', '\x02', 'W', 'i', 
 'n', 'd', 'o', 'w', 's', ' ', 'f', 'o', 'r', ' ', 'W', 'o', 'r', 'k', 'g', 'r', 'o', 
 ... more ]
于 2012-05-14T19:49:42.403 に答える
2

   """
content
"""

format は、Python で複数行の文字列リテラルを定義する簡単な方法です。これはコメント ブロックではありません。

[chr(int(a, 16)) for a in "00 00 00...".split()]リスト内包表記です。大きな文字列は配列に分割され (スペースで分割されます)、配列内の各項目について、それを 16 進数に変換し (int(a,16)文字列 a を int に変換することを意味し、文字列 a は基数 16 です)、その ascii を返します。chr(...)その整数で表されるchar ( )。

packet[:]listの浅いコピーを返しますpacket

choice(range(len(packet)))パケットの長さの範囲で乱数を返します。

chr(choice(range(256)))範囲 0,255 の乱数を選択し、それを ascii char として解釈し、最後のステートメントでその ascii char をランダムに選択された場所に挿入します。

于 2012-05-14T19:44:01.140 に答える
1

You're running into a couple different concepts here. Just slowly work backwards and you'll figure it out.

The """00 00 00 90 ff 53 4d 42 72 00 00 00 00 18 53 c8 00 00 00 00""" stuff is just a big string. The .split on it breaks it into an array on the spaces, so at that point you have something like ['00', '00', '00', '90' ....]

The rest of that line is a list comprehension -- its a fancy way of doing this:

new_list = []
for a in that_list_we_split_above:
    new_list.append( chr( int(a, 16) ) )

the int function is converting the string to an int in base 16 - http://docs.python.org/library/functions.html#int

the chr function is then getting the ascii character using that number

so at the end of all that nonsense you have a list 'packet'

the line defining where takes the length of that list, creates a new list with every number from 0 to the length (ie, every possible index of that), and randomly selects one of them.

the line for which picks a random int between 0 and 256 and gets the ascii character for it

the last line replaces the item in the packets list at the 'where' index with the random ascii character defined in which

tl;dr: go find different code to learn on - this is both confusing and uninspired

于 2012-05-14T19:47:52.607 に答える
0

問題のコードサンプルは、元のパケットでランダムに選択されたバイトを別のランダムなバイトに置き換えているようです(これはファジングの背後にあるアイデアの1つだと思います)。

packet = [chr(int(a, 16)) for a in """
 00 00 00 90 .... """.split()]

これは「文字列を空白で分割し、サブ文字列を16進数の整数からデコードされた文字として読み取ります(intの2番目の引数はベースです)。

what = packet[:]

packet「配列をにコピーする」のPythonイディオムwhat

where = choice(range(len(packet)))

パケット内のランダムなインデックスを選択します。

which = chr(choice(range(256)))

ランダムなキャラクターを作ります。

what[where] = which 

以前に選択したインデックスに置き換えます。

于 2012-05-14T19:48:37.487 に答える