Bluetooth Flooder per Symbian – 24/08/2009
Questa applicazione è stata creata da me per puro scopo didattico. Dovevo imparare ad utilizzare il bluetooth in Python e ho finito per creare questa simpatica applicazione.
Descrizione:
Una volta selezionato un file presente sul vostro cellulare, BT Flooder tenterà di inviarlo a tutte le periferiche bluetooth che sono nei paragi, tenendo una conta delle vittime che accettano il vostro file.
L’applicazione può essere utile per inviare un’immagine, magari un vostro sticker o una foto che volete condividere con tutti, oppure una semplice nota testo contenente un messaggio, un indirizzo di un sito internet, o qualsiasi cosa vi venga in mente.
L’applicazione supporta inoltre un filtro che permette di esonerare determinate periferiche dall’assillante invito a ricevere un file, e una funzione di logging, tramite la quale potrete conoscere, al termine dell’esecuzione, tutte le periferiche che hanno accettato il vostro file.
BT Flooder è stato scritto in Python, quindi necessita (ovviamente) che l’interprete sia installato sul vostro cellulare. Oltre a questo l’applicazione fa uso del modulo esterno LightBlue, necessario per cercare periferiche bluetooth silenziosamente. Il file di installazione è scaricabile a questo indirizzo, e va installato nella memoria interna, non sulla memory card.
– Download BT Flooder (versione .sis) –
– Download BT Flooder (versione .py) –
– Download modulo LightBlue –
Aggiornamento – 24/08/2009
Ho aggiornato l’applicazione perché presentava un bug nella codifica UTF-8. Non era infatti possibile selezionare periferiche e file con caratteri non-ASCII.
Segue il codice sorgente dell’applicazione.
import os import e32 import sys import socket import appuifw import globalui import graphics try: import lightblue except: appuifw.note(u'Modulo lightblue non trovato.', 'error') if appuifw.query(u'Scaricare il modulo richiesto?', 'query'): url = 'http://lightblue.sourceforge.net/#downloads' browser = 'BrowserNG.exe' e32.start_exe(browser, ' "4 %s"' % url, 1) sys.exit() #Variabili log_file = u'C:\\bt_flooder_log.txt' log_ok = False accept = 0 #Persone che accettano attemp = 0 #Tentativi di invio filtro = [] #Filtro di MAC devices = () #Periferiche obj = u'Nessuno' #File selezionato file_ok = False status = u'Flooder in pausa.' #Stato flooder #Draw PAD = 5 #Padding TXT = (0, 0, 0) #Colore testo VAL = (255, 0, 0) #Colore valore STATUS = (0, 200, 0) #Colore stato applicazione ABOUT = (180, 180, 180) #Colore about BACKGROUND = (240, 255, 255) MRG = 25 #Margin FONT_T = (None, 20) FONT_V = (None, 20, 1) def draw(r=None): """Disegna la schermata di stato""" global devices, status, attemp img.clear(BACKGROUND) #File oggetto img.text((PAD, MRG), u'File:', fill = TXT, font = FONT_T) X = img.measure_text(u'File: ', font = FONT_T)[1] img.text((PAD + X, MRG), u'%s' % obj[obj.rfind('\\')+1:], fill = VAL, font = FONT_V) #Log attivo/disattivo img.text((PAD, MRG * 2), u'Log:', fill = TXT, font = FONT_T) X = img.measure_text(u'Log: ', font = FONT_T)[1] img.text((PAD + X, MRG * 2), (log_ok and u'Attivato' or u'Disattivato'), fill = VAL, font = FONT_V) #Vittime che accettano img.text((PAD, MRG * 3), u'Vittime:', fill = TXT, font = FONT_T) X = img.measure_text(u'Vittime: ', font = FONT_T)[1] img.text((PAD + X, MRG * 3), u'%d' % accept, fill = VAL, font = FONT_V) #Tentativi di invio file img.text((PAD, MRG * 4), u'Tentativi invio:', fill = TXT, font = FONT_T) X = img.measure_text(u'Tentativi invio: ', font = FONT_T)[1] img.text((PAD + X, MRG * 4), u'%d' % attemp, fill = VAL, font = FONT_V) #Periferiche bluetooth nei paragi img.text((PAD, MRG * 5), u'Periferiche BT:', fill = TXT, font = FONT_T) X = img.measure_text(u'Periferiche BT: ', font = FONT_T)[1] img.text((PAD + X, MRG * 5), u'%d' % len(devices), fill = VAL, font = FONT_V) #Stato applicazione img.text((PAD, MRG * 6), status, fill = STATUS, font = FONT_V) #About img.text((PAD, MRG * 7 + 20), u'Created by Ale152', fill = ABOUT, font = FONT_T) img.text((PAD, MRG * 8 + 20), u'www.Wirgilio.it', fill = ABOUT, font = FONT_T) c.blit(img) #Canvas c = appuifw.Canvas(redraw_callback = draw) img = graphics.Image.new(c.size) appuifw.app.body = c def list(path): """Lista una directory e restituisce un file selezionato""" #Torna indietro if path.endswith('\\..'): #Mostra dischi if path in ['C:\\\\..', 'E:\\\\..']: files = ['C:', 'E:'] path = '' #Mostra directory precedente else: path = path[:path.rfind('\\\\..')] #Elimino il \\.. dal path path = path[:path.rfind('\\')] #Elimino l'ultima dir dal path #Listo la dir files = os.listdir(path) files.sort() files[0:0] = ['\\..'] #Lista directory elif path: files = os.listdir(path) files.sort() files[0:0] = ['\\..'] ufiles = [i.decode('utf-8') for i in files] #appuifw richiede unicode try: selected = files[appuifw.selection_list(ufiles, 1)] #1 abilita ricerca except: #Nessun file selezionato pass #Se hai selezionato E: non deve restituire \E: ! return path and path+'\\'+selected or selected def select_file(): """Seleziona un file da inviare alle vittime""" global log_ok, file_ok, obj appuifw.note(u'Selezionare un file da inviare alle vittime.') file_ok = False #File non selezionato path = 'C:\\\\..' #Torna indietro ai dischi temp = list(path) while not file_ok: temp = list(temp) #Se è un file, restituisce l'indirizzo #Se è una cartella, la lista if os.path.isfile(temp): file_ok = True obj = temp.decode('utf-8') appuifw.note(u'File selezionato.', 'conf') draw() if log_ok: log.write('%s> file = %s\n' % (strftime('%H:%M:%S'), obj)) def logging(): """Attiva o disattiva il file di log""" global log_ok, log, strftime log_ok = globalui.global_query(u'Salvare un file di log?') if log_ok: log = file(log_file, 'a') from time import strftime log.write('\n\nSession starts on %s\n' % strftime('%H:%M:%S')) appuifw.note(log_file+' creato.', 'conf') #Chiede di attivare il logging all'avvio dell'applicazione logging() #***************** # Filtro # #***************** def filter(action): """Gestisce il filtro periferiche. Le periferiche nel filtro non verranno infastidite dal flooder""" global filtro #Aggiungi periferica if action == 'add': try: mac = socket.bt_obex_discover()[0] if mac: filtro.append(mac) appuifw.note(u'Periferica aggiunta.', 'conf') else: appuifw.note(u'Periferica non raggiungibile!', 'error') except: appuifw.note(u'Periferica non raggiungibile!', 'error') #Mostra periferiche elif action == 'show': if filtro: ufiltro = [i.decode('utf-8') for i in filtro] appuifw.selection_list(ufiltro) else: appuifw.note(u'Nessuna periferica nel filtro!', 'error') #Elimina periferiche elif action == 'del': if filtro: ufiltro = [i.decode('utf-8') for i in filtro] delete = appuifw.selection_list(ufiltro) filtro.remove(filtro[delete]) appuifw.note(u'Periferica rimossa.', 'conf') else: appuifw.note(u'Nessuna periferica nel filtro!', 'error') #About def about(): appuifw.query(u'BT Flooder created by Ale152.', 'query') appuifw.query(u'www.wirgilio.it', 'query') #***************** # Applicazione # #***************** def app(oper): global log_ok, file_ok, run, accept, obj, devices, status, attemp ## ## Run ## if oper == 'run': run = True #Seleziona un file come oggetto if not file_ok: select_file() while run: #Cerco periferiche nei paragi status = u'Cerco periferiche...' draw() try: devices = lightblue.finddevices() if log_ok: log.write('%s> %d devices found!\n' % (strftime('%H:%M:%S'), len(devices))) except SymbianError: appuifw.note(u'Bluetooth disattivato!', 'error') app('stop') break #Cerco i servizi offerti for device in devices: try: #Supporta obex? status = 'Verifico '+device[1]+'...' draw() #obex = (mac, {'srv':chan}) obex = socket.bt_obex_discover(device[0]) if obex and obex[0] not in filtro: status = device[1]+' supporta OBEX!' draw() canale = obex[1].items()[0][1] indirizzo = obex[0] if log_ok: log.write('%s> trying to send "%s" to %s (%s)...' % (strftime('%H:%M:%S'), obj, indirizzo, str(device[1]))) status = u'Provo ad inviare il file...' attemp += 1 draw() try: #Provo ad inviare il file socket.bt_obex_send_file(indirizzo, canale, obj) accept += 1 status = u'File inviato!' draw() e32.ao_sleep(1) if log_ok: log.write(' file sent! (%d)\n' % accept) except: if log_ok: log.write(' file refused!\n') status = u'File rifiutato :(' draw() except: #Non supporta obex. status = device[1]+' non supportato.' draw() e32.ao_sleep(0.01) ## ## Stop ## elif oper == 'stop': run = False status = u'Flooder in pausa.' draw() ## ## Quit ## elif oper == 'quit': run = False #Chiude il log se aperto if log_ok: log.write('%s> victims = %d' % (strftime('%H:%M:%S'), accept)) log.write('\nSession ends on %s\n\n' % strftime('%H:%M:%S')) log.close() lock.signal() appuifw.app.set_exit() #Appuifw appuifw.app.title = u'BT Flooder' appuifw.app.exit_key_handler = lambda: app('quit') appuifw.app.menu = [(u'Flooder', ((u'Avvia', lambda: app('run')), (u'Arresta', lambda: app('stop')), (u'Seleziona file', select_file)) ), (u'Filtro periferiche', ((u'Mostra', lambda: filter('show')), (u'Aggiungi', lambda: filter('add')), (u'Elimina', lambda: filter('del')) )), (u'File log', logging), (u'About', about), (u'Esci', lambda: app('quit'))] lock = e32.Ao_lock() lock.wait()