你能帮我吗?
-避免程序在~16000次置换后挂起,
-如果找到解决方案(参见输出),
-给我一些建议,让我的代码变得更好、更快,并学习更多关于python的知识?在
我试着用暴力破解我真正的密码容器,因为我忘了密码。我还记得单词,但我忘了组合词。所以我想到了这个剧本。在
它应该怎么做?我给它一个单词表,它应该a)建立所有的排列和b)尝试如果它找到正确的一个。因为我在Windows7上工作,所以我使用True Crypt命令行界面进行尝试,我通过python子进程访问它。在
在写了一个single threaded version之后,我想让它更快一些。我首先尝试了多个线程,然后找到了GIL并使用了多处理。对我来说,这是一次学习经验,我以前从未使用过Python,只知道Java和PHP。我以前从没做过并行编程。在
代码:
import subprocess, os, sys, time, multiprocessing, Queue, itertools
wordlist = [
"foo",
"bar",
"zoo",
"hello",
"World",
]
tcFile = r"C:\dev\tc-brute-force\test.pa"
tcProg = r"C:\Program Files\TrueCrypt\TrueCrypt.exe"
tcMountLetter = "z"
verbose = 5 # as higher as more output is shown fatal=0-5=trace
counter = 0
numberofworkers = multiprocessing.cpu_count()*2
curenttime = time.time()
def getDuration(starttime):
return time.time() - starttime
def callTC(password, event):
commandArgs = [
tcProg,
'/a',
'/s',
'/q',
'/v', tcFile,
'/l', tcMountLetter,
'/p', password,
]
child = subprocess.Popen(commandArgs, \
stderr=open(os.devnull, 'w'), \
stdout=open(os.devnull, 'w'))
result = child.communicate() # Really important to get error code!
if verbose > 4:
print subprocess.list2cmdline(commandArgs).rstrip() + \
" Status out=" + str(result[0]) + \
" err=" + str(result[1]) + \
", code=" + str(child.returncode)
if child.returncode == 0:
event.set()
print "Successfully opened TrueCrypt file with '%s' at iteration %d, duration %.3fs" % (password, counter, getDuration(curenttime))
def callTCDaemon(queue, event):
while True:
if queue.empty():
break
else:
password = queue.get()
callTC(password, event)
if __name__ == '__main__':
manager = multiprocessing.Manager()
event = manager.Event()
worker = manager.Queue(numberofworkers)
# start processes
pool = []
for i in xrange(numberofworkers):
process = multiprocessing.Process(target=callTCDaemon, args=(worker, event))
process.start()
pool.append(process)
# generate permutations
for x in xrange(1, (len(wordlist)+1) ):
for permutation in itertools.permutations(wordlist, x):
# shutdown if result is found
if event.is_set():
# wait till finished
for p in pool:
p.join(2)
print "Finished TrueCrypt brute-force, after %d attempts, duration %.3fs" % (counter, getDuration(curenttime))
sys.exit(1)
counter += 1
combination = ""
# build string from permutation
for i in range(0, len(permutation)):
combination += permutation[i]
# output progress
if verbose == 4 and counter%100 == 0:
print "%15d|%15.3fs: %s" % (counter, getDuration(curenttime), combination)
# avoid queue overload
while worker.qsize() > 100:
if verbose > 3: print "Wait because queue is full, size=%d" % (worker.qsize)
time.sleep(4)
worker.put(combination)
输出示例(稍作修改):
^{pr2}$
暴力代码有三个主要部分:
生成密码
产生所有可能的排列:
检查密码
看TRUECRYPT EXPLAINED。也许您不需要为每个密码生成一个子进程。在
^{pr2}$同时检查多个密码
除了生成TrueCrypt命令行的
true_crypt_command()
函数外,它是完整的源代码。在另一个代码示例:Brute force http basic auth。在
如果您在
break
之后立即退出程序,那么OS会自动杀死所有剩余的线程(它们是守护进程线程,因此它们将无法生存)。在如果您的程序在循环之后继续运行,那么最多可以继续运行20个线程(池的大小)。如果取消注释
pool.join()
,则可以等待它们结束。在相关问题 更多 >
编程相关推荐