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 )
0 commit comments