Mercurial > projects > ddbg_continued
comparison src/disasm.d @ 1:4a9dcbd9e54f
-files of 0.13 beta
-fixes so that it now compiles with the current dmd version
author | marton@basel.hu |
---|---|
date | Tue, 05 Apr 2011 20:44:01 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:586e4a649642 | 1:4a9dcbd9e54f |
---|---|
1 /* Ddbg - Win32 Debugger for the D programming language | |
2 * Copyright (c) 2007 Jascha Wetzel | |
3 * All rights reserved. See LICENSE.TXT for details. | |
4 */ | |
5 | |
6 import util; | |
7 import dbgprocess; | |
8 import dbgthread; | |
9 public import udis86; | |
10 import util; | |
11 | |
12 import std.string; | |
13 | |
14 import win32.winnt; | |
15 | |
16 class DisAsm | |
17 { | |
18 /********************************************************************************************** | |
19 Calculates the absolute destination address of a jxx or call instruction. | |
20 Params: is_imm = if true, only JIMM destinations will be considered. Out value is whether destination was JIMM | |
21 **********************************************************************************************/ | |
22 static int calcJumpDestination(DbgProcess process, DbgThread thread, ud_t* ud_obj, inout bool is_imm) | |
23 { | |
24 if ( !isConditionalJump(ud_obj.mnemonic) | |
25 && ud_obj.mnemonic != ud_mnemonic_code.UD_Icall | |
26 && ud_obj.mnemonic != ud_mnemonic_code.UD_Ijmp ) | |
27 return 0; | |
28 | |
29 uint address, destination; | |
30 if ( ud_obj.operand[0].type == ud_type.UD_OP_MEM || ud_obj.operand[0].type == ud_type.UD_OP_REG ) | |
31 { | |
32 if ( is_imm ) { | |
33 is_imm = false; | |
34 return 0; | |
35 } | |
36 is_imm = false; | |
37 CONTEXT ctx; | |
38 thread.getContext(ctx, CONTEXT_FULL); | |
39 switch ( ud_obj.operand[0].base ) | |
40 { | |
41 case ud_type.UD_NONE: break; | |
42 case ud_type.UD_R_EAX: address = ctx.Eax; break; | |
43 case ud_type.UD_R_EBX: address = ctx.Ebx; break; | |
44 case ud_type.UD_R_ECX: address = ctx.Ecx; break; | |
45 case ud_type.UD_R_EDX: address = ctx.Edx; break; | |
46 case ud_type.UD_R_ESI: address = ctx.Esi; break; | |
47 case ud_type.UD_R_EDI: address = ctx.Edi; break; | |
48 default: | |
49 DbgIO.println("WARNING: yet unsupported register 0x%x used in jmp/call destination", ud_obj.operand[0].base); | |
50 break; | |
51 } | |
52 if ( ud_obj.operand[0].type == ud_type.UD_OP_MEM ) | |
53 { | |
54 switch ( ud_obj.operand[0].offset ) | |
55 { | |
56 case 8: address += ud_obj.operand[0].lval._ubyte; break; | |
57 case 16: address += ud_obj.operand[0].lval.uword; break; | |
58 case 32: address += ud_obj.operand[0].lval.udword; break; | |
59 default: | |
60 DbgIO.println("WARNING: yet unsupported offset size used in jmp/call destination"); | |
61 break; | |
62 } | |
63 process.readProcessMemory(address, &destination, uint.sizeof); | |
64 } | |
65 else | |
66 destination = address; | |
67 } | |
68 else if ( ud_obj.operand[0].type == ud_type.UD_OP_JIMM ) | |
69 { | |
70 is_imm = true; | |
71 address = cast(uint)ud_insn_off(ud_obj); | |
72 destination = address+ud_insn_len(ud_obj); | |
73 switch ( ud_obj.operand[0].size ) | |
74 { | |
75 case 8: | |
76 destination += ud_obj.operand[0].lval.sbyte; | |
77 break; | |
78 case 16: | |
79 destination += ud_obj.operand[0].lval.sword; | |
80 break; | |
81 case 32: | |
82 destination += ud_obj.operand[0].lval.sdword; | |
83 break; | |
84 case 48: | |
85 DbgIO.println("WARNING: 48bit immediate jump destinations not implemented, yet"); | |
86 break; | |
87 case 64: | |
88 DbgIO.println("WARNING: 64bit immediate jump destinations not implemented, yet"); | |
89 break; | |
90 default: | |
91 assert(0); | |
92 } | |
93 } | |
94 else | |
95 DbgIO.println("yet unsupported jmp/call destination"); | |
96 return destination; | |
97 } | |
98 | |
99 /********************************************************************************************** | |
100 Test if given mnemonic a a conditional jump (i.e. jxx, not jmp). | |
101 **********************************************************************************************/ | |
102 static bool isConditionalJump(ud_mnemonic_code opcode) | |
103 { | |
104 if ( ud_mnemonic_code.UD_Ijmp == opcode ) | |
105 return false; | |
106 if ( ud_mnemonic_code.UD_Ijcxz <= opcode && ud_mnemonic_code.UD_Ijnle >= opcode ) | |
107 return true; | |
108 if ( ud_mnemonic_code.UD_Ija <= opcode && ud_mnemonic_code.UD_Ijnc >= opcode ) | |
109 return true; | |
110 if ( ud_mnemonic_code.UD_Iloop <= opcode && ud_mnemonic_code.UD_Iloopz >= opcode ) | |
111 return true; | |
112 return false; | |
113 } | |
114 | |
115 /********************************************************************************************** | |
116 Wrapper function for disassembly. Calls the delegate callback for each instruction. | |
117 **********************************************************************************************/ | |
118 static void disasm(DbgProcess process, uint start, uint stop, bool delegate(ud_t*) callback) | |
119 { | |
120 ubyte[] code; | |
121 | |
122 bool disasm(uint length, bool abort_at_ret) | |
123 { | |
124 ud_t ud_obj; | |
125 ud_init(&ud_obj); | |
126 ud_set_pc(&ud_obj, start); | |
127 ud_set_input_buffer(&ud_obj, code.ptr, length); | |
128 ud_set_mode(&ud_obj, 32); | |
129 ud_set_syntax(&ud_obj, &ud_translate_intel); | |
130 | |
131 // init callback | |
132 callback(cast(ud_t*)null); | |
133 | |
134 while ( ud_disassemble(&ud_obj) ) | |
135 { | |
136 if ( !callback(&ud_obj) ) | |
137 return false; | |
138 if ( abort_at_ret && (ud_obj.mnemonic == ud_mnemonic_code.UD_Iret || ud_obj.mnemonic == ud_mnemonic_code.UD_Iretf) ) | |
139 return false; | |
140 } | |
141 return true; | |
142 } | |
143 | |
144 if ( stop > 0 && stop <= start ) { | |
145 DbgIO.println("ERROR: invalid address range: Eip=0x%x >= 0x%x", start, stop); | |
146 return; | |
147 } | |
148 | |
149 code.length = stop>0?stop-start:512; | |
150 bool more; | |
151 uint read; | |
152 do | |
153 { | |
154 read = process.readProcessMemory(start, code.ptr, code.length); | |
155 if ( read == 0 ) | |
156 DbgIO.println("ERROR: Couldn't read from process' memory for disassembly: %s", lastError); | |
157 if ( read > 0 ) | |
158 more = disasm(read, stop==0); | |
159 start += code.length; | |
160 } while ( stop == 0 && more && read > 0 ); | |
161 } | |
162 } |