Xxd çıktısını shellcode'a dönüştürme


15

Xxd'den bazı çıktılar almak ve elle kullanılabilir kabuk koduna dönüştürmek eğlenceli değildir, bu yüzden işiniz süreci otomatikleştirmek.

kurallar

Gönderiniz bir işlev, lambda, senaryo veya bunların makul bir eşdeğeri olabilir. Sonucu yazdırabilirsiniz veya gönderiminiz bir işlev / lambda ise, bunu da geri verebilirsiniz.

Program ilk böyle bir dosya adı dışında hiçbir savları tamamen XXd çıktısını, ran içeren bir dize olmak üç argüman almalıdır: xxd some_file. İlk argümanın nasıl görüneceğine bir örnek:

00000000: 31c0 b046 31db 31c9 cd80 eb16 5b31 c088  1..F1.1.....[1..
00000010: 4307 895b 0889 430c b00b 8d4b 088d 530c  C..[..C....K..S.
00000020: cd80 e8e5 ffff ff2f 6269 6e2f 7368 4e58  ......./bin/shNX
00000030: 5858 5859 5959 59                        XXXYYYY

Baytları içeren orta bölümü (ondan sonraki ilk 8 sütun :) almanız ve herhangi bir boşluğu kaldırarak ve ardından \xher bir bayttan önce bir koyarak kabuk koduna dönüştürmeniz gerekir .

Yukarıdaki girdi için çıktı ne olmalıdır (diğer argümanları yok sayarak):

\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x4e\x58\x58\x58\x58\x59\x59\x59\x59

İlk bağımsız değişkenin her zaman geçerli bir xxd çıktısı olacağını ve dosya adından başka bir bağımsız değişken olmadan çalıştırıldığını varsayabilirsiniz.

Çıktınız ayrıca ters eğik çizgilerin gerçek ters eğik çizgi olduğu, çıkış karakteri olarak kullanılmadığı bir dize olmalıdır. "\ X65" derken 0x65 baytından, hatta "A" harfinden bahsetmiyorum. Kodda, "\ x65" dizesi olurdu.

İkinci argüman, xxd çıktısında shellcode'un nerede başlayacağını ve üçüncüsü nerede bitmesi gerektiğini belirtir. Üçüncü argüman ise -1, xxd çıktısının sonunda sona erer. İkinci ve üçüncü argümanlar da üçüncü olmayan zamanlar hariç her zaman negatif olmayacaktır.-1

İşte bazı test örnekleri:

Tartışma 1:

00000000: 31c0 b046 31db 31c9 cd80 eb16 5b31 c088  1..F1.1.....[1..
00000010: 4307 895b 0889 430c b00b 8d4b 088d 530c  C..[..C....K..S.
00000020: cd80 e8e5 ffff ff2f 6269 6e2f 7368 4e58  ......./bin/shNX
00000030: 5858 5859 5959 59                        XXXYYYY

Bağımsız değişken 2:, 7Bağımsız değişken 3: e(bunların her ikisi de onaltılık sayıları temsil eden dizelerdir)

Çıktı: \xc9\xcd\x80\xeb\x16\x5b\x31\xc0

Tartışma 1:

00000000: 31c0 b046 31db 31c9 cd80 eb16 5b31 c088  1..F1.1.....[1..
00000010: 4307 895b 0889 430c b00b 8d4b 088d 530c  C..[..C....K..S.
00000020: cd80 e8e5 ffff ff2f 6269 6e2f 7368 4e58  ......./bin/shNX
00000030: 5858 5859 5959 59                        XXXYYYY

Argüman 2:, 0Argüman 3:2e

Çıktı: \x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x4e

Tartışma 1:

00000000: 31c0 b046 31db 31c9 cd80 eb16 5b31 c088  1..F1.1.....[1..
00000010: 4307 895b 0889 430c b00b 8d4b 088d 530c  C..[..C....K..S.
00000020: cd80 e8e5 ffff ff2f 6269 6e2f 7368 4e58  ......./bin/shNX
00000030: 5858 5859 5959 59                        XXXYYYY

Argüman 2:, aArgüman 3:-1

Çıktı: \xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x4e\x58\x58\x58\x58\x59\x59\x59\x59

En az bayt olan kod kazanır. Kazanan, 15 Ağustos 2016'da yedi gün içinde ilan edilecektir (ancak daha sonra yapılan başvurular hala takdir edilmektedir).

Güncelleme

@Adnan'a meydan okuduğu için tebrikler !


Sadece açıklığa kavuşturmak için girdiler bir dize döndürebilir mi yoksa yazdırmalılar mı?
Ürdün

Bir dize döndürmek, bir işlev, lambda veya bunun gibi bir şey olduğu sürece iyidir (siz istedikten sonra bunu belirtmek için kuralları güncelledim).
addison

1
Kod yazdırılabilirken de normal ASCII kodlarını döndürebilir miyiz? Örneğin ~yerine \x7e. Ve \tbunun yerine geri dönebilir miyiz \x09?
orlp

@orlp Üzgünüz hayır, tutarlı bir biçimde olması gerekiyor.
addison

Bağımsız değişkenlerin onaltılık olması gerekiyor mu? Ayrıca, ikinci örneği verdiğiniz şekilde 7sıfır tabanlı bir dizine benziyor ve etek tabanlı bir dizin ( e-7=7ancak çıktınızda 8 onaltılı kod var), yoksa bir şey mi görüyorum?
Neil

Yanıtlar:


5

05AB1E , 39 38 bayt

Formdaki giriş:

arg2
arg3
arg1

Kod:

²\|vy9F¦}40£ðK}J2ô„\xì²H>²®Qi²}£¹HF¦}J

Açıklama:

²\                                       # Get the first two inputs and discard them.
  |                                      # Take the rest of the input as an array.
   vy         }                          # For each line...
     9F¦}                                #   Ten times, remove the first character.
         40£                             #   Only remain the substring [0:40].
            ðK                           #   Remove spaces.
               J                         # Join the string.
                2ô                       # Split into pieces of 2.
                  „\xì                   # Prepend a "\x" at each string.
                      ²H                 # Convert the second line from hex to int.
                        >                # Increment by one.
                         ²               # Push the second input again.
                          ®Qi }          # If equal to -1...
                             ²           #   Push the second input again.
                               £         # Take the substring [0:(² + 1)].
                                ¹H       # Convert the first input from hex to int.
                                  F¦}    # Remove that many characters at the beginning.
                                     J   # Join the array and implicitly output.

CP-1252 kodlamasını kullanır . Çevrimiçi deneyin! .


12

Bash + coreutils + xxd, 73 71 69 bayt

printf \\x%s `xxd -r|xxd -p -s0x$1 -l$[(e=1+0x$2)?e-0x$1:-1]|fold -2`

STDIN üzerindeki hexdump ve başlangıç ​​/ bitiş komut satırı bağımsız değişkenleri olarak beklenir.

Bu, varsayılan olarak izin verilen STDERR'a bazı uyarılar yazdırır.


1
Birinin xxdçözümlerinde gerçekten kullanmasını umuyordum !
addison

@ adddison denedim, ancak dilim komut satırı girdisinde yeni satırları desteklemiyor. : c
Addison Crump

Ben değiştirmek mümkün duyuyorum 16#ile 0x?
Dijital Travma

@DigitalTrauma Bunun bir xxdşey olduğunu düşündüm , ama her yerde çalışıyor gibi görünüyor.
Dennis

1
Evet, bash 0xnonaltılık stil ve 0msekizli stil sayılarını kutudan ayırır : gnu.org/software/bash/manual/bash.html#Shell-Arithmetic . echo $[0x2a] $[052].
Dijital Travma

5

JavaScript, 84 bayt

(s,f,t,u)=>s.replace(/.*:|  .*\n?| /g,'').replace(/../g,'\\x$&').slice(f*4,++t*4||u)

Açıklama: Dökümün tüm istenmeyen kısımlarını kaldırır, \xher bir hex çiftinin başına geçer , ardından sonucun istenen kısmını çıkarır. ||u, dizenin sonuna kadar dilim oluşturan sihirli bir değer olan -1parametrenin artırılmasıyla elde edilen sıfırı dönüştürmek için kullanılır . 101 bayt ise ve onaltılık basamak dizeleridir:undefinedsliceft

(s,f,t,u)=>s.replace(/.*:|  .*\n?| /g,``).replace(/../g,`\\x$&`).slice(`0x${f}`*4,t<0?u:`0x${t}`*4+4)

Bunun yerine, birkaç bayt kaydetmek için (s,f,t,u)=>yapabilirsiniz s=>f=>t=>u=>.
Ismael Miguel

@IsmaelMiguel Üzgünüz, sadece tam olarak iki gerçek parametreye sahip bir işlev için çalışıyor. Benim özel durumumda uek bir parametre olmalı ve curried olamaz.
Neil

@IsmaelMiguel Ayrıca bu aslında daha uzun ...
Jakob

5

Yakut: 90 89 87 79 63 bayt

@Addison sayesinde -2 bayt @PiersMainwaring
sayesinde -8 bayt

->s,x,y{'\x'+s.scan(/(?<=.{9})\w\w(?=.* )/)[x.hex..y.hex]*'\x'}

Repl.it ile ilgili testlere bakın: https://repl.it/Cknc/5


2 bayt kaydetmek için .joinile değiştirebilirsiniz *"".
addison

8 bayt daha kaydetmek için .map{|h|h.to_i(16)}ile değiştirebilirsiniz .map(&:hex)!
piersadrian

Teşekkürler @PiersMainwaring! Aptalca bunu unutmak için. Aslında beni kurtardı çünkü .hexargümanları tek tek çağırmanın daha kısa olduğu ortaya çıktı !
Ürdün

4

Jöle , 48 44 bayt

ØhiЀɠ’ḅ¥®L’¤Ạ?⁴‘
ṣ⁷ṫ€⁵ḣ€40Fḟ⁶s©2ḣ¢ṫ¢[“\x”]p

Bu, hexdump öğesinin tek komut satırı bağımsız değişkeni olmasını ve bu sırada STDIN'deki bitiş ve başlangıç ​​noktalarını satır besleme ile ayırarak bekler.

Çevrimiçi deneyin!


Bunun için bir açıklama görmek isterim;)
Conor O'Brien

Daha sonra ekleyeceğim, ama önce biraz golf oynamaya çalışacağım. 51 bayt Jelly ve 69 bayt Bash doğru olamaz ...
Dennis

3

PowerShell v2 +, 175 157 142 133 129 bayt

param($a,$b,$c)'\x'+(($z=$a-split"`n"|%{$_[10..48]-ne32-join''-split'(..)'-ne''})["0x$b"..(("0x$c",$z.count)[$c-eq-1])]-join'\x')

Girişi alır $a, $b,$c , ile $abir değişmez satır ayrılmış dizge ya veya PowerShell ile `nçizgileri ayıran karakter. Yardımcı dizeyi aşağıdaki gibi $zyoğun bir şekilde $aişledik -

İlk önce -splitsatırsonlarındayız, sonra her satır |%{...}için orta bölümü dilimliyoruz [10..48],-ne32 dilimliyor, boşlukları kaldırmak için , -joinonu tekrar uzun bir dizeye, -splither iki karaktere (iki karakteri koruyarak) ve -ne''boş öğeleri kaldırmak için kullanıyoruz. Bu, iki öğeli dizelerden oluşan bir diziyle sonuçlanır ('31','c0','b0'...).

Daha sonra $b, değerine kadar onaltılık işleç ile almayı temel alarak bu diziye dilim yaparız $c. Biz ister hesapları burada sahte ve üçlü kullanmaya gerek $colduğunu -1ya da değil. Eğer öyleyse, .countöğesinin (yani son elemanını) seçeriz $z. Aksi takdirde, 0xonaltılı işlecini $cbir dize içine ekleriz. Bunun sıfır indekslendiğini unutmayın.

Bu dizi diliminin öğeleri var -join , bir \xdize oluşturmak için bir değişmez değerle birlikte düzenlenir . Bu başka bir değişmezle başlıyor\x ve sonuç boru hattında bırakılıyor. Yazdırma kapalı.

Misal

PS C:\Tools\Scripts\golfing> .\xxd-output.ps1 "00000000: 31c0 b046 31db 31c9 cd80 eb16 5b31 c088  1..F1.1.....[1..
00000010: 4307 895b 0889 430c b00b 8d4b 088d 530c  C..[..C....K..S.
00000020: cd80 e8e5 ffff ff2f 6269 6e2f 7368 4e58  ......./bin/shNX
00000030: 5858 5859 5959 59                        XXXYYYY" a -1
\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x4e\x58\x58\x58\x58\x59\x59\x59\x59

Shell'e bu dilde erişebiliyor musunuz?
Addison Crump

@VTCAKAVSMoACE Teorik olarak, Linux için yeni Windows Alt Sistemi göz önüne alındığında, işleri bir araya getirmek ve / veya komut satırı aracılığıyla parametreleri aktarmak mümkün olmalıdır. Uygulama okuyucu için bir alıştırma olarak bırakılmıştır. ;-)
AdmBorkBork

2

Jöle , 39 38 37 bayt

ØhiⱮɠ’ḅ¥ȷ9Ṃ?⁴‘
Ỵṫ€⁵ḣ€40Fḟ⁶s2ṭ€⁾\xḣ¢ṫ¢

Çevrimiçi deneyin!

Şimdi 05AB1E'yi yeniyor! ("onaltılıktan dönüştür" yerleşik olmamasına rağmen)

Dennis'in çözümü ile aynı girdi biçimi .

Kullanım (kısaca yeni bir özelliktir, Ѐ). Onsuz, bu 38 bayt alacaktı.


Sadece 1e9'a kadar olan girişlerde çalışır.
user202729

Ancak FAT32'de ise (giriş boyutunun en fazla 2GB olduğu yerlerde) yeterlidir.
user202729

1

Perl, 114 bayt

($_,$a,$b)=@ARGV;s/^.*:|\S*$|\s//gm;@_=(m/../g);for(@_){s/^/\\x/}$"='';say substr"@_",4*$a,$b!=-1?4*($a+$b):2<<20;

Komut satırında tırnak içine alınmış bir dize olarak verilen bağımsız değişkenler ve ardından iki sayı. Sayılar ondalık olarak alınır (Onaltılık örneklerde kullanıldığını biliyorum, ancak gönderide belirtilmedi)

Teknik olarak perl'in alt dize yöntemi saçma olduğundan 2 ^ 21 bayta kadar olan girişlerde çalışır


Örneğin böylece Anlaşılan aralığı dahil bunlar 7için euzunluğu 32 bir dizi yol açmalıdır
Neil

1

Python, 140 bayt

lambda O,a,b:''.join(sum([['\\x'+x[:2],('','\\x')[len(x)>2]+x[2:]]for x in O.split()if len(x)<5],[])[int(a,16):(int(b,16)+1,None)[b=='-1']])

https://repl.it/ClB3

Orijinal dizeyi böler ve beş karakterden daha azsa, ekleri \xve ikinci ve üçüncü bağımsız değişkenlere göre dilimler içeriyorsa öğeleri döker .

Soru tarafından belirtilmeyen diğer çıktı türlerini işlememiz gerekirse 162 baytlık sürüm:

import re
J=''.join
def f(x,a,b):r=J(J(re.findall(':(.*?)  ',x)).split());print J(['\\x'+i+j for i,j in zip(r,r[1:])][::2][int(a,16):(int(b,16)+1,None)[b=='-1']])

Örneğin, son satır 00000030: 5858 58 XXXson kısmı çekeceğinden ve böyle bir şey alacağınızdan böyle bir şey değilse, bu işe yaramaz \x58\x58\x58\xXX\xX.
AdmBorkBork

@TimmyD Bu davanın ele alınması gerektiğini düşünmüyordum, bu da meydan okuma özelliklerinden yola çıkarak.
atlasologist

Verilen ilk argüman sadece bir örnek olduğu için meydan okumayı okudum, bu yüzden xxdargüman olarak kullanılan başka bir çıktı olabilir . "İşte ilk argümanın nasıl görüneceğine bir örnek:"
AdmBorkBork

0

Python 2 ve 3 - 164162145142134 bayt

Şimdi ikinci ve üçüncü argümanlar için onaltılık dizeleri kabul eder.

j=''.join
def f(a,b,c):s=j(x[10:49].replace(' ','')for x in a.split('\n'));print(j('\\x'+s[i:i+2]for i in range(int(b,16)*2,1+2*int(c,16)%len(s),2))

0

Python 3.5, 125 bayt

import re
lambda s,b,e:re.sub(r'(\w\w)',r'\\x\1',re.sub(r'^.*?:|  .*$|\s','',s,0,8)[2*int(b,16):[2*int(e,16)+2,None][e<'0']])

Ungolfed:

def f(s,b,e):
    b = 2*int(b,16)
    e = [2*int(e,16)+2,None][e<'0']
    x = re.sub(r'''(?v)   # verbose (not in golfed version)
            ^.*?:     # match begining of line to the ':'
           |  .*$     # or match '  ' to end of line
           |\s        # or match whitespace
           ''',
           '',        # replacement
           s,
           0,         # replace all matches 
           re.M       # multiline mode
           )
    y = re.sub(r'(\w\w)', # match pairs of 'word' characters
           r'\\x\1',  # insert \x
            x[b:e])
    return y
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.