Binary Analysis – PART TWO

Binary Analysis – PART TWO

در قسمت قبل با فازهای کامپایل یک فایل سی آشنا شدیم.در این قسمت و قسمت های آینده نیز به مرور وارد مباحث سطح پایین میشویم و به بررسی بیشتر فایل های باینری میپردازیم.در قسمت قبل پس از بررسی مراحل کامپایل ، هویت فایل اجرایی را بررسی کردیم و به اطلاعاتی رسیدم.قرارمان بر این شد تا آخرین خروجی ابزار file را بررسی کنیم.به صورت پیشفرض، خروجی کامپایلر gcc به صورت a.out است.ولی میتوانیم با فلگ o- نامی معین برای فایل اجراییمان انتخاب کنیم.با توجه به خروجی ابزار file در شکل بالا میدانیم که با یک فایل اجرایی 64 بیتی ELF سروکار داریم.از دیگر اطلاعات مهم در خروجی بالا میتوان به داینامیک بودن این فایل اشاره کرد.به این معنا که از کتابخانه هایی استفاده میکند که به طور مستقیم در فایل اجرایی ادغام نمیشوند.در واقع کتابخانه های نصب شده بر روی سیستم‌عامل به صورت مجزا با آن به اشتراک گذاشته میشود.سرانجام عبارت interpreter /lib64/ld-linux-x86-64.so.2 به شما میگوید که فایل آبجکت توسط کدام لینکر تفسیر و تبدیل به فایل اجرایی شده.هنگام کامپایل یک سورس کد به یک زبان سطح بالا(مانند سی‌پلاس‌پلاس) ،فایل کامپایل شده میتوانند حاوی اطلاعاتی باشد که برای اجرای برنامه ضروری نیست اما برای دیباگینگ و یافتن مشکلات موجود در برنامه مفید هستند.از میان این اطلاعات میتوان به نام توابع،متغییر ها و سایر سمبل‌ها نظیر آدرس های حافظه اشاره کرد.برای آنکه یک ایده کلی از اطلاعات موجود در این سمبل ها داشته باشید ، من از ابزار readelf در لینوکس استفاده میکنم.readelf یکی از ابزار های قدرتمند برای تحلیل فایل‌های اجرایی ELF در سیستم عامل های خانواده یونیکس است.خوشبختانه این ابزار دارای یک manual page است که میتوانید برای کسب اطلاعات بیشتر آن را با این دستور مشاهده کنید: man readelf .با استفاده از دستور readelf –syms a.out برنامه ساخته شده در قسمت گذشته را مورد بررسی قرار میدهیم.برای بررسی بهتر، خروجی را در اختیارتان قرار میدهم:Symbol table ‘.dynsym’ contains 7 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[…]
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2)
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND […]@GLIBC_2.2.5 (2)
4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
5: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[…]
6: 0000000000000000 0 FUNC WEAK DEFAULT UND […]@GLIBC_2.2.5 (2)

Symbol table ‘.symtab’ contains 66 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000000002a8 0 SECTION LOCAL DEFAULT 1
2: 00000000000002c4 0 SECTION LOCAL DEFAULT 2
3: 00000000000002e8 0 SECTION LOCAL DEFAULT 3
4: 0000000000000308 0 SECTION LOCAL DEFAULT 4
5: 0000000000000328 0 SECTION LOCAL DEFAULT 5
6: 00000000000003d0 0 SECTION LOCAL DEFAULT 6
7: 0000000000000452 0 SECTION LOCAL DEFAULT 7
8: 0000000000000460 0 SECTION LOCAL DEFAULT 8
9: 0000000000000480 0 SECTION LOCAL DEFAULT 9
10: 0000000000000540 0 SECTION LOCAL DEFAULT 10
11: 0000000000001000 0 SECTION LOCAL DEFAULT 11
12: 0000000000001020 0 SECTION LOCAL DEFAULT 12
13: 0000000000001040 0 SECTION LOCAL DEFAULT 13
14: 00000000000011c8 0 SECTION LOCAL DEFAULT 14
15: 0000000000002000 0 SECTION LOCAL DEFAULT 15
16: 0000000000002014 0 SECTION LOCAL DEFAULT 16
17: 0000000000002048 0 SECTION LOCAL DEFAULT 17
18: 0000000000003de8 0 SECTION LOCAL DEFAULT 18
19: 0000000000003df0 0 SECTION LOCAL DEFAULT 19
20: 0000000000003df8 0 SECTION LOCAL DEFAULT 20
21: 0000000000003fd8 0 SECTION LOCAL DEFAULT 21
22: 0000000000004000 0 SECTION LOCAL DEFAULT 22
23: 0000000000004020 0 SECTION LOCAL DEFAULT 23
24: 0000000000004030 0 SECTION LOCAL DEFAULT 24
25: 0000000000000000 0 SECTION LOCAL DEFAULT 25
26: 0000000000000000 0 FILE LOCAL DEFAULT ABS abi-note.c
27: 00000000000002e8 32 OBJECT LOCAL DEFAULT 3 __abi_tag
28: 0000000000000000 0 FILE LOCAL DEFAULT ABS init.c
29: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
30: 0000000000001070 0 FUNC LOCAL DEFAULT 13 deregister_tm_clones
31: 00000000000010a0 0 FUNC LOCAL DEFAULT 13 register_tm_clones
32: 00000000000010e0 0 FUNC LOCAL DEFAULT 13 __do_global_dtors_aux
33: 0000000000004030 1 OBJECT LOCAL DEFAULT 24 completed.0
34: 0000000000003df0 0 OBJECT LOCAL DEFAULT 19 __do_global_dtor[…]
35: 0000000000001130 0 FUNC LOCAL DEFAULT 13 frame_dummy
36: 0000000000003de8 0 OBJECT LOCAL DEFAULT 18 __frame_dummy_in[…]
37: 0000000000000000 0 FILE LOCAL DEFAULT ABS file.c
38: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
39: 000000000000211c 0 OBJECT LOCAL DEFAULT 17 __FRAME_END__
40: 0000000000000000 0 FILE LOCAL DEFAULT ABS
41: 0000000000003df0 0 NOTYPE LOCAL DEFAULT 18 __init_array_end
42: 0000000000003df8 0 OBJECT LOCAL DEFAULT 20 _DYNAMIC
43: 0000000000003de8 0 NOTYPE LOCAL DEFAULT 18 __init_array_start
44: 0000000000002014 0 NOTYPE LOCAL DEFAULT 16 __GNU_EH_FRAME_HDR
45: 0000000000004000 0 OBJECT LOCAL DEFAULT 22 _GLOBAL_OFFSET_TABLE_
46: 0000000000001000 0 FUNC LOCAL DEFAULT 11 _init
47: 00000000000011c0 5 FUNC GLOBAL DEFAULT 13 __libc_csu_fini
48: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[…]
49: 0000000000004020 0 NOTYPE WEAK DEFAULT 23 data_start
50: 0000000000000000 0 FUNC GLOBAL DEFAULT UND [email protected]@GLIBC_2.2.5
51: 0000000000004030 0 NOTYPE GLOBAL DEFAULT 23 _edata
52: 00000000000011c8 0 FUNC GLOBAL HIDDEN 14 _fini
53: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_mai[…]
54: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 23 __data_start
55: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
56: 0000000000004028 0 OBJECT GLOBAL HIDDEN 23 __dso_handle
57: 0000000000002000 4 OBJECT GLOBAL DEFAULT 15 _IO_stdin_used
58: 0000000000001150 101 FUNC GLOBAL DEFAULT 13 __libc_csu_init
59: 0000000000004038 0 NOTYPE GLOBAL DEFAULT 24 _end
60: 0000000000001040 47 FUNC GLOBAL DEFAULT 13 _start
61: 0000000000004030 0 NOTYPE GLOBAL DEFAULT 24 __bss_start
62: 0000000000001139 23 FUNC GLOBAL DEFAULT 13 main
63: 0000000000004030 0 OBJECT GLOBAL HIDDEN 23 __TMC_END__
64: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[…]
65: 0000000000000000 0 FUNC WEAK DEFAULT UND [email protected]@[…]همانطور که مشاهده میکنید نمادها و سمبل هایی در خروجی این دستور نشان داده شد.در پارت های آینده این ابزار را بیشتر مورد بررسی قرار خواهم داد.از نکات جالب در این خروجی میتوان به خط 75 اشاره کرد.در این خط مقدار main در آدرس 0x001139 بارگیری(load) و با سایز 23 بایت ذخیره شده.همچنین نوع این سمبل از نوع FUNC به معنای تابع است.اطلاعات سمبلیک را میتوان به عنوان بخشی از یک فایل باینری (مثال بالا) و یا به صورت یک فایل سمبلیک به صورت مجزا منتشر کرد.لینکر فقط به سمبل‌های اساسی نیاز دارد،اما اطلاعات گسترده‌تری را میتواند برای دیباگینگ منتشر کند.در فایل‌های باینری با فرمت اجرایی ELF ، سمبل‌های دیباگینگ معمولا در قابل فرمت DWARF تولید میشوند. درحالی که باینری های PE معمولا از قالب اختصاصی Microsoft Portable Debugging (به اختصار PDB) استفاده میکنند.اطلاعات DWARF معمولا در خود باینری جاسازی میشوند،درحالی که در (PDB) به شکل یک فایل جداگانه در می آیند.احتمالا متوجه شده باشید که اطلاعات سمبلیک میتوانند برای آنالیز فایل‌های باینری مفید باشند.به عنوان مثال شما با داشتن چنین اطلاعاتی میتوانید فرایند دیس‌اسمبل و تحلیل آن را بسیار آسان کنید زیرا میتوانید از هر سمبلی به عنوان نقطه شروع دیس‌اسمبل کردن استفاده کنید.دانستن اینکه کدام قسمت باینری به کدام تابع تعلق دارد میتواند کار را برای مهندسی معکوس راحتتر کند.اگر یادتان باشد در مثالی که زده شد،فایل تولید شده از نوع استریپ نشده بود.ظاهرا gcc به صورت پیشفرض کد را استریپ نمیکند.در صورتی که کنکجاو هستید که این سمبل ها چگونه از بین میرود،باید بگویم این کار ساده است.میتوانید از ابزار strip به این شکل استفاده کنید :strip –strip-all <execfile>اکنون که با نحوه کامپایل آشنا شدیم،بیاید نگاهی به محتویات آبجکت فایل تولید شده در فاز اسمبلی بیندازیم.پس از آن من فایل قابل اجرای باینری را دیس‌اسمبل میکنم تا به شما تفاوت محتوای این دو را نشان دهم.به این ترتیب درک واضح‌تری از آنچه در یک آبجکت فایل است و آنچه در مرحله لینکر ساخته میشود خواهیم گرفت.در حال حاضر من از ابزار objdump برای نشان دادن نحوه دیس‌اسمبل کردن آن استفاده خواهم کرد.این ابزار یک دیس‌اسمبلر ساده و پرکاربرد است که در اکثر توزیع های لینوکسی به صورت دیفالت وجود دارد. همچنین برای ایده گرفتن سریع از کد و داده های موجود در باینری بسیار عالی است.اگر به تصویر دقت کنید خواهید دید که من دوبار objdump را فراخوانی کردم.ابتدا برای مشاهده سکشن rodata. که مخفف read-only-data است و بخشی از محتویات باینری در آن ذخیره میشود.از جمله استرینگ Hello,World که در کد وارد کرده بودیم.توجه داشته باشید که محتویات rodata. از یک کدگذاری اسکی(ASCII) تشکیل شده است که میتوانید آن را در سمت چپ خروجی و در سمت راست نیز بایت های قابل خوانش برای انسان را مشاهده کنید.دومین فراخوانی برای دیس‌اسمبل کردن تمام آبجکت فایل با سینتکس اینتل استفاده شده است.file.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <main>:
0: 55 push rbp
1: 48 89 e5 mov rbp,rsp
4: 48 8d 3d 00 00 00 00 lea rdi,[rip+0x0] # b <main+0xb>
b: e8 00 00 00 00 call 10 <main+0x10>
10: b8 00 00 00 00 mov eax,0x0
15: 5d pop rbp
16: c3 ret همانطور که مشاهده میکنید،این تنها شامل کد تابع main برنامه است(خط6) که آن را قبلا در داخل سورس کد تعریف کردیم.در اکثر مواقع ، این خروجی با کد اسمبلی که قبلا آن را در فاز کامپایل دیدیم مطابقت دارد.چیزی که در این کد باید به آن توجه کنیم،فراخوانی دهمین آفست تابع main است و مشخص نیست چه چیزی فراخوانی میشود اما چرا؟!چرا این فراخوانی به جای یک تابع به مکان نامشخصی اشاره میکند؟درواقع در آبجکت فایل ها منابع و سورس کد تعیین نشده و وظیفه تعیین کردن هربخش برعهده لینکر است.برای مشاهده رفرنس های این فایل از همان ابزار readelf و با فلگ relocs استفاده میکنیم.این فلگ محتویات بخش relocation را درصورت وجود نشان میدهد.Relocation section ‘.rela.text’ at offset 0x1f8 contains 2 entries:Offset Info Type Sym. Value Sym. Name + Addend000000000007 000500000002 R_X86_64_PC32 0000000000000000 .rodata – 400000000000c 000b00000004 R_X86_64_PLT32 0000000000000000 puts – 4Relocation section ‘.rela.eh_frame’ at offset 0x228 contains 1 entry:Offset Info Type Sym. Value Sym. Name + Addend000000000020 000200000002 R_X86_64_PC32 0000000000000000 .text + 0در خط سوم به لینکر گفته میشود که باید آدرس های فراخوانی را تعیین کند تا برنامه بتواند به هر آدرسی از سکشن rodata. دسترسی پیدا کند.همچنین در خط چهارم به لینکر گفته میشود که چگونه میتواند فراخوانی تابع Puts را تعیین کند.به جهت طولانی نشدن مطلب آن را همینجا به اتمام میرسانم در قسمت سوم به بررسی فایل های اجرایی خواهم پرداخت.

Author: admin

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *