1#!/usr/bin/env python
2# Copyright (c) 2003-2016 CORE Security Technologies
3#
4# This software is provided under under a slightly modified version
5# of the Apache Software License. See the accompanying LICENSE file
6# for more information.
7#
8# Description:
9#             ESE utility. Allows dumping catalog, pages and tables.
10#
11# Author:
12#  Alberto Solino (@agsolino)
13#
14#
15# Reference for:
16#  Extensive Storage Engine (ese)
17#
18
19import sys
20import logging
21import argparse
22
23from impacket.examples import logger
24from impacket import version
25from impacket.ese import ESENT_DB
26
27
28def dumpPage(ese, pageNum):
29    data = ese.getPage(pageNum)
30    data.dump()
31
32def exportTable(ese, tableName):
33    cursor = ese.openTable(tableName)
34    if cursor is None:
35        logging.error('Can"t get a cursor for table: %s' % tableName)
36        return
37
38    i = 1
39    print "Table: %s" % tableName
40    while True:
41        try:
42            record = ese.getNextRow(cursor)
43        except:
44            logging.error('Error while calling getNextRow(), trying the next one')
45            continue
46
47        if record is None:
48            break
49        print "*** %d" % i
50        for j in record.keys():
51           if record[j] is not None:
52               print "%-30s: %r" % (j, record[j])
53        i += 1
54
55def main():
56    print version.BANNER
57    # Init the example's logger theme
58    logger.init()
59
60    parser = argparse.ArgumentParser(add_help = True, description = "Extensive Storage Engine utility. Allows dumping "
61                                                                    "catalog, pages and tables.")
62    parser.add_argument('databaseFile', action='store', help='ESE to open')
63    parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON')
64    parser.add_argument('-page', action='store', help='page to open')
65
66    subparsers = parser.add_subparsers(help='actions', dest='action')
67
68    # dump page
69    dump_parser = subparsers.add_parser('dump', help='dumps an specific page')
70    dump_parser.add_argument('-page', action='store', required=True, help='page to dump')
71
72    # info page
73    subparsers.add_parser('info', help='dumps the catalog info for the DB')
74
75    # export page
76    export_parser = subparsers.add_parser('export', help='dumps the catalog info for the DB')
77    export_parser.add_argument('-table', action='store', required=True, help='table to dump')
78
79    if len(sys.argv)==1:
80        parser.print_help()
81        sys.exit(1)
82
83    options = parser.parse_args()
84
85    if options.debug is True:
86        logging.getLogger().setLevel(logging.DEBUG)
87    else:
88        logging.getLogger().setLevel(logging.INFO)
89
90    ese = ESENT_DB(options.databaseFile)
91
92    try:
93        if options.action.upper() == 'INFO':
94            ese.printCatalog()
95        elif options.action.upper() == 'DUMP':
96            dumpPage(ese, int(options.page))
97        elif options.action.upper() == 'EXPORT':
98            exportTable(ese, options.table)
99        else:
100            raise Exception('Unknown action %s ' % options.action)
101    except Exception, e:
102        if logging.getLogger().level == logging.DEBUG:
103            import traceback
104            traceback.print_exc()
105        print e
106    ese.close()
107
108
109if __name__ == '__main__':
110    main()
111    sys.exit(1)
112
113
114
115