تفکرات صفر و یکی

نوشته های من در مورد سیستم عامل، درایور نویسی، مهندسی معکوس، امنیت و هر چیز سطح پایین دیگر

تفکرات صفر و یکی

نوشته های من در مورد سیستم عامل، درایور نویسی، مهندسی معکوس، امنیت و هر چیز سطح پایین دیگر

آخرین نظرات

مقدماتی بر دیباگر windbg

چهارشنبه, ۲۷ فروردين ۱۳۹۳، ۱۱:۴۲ ق.ظ

در این پست می خواهم در مورد چگونگی کار با دیباگر windbg توضیحاتی بدهم. این آموزش با آموزش هایی که در آینده در مورد درایور نویسی خواهم داد مرتبط است.

مقدمه

windbg دیباگری است که توسط ماکروسافت تولید شده و در قالب بسته ای به نام Debugging Tools for Windows از سایت ماکروسافت قابل دریافت است. این بسته را می شد در ورژن های قدیمی تر  جداگانه نیز دریافتش کرد ولی در حال حاظر و در چند ورژن اخیر این بسته همراه بسته هایی نظیر SDK و WDK عرضه می شود. در نتیجه اگر بسته WDK را از پست های قبلی که گفته ام دریافت کرده اید و در هنگام نصب گزینه مربوط به دیباگر را انتخاب کرده باشید باید این ابزار روی سیستم شما نصب باشد.

همانطور که بالاتر اشاره کردم اگر بخواهید درایور بنویسید حتی برای تفریح حتما باید با یک دیباگر مثل windbg یا SoftIce آشنا باشید این کار هم برای اشکال زدایی درایور  لازم است و هم اینکه خیلی اطلاعات مانند یکسری ساختارها یا توابع که ماکروساف هیچ مستنداتی برایشان منتشر نکرده را بدست آورد. برای مثال ببینید در مورد ساختار EPROCESS تو سایت ماکروسافت چی پیدا می شود.

هدف از آموزش این است که بتوانیم از طریق windbg اطلاعاتی که مستند نیستن یا مطالبی که اطلاعات کافی از آنها در اینترنت یافت نمی شود  را خودمان بدست بیاوریم. لازم به ذکر است که در این مورد برخی از همین مطالب که توسط ماکروسافت مستند نشده اند، توسط افراد دیگری مورد بررسی قرار گرفته اند و با کمی جستجو می توان از نتایج کار این افراد استفاده کرد بدون اینکه مجبور به مهندسی معکوس باشیم.

آموزشی که در ادامه خواهیم داشت و آماده کرده ام شامل این عناوین می شود. 

تنظیم windbg برای گرفتن اطلاعات در سطح کرنل

ما قبلا گفتیم درایور در سطح کرنل اجرا می شود. خوب اینجا یک مساله ای به وجود می آید اونم این که برای دیباگ درایور و گرفتن اطلاعات ما به یک کامپیوتر دیگر احتیاج داریم. چرا؟ چون دیباگر برای دریافت وضعیت سیستم و درایوری که در سطح کرنل اجرا شده نیاز دارد که به  سیستم مربوطه متصل شود. در نتیجه واضحه که وقتی دیباگ می کنیم کل سیستم متوقف می شود. نحوه ارتباط دو کامپیوتر با استفاده از  کابل هایUSB, IEEE 1394, Null Modem(RS-232 Serial Cable)  امکان پذیر است. ولی یکسری راه حل وجود دارد که نیازی به سیستم دومی نباشد و روی سیستم خودمان کار گرفتن اطلاعات توسط windbg را انجام بدهیم. این راه ها به قرار زیر است

  1. استفاده از local kernel debuggin
  2. استفاده از liveKd
  3. استفاده از ماشین های مجازی مانند Vmware یا VirtualBox

۱. استفاده از local kernel debugging

در این حالت ما امکان اشکال زدایی (دیباگ) سیستم را نداریم و فقط برای گرفتن اطلاعات مثل کد اسمبلی توابع یا تعریف ساختارها  و ... مناسب است چون هدفمان هم فقط گرفتن همین اطلاعات است در نتیجه گزینه مناسبی برای ما خواهد بود. این امکان از ویندوز نسخه XP به بعد اضافه شد. 

برای وارد شدن به این حالت windbg را باز کنید. از منوی File گزینه Kernel Debug را انتخاب کنید. یا از کلیدهای ترکیبی Ctrl+K استفاده کنید. بعد این کار باید پنجره command برایتان باز شود که آماده برای گرفتن دستور است. مانند تصویر زیر

نکته: از ویندوز Vista به بعد باید با ابزار bcdedit قابلیت اشکال زدایی را فعال کنیم. در واقع می گوییم هنگام راه اندازی سیستم این قابلیت فعال باشد. یک cmd باز کنید و دستور زیر را وارد کنید. بعد یکبار سیستم را راه اندازی مجدد کنید.

bcdedit /debug on

۲. استفاده از liveKd

۳. استفاده از ماشین  مجازی مانند Vmware یا VirtualBox

این دو روش را کاری باهاشون ندارم و به عهده خودتان می گذارم. البته liveKd که نیاز به توضیح خاصی هم ندارد. خودتان دانلود کنید و امتحانش کنید لبخند. این ابزار را Mark Russinovich نوشته که نویسنده کتاب های Windows Internals است که به جزئیات داخلی و فنی سیستم عامل ویندوز پرداخته. همچنین این فرد مجموعه ابزارهای sysinternals را نیز نوشته است. خواندن کتابهای این فرد را به تمام علاقه مندان به مباحث سیستمی و جزئی سیستم عامل ویندوز توصیه میکنم.

برای استفاده از ماشین مجازی هم این لینک را ببینید. 

تنظیم Symbols

ما برای اینکه بتوانیم از قابلیت های windbg به درستی استفاده کنیم نیاز داریم یک کار دیگر هم انجام دهیم آن هم تنظیم symbols است. سیمبول ها فایلهایی هستند که هنگام کامپایل ایجاد می شود. این فرمت فایل توسط ماکروسافت ایجاد شده است و حاوی اطلاعاتی است که هنگام دیباگ برنامه توسط دیباگر مورد استفاده قرار می گیرد. در بخشی که در مورد دستورات مهم windbg صحبت می کنیم خواهید دید چه اطلاعاتی را می توانیم از این دیباگر بدست آوریم.

خوب گفتیم که باید symbols ها را تنظیم کنیم. راهی که خود من ترجیح می دهم استفاده از آدرس مربوط به سیمبول ها از سایت ماکروسافت است. که خوب قاعدتا در این حالت باید به اینترنت متصل باشید. تا سیمبول های مورد نیاز دانلود شوند بعد از اینکه سیمبول های مورد نیاز دانلود شد دیگر نیازی به اینترنت نیست. آدرس سایت سیمبول ها به صورت زیر تعریف شده

SRV*symbol_path*http://msdl.microsoft.com/download/symbols

که از این عبارت symbol_path باید با مسیری که می خواهد سیمبول های دریاف شده از سایت ماکروسافت در آن قرار گیرد تغییر کند. برای مثال عبارت زیر را ببینید. که من مسیر سیمبول ها را C:\Symbols قرار داده ام

SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols

و در نهایت قرار دادن این مقدار در متغیر محلی _NT_SYMBOL_PATH به صورتی که در ادامه توضیح داده ام.

۱. رسیدن به Environment Variables در نسخه های مختلف ویندوز

  • برای Windows XP: روی My Computer کلیک راست کنید از منوی ظاهر شده Properties را انتخاب کنید.
  • برای Windows 7 & 8: روی Computer (داخل برنامه مدیریت فایلهای ویندوز)کلیک راست کنید و از منو ظاهر شده Properties را انتخاب کنید. از پنجره ظاهر شده سمت راست عبارت Advanced system settings را انتخاب کنید.

۲. در صفحه جدید سربرگ Advaned را انتخاب کنید بعد دکمه Environment Variables را بزنید. د ر پنجره جدید قسمت بالا که نوشته user variables for [user user] دکمه New را بزنید بعد 

برای مقدار Variable name عبارت زیر را وارد کنید

_NT_SYMBOL_PATH

و برای مقدار Variable value عبارت زیر را

C:\Symbols

بعد همه پنجره ها را OK کنید. تصویر پایین هم همه این کارا را با شکل نشان داده لبخند

اگر windbg باز است ببندینش و دوباره بازش کنید وارد local kernel debuggin بشوید. دستور زیر را وارد کنید

.sympath

باید خروجی زیر را بگیرید، این یعنی همه چی به خوبی پیش رفته و حالا می توانیم برویم به مرحله بعدی که توضیح در مورد دستورات مهم است.

lkd> .sympath
Symbol search path is: srv*C:\Symbols*http://msdl.microsoft.com/download/symbols
Expanded Symbol search path is: srv*C:\Symbols*http://msdl.microsoft.com/download/symbols

دستورات مهم

میرسیم به قسمت اصلی این آموزش که کار با دستورات و گرفتن اطلاعاتی است که از windbg درخواست میکنیم. در حالت local kernel debuggin ما دستورات کمتری را می توانیم مورد استفاده قرار دهیم که فعلا برای شروع کار ما کافی است.

نکته: windbg به بزرگ و کوچیکی دستورات و ورودی دستورات حساس نیست.

دستور lm

دیباگر در هنگام دسترسی به ماژول ها اگر سیمبول برایش موجود باشد آن را load می کند. برای گرفتن لیست ماژول های load شده از این دستور استفاده میکنیم. خود این دستور به ما کمک میکند مطمعن شویم سیمبولها به درستی تنظیم شده اند. این خروجی است که من در سیستم خود بعد از وارد کردن این دستور گرفته ام

lkd> lm
start end module name
804d7000 806d0480 nt (pdb symbols) z:\sym\ntkrnlpa.pdb\8C74CE9DE6C64BEA87C53453264D39C91\ntkrnlpa.pdb

Unloaded modules:
b20c8000 b20f3000 kmixer.sys
b20c8000 b20f3000 kmixer.sys
b20c8000 b20f3000 kmixer.sys
..
..

در خروجی بالا سیمبول ntkrnlpa.pdb را می بینیم که load شده که مربوط به کرنل سیستم عامل است.

دستور .symfix

بالاتر راهی برای تنظیم سیمبول ها گفتم. دستور .symfix هم خیلی ساده تر سرور سیمبول های ماکروسافت را برای windbg تنظیم میکند و نیاز به آن راه نیست. التبه مزیت آن راه که بالا اشاره کردم این است که برای کل سیستم تنظیم می شود در نتیجه اگر برنامه دیگری به این سیمبول ها نیاز داشته باشد می تواند از مسیر تعیین شده استفاده کند

به هر حال استفاده از این دستور بسیار ساده است به این صورت کافیه وار بشود

.symfix[+] [DownstreamStore]

قسمت هایی که داخل [ ] هستن اختیاریند و می توانید وارد نکنید. اگر علامت + روبروی دستور را وارد کنید تنظیمات قبلی حفظ شده و تنظیمات جدید به آنها اضافه می شود. یعنی اگر از قبل مسیر دیگری به عنوان پوشه سیمبول به windbg داده بوده اید حالا هم می خواهید. سیمبول سرور ماکروسافت را نیز اضافه کنید با اضافه کردن علامت + این کار عملی می شود.به این صورت

lkd> .symfix+

به جای مقدار DownstreamStore هم می توانید مسیری که می خواهید سیمبول های دانلود شده قرار بگیرند را مشخص کنید. مثلا تنظیمات که در قسمت تنظیم symbols گفتم با این دستور بخواهیم انجام دهیم به صورت زیر می شود

lkd> .symfix C:\Symbols 

دستور .reload

گفتیم windbg در صورت دسترسی به یک ماژول سعی در load کردن سیمبول آن می کند اگر موفق شد که اطلاعات مربوطه را نمایش می دهد اگر موفق نشد خطا می دهد. حالا ممکن است ما بعد این کار و گرفتن خطا تغییری در قسمت سیمبول ها بدهیم و حالا به هر نحو windbg سیمبول هایی که تنظیم کرده ایم را load نکرده باشد. تکلیف چیست؟ خوب راه حل  این است که در این شرایط یکبار دستور زیر را وارد کنیم. 

lkd> .reload

به این صورت windbg دوباره سعی میکند از مسیر سیمبول های تعریف شده دوباره آنها را load کند

دستور x

با این دستور می توانیم اطلاعات سیمبول ها را نمایش دهیم. این دستور به صورت زیر استفاده می شود

x [Options] Module!Symbol

ما با قسمت Module و Symbol بیشتر کار داریم. Module مشخص میکند داخل چه ماژولی می خواهیم جستجو کنیم و Symbol عبارتی که داخل ماژول دنبال آن هستیم را مشخص میکند

مثلا می خواهیم تمام سیمبول های تعریف شده در کرنل ویندوز را ببینیم این دستور را وارد میکنیم. که لیست خیلی طولانی را نمایش می دهد. علامت * یعنی همه چی،‌ nt هم یعنی کرنل ویندوز

lkd> x nt!*

می خواهیم تمام سیمبول هایی که داخلش عبارت driver در بینشان است را نمایش دهیم. 

lkd> x nt!*driver*

خروجی به صورت زیر خواهیم داشت. هر جا عبارت driver قرار داشته باشد اینجا لیست می شود

lkd> x nt!*driver*
80558370 nt!MmSystemDriverPage = <no type information>
804f146c nt!IopWriteDriverList = <no type information>
806842d0 nt!ViMessageClassFailDriverLogo = <no type information>
80558480 nt!MiVerifyAllDrivers = <no type information>
804ef51e nt!IoCallDriver = <no type information>
80551560 nt!IovDriverListHead = <no type information>
8068a462 nt!PipInsertDriverList = <no type information>
...
...

به جای ماژول هم می توانیم علامت * قرار دهیم که به معنی هر ماژول است

lkd> x *!

دستور dt

این دستور برای گرفتن اطلاعات از متغییرها یا انواع داده مانند ساختارها است. این دستور پارامترهای مختلفی دارد ولی ما بیشتر با یک حالتش فعلا سروکار دارم آن هم برای نمایش ساختارهاست (نوع struct)

dt [-DisplayOpts] [module]!Name [Address]

در اینجا عبارات داخل [ ] اختیاری است و می توان واردشون نکرد. با مثالی کار این دستور را نشان می دهم.

ما قبلا با ساختاری به نام _DRIVER_OBJECT در آموزش دوم درایور نویسی اشنا شدیم. می خواهیم از طریق windbg عناصر تشکیل دهنده این ساختار را از طریق دستور dt به دست آوریم. به این صورت دستور را وارد میکنم. 

lkd> dt _DRIVER_OBJECT

و این خرورجی را می گیریم. می بینید که همه عناصر و آفست عناصر این ساختار نیز مشخص شده. این اطلاعات می تواند خیلی جاها مفید باشد خصوصا زمانی که اطلاعات کافی در مورد بخش مورد بررسی موجود نباشد. همچنین مجبور نیستیم برای اینکه ببینیم ساختار چطور تعریف شده به منبع دیگری مراجعه کنیم و می توان گفت بیشترین کاربرد این دستور در مهندسی معکوس کد است.

lkd> dt _DRIVER_OBJECT
nt!_DRIVER_OBJECT
+0x000 Type : Int2B
+0x002 Size : Int2B
+0x004 DeviceObject : Ptr32 _DEVICE_OBJECT
+0x008 Flags : Uint4B
+0x00c DriverStart : Ptr32 Void
+0x010 DriverSize : Uint4B
+0x014 DriverSection : Ptr32 Void
+0x018 DriverExtension : Ptr32 _DRIVER_EXTENSION
+0x01c DriverName : _UNICODE_STRING
+0x024 HardwareDatabase : Ptr32 _UNICODE_STRING
+0x028 FastIoDispatch : Ptr32 _FAST_IO_DISPATCH
+0x02c DriverInit : Ptr32 long
+0x030 DriverStartIo : Ptr32 void
+0x034 DriverUnload : Ptr32 void
+0x038 MajorFunction : [28] Ptr32 long

بگذارید مثالی دیگری بزنم. فرض بگیریم ما آدرسی داریم که میدانیم به یه ساختار از نوع _DRIVER_OBJECT اشاره دارد. می توانیم با این دستور آن آدرس را در قالب این ساختار نمایش دهیم. با مقادیر پر شده و گرفته شده از آدرسی که به آن دادیم

lkd> dt _DRIVER_OBJECT 8240bf38
nt!_DRIVER_OBJECT
+0x000 Type : 4
+0x002 Size : 168
+0x004 DeviceObject : 0x8240b670 _DEVICE_OBJECT
+0x008 Flags : 0x12
+0x00c DriverStart : 0xf8bc6000
+0x010 DriverSize : 0x1080
+0x014 DriverSection : 0x8242c368
+0x018 DriverExtension : 0x8240bfe0 _DRIVER_EXTENSION
+0x01c DriverName : _UNICODE_STRING "\Driver\Beep"
+0x024 HardwareDatabase : 0x80671860 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"
+0x028 FastIoDispatch : (null)
+0x02c DriverInit : 0xf8bc666c long +fffffffff8bc666c
+0x030 DriverStartIo : 0xf8bc651a void +fffffffff8bc651a
+0x034 DriverUnload : 0xf8bc6620 void +fffffffff8bc6620
+0x038 MajorFunction : [28] 0xf8bc646a long +fffffffff8bc646alkd> dt _DRIVER_OBJECT

میبینیم که آدرس وارد شده مربوط به درایور آبجکت Beep در سیستم می شود. همین ساختار داخل خود چند ساختار دیگر با عناوین _DEVICE_OBJECT, _DRIVER_EXTENTION, _UNICODE_STRING نیز دارد. می توانیم این ساختارها را هم بصورت جدا با آدرسی که روبرویشان است عناصر و اطلاعات داخلشان را دریافت کنیم و همچنین می توانیم با استفاده از پارامتر -r مشخص کنیم تا چند مرحله به صورت بازگشتی ساختار های داخلی را نیز نمایش دهد. دستور به این صورت می شود

lkd> dt -r1 _DRIVER_OBJECT 8240bf38
nt!_DRIVER_OBJECT
+0x000 Type : 4
+0x002 Size : 168
+0x004 DeviceObject : 0x8240b670 _DEVICE_OBJECT
+0x000 Type : 3
+0x002 Size : 0x110
+0x004 ReferenceCount : 0
+0x008 DriverObject : 0x8240bf38 _DRIVER_OBJECT
+0x00c NextDevice : (null)
+0x010 AttachedDevice : (null)
+0x014 CurrentIrp : (null)
+0x018 Timer : (null)
+0x01c Flags : 0x44
+0x020 Characteristics : 0x100
+0x024 Vpb : (null)
+0x028 DeviceExtension : 0x8240b728
+0x02c DeviceType : 1
+0x030 StackSize : 1 ''
+0x034 Queue : __unnamed
+0x05c AlignmentRequirement : 0
+0x060 DeviceQueue : _KDEVICE_QUEUE
+0x074 Dpc : _KDPC
+0x094 ActiveThreadCount : 0
+0x098 SecurityDescriptor : 0xe1020cf0
+0x09c DeviceLock : _KEVENT
+0x0ac SectorSize : 0
+0x0ae Spare1 : 0
+0x0b0 DeviceObjectExtension : 0x8240b780 _DEVOBJ_EXTENSION
+0x0b4 Reserved : (null)
+0x008 Flags : 0x12
+0x00c DriverStart : 0xf8bc6000
+0x010 DriverSize : 0x1080
+0x014 DriverSection : 0x8242c368
+0x018 DriverExtension : 0x8240bfe0 _DRIVER_EXTENSION
+0x000 DriverObject : 0x8240bf38 _DRIVER_OBJECT
+0x004 AddDevice : (null)
+0x008 Count : 0
+0x00c ServiceKeyName : _UNICODE_STRING "Beep"
+0x014 ClientDriverExtension : (null)
+0x018 FsFilterCallbacks : (null)
+0x01c DriverName : _UNICODE_STRING "\Driver\Beep"
+0x000 Length : 0x18
+0x002 MaximumLength : 0x18
+0x004 Buffer : 0xe18f6300 "\Driver\Beep"
+0x024 HardwareDatabase : 0x80671860 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"
+0x000 Length : 0x5a
+0x002 MaximumLength : 0x5c
+0x004 Buffer : 0x80674558 "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"
+0x028 FastIoDispatch : (null)
+0x02c DriverInit : 0xf8bc666c long +fffffffff8bc666c
+0x030 DriverStartIo : 0xf8bc651a void +fffffffff8bc651a
+0x034 DriverUnload : 0xf8bc6620 void +fffffffff8bc6620
+0x038 MajorFunction : [28] 0xf8bc646a long +fffffffff8bc646a

که تا یک مرحله هر ساختار داخل _DRIVER_OBJECT را پیمایش و عناصر آن را نمایش می دهد

دستور u

این دستور برای disassemble (نمایش کد اسمبلی) کردن آدرسی که به عنوان ورودی به این دستور می دهیم است و به صورت زیر استفاده می شود.

u Range
u Address

آدرس هم می تواند به صورت عدد باشد هم میتواند از سیمبول ها (مثلا نام یک تابع) به عنوان ورودی استفاده کرد.

برای مثال برای نمایش کد امسبلی تابع IoGetLowerDeviceObject دستوری به صورت زیر وارد می کنیم

u IoGetLowewrDeviceObject

خروجی زیر را می گیریم

lkd> u IoGetLowerDeviceObject
nt!IoGetLowerDeviceObject:
804ef7f8 8bff mov edi,edi
804ef7fa 55 push ebp
804ef7fb 8bec mov ebp,esp
804ef7fd 53 push ebx
804ef7fe 56 push esi
804ef7ff ff1514774d80 call dword ptr [nt!_imp__KeRaiseIrqlToDpcLevel (804d7714)]
804ef805 8ad8 mov bl,al
804ef807 8b4508 mov eax,dword ptr [ebp+8]

خروجی که به شما داده می شود به اندازه ۱۰ دستور است بصورت پیشفرض ولی می توان تعیین کرد تا چه اندازه یا به چه تعداد دستور نمایش دهد

مثلا برای اینکه ۱۶ دستور بخواهیم در خروج نمایش داده شود این دستور را وارد میکنیم، لازم به ذکر است که اعدادی که وارد میکنیم همه در مبنای ۱۶ است یعنی عدد ۱۰ در اینجا در واقع ۱۶ در مبنای ده دهی می باشد

lkd> u IoGetLowerDeviceObject L10

دستور uf

این دستور معادل دستور قبلی است با این تفاوت که کد اسکبلی کامل یک تابع را نشان می دهد. در واقع از ابتدا تا انتهای تابع را تشخیص می دهد و آن محدوده آدرس را disassemble می کند

به این صورت دستور را وارد می کنیم

uf IoGetLowewrDeviceObject

و این خرووحی برگردانده می شود

lkd> uf IoGetLowerDeviceObject
nt!IoGetLowerDeviceObject:
804ef7f8 8bff mov edi,edi
804ef7fa 55 push ebp
804ef7fb 8bec mov ebp,esp
804ef7fd 53 push ebx
804ef7fe 56 push esi
804ef7ff ff1514774d80 call dword ptr [nt!_imp__KeRaiseIrqlToDpcLevel (804d7714)]
804ef805 8ad8 mov bl,al
804ef807 8b4508 mov eax,dword ptr [ebp+8]
804ef80a 8b80b0000000 mov eax,dword ptr [eax+0B0h]
804ef810 33f6 xor esi,esi
804ef812 f640100f test byte ptr [eax+10h],0Fh
804ef816 7510 jne nt!IoGetLowerDeviceObject+0x30 (804ef828)

nt!IoGetLowerDeviceObject+0x20:
804ef818 8b4018 mov eax,dword ptr [eax+18h]
804ef81b 85c0 test eax,eax
804ef81d 7409 je nt!IoGetLowerDeviceObject+0x30 (804ef828)

nt!IoGetLowerDeviceObject+0x27:
804ef81f 8bf0 mov esi,eax
804ef821 8bce mov ecx,esi
804ef823 e868310300 call nt!ObfReferenceObject (80522990)

nt!IoGetLowerDeviceObject+0x30:
804ef828 8acb mov cl,bl
804ef82a ff151c774d80 call dword ptr [nt!_imp_KfLowerIrql (804d771c)]
804ef830 8bc6 mov eax,esi
804ef832 5e pop esi
804ef833 5b pop ebx
804ef834 5d pop ebp
804ef835 c20400 ret 4

دستور d*

مجموعه دستوراتی داریم برای استخراج اطلاعات در قالب فرمت های مختلف مثلا بایت،‌دو بایت،‌ چهار بایت، رشته و امثالهم. 

d     آخرین حالت از حالت های این دستور دوباره تکرار می شود
db استخراج اطلاعات بصورت بایت با نمایش اسکی معادل هر بایت
dd نمایش اطلاعات به صورت چهار بایتی
da نمایش اطلاعات به صورت رشته از نوع اسکی
du نمایش اطلاعات به صورت یک رشته از نوع یونیکد

مثال برای هر کدام

گفتیم برای نمایش بایتی و معادل اسکی (ASCII) آدرس وارد شده را می توانیم با دستور زیر دریافت کنیم

db

مثلا برای استخرراج اطلاعات از آدرس e18a5358 به صورت زیر با خروجی،‌ 

lkd> db e18a5358
e18a5358 5c 00 44 00 72 00 69 00-76 00 65 00 72 00 5c 00 \.D.r.i.v.e.r.\.
e18a5368 42 00 65 00 65 00 70 00-04 04 0d 0c 53 65 63 f4 B.e.e.p.....Sec.
e18a5378 40 00 00 00 90 00 00 00-00 08 00 00 00 00 00 00 @...............
e18a5388 a0 44 90 e1 10 00 10 00-00 8a 6b e1 01 00 00 00 .D........k.....
e18a5398 01 00 00 00 00 00 00 00-30 43 5c 82 10 00 20 10 ........0C\... .
e18a53a8 80 a3 55 80 1f 20 89 e1-00 00 00 00 18 ee 71 e1 ..U.. ........q.
e18a53b8 00 00 00 00 30 ee 71 e1-ff ff ff ff 30 05 8c e1 ....0.q.....0...
e18a53c8 00 30 00 00 00 00 00 00-a0 08 01 00 10 00 00 00 .0..............

اطلاعات به صورت چهار بایتی

dd
lkd> dd e18a5358
e18a5358 0044005c 00690072 00650076 005c0072
e18a5368 00650042 00700065 0c0d0404 f4636553
e18a5378 00000040 00000090 00000800 00000000
e18a5388 e19044a0 00100010 e16b8a00 00000001
e18a5398 00000001 00000000 825c4330 10200010
e18a53a8 8055a380 e189201f 00000000 e171ee18
e18a53b8 00000000 e171ee30 ffffffff e18c0530
e18a53c8 00003000 00000000 000108a0 00000010

برای da و du هم به همین منوال اگر آدرس یک رشته معتبر به صورت اسکی یا یونیکد باشد با این دستورات قابل مشاهده است. تمام این دستورات مانند دستور u قابلیت گرفتن اندازه داده خروجی را دارند کافیه دستور خود را به این صورت وارد کنیم

lkd> dd e18a5358 L100

که در این حالت ۲۵۶ (۱۰۰ هگزادسیمال)عدد چهار بایتی از آدرس e18a5358 نمایش داده می شود.

 پایان

خوب به پایان آموزش رسیدیم. امیدوارم آموزش مفید واقع بشود. البته windbg خیلی بیشتر از این آموزش دستورات مختلف دارد و پرداختن به همه آن نیاز به نوشتن یک کتاب دارد ولی اگر در این زمینه علاقه دارین می توانید کتاب Advanced Windows Debugging را پیدا و مطالعه کنید.

  • موافقین ۱ مخالفین ۰
  • ۹۳/۰۱/۲۷
  • ۵۱۹۹ نمایش
  • آرش اسلامی

kernel debugging

pdb

symbols

windbg

مهندسی معکوس

نظرات (۴)

  • پرستوی مهاجر
  • سلام. وقتتون به خیر. متشکر از مطالب خوب و مفیدتون. استفاده کردم. 
    سلام
    خیلی ممنون از مطالب جالبتون
    امیدوارم ادامه بدین
    بنده می خواستم به عنوان پروژه ابزاری تهیه کنم که با اون بتونم وجود Rootkit رو تشخیص بدم
    در حال مطالعه کتاب Windows Internals هستم
    میشه راهنمایی کنید و بگید کدوم فصول این کتاب را باید مطالعه کنم و یا چه منابع دیگری
    خیلی ممنون
    پاسخ:
    سلام، ممنون :)
    در مورد کتاب که گفتین، این کتاب محوریتش اصلا Rootkit نیست و برای شما که می خوهید ابزر برای تشخیص روتکیت بنویسید بکار نمی آید
    پیشنهاد می کنم برای شروع کتاب Rootkit Arsenal رو بخونید.
    با سلام
    داداش این آدرس
    https://msdl.microsoft.com/download/symbols
    رو می زنم هیچ صفحه ای لو نمیشه...

    پاسخ:
    سلام
    مستقیم نمیشه از این آدرس استفاده کرد تو همین آموزش بخش تنظیم Symbols توضیح دادم چطور باید تنظیمش کرد.
    سلام خسته نباشین
    من خیلی گشتم ولی جایی پیدا نکردم کتاب روتکیت آرسنال رو ترجمه کرده باشه،شما جایی میشناسین که ترجمه گذاشته باشه؟
    پاسخ:
    سلام
    ممنون
    خیر بنده هم اطلاعی از ترجمه این کتاب ندارم.
    ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
    شما میتوانید از این تگهای html استفاده کنید:
    <b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
    تجدید کد امنیتی