用python写了一个检索题目信息(WP题目)与关键知识点的小工具

引言:一个工具之所以被开发出来,肯定是先有的需求,然后才去想办法开发。

这个程序能干什么?

这个程序可以帮你检索信息你可以把你的WP的题目存上来,然后再针对这个题目存一些你这个WP里的相关知识点。当你做了一道新的题目,需要去重温一下之前某个WP上的知识点,这时候你就可以用这个工具来进行检索了。比如你输入以前存的某一个关键点,这个程序就可以去检索到,这个知识点相关的所有题目,你也可以继续去输入知识点,来精准的查找到你的某个WP,当检索到之后,这个程序还可以帮你把这个WP顺便给运行了
程序效果如图

怎么使用这个程序?

​ ①如果你要是用我的源码的话(源码在最后),那就要自己用python去运行,然后把这个文件和你写的所有WP放在一个目录下面即可(不然程序是打不开WP的),然后先要存入每道题目和对应的关键词(这个还是要自己手动输入的)(这只是个检索的小工具),至于怎么存,运行一下程序应该就知道了。然后存的时候还会生成一个database.txt文件,你输入的数据就存储到这个文件里了,可千万不要不小心去删了(并且这个文件也要和search.py.py放在一个目录里面)

​ ②如果你使用的是我转换好的exe文件(文件在最后),那么是需要把WP放进dist里面的search文件夹里面

然后运行这个search.py.exe即可(不过里面的信息依然是要自己手动填写)

使用的注意事项:

1、由于本人目前实力有限,无法增加删除功能,需要手动删除,要想查看详情,请选择程序菜单中的4(这个程序菜单是进入程序里面之后选择4)
2、菜单功能中的1(进入程序之后选择的1),一旦进入,就必须要输入内容,不然会多出来一条分界线,这样对于之后的检索有可能出现问题,如果你这么做了,那么请看第四条。
3、如果是正常使用,还出现了检索问题,请去database.txt文件中,看一下存储的格式是否正确
4、database.txt正确格式为一条分界线(分界线就是10个_),然后题目,然后是关键词,每个内容都是独占一行,如果不是这个格式,请去database.txt里面手动改一下(只要是正常使用,就应该不会出现格式问题,至少我现在还没遇见过)
5、并且database.txt文件内容的最后结尾是没有分界线的
6、所有的信息都会被存储在database.txt文件中,该文件绝对不可以被删除
7、本程序一定要与WP的文件放在一个目录中,不然是没办法运行WP的

为什么要写这个程序?

​ 本人刚刚开始学pwn,在刷题的时候,每次写过一道题,基本都会自己去写一下这道题的WP,起初刚写完的时候,还对里面的知识点记忆犹新,可是过了几天之后,知识点基本就忘的差不多了(如果点进去看的话,肯定扫一眼,就又想起来知识点了)但如果不点进去的话,基本光看题目,就不知道这个WP写的是什么,后来我去把每道题目的知识点,命名成WP的名字。WP少的时候还行,可是WP越来越多,即使每个题目上都写着知识点,再找的时候,也比较麻烦。于是乎,就有了想写个工具,来帮我检索信息的想法。

​ 因为前一段时间花了将近一个星期的时间去学习python,因此这里就想着去用python去来开发这个程序。

声明:

​ 本人是初学python(就学了不到一个星期...),并且能力有限,因此如果程序使用中出现了bug,欢迎大家与我联系,我会尽力修复。并且这个程序我还有四个想法,鉴于目前能力有限,无法写出来。它们分别是

①增加一个删除指定信息的功能

②增加一个修改指定信息功能(如果①实现的话,那么②应该指日可待了)

③增加一个图形化界面,这个应该是比较难的,但如果可以的话,谁想面对一个黑漆漆的程序窗口呢

④增加一个模糊搜索功能,针对关键词而已,如果我们记得不太清楚了,五个字的栈迁移原理,我们输入成了栈迁移就无法被检索出来,这个模糊功能我是想让它实现输入一部分的字,也可以检索出来我们要找的关键字

如果大家有思路,并且想与我共同完成这个程序剩下功能的开发,那么我是十分欢迎您与我联系的。

源代码

代码写的很烂...请见谅。

# -*- codeing = utf-8 -*-
# @Time : 2022/1/20 15:49
# @Author : ZIKH
# @File : search.py
# @Software : PyCharm
import os
import sys


def create_contents():  # 该函数用于存入题目以及关键词
    fd = open('database.txt', 'a')  # 加换行是因为每一行只存储一个信息
    fd.write('__________\n')
    title = input('请输入题目\n')
    fd.write(title + '\n')
    key_word = '1'                  #初始化这个变量
    while True:
        key_word = input('每次请输入一个关键词然后按下回车,输入q则代表存储完毕\n')
        if key_word == 'q':
            fd.close()
            break
        fd.write(key_word + '\n')
    fd.close()


def search_add_keyword(list, add_word):  # 经过第一次筛选之后,再添加关键词,则进入本函数
    # list为第一轮筛选关键词之后符合题目的列表
    # add_word为添加的关键词
    for title in list.copy():  # 遍历每一个存在列表中的元素
        fd = open('database.txt', 'r')
        flag = 0  # flag为1表示在这个题目中找到了新加关键词,为0代表没找到
        ret = 0  # ret为1用来结束第二个循环
        while True:  # 一直读,直到遇见当前的content,再进行判断
            content = fd.readline()
            if not content:
                break
            if title == content:
                while True:
                    content = fd.readline()
                    if content == '__________\n':  # 这个循环本就是搜寻当下题目的关键字,如果在到达下个题目之前,没找到,那就退出
                        ret = 1  
                        break
                    if not content:  # 但如果题目正好是最后一个那么下面就没有分界线
                        break  # 因此需要加上这句
                    if add_word + '\n' == content:
                        flag = 1
                        break
                if flag == 1:
                    break
                if flag == 0:
                    list.remove(title)  # 当题目中没有要检索的新增关键词,那就删除列表中的元素
                if ret == 1:
                    break
        fd.close()
    return list


def title_search(target):  # 这个函数用于检索题目
    fd = open('database.txt', 'r')
    biaohao = 0  # 标号是给每个题目添加一个序号,便于下面函数运行该题目
    flag = 0
    while True:
        content = fd.readline()
        biaohao = biaohao + 1  # 只要每读一行的内容,就让标号+1
        if not content:
            break
        if content == '__________\n':  # 此时content的下一个就是题目
            content = fd.readline()  # 此时的content为题目
            biaohao = biaohao + 1
            if content == target + '\n':  # 此时检索到了要找寻的题目
                flag = 1  # 这个值用于判断是否,检索到数据库里的题目
                print('标号为' + str(biaohao) + '的' + target + '的关键知识点如下')
                while True:  # 开始打印这个题目对应的知识点
                    content = fd.readline()
                    biaohao = biaohao + 1
                    if not content:
                        break
                    if content == '__________\n':
                        break
                    print(content, end='')
                print('\n')  # 此处在关键词的结尾加一个换行,为了整洁
            else:
                pass
        else:  # 只要没有遇到__________,那就说明下一个不是标题,那就跳过
            continue
    if flag == 0:
        print('没有检索到您输入的题目,请您检查下是否输入了文件类型的后缀')
        print('程序将退出')
        fd.close()
        sys.exit(1)
    fd.close()


def print_title_word(titles):  # 打印当前列表中存储的题目
    for title in titles:
        title_search(title.strip())  # 进入title_search判断的时候会加上一个回车,因此这里要删掉本身的回车


def keyword_search(word):  # 检索关键词,把出现过的关键词对应的标题存入列表中
    fd = open('database.txt', 'r')
    titles = []  # 这个列表是用来储存具有要检索关键词的题目(这样的题目不唯一)
    flag = 0  # 所以要用列表来存储题目
    flag_panduan = 0  # 这个标志点用来检测程序是否检索到关键词
    while True:
        if flag != 1:  # 防止在这里读了两次,在下面的循环中已经读到__________了
            content = fd.readline()
            if not content:  # 如果读完了整个文件,那么就进行退出
                break
        flag = 0  # 让标志点重新归零,不然以后都进不来这个的if
        if content == '__________\n':  # 当发现__________之后,把下面的题目存储在head中
            content = fd.readline()
            head = content  # 只要接下来出现的word是被检索的,那就把这个head放进title列表
            continue  # 然后continue一次,目的为了是从关键词开始读
        if content == word + '\n':
            titles.append(head)
            flag_panduan = 1
            while True:  # head只要在列表里存储一次即可,该循环用于跳出这个题目下所有关键词
                content = fd.readline()
                if not content:
                    break
                if content == '__________\n':
                    flag = 1  # 设置标志点,不然刚进入大循环的时候,就会再读一次
                    break
    if flag_panduan == 0:
        print('未检测到关键词,请检查后输入')
        return
    print_title_word(titles)  # 第一轮检索完毕,打印列表中的题目,以及题目所属的关键词
    while len(titles) > 1:
        panduan = input('您是否需要继续输入关键词来筛选[Y/N]')
        if panduan == 'Y':
            add_word = input('请您继续输入关键词')
            titles = search_add_keyword(titles, add_word)
            print_title_word(titles)
        if panduan == 'N':
            print('您可以选择输入标题对应的标号,我可以帮您运行它')
            number = input('如果您不需要运行,请输入q,进行退出')
            if number == 'q':
                sys.exit(0)
            else:
                run(number)  # 运行对应的标号,在run函数里面,会对标号进行遍历
    print('您可以选择输入标题对应的标号,我可以帮您运行它')
    number = input('如果您不需要运行,请输入q,进行退出')
    if number == 'q':
        sys.exit(0)
    else:
        number = int(number)  # 如果这里不是q的话,就把输入的内容当做标号来处理
        run(number)  # 去运行标号对应的题目文件


def search():  # 检索信息时的交互函数
    panduan = input('如果您是搜索题目,请输入1,如果你是搜索关键词,请输入2\n')
    if panduan == '1':
        target = input('请输入您要搜索的标题,我将为您展示它的关键词')
        title_search(target)
    if panduan == '2':
        word = input('请输入您要搜索的关键词')  # word为要检索的关键词
        keyword_search(word)
    if panduan != '1' and panduan != '2':
        print('请输入有效数字,程序将退出')
        sys.exit(0)


def run(biaohao):  # 先检索到标号对应的题目,然后去运行该题目
    fd = open('database.txt', 'r')
    biaohao = int(biaohao)
    try:
        for i in range(biaohao):
            content = fd.readline()
    except :
        print('非法标号,请输入正确的标号')
        print('程序将退出')
        sys.exit(1)
    try:
        os.system(content)
    except :
        print('非法标号,请输入正确的标号')
        print('程序将退出')
        sys.exit(1)
    print('程序已经帮您运行')
    print('感谢您的使用')
    sys.exit(0)


def main():  # 主函数,用来交互
    print('欢迎使用本程序')
    while True:
        print('——————————————————————————————')
        print('如果您是要存入题目信息请输入1')
        print('如果您是要检索信息请输入2')
        print('如果您是要打开某道题目请输入3')
        print('如果您是要删除或者信息。请输入4')
        print('如果你想要退出,请输入q')
        print('——————————————————————————————')
        number = input()
        if number == '1':
            create_contents()
        elif number == '2':
            search()
        elif number == '3':
            program = input('您要运行的程序标号为')
            run(program)
        elif number == '4':
            delete_content()
        elif number == 'q':
            print('感谢使用')
            sys.exit(0)
        else:
            print('请输入有效数字,程序将结束')
            sys.exit(0)


def delete_content():
    print('鉴于本人目前实力有限,这部分的功能,暂且没办法用代码来实现')
    print('如果您需要删除题目,以及题目下的关键词,请去database.txt文件中手动删除')
    print('从题目上面的分界线(包括这个分界线)删除到题目下一个分界线(不包括这个分界线)即可')
    print('如果您要修改或删除某个题目的关键词,那么在database.txt文件中找到对应题目,删除或修改关键词即可')
    print('\n')


main()

代码中有很多的不足,如果您能与我联系并给予指正,我将感激不尽。

exe文件

生成的exe文件我上传到百度网盘了 网址https://pan.baidu.com/s/1djrHBytgDdtzNvu5O4iOXw?pwd=8nme 提取码8nme
使用的方法,上文也已经说明

程序的设计思路

​ 下面是写程序之前的预想思路和实际实现功能的思路,我做了一个对比,这个对比其实更多的还是给我自己看的,看下预想和实际的区别。

程序名称:WP的检索关键词小程序

程序功能:①去存入一个题目名称,和一些关键词
②进行检索(输入题目名称或者关键词,都可以检索出来对应的所有信息)(也可以输入多个关键词,来准确找出题目(同一个关键词可能对应多个题目))
③去运行这个检索到的wp

针对功能①

初期大体思路:
创建一个储存信息的数据库(用字典,键来存储题目名称,值用列表,来储存关键词)(这个数据库要存储到一个新的文件里)

实际大体思路:
把信息直接写到文件里面,不用字典,第一行写入题目,剩下的行依次写入关键词(一行一个)(用一条分界线(我用了十个_来表示)来划分题目)

针对功能②

初期大体思路
先对键进行遍历,每次检查一个键的时候,再对这个值(也就是列表)进行遍历,如果输入的内容与列表中的关键词相同,那么去把这个键存到一个新建的列表中,最后输出列表
中的内容。
如果要检索多个关键词,那就先对第一个关键词执行上一段的操作,然后把符合条件的题目都先放到列表中,然后再对第二个关键词执行操作(此时去遍历新建列表中的键的值)
然后不符合条件的删掉即可,如果还有关键词,就依旧同上操作。

实际大体思路:
如果搜索题目的话,那就去遍历文件的每一行,如果没有碰见分界线的话(分界线下面就是题目),那就继续直接跳到下一轮循环,去读入下一行内容。如果碰到分界线的话
那就去读入下一行的内容,去与要搜索的题目,进行对比,如果一样的话,那就去打印他们下面的每一行内容(这些内容都是关键词),直到读到下一个分界线,就停止
如果是搜索关键词的话,也是遍历文件的每一行,只不过用一个head变量来存储当前检索关键词的题目,如果找到了关键词,那就把这个题目存到一个列表里面
然后找完了所有具有关键词的题目,然后用for遍历整个列表,每从列表里拿出一个元素,就把这个元素当做参数去放到搜索题目的那个函数里面,去一次打印每个题目里的关键词

新增功能:检索完一次关键词之后,可能依然有很多的题目,这时候可以继续去检索关键词,以来筛选出,我们最想要的题目。具体实现是让文件从头开始跑一次
然后遇到列表中的题目,就去检索一下其中的关键词,如果发现了要找的关键词,则去检索列表的下一个题目,如果遍历完整个文件没有发现当前题目中具有新输入的关键词
那就将它从列表中 删除。依次来达到筛选的目的

针对功能③

初期思路:
得到题目之后,把题目当做路径,然后用函数直接运行题目的WP即可(要将本程序和题目的WP放在一起)

实际思路:
先创建一个标号的变量。从最开始,程序只要往下读一行,就会让标号+1,这样题目就有了属于自己的标号
然后让用户输入标号,输入完毕之后,直接进行循环(从头开始),每次循环就往下读一行,循环标号的次数,然后得到标号对应的题目,因为文件名就是题目,因此
用os.system()直接调用这个题目即可

强化功能(未完成):如果关键词是 shellcode的构造及利用 那么我希望在检索的时候只输入一个shellcode,也能让找到shellcode的构造及利用这个关键词对应的题目
针对这个功能,暂时还没有什么思路

写程序的时候,有一些新发现:

list = [1,2,3,4,5,6,7,8,9,10]
for i in list:
    list.remove(i)
print(list)

你认为这个最后的结果会是什么

没错,结果并不是[],这是为什么呢?

因为当第一次循环的时候是要把下标为0的元素删掉,因此删掉了1,然后第二次循环的时候.本应该是删除下标为1的元素了。可此时的列表已经是2,3,4,5,6,7,8,9,10,因此在删掉下标为1的元素的时候(这里说删掉其实有点不合适,更准确的应该说是在第二次遍历的时候,是取出的下标为1的元素覆给了i),因此第二次循环的i其实是3,并非是2。之后的情况也是如此。这个点在我写程序的时候,困扰我了很久,最后看了这篇文章才理解Python中使用for循环遍历操作时容易踩的坑 - 小博测试成长之路 - 博客园 (cnblogs.com)

解决办法就是把这个list先给复制一份(从这个复制的这个list取出i,这样列表就不会因为删掉了元素,而导致列表是变化的) 如下

list = [1,2,3,4,5,6,7,8,9,10]
for i in list.copy():    
    list.remove(i) 
print(list)

此时得到了我们想要的结果

心得:

​ 第一次用python写了一个这么长的程序(至少以目前我的水平而言,我感觉两百多行还是比较长的),上一回写两百多行还是用c写了个小程序,也是自己第一次真正的写了一个小工具(尽管这个小工具可能存在bug,尽管它没图形化界面,尽管它的功能并不多,但毕竟是一个工具,而非没有意义的程序。

​ 说实话写的时候,还是遇到了不少的问题,最开始是有了思路,然后思考用代码怎么实现,后来是开始写,写的时候,并不算太困难,我感觉我的这个工具逻辑并不复杂。最痛苦的时候,其实就是写完之后,程序一堆bug,最开始的时候还可以通过调试找出来问题,但是如同我上面写的那个发现一样,这个就调试不出来,只知道是哪出了问题,但是根本想不通为什么会这样,不过好在身处互联网时代,干什么都能搜,并且幸运的被我搜到了问题,以此得以解决。最后开始完善交互,并且还在有的地方画蛇添足,结果又增加了点bug,不过最后还是一一给排查掉了。

​ 收获也是显而易见的,最直接的莫过于得到了一个检索题目信息的工具,这样以后想看以前的知识点了,只要输入一下知识点,就可以找到对应的wp。其次就是编程能力得到了不小的提升,这个程序里面的每个部分功能都是用函数来实现的,处理每个函数的时候,也确实锻炼自己的编程能力。再者就是提升了自己思考程序设计的能力,一个程序首先要根据自己所掌握的知识想出来一个绝佳的思路,才能去编写它,说实话我最开始,只是想用字典去写,但是后来发现,感觉用文件一行一行,来存储信息也不错。写了这一个工具确实是受益匪浅。

posted @ 2022-01-21 20:00  ZikH26  阅读(289)  评论(0编辑  收藏  举报