Skip to content
This repository was archived by the owner on Mar 29, 2024. It is now read-only.

Commit 6c227a3

Browse files
committed
first commit
0 parents  commit 6c227a3

8 files changed

+216
-0
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# TWindbg
2+
PEDA-like debugger UI for WinDbg

TWindbg/TWindbg.py

+186
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import pykd
4+
import color
5+
import sys
6+
import traceback
7+
8+
ARCH = None
9+
MAX_DEREF = 20
10+
11+
cpu_mode = pykd.getCPUMode()
12+
if cpu_mode == pykd.CPUType.I386:
13+
ARCH = 'x86'
14+
elif cpu_mode == pykd.CPUType.AMD64:
15+
ARCH = 'x64'
16+
else:
17+
pykd.dprintln("CPU mode: {} not supported.".format(cpu_mode))
18+
sys.exit(-1)
19+
20+
class Context():
21+
def __init__(self):
22+
self.regs_name = []
23+
self.seg_regs_name = ['cs', 'ds', 'es', 'fs', 'gs', 'ss']
24+
self.regs = {}
25+
self.eflags_tbl = {
26+
0: "carry",
27+
2: "parity",
28+
4: "auxiliary",
29+
6: "zero",
30+
7: "sign",
31+
8: "trap",
32+
9: "interrupt",
33+
10: "direction",
34+
11: "overflow",
35+
14: "nested",
36+
16: "resume",
37+
17: "virtualx86",
38+
}
39+
self.is_changed = {}
40+
self.sp_name = ""
41+
self.sp = None
42+
self.pc_name = ""
43+
self.pc = None
44+
45+
self.init_regs_name()
46+
self.init_regs()
47+
48+
def init_regs_name(self):
49+
if ARCH == 'x86':
50+
self.regs_name = ['eax', 'ebx', 'ecx', 'edx', 'edi', 'esi', 'ebp', 'esp', 'eip']
51+
self.sp_name = 'esp'
52+
self.pc_name = 'eip'
53+
else:
54+
self.regs_name = ['rax', 'rbx', 'rcx', 'rdx', 'rdi', 'rsi', 'r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15', 'rbp', 'rsp', 'rip']
55+
self.sp_name = 'rsp'
56+
self.pc_name = 'rip'
57+
58+
def init_regs(self):
59+
for reg_name in self.regs_name + self.seg_regs_name:
60+
self.regs[reg_name] = None
61+
self.is_changed[reg_name] = False
62+
63+
def update_regs(self):
64+
# for general regs
65+
for reg_name in self.regs_name + self.seg_regs_name:
66+
reg_data = pykd.reg(reg_name)
67+
if reg_data != self.regs[reg_name]: # is changed
68+
self.is_changed[reg_name] = True
69+
else:
70+
self.is_changed[reg_name] = False
71+
72+
self.regs[reg_name] = reg_data
73+
if reg_name == self.sp_name:
74+
self.sp = reg_data
75+
if reg_name == self.pc_name:
76+
self.pc = reg_data
77+
78+
class ContextHandler(pykd.eventHandler):
79+
def __init__(self, context):
80+
pykd.eventHandler.__init__(self)
81+
self.context = context
82+
83+
def onExecutionStatusChange(self, status):
84+
if status == pykd.executionStatus.Break: # step, continue, ...
85+
self.context.update_regs()
86+
self.print_context()
87+
88+
def print_context(self):
89+
#pykd.dbgCommand('.cls')
90+
pykd.dprintln(color.yellow("[------ Register --------------------------------------------------------------------------------------------]"), dml=True)
91+
self.print_regs()
92+
pykd.dprintln(color.yellow("[------ Code ------------------------------------------------------------------------------------------------]"), dml=True)
93+
self.print_code()
94+
pykd.dprintln(color.yellow("[------ Stack -----------------------------------------------------------------------------------------------]"), dml=True)
95+
self.print_stack()
96+
pykd.dprintln(color.yellow("[------------------------------------------------------------------------------------------------------------]"), dml=True)
97+
98+
def print_regs(self):
99+
# general regs
100+
for reg_name in self.context.regs_name:
101+
reg_data = self.context.regs[reg_name]
102+
reg_str = '{:3}: {:#x}'.format(reg_name.upper(), reg_data)
103+
reg_color = None
104+
if self.context.is_changed[reg_name]:
105+
reg_color = color.red
106+
else:
107+
reg_color = color.lime
108+
109+
pykd.dprintln(reg_color(reg_str), dml=True)
110+
111+
# segment regs
112+
first_print = True
113+
for reg_name in self.context.seg_regs_name:
114+
reg_data = self.context.regs[reg_name]
115+
reg_str = '{:2}={:#x}'.format(reg_name.upper(), reg_data)
116+
reg_color = None
117+
if self.context.is_changed[reg_name]:
118+
reg_color = color.red
119+
else:
120+
reg_color = color.green
121+
if first_print:
122+
pykd.dprint(reg_color(reg_str), dml=True)
123+
first_print = False
124+
else:
125+
pykd.dprint(" | " + reg_color(reg_str), dml=True)
126+
pykd.dprintln("")
127+
128+
# eflags reg
129+
eflags = pykd.reg('efl')
130+
eflags_str = color.green("EFLAGS: {:#x}".format(eflags))
131+
eflags_str += " ["
132+
for bit, flag_name in self.context.eflags_tbl.items():
133+
is_set = eflags & (1<<bit)
134+
eflags_str += " "
135+
if is_set:
136+
eflags_str += color.dark_red(flag_name)
137+
else:
138+
eflags_str += color.green(flag_name)
139+
eflags_str += " ]"
140+
pykd.dprintln(eflags_str, dml=True)
141+
142+
def print_code(self):
143+
pc = self.context.pc
144+
# print the previous assembly ( 3 lines )
145+
before_pc = pykd.dbgCommand("ub {:#x} L3".format(pc))
146+
pykd.dprint(before_pc)
147+
# print the current pc position ( 5 lines )
148+
after_pc = pykd.dbgCommand("u {:#x} L5".format(pc)).split("\n")
149+
for index,code in enumerate(after_pc[1::]):
150+
if index == 0: # current pc, highlight
151+
pykd.dprintln(color.lime_highlight(code), dml=True)
152+
else:
153+
pykd.dprintln(code)
154+
155+
def print_stack(self):
156+
size = None
157+
if ARCH == 'x86':
158+
size = 4
159+
else:
160+
size = 8
161+
162+
sp = self.context.sp
163+
for i in xrange(8):
164+
cur_sp = sp + i*size
165+
pykd.dprint("{:02d}:{:04x}|".format(i, i*size))
166+
ptr_values = self.smart_dereference(cur_sp)
167+
stack_str = '{:#x}'.format(cur_sp)
168+
for val in ptr_values:
169+
stack_str += " --> {:#x}".format(val)
170+
171+
pykd.dprintln(stack_str)
172+
173+
def smart_dereference(self, addr):
174+
ret = []
175+
for _ in xrange(MAX_DEREF):
176+
try:
177+
val = pykd.loadPtrs(addr, 1)[0]
178+
ret.append(val)
179+
addr = val
180+
except MemoryException: # no more dereference
181+
break
182+
183+
return ret
184+
185+
context = Context()
186+
context_handler = ContextHandler(context)

TWindbg/color.py

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
RED = ("errfg", "wbg")
2+
ORANGE = ("warnfg", "wbg")
3+
BLUE = ("verbfg", "wbg")
4+
GRAY = ("subfg", "wbg")
5+
DARK_RED = ("srcstr", "wbg")
6+
GREEN = ("srccmnt", "wbg")
7+
WHITE = ("emphbg", "wbg")
8+
YELLOW = ("srcdrct", "wbg")
9+
LIME = ("wfg", "wbg")
10+
LIME_HIGHLIGHT = ("wbg", "wfg")
11+
12+
def red(content): return colorize(RED, content)
13+
def yellow(content): return colorize(YELLOW, content)
14+
def orange(content): return colorize(ORANGE, content)
15+
def blue(content): return colorize(BLUE, content)
16+
def gray(content): return colorize(GRAY, content)
17+
def dark_red(content): return colorize(DARK_RED, content)
18+
def green(content): return colorize(GREEN, content)
19+
def white(content): return colorize(WHITE, content)
20+
def lime(content): return colorize(LIME, content)
21+
def lime_highlight(content): return colorize(LIME_HIGHLIGHT, content)
22+
def colorize(col, content): return "<col fg=\"{}\" bg=\"{}\">{}</col>".format(col[0], col[1], content)

batch/TWindbg_x64.bat

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@echo off
2+
"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe" -a pykd.pyd -c "!py -g winext\TWindbg\TWindbg.py"

batch/TWindbg_x86.bat

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@echo off
2+
"C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\windbg.exe" -a pykd.pyd -c "!py -g winext\TWindbg\TWindbg.py"

batch/del_windbg_reg.bat

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@echo off
2+
reg delete HKCU\Software\Microsoft\Windbg

matrix_theme.WEW

1.53 KB
Binary file not shown.

matrix_theme.reg

10.1 KB
Binary file not shown.

0 commit comments

Comments
 (0)