예제 #1
0
    def getItemList_homeplate_root(self, ):
        self.sql = "SELECT NUM, NAME, TYPE, PATH, SIZE, MODIFY_TIME, ACCESS_TIME, CREATE_TIME, MODIFY_ATTRIBUTE_TIME, BACKUP_TIME FROM evidences"
        main.printDebugMessage("make sql string :" + self.sql)
        self.cur.execute(self.sql)
        main.printDebugMessage("execute sql ")

        return self.cur.fetchall()
예제 #2
0
 def beginParsing(self, UI):
     self.UI = UI
     self.node_list = []
     self.dir_dict = {}
     self.file_list = []
     self.folder_list = []
     self.evidence_list = []
     self.folder_count_dict = {}
     self.evidence_count_dict = {}
     self.homplate_folder_list = []
     self.getPhysicalDrives()
     #시그니처 위치 찾는 부분 추후 추가 예정
     self.f.seek(0xC805400, 0)  # initalize 0xC805400
     fr = self.f.read(4096)  #block size는 아직 모르지만, 일단 4096 읽기
     self.signature = struct.unpack_from(">I", fr, 0x0 + 0)[0]
     if self.signature != 0x482B0004:
         print("It is not HFS+ FileSystem, " + str(self.signature) + " " +
               str(self.volume_start))
         exit(-1)
     else:
         print("It is HFS+ FileSysem")
     self.block_size = struct.unpack_from(">I", fr, 0x0 + 0x28)[0]
     main.db1.updateDB_setup("BLOCK_SIZE", str(self.block_size))
     self.catalog_file = struct.unpack_from(">I", fr, 0x0 + 0x120)[0]
     main.printDebugMessage("signature : " + str(self.signature) +
                            " block_size : " + str(self.block_size) +
                            " catalog_file : " + str(self.catalog_file))
     self.catalog_file_location = self.volume_start + self.block_size * self.catalog_file  #카탈로그파일 위치 기록
     self.make_tree(UI)
예제 #3
0
 def updateDB_setup(self, opcode, value):
     if type(value) == str:
         value = "'" + value + "'"
     self.sql = "UPDATE setup SET CONTENTS = " + value + " WHERE NAME is '" + opcode + "'"
     main.printDebugMessage("sql : " + self.sql)
     self.cur.execute(self.sql)
     self.commit()
예제 #4
0
    def getItemList_bookmark(self, bookmark_evidence_list):
        self.sql = "SELECT NUM, NAME, TYPE, PATH, SIZE, MODIFY_TIME, ACCESS_TIME, CREATE_TIME, MODIFY_ATTRIBUTE_TIME, BACKUP_TIME FROM EVIDENCES WHERE NUM = "
        self.sql += " OR NUM = ".join(
            str(tmp[1]) for tmp in bookmark_evidence_list)
        self.cur.execute(self.sql)
        main.printDebugMessage("sql : " + self.sql)

        return self.cur.fetchall()
예제 #5
0
    def getItemList_homeplate(self, homeplate_folder_list):
        self.sql = "SELECT NUM, NAME, TYPE, PATH, SIZE, MODIFY_TIME, ACCESS_TIME, CREATE_TIME, MODIFY_ATTRIBUTE_TIME, BACKUP_TIME FROM evidences WHERE FOLDER = "
        self.sql += " OR FOLDER = ".join(
            str(tmp[0]) for tmp in homeplate_folder_list)
        main.printDebugMessage("getItemList_homeplate sql : " + self.sql)
        self.cur.execute(self.sql)

        return self.cur.fetchall()
예제 #6
0
    def executeOneQueryMany(self, sql):
        try:
            main.printDebugMessage("sql : " + sql)
            self.sql = sql
            self.cur.execute(self.sql)
            #self.conn.commit()
            self.row = self.cur.fetchall()

        except:
            print("DB에러 발생2")
            self.row = None

        return self.row
예제 #7
0
    def executeOneQuery(
        self, sql
    ):  # dictionary 안붙을떄 SQL실행시켜주는 함수 executeOneQuery("SELECT * FROM asdf WHERE NAME IS ASDF")
        try:
            main.printDebugMessage("sql : " + sql)
            self.sql = sql
            self.cur.execute(self.sql)
            #self.conn.commit()
            self.row = self.cur.fetchone()

        except:
            print("DB에러 발생1")
            self.row = None
        return self.row
예제 #8
0
 def getPhysicalDrives(self):
     physicalDrivesList = []
     if main.os_mode == "WINDOWS":
         w = wmi.WMI()
         for drive in w.Win32_DiskDrive():
             physicalDrivesList.append(drive.Model + "   " +
                                       drive.DeviceID + "  " + drive.SIZE)
     elif main.os_mode == "MACOS":
         cmd_result = subprocess.check_output('diskutil list | grep 0:',
                                              shell=True,
                                              universal_newlines=True)
         physicalDrivesList = cmd_result.splitlines()
         main.printDebugMessage(cmd_result.splitlines())
     return physicalDrivesList
예제 #9
0
    def parse_root_node(self):
        self.f.seek(self.catalog_file_location +
                    self.node_size * self.root_node, 0)  #f pointer 해당 노드위치로 변경
        fr = self.f.read(self.block_size)  #block size만큼 읽어옴
        parse_location = 0xE  #레코드 위치 쭉 따라가기 위한 변수, 0xE부터 첫 번째 레코드 시작
        record_num = struct.unpack_from(">H", fr, 0x0 + 0xA)[0]
        for i in range(record_num):
            n = RootNode()

            key_length = struct.unpack_from(
                ">H", fr, parse_location + 0x0)[0] + 4  #레코드의 길이
            main.printDebugMessage("key_length : " + str(key_length))
            name_length = struct.unpack_from(">H", fr,
                                             parse_location + 0x6)[0]  #이름길이 파싱

            n.parent_node_id = struct.unpack_from(">I", fr, parse_location +
                                                  0x2)[0]  #부모노드 id 파싱
            n.name = ""
            for i in range(name_length):
                n.name += chr(
                    struct.unpack_from(">" + str(name_length) + "H", fr,
                                       parse_location + 0x8 +
                                       i * 2)[0])  #이름 파싱
            main.printDebugMessage("n.name : " + n.name)

            n.child_node_id = struct.unpack_from(
                ">I", fr, parse_location + 0x8 + name_length * 2)[0]

            parse_location += key_length  #다음 레코드 파싱을 위해 현재 위치 기록해둠

            #self.node_list.append(n)
            main.printDebugMessage("node added")
        main.printDebugMessage("parse_rootnode_end")
예제 #10
0
    def getItemList_search(self, keyword):  #탐색기에서 ls할때 DB에서 가져오는거

        self.sql = "SELECT NUM, NAME, TYPE, PATH, SIZE, MODIFY_TIME, ACCESS_TIME, CREATE_TIME, MODIFY_ATTRIBUTE_TIME, BACKUP_TIME FROM evidences WHERE NAME REGEXP \"" + keyword + "\""  # 정규표현식으로 keyword포함된 evidences 가져옴
        self.cur.execute(self.sql)
        self.conn.commit()
        self.row_evidences = self.cur.fetchall()
        main.printDebugMessage("sql : " + self.sql)

        self.sql = "SELECT NUM, NAME, PATH, MODIFY_TIME, ACCESS_TIME, CREATE_TIME, MODIFY_ATTRIBUTE_TIME, BACKUP_TIME FROM folder WHERE NAME REGEXP \"" + keyword + "\""  # 정규표현식으로 keyword포함된 folders 가져옴
        self.cur.execute(self.sql)
        self.conn.commit()
        self.row_folders = self.cur.fetchall()
        main.printDebugMessage("sql : " + self.sql)

        return self.row_evidences, self.row_folders
예제 #11
0
    def parsingMetadata(self, location, name):
        self.block_size = 4096
        self.f.seek(location - location % self.block_size,
                    0)  #계속 에러나길래 blocksize단위로 읽게 약간 뒤로 감
        fr = self.f.read(self.block_size)
        fw = open(name + ".mzmd", "wb")
        start_location = location % self.block_size
        name_len = len(name)

        main.printDebugMessage("location : " + str(location) + " name_len : " +
                               str(name_len))
        i = 0
        while i < 96 + name_len * 2:
            fw.write(struct.unpack_from("c", fr, start_location + i)[0])
            i += 1
        fw.close()
예제 #12
0
    def parsingData(self, location, name, size):
        self.block_size = 4096
        self.f.seek(location - location % self.block_size,
                    0)  # 계속 에러나길래 blocksize단위로 읽게 약간 뒤로 감
        fr = self.f.read(self.block_size)
        fw = open(name, "wb")
        start_location = location % self.block_size
        extent_discriptor_list = []
        total_block = struct.unpack_from(">I", fr, start_location + 0xC)[0]
        #        main.printDebugMessage("carving total_block : " + str(total_block))
        i_block = 0  # carving하고있는 block의 위치
        i_count = 0  # block위치를 센 횟수
        while i_block < total_block:
            ed = ExtentDiscriptor()

            ed.start_block = struct.unpack_from(
                ">I", fr, start_location + 0x10 + i_count * 8)[0]
            ed.block_count = struct.unpack_from(
                ">I", fr, start_location + 0x14 + i_count * 8)[0]
            if ed.block_count == 0:
                break
            i_count += 1
            i_block += ed.block_count
            extent_discriptor_list.append(ed)
            main.printDebugMessage("block : " + str(i_block) +
                                   " start_block : " + str(ed.start_block) +
                                   " block_count : " + str(ed.block_count))

        test_index = 0
        for i in extent_discriptor_list:
            for j in range((i.block_count)):
                test_index = test_index + 1
        test_index = test_index - 1

        count = 0
        for i in extent_discriptor_list:
            self.f.seek((self.volume_start + i.start_block * self.block_size),
                        0)
            for j in range((i.block_count)):
                if (test_index == count):
                    fw.write(self.f.read(size % self.block_size))
                    break
                fw.write(self.f.read(self.block_size))
                count = count + 1
        fw.close()
예제 #13
0
 def moveEvidence(self, bookmark_file_list):
         if main.os_mode == "WINDOWS" :
             for bookmark_file in bookmark_file_list :
                 print(bookmark_file_list)
                 file_row = main.db1.executeOneQuery("SELECT * FROM evidences WHERE NUM = " + str(bookmark_file))
                 file_name = file_row[1]
                 file_location = file_row[14]
                 main.printDebugMessage("파싱할 파일이름 : " + file_name + " 위치 : " + str(file_location))
                 hfs = HFSP(main.disk_num)
                 hfs.block_size = main.block_size
                 file_size = file_row[3]
                 hfs.parsingData(file_location, file_name , file_size)
                 os.system("move \"C:\\Users\\Kang\\Desktop\\강성철\\BOB\\프로젝트\\matzip-forensics\\"
                       + file_name + "\" \"" + self.disk_path + "\\" + file_name + "\"")
         elif main.os_mode == "MACOS" :
             for bookmark_file in bookmark_file_list :
                 file_row = main.db1.executeOneQuery("SELECT * FROM evidences WHERE NUM is " + str(bookmark_file))
                 file_name = file_row[1].replace(" ", "\\ ") # 메타데이터 확장자 : mzmd
                 file_path = file_row[2].replace(" ", "\\ ")
                 file_path = file_path.replace("/Users", "\\ 1/Users")
                 os.system("cp /Volumes" + file_path + file_name  + " " + self.disk_path + "/" + file_name)
                 print("cp /Volumes" + file_path + file_name + " " + self.disk_path + "/" + file_name)
예제 #14
0
    def updateDB(self, opcode, item_dict):  # insertDB("EVIDENCE", 사전정보) 이런식
        # evidence
        if opcode == "BOOKMARK_ITEM":
            self.sql = "UPDATE evidences SET BOOKMARK = :bookmark_num WHERE NAME is :name AND PATH is :path"
            main.printDebugMessage("sql : " + self.sql)
            self.cur.execute(self.sql, item_dict)

        if opcode == "FOLDER_COUNT":
            self.sql = "UPDATE folder SET FOLDER_COUNT = :folder_count WHERE NUM is :num"
            main.printDebugMessage("sql : " + self.sql)
            self.cur.execute(self.sql, item_dict)

        if opcode == "EVIDENCE_COUNT":
            self.sql = "UPDATE folder SET EVIDENCE_COUNT = :evidence_count WHERE NUM is :num"
            main.printDebugMessage("sql : " + self.sql)
            self.cur.execute(self.sql, item_dict)
예제 #15
0
    def insertDBMany(self, opcode, item_list):
        if opcode == "EVIDENCE":
            self.sql = "INSERT INTO evidences (NUM, NAME, PATH, SIZE, MD5, SHA1, " \
                       "MODIFY_TIME, ACCESS_TIME, CREATE_TIME, MODIFY_ATTRIBUTE_TIME, BACKUP_TIME, INDEX_NUM, FILE_NODE_NUM, KEY_LENGTH, DATA_LOCATION, FOLDER, TYPE, BOOKMARK)" \
                       " VALUES (:num, :name, :path, :size, :md5, :sha1, :modify_time, :access_time, :create_time, :modify_attribute_time, :backup_time, :index_num, :file_node_num, :key_length, :data_location, :folder, :type, :bookmark)"

            main.printDebugMessage("sql : " + self.sql)
            self.cur.executemany(self.sql, item_list)
        if opcode == "FOLDER":
            self.sql = "INSERT INTO FOLDER (NUM, NAME, PATH,  MODIFY_TIME, ACCESS_TIME, CREATE_TIME, MODIFY_ATTRIBUTE_TIME, BACKUP_TIME, UPPER_NUM, PARSED, FOLDER_COUNT, EVIDENCE_COUNT) VALUES (:num, :name, :path, :modify_time, :access_time, :create_time, :modify_attribute_time, :backup_time,   :upper_num, :parsed, :folder_count, :evidence_count)"
            main.printDebugMessage("sql : " + self.sql)
            self.cur.executemany(self.sql, item_list)

        if opcode == "HOMEPLATE_FOLDER":
            self.sql = "INSERT INTO HOMEPLATE_FOLDER (FOLDER_NUM, LOWER_FOLDER_NUM) VALUES (:folder_num, :lower_folder_num)"
            main.printDebugMessage("sql : " + self.sql)
            self.cur.executemany(self.sql, item_list)
예제 #16
0
    def updateDB(self, opcode, item_dict):  # updateDB("EVIDENCE", 사전정보) 이런식
        #evidence
        if opcode == "EVIDENCE":
            self.sql = "INSERT INTO evidences (NAME, PATH, SIZE, MD5, SHA1, "\
                                        "MODIFY_TIME, ACCESS_TIME, CREATE_TIME, INDEX_NUM, FOLDER)" \
                                        " VALUES (:name, :path, :size, :md5, :sha1, :modify_time, :access_time, :create_time, :index_num, :folder)"

            main.printDebugMessage("sql : " + self.sql)
            self.cur.execute(self.sql, item_dict)
            self.conn.commit()  # 트랜잭션 처리

        #folder
        if opcode == "FOLDER":
            self.sql = "INSERT INTO FOLDER (NUM, NAME, PATH, UPPER_NUM) VALUES (:num, :name, :path, :upper_num)"
            main.printDebugMessage("sql : " + self.sql)
            self.cur.execute(self.sql, item_dict)
            self.conn.commit()  # 트랜잭션 처리

        if opcode == "SETUP":
            self.sql = "INSERT INTO SETUP(NAME, CONTENTS) VALUES (:name, :contents)"
            main.printDebugMessage("sql : " + self.sql)
            self.cur.execute(self.sql, item_dict)
            self.conn.commit()  # 트랜잭션 처리
예제 #17
0
 def signature_maker(self, location, hoffset, foffset, size):
     main.printDebugMessage("done?1")
     return self.signaturehandler(location, hoffset, foffset, size)
예제 #18
0
 def selectDB_setup(self, opcode):
     self.sql = "SELECT CONTENTS FROM setup WHERE NAME = '" + opcode + "'"
     main.printDebugMessage("sql : " + self.sql)
     self.cur.execute(self.sql)
     self.row = self.cur.fetchone()
     return self.row[0]
예제 #19
0
    def signaturehandler(self, location, hoffset, foffset, size):

        self.block_size = 4096

        h_flag = 0
        f_flag = 0
        header_offset = 0
        footer_offset = 0

        if (hoffset != "none"):
            h_flag = 1
            header_offset = 0
            if (int(hoffset) > self.block_size):
                header_read = int(int(hoffset) / self.block_size)
        if (foffset != "none"):
            f_flag = 1
            footer_offset = 0
            if (int(foffset) > self.block_size):
                footer_offset = int(int(foffset) / self.block_size)
        main.printDebugMessage("footer offset was : " + str(footer_offset))

        self.f.seek(location - location % self.block_size,
                    0)  # 계속 에러나길래 blocksize단위로 읽게 약간 뒤로 감
        if location == 3432911502:
            print("1")
        fr = self.f.read(self.block_size)
        if location == 3432911502:
            print("1")
        start_location = location % self.block_size
        if location == 3432911502:
            print("1")
        extent_discriptor_list = []
        if location == 3432911502:
            print("1")
        total_block = struct.unpack_from(">I", fr, start_location + 0xC)[0]
        if location == 3432911502:
            print("1")

        i_block = 0  # carving하고있는 block의 위치
        i_count = 0  # block위치를 센 횟수

        while i_block < total_block:
            ed = ExtentDiscriptor()
            #print("i_block : " + str(i_block) + " total_block : " + str(total_block))
            try:
                ed.start_block = struct.unpack_from(
                    ">I", fr, start_location + 0x10 + i_count * 4)[0]
                ed.block_count = struct.unpack_from(
                    ">I", fr, start_location + 0x14 + i_count * 4)[0]
                if i_block + ed.block_count > total_block:
                    break
                i_count += 1
                i_block += ed.block_count
                extent_discriptor_list.append(ed)
                #ㄴㅁㅇㄹㄴㅁㅇㄹㄴㅇㅁㄻㄴㅇㄹㄴㅇㅁㄹㄴㅁㅇㄹㄴㅁㅇㄻㄴㅇ db파일 block_count 수정
                if location == 3432911502:
                    print("i_block : " + str(i_block) + " total_block : " +
                          str(total_block) + " location : " + str(location))
            except:
                break

        index = 0

        test_index = 0
        for i in extent_discriptor_list:
            for j in range((i.block_count)):
                test_index = test_index + 1
        test_index = test_index - 1

        header_str_return = b""
        footer_str_return = b""

        for i in extent_discriptor_list:
            self.f.seek((self.volume_start + i.start_block * self.block_size),
                        0)
            for j in range((i.block_count)):
                # print("_____________________")
                # print("idex is " , index)
                # print(binascii.hexlify(self.f.read(self.block_size).rstrip(b"\x00")).decode("ISO-8859-1"))#binascii.hexlify(self.f.read(self.block_size)).decode("ISO-8859-1"))
                if (index == test_index):
                    result = self.f.read(size % self.block_size)
                else:
                    result = self.f.read(self.block_size)
                if (h_flag == 1):
                    if (header_offset >= index):
                        header_str_return = header_str_return + result
                        #print("header")
                        #print(binascii.hexlify(header_str_return).decode("ISO-8859-1"))
                if (f_flag == 1):
                    if (test_index - footer_offset <= index):
                        #print("what i read index was :" , index , "test index was : " , test_index - footer_offset)
                        footer_str_return = footer_str_return + result
                        #print(binascii.hexlify(footer_str_return).decode("ISO-8859-1"))
                index = index + 1

        main.printDebugMessage("done" + " index number is : " + str(index))
        result111 = {
            "h_offset_block": header_str_return,
            "f_offset_block": footer_str_return
        }
        return result111
예제 #20
0
 def deleteDB_bookmark_evidence(self, bookmark_num, evidence_num):
     self.sql = "DELETE FROM bookmark_evidences WHERE BOOKMARK_NUM = " + str(
         bookmark_num) + " AND EVIDENCE_NUM = " + str(evidence_num)
     main.printDebugMessage("sql : " + self.sql)
     self.cur.execute(self.sql)
예제 #21
0
    def insertDB(self, opcode, item_dict):  # insertDB("EVIDENCE", 사전정보) 이런식
        #evidence
        if opcode == "EVIDENCE":
            self.sql = "INSERT INTO evidences (NUM, NAME, PATH, SIZE, MD5, SHA1, "\
                                        "MODIFY_TIME, ACCESS_TIME, CREATE_TIME, MODIFY_ATTRIBUTE_TIME, BACKUP_TIME, INDEX_NUM, FILE_NODE_NUM, KEY_LENGTH, DATA_LOCATION, FOLDER, BOOKMARK)" \
                                        " VALUES (:num, :name, :path, :size, :md5, :sha1, :modify_time, :access_time, :create_time, :modify_attribute_time, :backup_time, :index_num, :file_node_num, :key_length, :data_location, :folder, :bookmark)"

            main.printDebugMessage("sql : " + self.sql)
            self.cur.execute(self.sql, item_dict)

        #folder
        if opcode == "FOLDER":
            self.sql = "INSERT INTO FOLDER (NUM, NAME, PATH, MODIFY_TIME, ACCESS_TIME, CREATE_TIME, MODIFY_ATTRIBUTE_TIME, BACKUP_TIME, UPPER_NUM, PARSED, FOLDER_COUNT, EVIDENCE_COUNT) VALUES (:num, :name, :path, :modify_time, :access_time, :create_time, :modify_attribute_time, :backup_time,  :upper_num, :parsed, :folder_count, :evidence_count)"
            main.printDebugMessage("sql : " + self.sql)
            self.cur.execute(self.sql, item_dict)

        if opcode == "FOLDER_PARSED":
            self.sql = "UPDATE FOLDER SET PARSED = 1 WHERE NAME is :name AND PATH is :path"
            main.printDebugMessage("sql : " + self.sql)
            self.cur.execute(self.sql, item_dict)

        if opcode == "SETUP":
            self.sql = "INSERT INTO SETUP(NAME, CONTENTS) VALUES (:name, :contents)"
            main.printDebugMessage("sql : " + self.sql)
            self.cur.execute(self.sql, item_dict)

        if opcode == "BOOKMARK":
            self.sql = "INSERT INTO BOOKMARK(NUM, NAME, EDITOR, CREATE_TIME, EXPLANATION) VALUES (:num, :name, :editor, :create_time, :explanation)"
            main.printDebugMessage("sql : " + self.sql)
            self.cur.execute(self.sql, item_dict)

        if opcode == "BOOKMARK_EVIDENCES":
            self.sql = "Select count(*) from BOOKMARK_EVIDENCES Where BOOKMARK_NUM = :bookmark_num AND EVIDENCE_NUM = :evidence_num"  #이미 bookmark_evidences있는지 탐색
            main.printDebugMessage("sql : " + self.sql)
            self.cur.execute(self.sql, item_dict)  # evidences라는 테이블이 있는지 본다.
            self.row = self.cur.fetchone()  # 결과를 가져옴

            if self.row[0] == 0:
                self.sql = "INSERT INTO BOOKMARK_EVIDENCES(BOOKMARK_NUM, EVIDENCE_NUM) VALUES (:bookmark_num, :evidence_num)"
                main.printDebugMessage("sql : " + self.sql)
                self.cur.execute(self.sql, item_dict)
예제 #22
0
    def make_tree(self, UI):
        self.f.seek(self.catalog_file_location, 0)
        fr = self.f.read(self.block_size)
        self.node_size = struct.unpack_from(">H", fr, 0x0 + 0x20)[0]
        self.root_node = struct.unpack_from(">I", fr, 0x0 + 0x10)[0]
        self.first_leaf_node = struct.unpack_from(">I", fr, 0x0 + 0x18)[0]
        self.last_leaf_node = struct.unpack_from(">I", fr, 0x0 + 0x1C)[0]
        main.printDebugMessage("ns : " + str(self.node_size) + " rn : " +
                               str(self.root_node) + " fl : " +
                               str(self.first_leaf_node))
        #        self.parse_root_node()

        self.leaf_node_count_max = self.first_leaf_node - self.last_leaf_node  #UI ProgressBar
        self.leaf_node_count = 0
        self.parse_leaf_node_progress_one_node_time = 0
        flink = self.first_leaf_node  # 재귀형식을 갖기위하여 flink를 first_leaf_node로 설정해놓음
        start_time = time.time()
        t = threading.Thread(target=self.parse_leaf_node_progress_UI,
                             args=(UI, start_time))
        t.start()

        while flink != 0:  #flink가 더 이상 없을 때 까지
            before_time = time.time()
            flink = self.parse_leaf_node(flink)
            self.parse_leaf_node_progress_one_node_time = (
                self.parse_leaf_node_progress_one_node_time *
                self.leaf_node_count + time.time() - before_time) / (
                    self.leaf_node_count + 1)  #계속하여 시간 업데이트

            UI.progressBar.setProperty(
                "value",
                str(
                    int((self.leaf_node_count / self.leaf_node_count_max) *
                        100)))  # UI Progress bar
            QApplication.processEvents()
            self.leaf_node_count += 1

        #db에 넣기

        main.db1.insertDBMany("FOLDER", self.folder_list)
        main.db1.insertDBMany("EVIDENCE", self.evidence_list)

        #홈플레이트 트리구조 저장
        main.db1.insertDBMany("HOMEPLATE_FOLDER", self.homplate_folder_list)

        #폴더갯수, 파일갯수저장
        for folder_count_tmp in self.folder_count_dict.items():
            item_dict = {}
            item_dict["num"] = folder_count_tmp[0]  #어떤 폴더인지
            item_dict["folder_count"] = folder_count_tmp[1]  #그 폴더 안의 폴더갯수
            main.db1.updateDB("FOLDER_COUNT", item_dict)

        for evidence_count_tmp in self.evidence_count_dict.items():
            item_dict = {}
            item_dict["num"] = evidence_count_tmp[0]  # 어떤 폴더인지
            item_dict["evidence_count"] = evidence_count_tmp[1]  # 그 폴더 안의 폴더갯수
            main.db1.updateDB("EVIDENCE_COUNT", item_dict)

        main.db1.commit()
        main.printDebugMessage("dicts > ")
        for a in self.dir_dict.keys():
            main.printDebugMessage("이름 : " + str(self.dir_dict[a].name) +
                                   " object_id : " +
                                   str(self.dir_dict[a].object_id) +
                                   " parent_node : " +
                                   str(self.dir_dict[a].parent_node) +
                                   "경로 : " + str(self.dir_dict[a].path))
            #for b in self.file_list :
#                print(str(a) + "and " + str(b.parent_node))
#                if int(a) == int(b.parent_node) :
#                    print(str(b.name)+ " ",end="")
#            print("")

        return 0
예제 #23
0
    def parse_leaf_node(self, node_num):  #node_num에 해당하는 node를 한번 파싱해줌
        """

        :rtype: int
        """
        self.f.seek(self.catalog_file_location + self.node_size * node_num,
                    0)  #f pointer 해당 노드위치로 변경
        main.printDebugMessage("location : " + str(self.catalog_file_location +
                                                   self.node_size * node_num))
        fr = self.f.read(self.block_size * 2)  #block size * 2만큼 읽어옴
        flink = struct.unpack_from(">I", fr, 0x0 + 0x0)[0]
        blink = struct.unpack_from(">I", fr, 0x0 + 0x4)[0]
        type = struct.unpack_from(">B", fr, 0x0 + 0x8)[0]
        height = struct.unpack_from(">B", fr, 0x0 + 0x9)[0]
        record_num = struct.unpack_from(">H", fr, 0x0 + 0xA)[0]
        main.printDebugMessage("record_num : " + str(record_num) + " " +
                               str(node_num))
        # 2 byte reserved
        for i in range(record_num):
            oi = ObjectItem()  #파일 및 폴더
            record_location = struct.unpack_from(
                ">H", fr,
                self.block_size * 2 - (i + 1) * 2)[0]  # 2000 - (n + 1) * 2
            main.printDebugMessage("i : " + str(i) + " record_location : " +
                                   str(record_location) + " block size : " +
                                   str(self.block_size))
            oi.key_length = struct.unpack_from(">H", fr, record_location)[0]
            oi.parent_node = struct.unpack_from(">I", fr,
                                                record_location + 0x2)[0]
            name_length = struct.unpack_from(">H", fr, record_location +
                                             0x6)[0]  # 이름길이 파싱
            oi.name = ""  #파일 및 폴더의 이름 구하기
            for i in range(name_length):
                oi.name += chr(
                    struct.unpack_from(">H", fr, record_location + 0x8 +
                                       i * 2)[0])  # 이름 파싱
            oi.type = struct.unpack_from(
                ">H", fr,
                record_location + 0x8 + name_length * 2)[0]  # 1 폴더 2 파일
            if int(oi.type) == 3 or int(oi.type) == 4:
                continue
            oi.object_id = struct.unpack_from(
                ">I", fr, record_location + 0x8 + name_length * 2 + 0x8)[0]
            oi.create_time = struct.unpack_from(
                ">I", fr, record_location + 0x8 + name_length * 2 + 0xC)[0]
            oi.modify_time = struct.unpack_from(
                ">I", fr, record_location + 0x8 + name_length * 2 + 0x10)[0]
            oi.modify_attribute_time = struct.unpack_from(
                ">I", fr, record_location + 0x8 + name_length * 2 + 0x14)[0]
            oi.access_time = struct.unpack_from(
                ">I", fr, record_location + 0x8 + name_length * 2 + 0x18)[0]
            oi.backup_time = struct.unpack_from(
                ">I", fr, record_location + 0x8 + name_length * 2 + 0x1C)[0]
            oi.permission = 0
            oi.user_inform = 0
            oi.finder_inform = 0
            oi.text_encoding = struct.unpack_from(
                ">I", fr, record_location + 0x8 + name_length * 2 + 0x4C)[0]
            #reserved 4byte
            oi.data_location = self.catalog_file_location + self.node_size * node_num + record_location + 0x8 + name_length * 2 + 0x58
            #print(str(struct.unpack_from(">Q", fr,  record_location + 0x8 + name_length * 2 + 0x58)[0]) + " blocksize : " + str(self.block_size))
            #if oi.type == 2 : #이 object가 파일이면
            #    next_record_location = struct.unpack_from(">B", fr, self.block_size - (i + 2) * 2)[0]  # 2000 - (n + 1) * 2
            #    for j in range((next_record_location - record_location - 0x8 - name_length * 2 - 0x4E) / 4) : # start_block, block_count 몇 번 나올지 예상
            #        oi.start_block = struct.unpack_from(">I", fr, record_location + 0x8 + name_length * 2 + 0x52)[0]
            #        oi.block_count = struct.unpack_from(">I", fr, record_location + 0x8 + name_length * 2 + 0x56)[0]
            #

            main.printDebugMessage("n.name : " + oi.name + " parent_node : " +
                                   str(oi.parent_node) + " type : " +
                                   str(oi.type) + " name_length : " +
                                   str(name_length))
            if oi.type == 1:  #이 object가 폴더면
                self.dir_dict[oi.object_id] = oi
                if oi.object_id == 2:  # if root
                    self.root_folder_path = "/" + oi.name + "/"
                object_id_temp = oi.parent_node  #경로명을 알기위한 임시변수, 재귀형식을 갖기 위해 oi.parent_node로 설정
                object_id_temp2 = oi.object_id  #홈플레이트 트리구조 만들기 위한 임시변수, 재귀형식 갖기 위해 oi.parent_node로 설정
                folder_path_parsed = 0  #경로가 파싱되었는지
                #print("object_id_temp : " + str(folder_path_parsed) + " folder_path_parsed : " + str(folder_path_parsed))
                while object_id_temp != 1 and folder_path_parsed == 0:  #경로명 구하기
                    object_id_temp, string, folder_path_parsed = self.get_parent_name(
                        object_id_temp)
                    if object_id_temp == -1:
                        break
                    oi.path = string + "/" + oi.path
                #oi.path = oi.path + "/"# 끝 마무리 / 붙여주기
                #oi.path = oi.path[:-1]
                if oi.path == "":  # 경로가 공백이면 / 붙여줌 (root)
                    oi.path = "/"
                oi.path_parsed = 1

                item_dict_tmp = {}
                item_dict_tmp['folder_num'] = str(object_id_temp2)
                item_dict_tmp['lower_folder_num'] = str(oi.object_id)
                self.homplate_folder_list.append(item_dict_tmp)
                while object_id_temp2 != 1:  #홈플레이트 트리구조
                    object_id_temp2 = self.get_homeplate_tree(object_id_temp2)
                    if object_id_temp2 == -1:
                        break
                    item_dict = {}
                    item_dict['folder_num'] = str(object_id_temp2)
                    item_dict['lower_folder_num'] = str(oi.object_id)
                    #print("folder_num : " + item_dict['folder_num'] + " lower_folder_num : " + item_dict['lower_folder_num'])
                    self.homplate_folder_list.append(item_dict)
                item_dict = {}
                item_dict['num'] = oi.object_id
                item_dict['name'] = oi.name
                item_dict['path'] = oi.path
                item_dict['modify_time'] = oi.modify_time
                item_dict['access_time'] = oi.access_time
                item_dict['create_time'] = oi.create_time
                item_dict['modify_attribute_time'] = oi.modify_attribute_time
                item_dict['backup_time'] = oi.backup_time
                item_dict['upper_num'] = oi.parent_node  # db 업데이트를 위한 사전
                item_dict['parsed'] = 1
                item_dict['folder_count'] = 0
                item_dict['evidence_count'] = 0
                #main.db1.insertDB("FOLDER", item_dict)  # db에 저장
                self.folder_list.append(item_dict)  #리스트에 저장

                self.folder_count_dict[oi.object_id] = 0  #폴더갯수 세기
                self.evidence_count_dict[oi.object_id] = 0  # 폴더갯수 세기
                if oi.object_id != 2 and oi.parent_node in self.folder_count_dict:
                    self.folder_count_dict[
                        oi.parent_node] += 1  #상위폴더의 폴더갯수 +=1
            else:  #이 object가 파일이면

                #데이터 먼저 추출
                self.file_list.append(oi)

                object_id_temp = oi.parent_node  # 경로명을 알기위한 임시변수, 재귀형식을 갖기 위해 oi.parent_node로 설정
                folder_path_parsed = 0  # 경로가 파싱되었는지
                #print(
                # "object_id_temp : " + str(folder_path_parsed) + " folder_path_parsed : " + str(folder_path_parsed))
                while object_id_temp != 1 and folder_path_parsed == 0:  # 경로명 구하기
                    object_id_temp, string, folder_path_parsed = self.get_parent_name(
                        object_id_temp)
                    if object_id_temp == -1:
                        break
                    oi.path = string + "/" + oi.path
                # oi.path = oi.path + "/"# 끝 마무리 / 붙여주기
                # oi.path = oi.path[:-1]
                if oi.path == "":  # 경로가 공백이면 / 붙여줌 (root)
                    oi.path = "/"
                oi.path_parsed = 1

                while (True):
                    regex = re.compile(
                        '(\.otf)|(\.pdf)|(\.txt)|(\.ttxt)|(\.xlsx)|(\.ppt)|(\.pptx)|(\.hwp)'
                    )
                    condition1 = regex.search(oi.name) is not None  #포함

                    regex = re.compile(
                        '(' + self.root_folder_path.replace('/', '\/') +
                        'Users)')
                    #print('(' + self.root_folder_path.replace('/', '\/') + 'Users)')
                    #regex = re.compile('(/)')
                    condition2 = regex.search(oi.path) is not None  #포함
                    regex = re.compile(
                        '(' + self.root_folder_path.replace('/', '\/') +
                        'Users\/(.*?)\/Library)')
                    condition3 = regex.search(oi.path) is None  # 제외
                    if condition1 and condition2 and condition3 == True:
                        oi.keyfile_type = 1
                        break
                    regex = re.compile(
                        '(\.zip)|(\.tar)|(\.tar\.gz)|(\.alz)|(\.gz)|(\.7z)')
                    condition1 = regex.search(oi.name) is not None
                    if condition1 and condition2 and condition3 == True:
                        oi.keyfile_type = 2
                        break
                    regex = re.compile(
                        '(\.jpg)|(\.jpeg)|(\.png)|(\.icns)|(\.thm)|(\.aae)|(\.itc)|(\.itc2)|(\.pict)|(\.pictclipping)'
                    )
                    condition1 = regex.search(oi.name) is not None
                    if condition1 and condition2 and condition3 == True:
                        oi.keyfile_type = 3
                        break
                    regex = re.compile(
                        '(\.snd)|(\.song)|(\.avi)|(\.mp4)|(\.mp3)')
                    condition1 = regex.search(oi.name) is not None
                    if condition1 and condition2 and condition3 == True:
                        oi.keyfile_type = 4
                        break

                    regex = re.compile('(\.plist)')
                    condition1 = regex.search(oi.name) is not None
                    if condition1 and condition2 == True:
                        oi.keyfile_type = 5
                        break
                    regex = re.compile(
                        '(\/Library\/Safari\/)|(/Library/Application Support/Firefox/Profiles/*.default/places.sqlite)|(\/Library\/Application \\ Support\/com.operasoftware.Opera/history)'
                    )
                    condition1 = regex.search(oi.path) is not None
                    if condition1 == True:
                        oi.keyfile_type = 6
                        break

                    oi.keyfile_type = 0
                    break
                oi.size = int(
                    struct.unpack_from(
                        ">Q", fr, record_location + 0x8 + name_length * 2 +
                        0x58)[0])  #파일 size
                #print(str(struct.unpack_from(">Q", fr, record_location + 0x8 + name_length * 2 + 0x58)[0]) + " block size : " + str(self.block_size))
                file_inform = {}
                file_inform['num'] = self.file_count
                main.printDebugMessage("parsing NAME")
                file_inform['name'] = oi.name  # 파일이름 파싱
                main.printDebugMessage("parsing PATH")
                file_inform['path'] = oi.path  # 파일 path 파싱
                main.printDebugMessage("parsing SIZE")
                file_inform['size'] = oi.size
                # file_inform['size'] = 0
                main.printDebugMessage("parsing MD5")
                #file_inform['md5'] = file_hash.md5_for_largefile(path + "\\" + file_inform['name'], 4096)
                file_inform['md5'] = 0  # 일딴뺐음
                main.printDebugMessage("parsing SHA1")
                #file_inform['sha1'] = file_hash.sha1_for_largefile(path + "\\" + file_inform['name'], 4096)
                file_inform['sha1'] = 0  # 속도떄문에 일딴뺐음
                main.printDebugMessage("parsing MAC")
                file_inform['modify_time'] = oi.modify_time
                file_inform['access_time'] = oi.access_time
                file_inform['create_time'] = oi.create_time
                file_inform['modify_attribute_time'] = oi.modify_attribute_time
                file_inform['backup_time'] = oi.backup_time
                file_inform['index_num'] = 0  # 나중에 중복처리하는부분
                file_inform['file_node_num'] = oi.object_id
                file_inform['key_length'] = oi.key_length
                file_inform['folder'] = oi.parent_node
                file_inform['type'] = oi.keyfile_type
                file_inform['data_location'] = oi.data_location
                file_inform['parsed'] = 1
                file_inform['bookmark'] = 0
                # item_tuple = tuple(file_inform.values()) # db 업데이트를위한 튜플화

                #main.db1.insertDB("EVIDENCE", file_inform)  # db에 저장
                self.evidence_list.append(file_inform)  # 리스트에 저장

                self.file_count += 1  #파일갯수 카운트
                if oi.parent_node in self.evidence_count_dict:
                    self.evidence_count_dict[oi.parent_node] += 1
            main.printDebugMessage("node added")
        return flink