-
Notifications
You must be signed in to change notification settings - Fork 14
/
windbg.py
136 lines (116 loc) · 5.06 KB
/
windbg.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import pykd
import logging
import subprocess
import psutil
import os
from optparse import OptionParser
from time import sleep
__author__ = 'susperius'
class ExceptionHandler(pykd.eventHandler):
def __init__(self):
pykd.eventHandler.__init__(self)
self.count = 0
self.exception_occurred = False
self.interesting_exceptions = {0x80000001: "GUARD_PAGE_VIOLATION",
0x80000005: "BUFFER_OVERFLOW",
0xC0000005: "ACCESS_VIOLATION",
0xC000001D: "ILLEGAL_INSTRUCTION",
0xC0000144: "UNHANDLED_EXCEPTION",
0xC0000409: "STACK_BUFFER_OVERRUN",
0xC0000602: "UNKNOWN_EXCEPTION",
0xC00000FD: "STACK_OVERFLOW",
0XC000009D: "PRIVILEGED_INSTRUCTION"}
self.exception_info = None
def exceptionOccurred(self):
return self.exception_occurred
def getExceptionInfo(self):
return self.exception_info
def onException(self, exceptInfo):
if not exceptInfo.firstChance:
#self.exception_info = (exceptInfo.ExceptionCode, self.interesting_exceptions[exceptInfo.ExceptionCode],
# exceptInfo)
self.exception_occurred = True
return pykd.eventResult.Break
return pykd.eventResult.NoChange
class Debugger:
def __init__(self):
pykd.initialize()
self._process_id = None
self._event_handler = ExceptionHandler()
self._crash_occurred = False
self._logger = logging.getLogger(__name__)
def start_process(self, path, arguments, debug_child=False):
self._process_id = pykd.startProcess(path + " " + arguments, debugChildren=debug_child)
self._logger.debug("Process created")
def attach_to_pid(self, pid):
self._process_id = pid
pykd.attachProcess(pid)
def run(self):
while not self._event_handler.exceptionOccurred():
pykd.go()
self._logger.debug("Crash occurred")
self._crash_occurred = True
def get_except_info(self):
return self._event_handler.exception_info
def involve_msec(self):
pykd.dbgCommand(u".load C:\pyfuzz2\\node\debugging\msec\MSEC.dll")
msec = pykd.dbgCommand(u"!exploitable -v")
return msec if msec is not None else "MSEC not found\r\n"
def issue_dbg_command(self, cmd):
return pykd.dbgCommand(unicode(cmd))
def kill_process(self):
pykd.killAllProcesses()
@property
def crashed(self):
return self._crash_occurred
def option_parsing():
parser = OptionParser()
parser.add_option("-p", "--path", dest="path", help="The path of the executable", metavar="PATH")
parser.add_option("-t", "--testcase", dest="testcase", help="The path of the testcase", metavar="TESTCASE")
parser.add_option("-c", "--child", dest="dbg_child", action="store_true", default=False)
parser.add_option("-i", "--instruction", dest="instruction", help="Debugger instruction to run before start",
default=None)
parser.add_option("-X", "--execute", dest="execute", action="store_true", default=False,
help="Start the debugger inside this process")
parser.add_option("-a", "--attach", dest="attach", default=None, help="Attach debugger to PID")
return parser.parse_args()
if __name__ == "__main__":
options, args = option_parsing()
processes = []
if options.execute:
dbg = Debugger()
dbg.start_process(options.path, options.testcase)
dbg.issue_dbg_command(u".childdbg 1")
if options.instruction is not None:
options.instruction = options.instruction.replace("'", '"')
dbg.issue_dbg_command(options.instruction)
dbg.run()
crash_report = ""
if dbg.crashed:
crash_report += "Crash Report\r\n"
crash_report += dbg.issue_dbg_command(u"ub eip")
crash_report += dbg.issue_dbg_command(u"r")
crash_report += "\r\n"
crash_report += dbg.issue_dbg_command(u"kb")
crash_report += "\r\n"
crash_report += dbg.involve_msec()
with open("tmp_crash_report", 'a+') as fd:
fd.write(crash_report)
print crash_report
elif options.attach is not None:
dbg = Debugger()
dbg.attach_to_pid(int(options.attach))
dbg.run()
crash_report = ""
if dbg.crashed:
crash_report += "Crash Report Subprocess\r\n"
crash_report += dbg.issue_dbg_command(u"ub eip")
crash_report += dbg.issue_dbg_command(u"r")
crash_report += "\r\n"
crash_report += dbg.issue_dbg_command(u"kb")
crash_report += "\r\n"
crash_report += dbg.involve_msec()
with open("tmp_crash_report", 'a+') as fd:
fd.write(crash_report)
print crash_report
pass