LIST_ENTRY に関するデバッグコマンド

LIST_ENTRY に関するデバッグ方法

この資料では LIST_ENTRY の仕組みと利用方法 で作成したプログラムを利用して、 LIST_ENTRY に関するデバッグ方法、デバッグコマンドを紹介します。

デバッガで LIST_ENTRY をどのようにたどって、 どのように元のデータを確認できるか示します。

以下のデバッグログでは、listtest.exe をスタートした後、 listtest!PrintAllItems にブレークポイントを設定しています。 このブレークポイントがヒットしたところでは、既に LIST_ENTRY にデータがぶら下がっているはずですから、そこでデータを見てみましょう。

尚、リストヘッドはわざとらしく (笑)、LIST_ENTRY g_MyListdata グローバル変数に置いてますから、 dl コマンドで簡単に出力できます。

>c:\debuggers\cdb listtest

Microsoft (R) Windows Debugger Version 6.11.0001.404 X86
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: listtest
Symbol search path is: srv*C:\websymbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
ModLoad: 00400000 00423000   listtest.exe
ModLoad: 77290000 773b7000   ntdll.dll
ModLoad: 75d50000 75e2c000   C:\Windows\system32\kernel32.dll
(1b4.ea0): Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=00000000 ecx=0012faf8 edx=772f5e74 esi=fffffffe edi=772dc19e
eip=772d8b2e esp=0012fb10 ebp=0012fb40 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!DbgBreakPoint:
772d8b2e cc              int     3
0:000> x listtest!Print*
00401110 listtest!PrintAllItems (void)
0040ae02 listtest!printf (char *)
0040aee3 listtest!printf_s (char *)
0:000> bp listtest!PrintAllItems
0:000> g
--- Add Three Items ---
Adding: Outlook
Adding: Excel
Adding: Word
Breakpoint 0 hit
eax=00221458 ebx=7ffdd000 ecx=00221688 edx=00420f40 esi=00000000 edi=00000000
eip=00401110 esp=0012ff3c ebp=0012ff40 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
listtest!PrintAllItems:
00401110 55              push    ebp
0:000> x listtest!g_*
004215a0 listtest!g_pfnRtlGenRandom = 0x57490b77
00420f40 listtest!g_MyListdata = struct _LIST_ENTRY [ 0x221688 - 0x221228 ]
0:000> dl listtest!g_MyListdata
00420f40  00221688 00221228 00000000 00000000
00221688  00221458 00420f40 00000000 006f0057
00221458  00221228 00221688 00000000 00780045
00221228  00420f40 00221458 00000000 0075004f
0:000> dt listtest!_MY_LISTDATA
   +0x000 data1            : Uint4B
   +0x004 data2            : Uint4B
   +0x008 linkField        : _LIST_ENTRY
   +0x010 data3            : Uint4B
   +0x014 szName           : [256] Wchar
   +0x214 data4            : Uint4B
0:000> dt listtest!_MY_LISTDATA 00221688-0x8
   +0x000 data1            : 0
   +0x004 data2            : 0
   +0x008 linkField        : _LIST_ENTRY [ 0x221458 - 0x420f40 ]
   +0x010 data3            : 0
   +0x014 szName           : [256]  "Word"
   +0x214 data4            : 0
0:000> dt listtest!_MY_LISTDATA 00221458-0x8
   +0x000 data1            : 0
   +0x004 data2            : 0
   +0x008 linkField        : _LIST_ENTRY [ 0x221228 - 0x221688 ]
   +0x010 data3            : 0
   +0x014 szName           : [256]  "Excel"
   +0x214 data4            : 0
0:000> dt listtest!_MY_LISTDATA 00221228-0x8
   +0x000 data1            : 0
   +0x004 data2            : 0
   +0x008 linkField        : _LIST_ENTRY [ 0x420f40 - 0x221458 ]
   +0x010 data3            : 0
   +0x014 szName           : [256]  "Outlook"
   +0x214 data4            : 0
0:000>

上記では dt listtest!_MY_LISTDATA で MY_LISTDATA の内容を確認することで、 LIST_ENTRY が MY_LISTDATA の先頭から 0x008 のオフセットにあることを確認しています。

従って、逆に LIST_ENTRY の場所から MY_LISTDATA の先頭を求めるには、 LIST_ENTRY のアドレスから -0x008 としています。

!list コマンドの活用

さらに、上記の内容を !list コマンドで自動化すると、次のようになります。(コマンドは実際は一行)

0:000> dd listtest!g_MyListdata l2
00420f40  00221688 00221228
0:000> !list "-t ntdll!_LIST_ENTRY.Flink -e -x 
	\"dt listtest!_MY_LISTDATA @$extret-0x8\" 00221688"
dt listtest!_MY_LISTDATA @$extret-0x8
   +0x000 data1            : 0
   +0x004 data2            : 0
   +0x008 linkField        : _LIST_ENTRY [ 0x221458 - 0x420f40 ]
   +0x010 data3            : 0
   +0x014 szName           : [256]  "Word"
   +0x214 data4            : 0

dt listtest!_MY_LISTDATA @$extret-0x8
   +0x000 data1            : 0
   +0x004 data2            : 0
   +0x008 linkField        : _LIST_ENTRY [ 0x221228 - 0x221688 ]
   +0x010 data3            : 0
   +0x014 szName           : [256]  "Excel"
   +0x214 data4            : 0

dt listtest!_MY_LISTDATA @$extret-0x8
   +0x000 data1            : 0
   +0x004 data2            : 0
   +0x008 linkField        : _LIST_ENTRY [ 0x420f40 - 0x221458 ]
   +0x010 data3            : 0
   +0x014 szName           : [256]  "Outlook"
   +0x214 data4            : 0

0:000>

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Web/DB プログラミング徹底解説