من اغلب با دادههای باینری کار میکنم که قالبی دارند که میتوانم آنها را به شکلی قابل خواندن توسط انسان ببینم. اکثر ویرایشگرهای متن استفاده زیادی ندارند. یکی از راه های حل این مشکل استفاده از ابزار hexdump است. hexdump بسیار متنوع است و به شما این امکان را می دهد که به ساختار درون فایل های باینری همانطور که مناسب می دانید نگاه کنید و هنگامی که نحوه استفاده از آن را یاد گرفتید می توانید آن را به سرعت برای بسیاری از مشکلات اعمال کنید. من فکر می کنم که به راحتی قابل قبول است.
اگر از صفحه man hexdump استفاده کردهاید، ممکن است دستور قالببندی را بسیار ترسناک بدانید. بخشی از نحو فرمت تقریباً مشابه یک تابع رایج در زبان برنامه نویسی C است. من سینتکس hexdump را دشوار دیدم و من یک برنامه نویس C هستم. در حقیقت درک آن واقعاً دشوار نیست، اما بدون مثال برای استفاده در حین خواندن اسناد، ممکن است نحوه اعمال گزینه های قالب بندی مشخص نباشد.
استفاده اساسی
نقطه شروع با حدس زدن است و فقط نام فایل داده ای را به hexdump بدهید و هر فرمت پیش فرضی که hexdump استفاده می کند را دریافت کنید:
آنچه در آنجا مشاهده می کنید، محتویات باینری فایل mydata است که به صورت خطوطی از 8 مقدار 16 بیتی جداگانه در هگزادسیمال نشان داده شده است. اولین عدد در هر خط، آفست شروع در فایل برای اولین مقدار از 8 مقدار زیر در آن خط است. علامت * نشان میدهد که تمام خطوط از 0000030 تا 0001020 با خط 0000020 برابر است و خروجی را برای فایلهای بزرگ با دنبالههای تکراری طولانی و تراز شده فشرده نگه میدارد. توجه داشته باشید که بدون گزینه های خط فرمان، hexdump کل فایل را روی صفحه نمایش می گذارد، بنابراین از آن با احتیاط در فایل های بزرگ استفاده کنید.
16 بیت اول فایل مثال مقدار هگزادسیمال 457f است. توجه به این نکته مهم است که مقدار نشان داده شده مطابق با CPU Intel x86 است. در برخی دیگر از انواع CPU، به دلیل تفاوت در چیزی به نام ترتیب بایت، این مقدار می تواند به عنوان 7f45 خروجی باشد. اگر با این اصطلاح آشنا نیستید، احتمالاً ارزش خواندن در مورد آن را دارد، به عنوان مثال در ویکی پدیا.
اگر مقادیر 16 بیتی واقعاً آن چیزی نیست که به دنبال آن بودید، بررسی سریع صفحه man hexdump نشان می دهد که چندین سوئیچ وجود دارد که فرمت های خروجی از پیش تعریف شده دیگری را انتخاب می کنند. تنها یک گزینه دیگر وجود دارد، -C، که خروجی هگزادسیمال تولید می کند:
اکنون می توانید مقادیر تک بایت را ببینید و حتی متن آن قسمت هایی از فایل را که کاراکترهای متنی معمولی هستند مشاهده کنید. بنابراین، اکنون از امضای "ELF" حدس می زنم که این فایل احتمالاً یک برنامه قابل اجرا است.
مشاهده تنها بخشی از یک فایل
اگر یک فایل واقعاً بزرگ دارید که فقط علاقه مند به دیدن برخی از داده ها هستید، می توانید از گزین ه-n برای تعیین تعداد بایت استفاده کنید.-n 32 در مثال زیر باعث می شود که hexdump فقط 32 بایت از فایل را نشان دهد.
اگر فقط به داده ها در فاصله ای از فایل علاقه مند هستید، می توانید از گزین ه-s برای تعیین فاصله در فایل برای شروع تخلیه استفاده کنید.-s 16 در مثال زیر باعث می شود که hexdump محتوای فایل را نشان دهد که از ابتدا 16 بایت شروع می شود و تا انتهای فایل ادامه می یابد.:
همچنین میتوانید این دو سوییچ را با هم ترکیب کنید تا زیرمجموعهای از دادهها را در فایل مشاهده کنید. در این مثال، استفاده از هر د و-s 16 و-n 32 باعث می شود که hexdump 32 بایت از فایل را که از ابتدا 16 بایت شروع می شود، نشان دهد.
با استفاده از گزین ه-v می توانید از جایگزینی خطوط تکراری با * جلوگیری کنید. در مثال زی ر-v باعث میشود که ردیفهای تکراری قبلا جمعشده در آفست 30 هگز و 40 هگز نمایش داده شوند:
این شامل استفاده اساسی از hexdump است و تا همین اواخر برای تمام نیازهای من کافی بوده است.
به عنوان مثال ، یک جدول پارتیشن با استفاده از hexdump
من می خواستم جدول پارتیشن را روی دیسک ریخته باشم تا بتوانم آن را از طریق یک دستگاه loopback سوار کنم. دریافت اطلاعات لازم از FDISK با تعویض آن برای نشان دادن واحدهای به اندازه بخش آسان است اما فکر می کردم با HexDump بازی می کنم تا خودم را مجبور کنم از نحو قالب استفاده کنم. این جایی است که ما به سر می بریم:
جدول پارتیشن شامل چهار ورودی 16 بایت در افست 446 بایت در دیسک است (یعنی در بخش اول یک دیسک معمولی). در اینجا مثالی از تصویری از دیسک وجود دارد که یک پارتیشن واحد دارد:
به طور تصادفی طول ورود جدول پارتیشن و طول خط پیش فرض Hexdump 16 بایت است بنابراین هر خط یک ورودی جدول کامل است.
احتمالاً بهتر است که Hexdump به جای چگال کردن خطوط تکراری ، کل بلوک را نشان دهد:
رمزگشایی این مسئله به ویژه دشوار نیست که با توجه به اطلاعات منتشر شده در مورد قالب ورودی های جدول پارتیشن ، اما می توانید Hexdump را به تنهایی انجام دهید و به اندازه کافی در مورد Hexdump بیاموزید تا بتوانید در آینده آن را در مورد چیزهای دیگر اعمال کنید. برای این کار لازم است که به نحو قالب بندی حفر شود.
معرفی رشته فرمت
یک رشته فرمت با گزینه خط فرما ن-e مشخص شده است. صفحه Hexdump Man تمام عناصر نحوی را توصیف یا ارجاع می دهد و نمونه هایی از آن را ارائه می دهد اما برای تعیین چگونگی انجام کاری نه در مثالها ، کار لازم است. در اینجا چیز بسیار ساده ای وجود دارد که فقط کل جدول را به عنوان مقادیر جدا شده بایت در شش ضلعی جدا می کند:
شما استفاده ا ز-n ، -s و-v را تشخیص خواهید داد تا 64 بایت را در افست 446 بدون فروپاشی تکثیر کند. بقیه عبارت فرمت و پرونده برای حذف است. توجه داشته باشید که بیان قالب در نقل قول های منفرد محصور شده است: ‘. 1/1 به معنای فرآیند یک بایت در گروه های یک است. نحو N/M مختص Hexdump است و چند مورد دیگر از Hexdump وجود دارد اما عنصر شروع با یک ٪ از خانواده عملکرد C PrintF می آید ، در صفحه Hexdump Man به آن اشاره شده است و می توانید به نحو بیشتر نگاه کنیدجزئیات با Man 3 Printf.
به عنوان مثال ، "٪ 02x" به معنای خروجی فضایی است که به دنبال آن مقدار یک بایت منفرد به عنوان دو رقم شش ضلعی با صفر پیشرو است.٪ به معنای درج مقادیر از پرونده در این مرحله در خروجی است و آنچه در زیر ٪ دنبال می شود ، نحوه انجام این کار را توصیف می کند. X به معنای خروجی در شش ضلعی و 2 به معنای خروجی به عنوان یک عدد دو رقمی و صفر به معنای خروجی صفرهای پیشرو در هنگام طول کمتر از دو رقم است.
استفاده از یک حروف بزرگ به این معنی است که رقم A از طریق F در اعداد شش ضلعی در حروف بزرگ قرار می گیرد. با استفاده از یک حروف کوچک ، باعث می شود که این رقم ها به عنوان یک از طریق F در حروف کوچک تولید شوند.
دریافت خروجی در خطوط
# در انتهای خروجی در مثال بالا ، سریع پوسته بعدی است ، من هیچ قالب بندی انتهای خط را در مثال درج نکردم ، بنابراین ابتدا آن را اصلاح می کنم. از دنباله کاراکتر \ n برای مشخص کردن یک خط جدید استفاده می شود و همچنین از خانواده C PrintF تهیه می شود. اما اگر فقط یک \ n اضافه کنم ، 64 خط خروجی با یک مقدار بایت دریافت می کنم:
این به این دلیل است که کل بیان نقل شده به طور مکرر به طور مکرر تجزیه می شود تا زمانی که کل مقدار سوئی چ-n برآورده نشود. مثال بالا بیان یک بار یک بایت را پردازش می کند و یک فید خط اضافه می کند. این امر برای تأمین نیا ز-N 64 باید 64 بار انجام شود.
بلوک های دامپینگ داده ها (M/N)
اگر به آن 1/1 برگردیم ، می توانیم با مشخص کردن 16/1 به جای 1/1 ، به Hexdump بگوییم که بایت های خروجی را در گروه های 16 (اندازه یک جدول یک پارتیشن) به دست آورد:
16/1 برگشت پذیر نیست ، شماره اول تعداد عناصر برای پردازش در یک گروه و شماره دوم طول عنصر است. شانزده ارزش بایت تک آن چیزی است که من به دنبال آن هستم. راه دیگر ، 1/16 ، یک مقدار شانزده بایت خواهد بود. این منجر به خطای "شمارش بایت بد برای شخصیت تبدیل x" می شود. مقدار پس از / تعداد بایت برای پردازش برای هر ٪ 02x و مقدار قبل از / تعداد دفعات تکرار آن عمل است.٪ 02x مقدار 128 بیتی (16 بایت) را رمزگشایی نمی کند ، از این رو خطا. بنابراین ، 16/1 نحو مناسب است.
تقسیم عناصر فردی از داده های ساختاری
اکنون باید برخی از جزئیات را پر کنم. اولین بایت یک جدول پارتیشن یک مقدار وضعیت است که نشان می دهد پارتیشن قابل بوت است یا خیر. من آن را به عنوان گزینه رمزگشایی خود با استفاده از اولین بایت در انزوا و 15 بایت باقیمانده در هر پارتیشن به عنوان یک گروه جدا می کنم:
البته این به نظر نمی رسد متفاوت باشد ، اما من به سختی شروع کرده ام. بعدی در یک جدول جدول پارتیشن ، یادگار اولین رایانه های شخصی با دیسک های سخت است. سه مقدار بایت فردی وجود دارد که مکان شروع ، بخش و سیلندر (حداقل 8 بیت قابل توجه) را برای پارتیشن مشخص می کند. این یک گروه از سه مقدار بایت واحد است:
3/1 "٪ 02x" 12/1
خروجی دهدهی
این هنوز فرقی ندارد ، رئیس ، بخش و سیلندر از اهمیت عددی برخوردار هستند ، بنابراین من آنها را در اعشاری برای خوانایی انسان نشان خواهم داد:
عنصر فرمت جدید "٪ 3D" است ، به این معنی که یک فضا را به دنبال آن یک میدان سه کاراکتر در اعشاری قرار می دهد. مقادیر بایت می تواند بین صفر تا 255 در اعشاری باشد ، بنابراین نمی تواند بیش از سه رقم باشد. از آنجا که مقدار عددی مرتبط است ، من پیشوند صفر را بدون ریختن پیشوند طول کاهش داده و یک قسمت مناسب و مناسب و مناسب را دریافت می کنم. می بینید که پارتیشن 1 دارای کد وضعیت صفر است و از سیلندر صفر ، سر 1 ، بخش 1. شروع می شود. این مکان عادی برای اولین پارتیشن روی دیسک است.
بعدی نوع پارتیشن ، یک بایت منفرد دیگر:
1/1 "٪ 02x" 11/1
بعدی ، بخش و سیلندر (حداقل 8 بیت قابل توجه) محل پایان پارتیشن است. من دوباره در اعشاری انجام خواهم داد:
داده های 32 بیتی
اکنون ساختار شروع به نمایش می کند. پس از آن به مقادیری که در نصب سیستم های فایل مفید خواهد بود و برای کدام یک از خروجی های بایت تنها مفید نیست. شماره بخش شروع (آدرس بلوک منطقی ، یا LBA) و طول (در بخش ها) برای پارتیشن به عنوان 32 مقادیر بیتی آورده شده است:
توجه داشته باشید که آخرین تغییر به یک مشخص کننده شمارش 2/4 اضافه می کند ، یعنی 2 نمونه از یک مقدار 4 بایت (32 بیتی). قالب ٪ 08x به معنای خروجی مقدار به عنوان یک عدد شش ضلعی شش ضلعی با صفرهای پیشرو است. از آنجا که مقادیر LBA دارای اهمیت عددی هستند ، در اعشاری و بدون صفر paddingl مفیدتر خواهد بود
طولانی ترین تعداد اعشاری 32 بیتی دارای نه رقم است ، در مقابل هشت رقم برای همان تعداد در شش ضلعی ، بنابراین "٪ 08x" را به "٪ 9d" تغییر دادم.
امضا شده/بدون امضا
این تمام چیزی بود که نیاز داشتم، اما کمی بی دقت بودم، اگرچه این بار بر خروجی تأثیری نداشت. کاراکتر فرمت d می گوید که مقدار امضا شده است (می تواند مثبت یا منفی باشد). پارتیشن ها نمی توانند مقادیر سکتور، سر، سیلندر یا LBA منفی داشته باشند. در بیشتر پلتفرمها، یک مقدار صحیح را نمیتوان تنها بر اساس مقادیر بایتها بهعنوان امضا یا بدون علامت شناسایی کرد. دانش خارجی مورد نیاز است که بیان کند آیا باید یک مقدار را به صورت امضا شده یا بدون علامت تفسیر کرد. از آنجایی که میدانم همه مقادیر بدون علامت هستند، در هر جایی که یک d با فرمت % داشتم، باید آن را با یک u جایگزین کنم تا نشان دهد مقدار بدون علامت است (فقط مقادیر مثبت):
اضافه کردن متن اضافی به خروجی
شما می توانید متن تحت اللفظی انتخابی خود را در خروجی از hexdump داشته باشید. ما در واقع قبلاً مقدار زیادی از آن را در فضاها و
مقادیری که استفاده کردهایم داشتهایم. می توانید چیزهای دیگری اضافه کنید و خروجی را معنادارتر کنید:
“پارتیشن:|%02x”
آن تغییرات به ما حاشیه های ستون و یک کلمه مقدماتی در هر خط داد.
آن را در یک پوسته اسکریپت با مقداری طرح بندی قرار دهید
بنابراین، اکنون من یک خط فرمان hexdump دارم که جدول پارتیشن را تخلیه می کند. در اینجا در یک پوسته اسکریپت با چند حاشیه سلول اضافه شده است:
آن را به عنوان partdump در جایی در مسیر ذخیره کنید، حالت را به اجرایی تغییر دهید و یک ابزار جالب جدید دارید:
این یک دنیای 64 بیتی است!
به همان اندازه که خوب است، به سختی سطح کاری را که می توانید با هگزدامپ انجام دهید خراش می دهد. تمام کاری که ما انجام دادهایم این است که مقادیر 8 بیتی و 32 بیتی را به صورت اعشاری هگزادسیمال و علامتدار/بدون علامت با عرض فیلدهای مختلف و طرحبندیهای مقادیر مختلف مانند صفرهای اصلی یا فاصلهها مدیریت کنیم. اینها عملیات اعداد صحیح هستند. این روزها باید بتوانید با مقادیر بیش از 32 بیت مقابله کنید. دستور printf برای مقادیر 64 بیتی در hexdump ضروری نیست. شما فقط می توانید مشخص کنید که با یک مقدار 64 بیتی (8 بایت) کار می کنید و چه فرمت خروجی را می خواهید. به عنوان مثال، اگر مقادیر LBA یک 64 بیتی بودند، می توانید این کار را انجام دهید تا آنها را به صورت هگزادسیمال ببینید - توجه داشته باشید که این دیگر تفسیر معتبری از جدول پارتیشن نیست:
توجه داشته باشید که مقدار ffead50000003f در پایان به صورت یک مقدار 8 بایتی (1/8) و خروجی در هگزادسیمال %x فرمت شده است. می توانید از %16x برای حفظ تراز ستون عددی استفاده کنید:
و می توانید صفرهای ابتدایی را وارد کنید:
و می توانید به جای هگزادسیمال از اعشار امضا شده استفاده کنید:
و می توانید به جای هگزادسیمال از اعشار بدون علامت استفاده کنید:
متن در یک فایل
همه مقادیر در یک فایل باینری عددی نیستند، فایل ممکن است حاوی متن نیز باشد. hexdump راهی برای نشان دادن آن نیز فراهم می کند. برخلاف خانواده توابع C printf، شما باید از قبل بدانید متن چقدر طولانی است و راه های زیادی برای رسیدن به همان چیز وجود دارد. با بازگشت به فایل اجرایی ELF که با آن شروع کردم، می توانید امضا را همانطور که هست حذف کنید:
با هر یک از اینها تأثیر یکسانی خواهید داشت:
مثالهای بسیار دیگری وجود دارد که از همان سه کاراکتر اما با ترتیببندیهای مختلف فیدهای خط خروجی میدهند. مثال های _p، _c و _u مختص hexdump هستند و بخشی از نحو printf نیستند. _p باعث می شود کاراکترهایی که علامت استاندارد ندارند به عنوان یک خروجی داده شوند.- می توانیم ببینیم که با چند بایت فراتر از F در امضای ELF:
توجه داشته باشید که اولی با استفاده از استاندارد printf %c چیزی را برای دو کاراکتر بعد از ELF نمایش نمیدهد، اما دومی یک نقطه برای هر کاراکتر بعد از ELF نمایش میدهد. این به تراز کمک می کند و نشان می دهد که چه زمانی داده ها از متن (نویسه های چاپی) به غیر متن (نویسه های غیر چاپی) تغییر می کنند.
مثال _c متن را در مجموعه شخصیت پیش فرض میزبان خروجی می کند و شخصیت های غیر چاپی را بر اساس مقدار در اکتال (پایه 8) نشان می دهد:
بنابراین ، نقاط پس از ELF مقادیر بایت 2 و 1 هستند (اکتال در اینجا به عنوان سه رقم خروجی است).
مثال _u متن را در ما ASCLL با کاراکترهای کنترل (کسانی که دارای مقادیر بایت اعشاری کمتر از 32 و مقدار 255 هستند) با نام کنترل سه شخصیت آنها نمایش داده می شود:
این یک شروع شخصیت کنترل متن است که به دنبال آن شروع شخصیت کنترل عنوان است. در این پرونده ، مقادیر بایت آن کاراکترهای کنترل ASCII را نشان نمی دهد ، اما می توانید ببینید که چگونه می توانید از ٪ s ، ٪ _p ، ٪ _c و ٪ _u در صورت مناسب برای انواع مختلف فایلهای ورودی استفاده کنید.
پرونده هایی با متن و داده های عددی
درست همانطور که ما خروجی 8 ، 32 و 64 ٪ x را با یکدیگر ترکیب کردیم و با مقادیر اعشاری 8 ، 32 و 64 بیتی زودتر ، می توانیم مقادیر عددی و متنی را در همان خط فرمان ترکیب کنیم:
‘1/1" ٪ 02x "3/1" ٪ _u "2/1" ٪ 02x "
م ن-s 1 را حذف کردم تا بتوانید متن را بین برخی دیگر از داده ها مشاهده کنید.
اعداد با یک قسمت کسری
در دنیای برنامه نویسی آنها به عنوان شماره های نقطه شناور شناخته می شوند. hexdump می تواند آنها را نشان دهد اما هیچ تضمینی وجود ندارد که مقدار نقطه شناور در یک پرونده در قالب نقطه شناور بومی میزبان باشد. با این اوصاف. اگر می دانستید که یک مقدار نقطه شناور 5213 بایت در آن پرونده ELF وجود دارد (که در واقعیت وجود ندارد):
-n 8-v -e ‘1/8" ٪ f "
یک بار دیگر می توانید آن را با گزینه های دیگر با سایر گزینه ها ترکیب کنید تا به عناصر پی در پی پرونده که دارای قالب های مختلف هستند نگاه کنید. طول پیش فرض تبدیل ٪ f 8 بایت است ، بنابراین می توانید 1/8 را از مثال رها کنید زیرا هیچ مقدار فرمت دیگری وجود ندارد و طول زباله 8 است. اگر این تعداد دارای رقم های زیادی باشد ، می توانید آن را نشان دهیدقالب نمایی:
اگر ترجیح می دهید E با حروف بزرگ باشد ، می توانید از ٪ g استفاده کنید:
هر سه این قالب های نقطه شناور نیز می توانند بر روی 4 نوع نقطه شناور بایت کار کنند:
من دیگر نمی دانم کجا در پرونده هستم
هنگامی که تعداد زیادی از عناصر را در یک پرونده رمزگشایی می کنید ، می توانید به آن چنان خروجی بپردازید که نمی توانید بگویید مقدار مشخصی در پرونده است. در نمونه های اول که دیدید Hexdump خروجی را در ستون اول وارد پرونده می کند:
شما می توانید همان را به رمزگشایی خود اضافه کنید و یک پیشوند _A را به هر یک از انواع فرمت عدد صحیح اضافه کنید: x ، d ، o. اگر پرونده نمونه دارای 8 مقدار نقطه شناور 4091 بایت در پرونده بود و من می خواستم مکان هر یک را بدانم:
من نوار را درج کردم تا بتوانید مشکل را مشاهده کنید که مقدار سرریز شود تا یک رقم جدید اضافه شود. ما می توانیم از همان پیشوندها به ٪ _ax و ٪ _ad استفاده کنیم که می توانیم به ٪ x و ٪ d عادی باشیم:
اعشاری احتمالاً برای خوانایی انسان مفیدتر است:
یک نسخه خاص از گزینه File-Position وجود دارد که موقعیت بایت بعدی را در پرونده پس از آخرین خروجی مقدار ، _a نشان می دهد:
4155 تأثیر ٪ _ad است ، تورفت اضافی عمدی بود. گزینه _A می تواند در هنگام ساخت خروجی از چندین خط فرمان hexdump مفید باشد و می خواهید بدانید که بدون نیاز به محاسبه آن ، چه مقدار از دستور بعدی استفاده کنید.
عرض زمینه سفارشی
هنگام مشخص کردن عرض میدان بعد از ٪ ، می توانید از نحو دیگری برای توصیف عرض کلی برای خروجی مقدار در و تعداد رقم های خروجی استفاده کنید. به عنوان مثال ، موارد زیر معادل است:
در حالت دوم ٪ 08x را با 8. 8x ٪ جایگزین کردم. در نحو دوم ، تعداد قبل از نقطه ، عرض کلی این زمینه است و تعداد بعد از نقطه تعداد رقم های خروجی برای تولید است. اگر شماره اول از دوم بزرگتر باشد ، مقدار خروجی مناسب است. بنابراین ، ما می توانیم مقدار 8 رقمی Hex را در یک قسمت 10 کاراکتر داشته باشیم:
مقدار شماره اول یا دوم هر چه باشد ، کل طول که از طول ورودی دلالت دارد و کاراکتر فرمت خروجی است ، بنابراین شما نمی توانید هگزدپ را با 0. 0x ٪ فریب دهید:
مقادیر به طور کامل خروجی و توجیه شده باقی مانده بودند.
همه اش را بگذار کنار هم
در زیر یک نمونه واقعاً بزرگ است که از بسیاری از دستورات Hexdump با متغیرهای پوسته ، عملیات حسابی و منطق استفاده می کند تا یک بسته را از یک پرونده TCPDump به پایین به عنوان TCP برساند - درج جبران صحیح برای برخی دیگر از پرونده های TCPDump به عنوان یک تمرین برای یک تمرین برایخواننده: