成功提取zip后如何杀死多进程池?

时间:2019-02-05 22:29:38

标签: python multiprocessing pool kill-process

我已经写了一个.zip暴力破解程序,但我相信它会继续/试图找到密码,即使它已经找到(密码存储在Program.py -z zipname.zip -f filename.txt所调用的.txt中

我不确定一旦找到密码就如何停止程序并暂停该池。主要是因为我正在使用multiprocessing.Pool。我的代码如下:

import argparse
import multiprocessing
import zipfile

parser = argparse.ArgumentParser(description="Unzips a password protected .zip", usage="Program.py -z zip.zip -f file.txt")
# Creates -z arg
parser.add_argument("-z", "--zip", metavar="", required=True, help="Location and the name of the .zip file.")
# Creates -f arg
parser.add_argument("-f", "--file", metavar="", required=True, help="Location and the name of the file.txt.")
args = parser.parse_args()


def extract_zip(zip_filename, password):
    try:
        with zipfile.ZipFile(zip_filename, 'r') as zip_file:
            zip_file.extractall('Extracted', pwd=password)
            print(f"[+] Password for the .zip: {password.decode('utf-8')} \n")
    except:
        # If a password fails, it moves to the next password without notifying the user. If all passwords fail, it will print nothing in the command prompt.
        pass


def main(zip, file):
    if (zip == None) | (file == None):
        # If the args are not used, it displays how to use them to the user.
        print(parser.usage)
        exit(0)
    # Opens the word list/password list/dictionary in "read binary" mode.
    txt_file = open(file, "rb")
    # Allows 8 instances of Python to be ran simultaneously.
    with multiprocessing.Pool(8) as pool:
        # "starmap" expands the tuples as 2 separate arguments to fit "extract_zip"
        pool.starmap(extract_zip, [(zip, line.strip()) for line in txt_file])


if __name__ == '__main__':
    main(args.zip, args.file)

现在,file.txt通常有数百行到数千行(所谓“千我实际上是数千”,例如300k或1500k)。密码随处可见;从第一行到最后一行。一旦确定密码,我不确定如何实施/放置此“握手”。我曾考虑过使用break,但是在我使用multiprocessing.Pool时这似乎是不正确的,而且如果我将其放在print()中的try/except之后,它将得到outside loop错误。

我确实看到了this线程,但不确定是否适用于我的实例;因为我不确定如何表达“找到密码”并将event/Event传递给def extract_zip(zip_filename, password)

任何帮助或指导将不胜感激!

1 个答案:

答案 0 :(得分:0)

执行此操作的一种方法是使用Queue(或在进程之间发出信号的其他方法)。

要给我们Queue,请在创建main之前在Queue中添加行以创建Pool

m = multiprocessing.Manager()
q = m.Queue()

这为您提供了可共享的Queue,可以将其传递给池进程。将q添加到传递给extract_zip()方法的参数中。然后修改您的extract_zip()方法以使用q

def extract_zip(zip_filename, password, que):
    try:
        with zipfile.ZipFile(zip_filename, 'r') as zip_file:
            zip_file.extractall('Extracted', pwd=password)
            print(f"[+] Password for the .zip: {password.decode('utf-8')} \n")
            que.put('Done')    # signal success
    except:
        # If a password fails, it moves to the next password without notifying the user. If all passwords fail, it will print nothing in the command prompt.
        pass

您将需要使用asyncStarMap。因此,您的main方法如下:

def main(zip, file):
    if (zip == None) | (file == None):
        # If the args are not used, it displays how to use them to the user.
        print(parser.usage)
        exit(0)
    # Opens the word list/password list/dictionary in "read binary" mode.
    txt_file = open(file, "rb")

    # create a Queue
    m = multiprocessing.Manager()
    q = m.Queue()

    # Allows 8 instances of Python to be ran simultaneously.
    with multiprocessing.Pool(8) as pool:
        # "starmap" expands the tuples as 2 separate arguments to fit "extract_zip"
        pool.starmap_async(extract_zip, [(zip, line.strip(), q) for line in txt_file])
        pool.close()
        q.get(True)    # wait for a process to signal success
        pool.terminate()    # terminate the pool
        pool.join()

您可以在timeout上添加q.get()来处理找不到密码的情况。