2014-11-20 191 views
3

我想在命令窗口中鍵入一個子類的對象到WinDbg中的父類。Windbg類型鑄造

示例類

class parent 
{ 
public: 
    int a; 
    int b; 
    parent(){ a = 10; b = 10; } 
    parent(int c) : a(a){} 
}; 

class child : public parent 
{ 
public: 
    int a; 
    int b; 
    child(){ a = 20; b = 20; } 
    child(int d) : b(d){} 
}; 

我使用WinDBG的,我是通過幫助文件中讀取。它顯示了在C++數字和運算符號,我可以從WinDbg的命令窗口中,執行以下typecastings:

dynamic_cast <type>(Value) 
static_cast <type>(Value) 
reinterpret_cast <type>(Value) 
const_cast <type>(Value) 
(type) Value 

所以我會鍵入WinDbg的命令窗口:

?? (type) Value 

什麼工作是

?? (char)a 
?? static_cast<char>(a) 

其中a是一個int。

什麼不工作是

?? (parent)chld 
?? static_cast<parent>(chld) 
?? static_cast<mod!parent>(chld) 

其中CHLD是階級的孩子和孩子的對象繼承父類。

對象例如:

child chld; 

返回的錯誤是

類型衝突錯誤在 '<EOL>'

如果我做了x mod!*我得到一個巨大的名單,在該列表中是

MOD!parent 
MOD!child 

如果我做一個?? chld然後對象被轉儲到屏幕就好了。

爲什麼我想這樣做?那麼你可以做

?? chld.childattr++,所以我想真正做?? ((parent)chld).parentattr++

WinDbg的幫助說:

符號在C++表達式

在C++的表達,每一個符號解釋根據其類型。根據符號引用的內容,可能會將其解釋爲整數,數據結構,函數指針,或任何其他數據類型。如果在C++表達式中使用不符合C++數據類型的符號(例如未修改的模塊名稱),則會發生語法錯誤。

所以我看不出任何理由,我不應該能夠將一個對象轉換爲父數據類型。

我做了很多搜索,沒有真正出現這個,如果有人能指出我在正確的方向,這樣我可以讀到爲什麼這應該或不應該工作,或者我可能需要做的是成功,甚至爲什麼這不是我應該從WinDbg期待的。

修改:添加代碼示例。

回答

5

代碼片斷或任何可再現於其他機器一定程度上可以提供更強大的和明確的答案,而不是乾的理論問題

我理解你的問題是類型的可PE頭被傾倒的_EPROCESS結構

如果是這樣,你可以做一些這樣的事

lkd> ?? (char *)@$proc->ImageFileName 
char * 0x866be194 
"windbg.exe" 
lkd> lm m windbg 
start end  module name 
01000000 01097000 windbg  (pdb symbols)   
lkd> db windbg l10 
01000000 4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00 MZ.............. 
lkd> da windbg+4e 
0100004e "This program cannot be run in DO" 
0100006e "S mode....$" 
lkd> ?? (char *)((nt!_EPROCESS *) @@masm(windbg - 174+4e))->ImageFileName 
char * 0x0100004e 
"This program cannot be run in DOS mode....$" 

雖然仍處於虧損此編輯爲響應編輯的問題

的演練 你的父類完整的源代碼稍加修改,以消除未引用參數的警告和輸出的模糊性和內部功能主要用於

:\>type parchiltst.cpp 
#include <stdio.h> 
class parent 
{ 
public: 
    int a; 
    int b; 
    parent(){ a = 35; b = 28; } 
    parent(int c) : a(c){} 
}; 
class child : public parent 
{ 
public: 
    int a; 
    int b; 
    child(){ a = 20; b = 20; } 
    child(int d) : b(d){} 
}; 
int main (void) { 
    parent par,papa,mama,gramp; 
    child chill,bigbro,lilsis,crybab; 
    par.a=70;par.b=65;chill.a=4;chill.b=8; 
    gramp=parent(par); papa=parent(); mama=parent(1234); 
    bigbro=child(chill);lilsis=child();crybab=child(5678); 
    printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", 
     chill.a,chill.b,gramp.a,gramp.b,papa.a,papa.b,mama.a,mama.b, 
     bigbro.a,bigbro.b,lilsis.a,lilsis.b,crybab.a,crybab.b); 
    return 0; 
} 

編譯,鏈接和執行,以顯示輸出

:\>cl /Zi /nologo /W4 /analyze parchiltst.cpp /link /RELEASE 
parchiltst.cpp 

:\>parchiltst.exe 
4 8 70 65 35 28 1234 0 4 8 20 20 196608 5678 ` 

加載它下windbg和加強到printf,以便所有當地人 被正確初始化

:\>cdb parchiltst.exe 

0:000> g main 
parchiltst!main: 
00401000 55    push ebp 
0:000> dv -V -t -i 
prv local 0013ff18 @ebp-0x60 class child lilsis = class child 
prv local 0013ff28 @ebp-0x50 class parent par = class parent 
prv local 0013ff30 @ebp-0x48 class parent gramp = class parent 
prv local 0013ff38 @ebp-0x40 class parent papa = class parent 
prv local 0013ff40 @ebp-0x38 class parent mama = class parent 
prv local 0013ff48 @ebp-0x30 class child chill = class child 
prv local 0013ff58 @ebp-0x20 class child bigbro = class child 
prv local 0013ff68 @ebp-0x10 class child crybab = class child 
0:000> .lines 
Line number information will be loaded 
0:000> l+* 
0:000> p 
> 19:  parent par,papa,mama,gramp; 
0:000> 
> 20:  child chill,bigbro,lilsis,crybab; 
0:000> 
> 21:  par.a=70;par.b=65;chill.a=4;chill.b=8; 
0:000> 
> 22:  gramp=parent(par); papa=parent(); mama=parent(1234); 
0:000> 
> 23:  bigbro=child(chill);lilsis=child();crybab=child(5678); 
0:000> 
> 26:   bigbro.a,bigbro.b,lilsis.a,lilsis.b,crybab.a,crybab.b); 

評估與C++ EXP評估

0:000> !for_each_local "?? @#Local" 
class child 
    +0x000 a    : 0n35 
    +0x004 b    : 0n28 
    +0x008 a    : 0n4 
    +0x00c b    : 0n8 
class child 
    +0x000 a    : 0n35 
    +0x004 b    : 0n28 
    +0x008 a    : 0n4 
    +0x00c b    : 0n8 
class child 
    +0x000 a    : 0n35 
    +0x004 b    : 0n28 
    +0x008 a    : 0n2090270496 
    +0x00c b    : 0n5678 
class parent 
    +0x000 a    : 0n70 
    +0x004 b    : 0n65 
class child 
    +0x000 a    : 0n35 
    +0x004 b    : 0n28 
    +0x008 a    : 0n20 
    +0x00c b    : 0n20 
class parent 
    +0x000 a    : 0n1234 
    +0x004 b    : 0n0 
class parent 
    +0x000 a    : 0n35 
    +0x004 b    : 0n28 
class parent 
    +0x000 a    : 0n70 
    +0x004 b    : 0n65 

所有的當地人並逐一檢查

0:000> ?? ((child *) @@masm(mama))->a 
int 0n35 
0:000> ?? ((parent *) @@masm(mama))->a 
int 0n1234 
0:000> ?? ((parent *) @@masm(papa))->a 
int 0n35 
0:000> ?? ((child *) @@masm(papa))->a 
int 0n1234 
0:000> ?? ((child *) @@masm(lilsis))->a 
int 0n20 
0:000> ?? ((parent *) @@masm(lilsis))->a 
int 0n35 
0:000> ?? ((parent *) @@masm(lilsis)) 
class parent * 0x0013ff18 
    +0x000 a    : 0n35 
    +0x004 b    : 0n28 
0:000> ?? ((child *) @@masm(lilsis)) 
class child * 0x0013ff18 
    +0x000 a    : 0n35 
    +0x004 b    : 0n28 
    +0x008 a    : 0n20 
    +0x00c b    : 0n20 
0:000> ?? ((child *) @@masm(mama)) 
class child * 0x0013ff40 
    +0x000 a    : 0n1234 
    +0x004 b    : 0n0 
    +0x008 a    : 0n35 
    +0x00c b    : 0n28 
0:000> ?? ((parent *) @@masm(mama)) 
class parent * 0x0013ff40 
    +0x000 a    : 0n1234 
    +0x004 b    : 0n0 
0:000> 

的問題和答案線索,可能會導致解決方案

我們想顯示什麼?

a pointer to a class 

什麼是

somefoo 

所以顯示的指針在C++表達式求值來somefoo類的類型

?? (somefoo *) should be used 

的指針需要的地址或一個表達式,其值爲地址

lilsis,爸爸,somefoo等是可以在兩個MASM和c被解釋表達式++評價者

所以以避免歧義we need to explicitly state that lilsis etc needs to be evaluated as masm expression not as c++ expression because ?? tries to interpret lilsis , somefoo as c++ expression
所以充分表達將?? (somefoo *) @@(someotherfoo)

通知@@ only是足以表示masm表達,但爲了進一步避免模棱兩可,指定表達評估者explicitly like @@masm(, @@c++(等等爲好習慣

見下面單個?在類指針上返回一個地址和一個??返回類型

0:000> ? mama 
Evaluate expression: 1310528 = 0013ff40 
0:000> ?? mama 
class parent 
    +0x000 a    : 0n1234 
    +0x004 b    : 0n0 
0:000> ?? lilsis 
class child 
    +0x000 a    : 0n35 
    +0x004 b    : 0n28 
    +0x008 a    : 0n20 
    +0x00c b    : 0n20 
0:000> ? lilsis 
Evaluate expression: 1310488 = 0013ff18 
0:000> ?? @@(mama) 
unsigned int64 0x13ff40 
0:000> ?? @@masm(mama) 
unsigned int64 0x13ff40 
0:000> ?? @@c++(mama) 
class parent 
    +0x000 a    : 0n1234 
    +0x004 b    : 0n0 
0:000> ?? @@c++(crybab) 
class child 
    +0x000 a    : 0n35 
    +0x004 b    : 0n28 
    +0x008 a    : 0n2090270496 
    +0x00c b    : 0n5678 
0:000> 

這不僅適用於類,但也types displayed with dt

!NT _EPROCESS如下操作不同的scenerios作爲一個例子

LKD> ?? (!(NT _EPROCESS)@ $ PROC) - >映像文件名稱

Type conflict error at ')->ImageFileName' 

LKD> ?? (!(NT _EPROCESS *)@ $ PROC) - >映像文件名稱

unsigned char [16] 0x86305f14 
0x6b 'k' 

LKD> ?? (字符*)(!(NT _EPROCESS *)@ $ PROC) - >映像文件名稱

char * 0x86305f14 
"kd.exe" 

LKD> ?? (字符*)((NT _EPROCESS *)!NT) - >映像文件名稱

Couldn't resolve error at 'nt)->ImageFileName' 

LKD> ?? (字符*)((NT _EPROCESS *)@@(NT)!) - >映像文件名稱

char * 0x804d7174 
"" 

? #FIELD_OFFSET(新臺幣!_EPROCESS,映像文件名稱)

long 0n372 

LKD>?0n372

Evaluate expression: 372 = 00000174 

LKD>? @@ C++(#FIELD_OFFSET(NT!_EPROCESS,映像文件名稱))+ NT

Evaluate expression: -2142408332 = 804d7174 

LKD>? @@ C++(#FIELD_OFFSET(NT!_EPROCESS,映像文件名稱))+ NT

Couldn't resolve error at 'nt' 

LKD>? @@ C++(#FIELD_OFFSET(NT _EPROCESS,映像文件名稱)!)+ @@(NT)

unsigned int64 0xffffffff`804d7174 
lkd> 
+0

我明白這個問題的方法是:它可以與內置的數據類型,而不是C++的自定義類。 – 2014-11-22 21:17:48

+0

是的,Thomas W.在我所問的問題上是正確的。我將編輯問題並添加示例。謝謝你的迴應Blabb。 – 2014-11-23 20:13:19

+0

增加了一些可重現的編輯到我原來​​的答案看看,看看是否有幫助 – blabb 2014-11-24 19:22:27