زنگ.

کسانی هستند که این خبر را قبل از شما خوانده اند.
مشترک شدن برای دریافت مقالات تازه.
پست الکترونیک
نام
نام خانوادگی
چگونه می خواهید زنگ را بخوانید
بدون هرزنامه

اختیاری و به نام استدلال

استدلال اختیاری

در نسخه C # 4.0، یک ابزار جدید افزایش راحتی مشخص کردن استدلال در هنگام فراخوانی یک روش است. این ابزار نامیده می شود استدلال اختیاری و اجازه می دهد تا شما را به تعیین مقدار پیش فرض برای پارامتر روش. این مقدار این به طور پیش فرض مورد استفاده قرار می گیرد اگر استدلال مربوطه برای پارامتر مشخص نشده باشد، زمانی که روش نامیده می شود. در نتیجه، این استدلال را مشخص کنید که چنین پارامتر لازم نیست. استدلال های اختیاری به شما این امکان را می دهد که تماس را به روش هایی که استدلال های پیش فرض به برخی از پارامترها اعمال می شود، ساده کنید. آنها همچنین می توانند به عنوان یک فرم "اختصار روش های بیش از حد استفاده شوند.

محرک اصلی برای اضافه کردن استدلال اختیاری، نیاز به ساده سازی تعامل با امکانات COM بود. در چندین مدل مایکروسافت شی (به عنوان مثال، مایکروسافت آفیس)، عملکرد از طریق امکانات COM ارائه شده است، که بسیاری از آنها مدت ها پیش نوشته شده اند و برای استفاده از پارامترهای اختیاری طراحی شده اند.

یک مثال از استفاده از استدلال های اختیاری در زیر نشان داده شده است:

استفاده از سیستم؛ با استفاده از system.collections.genic؛ با استفاده از system.linq؛ با استفاده از system.text؛ فضای نام ConsoleApplication1 (برنامه کلاس (// arguments b و با مشخص کردن زمانی که فراخوانی استاتیک INT Mysum (int a، int b \u003d 5، int c \u003d 10) (بازگشت A + B + C؛) استاتیک Void Main () (Int Sum1 \u003d mysum (3)؛ int sum2 \u003d mysum (3،12)؛ console.writeline ("sum1 \u003d" + sum1)؛ console.writeline ("sum2 \u003d" + sum2)؛ console.readline ()؛))

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

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

به نام استدلال

یکی بیشتر عملکردکه به C # اضافه شده است با نسخه خروجی نسخه .NET 4.0، حمایت از به اصطلاح است به نام استدلال (به نام استدلال). همانطور که شناخته شده است، هنگام انتقال استدلال، روش آنها به دنبال آنها، به عنوان یک قاعده، باید با این نظم هماهنگ شود که در آن پارامترها در روش خود تعریف شده است. به عبارت دیگر، ارزش این استدلال به پارامتر توسط موقعیت آن در لیست استدلال اختصاص داده شده است.

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

نام پارامتر: ارزش

اینجا نام پارامتر نام پارامتر را نشان می دهد که مقدار آن منتقل می شود. البته، Parameter_Name باید نام پارامتر معتبر را برای روش نامیده شده نشان دهد.

برچسب ها: مولفه های خط فرمان

تنظیمات خط فرمان

C و - زبان کامپایل شده. پس از مونتاژ، این برنامه یک فایل اجرایی است (ما ایجاد کتابخانه های پویا، رانندگان، و غیره را در نظر نمی گیریم). برنامه های ما بسیار ساده هستند و شامل کتابخانه های زمانبندی (کتابخانه های زمانبندی) نیستند، بنابراین آنها می توانند به یک کامپیوتر با همان سیستم عامل (و معماری مشابه) منتقل شوند و در حال اجرا هستند.

این برنامه در هنگام راه اندازی می تواند پارامترها را انجام دهد. آنها استدلال عملکرد اصلی هستند. نمای کلی عملکرد اصلی بعدی

void main (int argc، char ** argv) (...)

اولین استدلال ARGC تعداد توابع پارامتر منتقل شده است. استدلال دوم یک آرایه از رشته ها است - پارامترها در واقع هستند. از آنجا که پارامترهای تابع می تواند هر یک باشد، آنها به عنوان رشته ها منتقل می شوند، و برنامه خود باید آنها را از هم جدا کند و منجر به نوع مورد نظر شود.

اولین استدلال (ARGV) همیشه نام برنامه است. در این مورد، نام بسته به جایی که برنامه در حال اجرا بود، نام نمایش داده می شود.

#عبارتند از. #عبارتند از. void main (int argc، char ** argv) (printf ("٪ s"، argv)؛)

در حال حاضر یاد بگیرید که کمی با خط فرمان کار کنید. برای انتقال استدلال به برنامه ما، لازم است. ترکیبی از کلید Win + R پنجره «اجرای» را فراخوانی می کند. CMD را در آن تایپ کنید و خط فرمان را باز کنید. شما همچنین می توانید جستجو cmd.exe را در منوی شروع پیدا کنید. در یونیکس مانند سیستم های عاملآه، شما می توانید برنامه "ترمینال" را فراخوانی کنید.

ما تیم های زیادی را مطالعه نخواهیم کرد. فقط کسانی که در کار مورد نیاز است.

استاندارد برای تمام سیستم عامل، انتقال فرمان CD به پوشه مورد نظر منتقل می شود. دو نام رزرو شده وجود دارد -. (نقطه) و. (دو امتیاز). نکته نام پوشه فعلی است.

هیچ جا نمی رود

تجدید نظر به پوشه والدین

انتقال به پوشه والدین

برای انتقال به آدرس CD مورد نظر نوشته شده است. به عنوان مثال، شما باید به ویندوز به پوشه C: \\ Windows \\ System32 بروید

CD C: \\ Windows \\ System32

در لینوکس اگر شما نیاز به رفتن به پوشه / var / mysql دارید

CD / var / mysql

اگر مسیر شامل فضاهای باشد، آن را در دو نقل قول نوشته شده است

CD "D: \\ DOCUNTS و تنظیمات \\ Prolog"

ترمینال دارای ویژگی های مفید زیر است: اگر فلش بالا را فشار دهید، فرمان قبلی اجرا می شود. اگر شما برگه را فشار دهید، ترمینال سعی خواهد کرد یک رشته را به فرمان شناخته شده به آن اضافه کند یا مسیر را اضافه کند، تمام پوشه ها و فایل ها را در پوشه فعلی تبدیل کنید.
شماره گیری CD C:
برگه را فشار دهید و ببینید چه اتفاقی می افتد.

یکی دیگر از دستورالعمل های مهم DIR در ویندوز و LS در لینوکس، محتویات پوشه فعلی را به کنسول نمایش می دهد (پوشه ای که در آن شما در حال حاضر هستید)

برنامه شما نام کامل شما را بازگرداند به پوشه ای که برنامه شما واقع شده است بروید و محتویات آن را ببینید.


در حال حاضر، پس از اینکه ما به پوشه ما تغییر کردیم، می توانید برنامه ما را انجام دهید. برای انجام این کار، نام او را تایپ کنید.


توجه - نام تغییر کرده است از آنجا که برنامه از پوشه آن نامیده می شود، آن را نسبت به نام نمایش داده می شود. حالا شما برنامه را تغییر دهید و تمام استدلال ها را انجام دهید. چه کسی به او منتقل می شود

#عبارتند از. #عبارتند از. void main (int argc، char ** argv) (int i؛ برای (i \u003d 0؛ i< argc; i++) { printf("%s\n", argv[i]); } }

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


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

#عبارتند از. #عبارتند از. #عبارتند از. void main (int argc، char ** argv) (int a، b؛ اگر (argc! \u003d 3) (printf ("خطا: argment٪ d یافت می شود. دقیقا 2"، argc-1)؛ خروج (1)؛ ) a \u003d atoi (argv)؛ b \u003d atoi (argv)؛ printf ("٪ d"، a + b)؛)

ما جمع آوری و تماس می گیریم


بنابراین، اکثر برنامه ها کار می کنند. روی یک برچسب کلیک کنید، شما برنامه را که به آن اشاره می کنید تماس بگیرید. اکثر برنامه ها نیز استدلال های مختلفی را انجام می دهند. به عنوان مثال، شما می توانید تماس بگیرید مرورگر فایرفاکس از خط فرمان و استدلال انتقال
فایرفاکس.exe "www.mozilla.org" سایت "و آن را بلافاصله سایت ها را در دو زبانه در آدرس های مشخص شده باز کنید.

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

فقط پوشه ها را نمایش می دهد، و در ترمینال لینوکس

ls -l تمام فایل ها و پوشه ها را با ویژگی ها نمایش می دهد

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

هنگام ایجاد یک برنامه کنسول در زبان برنامه نویسی C ++، یک رشته به طور خودکار بسیار شبیه به این است:

int main (int argc، char * argv) // پارامترهای اصلی ()

این رشته یک هدر است تابع اصلی اصلی ()، پارامترهای ARGS و ARGV در براکت ها اعلام می شود. بنابراین، اگر برنامه را از طریق خط فرمان اجرا کنید، ممکن است هر گونه اطلاعاتی را به این برنامه انتقال دهید، برای این، و پارامترهای ARGC و ARGV وجود دارد. پارامتر ARGC دارای نوع داده int است و شامل تعداد پارامترهای منتقل شده به عملکرد اصلی است. علاوه بر این، ARGC همیشه حداقل 1 است، حتی زمانی که ما هیچ اطلاعاتی را انتقال نمی دهیم، زیرا پارامتر اول نام تابع است. پارامتر ARGV مجموعه ای از اشاره گرها به رشته ها است. از طریق خط فرمان، تنها نوع رشته می تواند منتقل شود. اشاره گرها و خطوط دو موضوع بزرگ هستند که بخش های جداگانه ای ایجاد می شوند. بنابراین از طریق پارامتر ARGV است و هر گونه اطلاعات انتقال می یابد. ما یک برنامه را توسعه خواهیم داد که ما از طریق فرمان اجرا خواهیم کرد رشته ویندوز، و برخی از اطلاعات را به آن انتقال دهید.

// argc_argv.cpp: نقطه ورودی را برای برنامه کنسول تعیین می کند. #include "stdafx.h" #include استفاده از Namespace STD؛ int main (int argc، char * argv) (اگر (argc\u003e<< argv<

// کد کد :: بلوک ها

// کد DEV-C ++

// argc_argv.cpp: نقطه ورودی را برای برنامه کنسول تعیین می کند. #عبارتند از. استفاده از Namespace STD؛ int main (int argc، char * argv) (اگر (argc\u003e 1) // اگر ما استدلال را انتقال دهیم، ARGC بیشتر از 1 (بسته به تعداد استدلال) (COUT<< argv<

پس از اینکه برنامه را شلاق زده اید، خط فرمان ویندوز را باز کنید و به پنجره خط فرمان برنامه ما در پنجره خط فرمان بکشید، مسیر کامل برنامه بر روی خط فرمان نمایش داده می شود (اما می توانید مسیر را تجویز کنید برنامه دستی)، سپس شما می توانید کلیک کنید وارد و برنامه شروع خواهد شد (شکل 1 را ببینید).

شکل 1 - تنظیمات عملکرد اصلی

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

شکل 2 - پارامترهای اصلی عملکرد

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

شکل 3 - پارامترهای اصلی عملکرد

و اگر نقل قول ها را حذف کنید من فقط کلمه آن را خواهم دید. اگر قصد ندارید هر گونه اطلاعاتی را هنگام شروع برنامه برنامه انتقال ندهید، می توانید استدلال را در عملکرد اصلی () حذف کنید، همچنین می توانید نام استدلال را تغییر دهید. گاهی اوقات اصلاح پارامترهای ARCC و ARGV وجود دارد، اما این همه بستگی به نوع برنامه ایجاد شده یا از محیط توسعه دارد.

با ایجاد خودکار یک برنامه کنسول در زبان برنامه نویسی C ++، عملکرد اصلی به طور خودکار بسیار شبیه به این است:

int main (int argc، char * argv)
{…}

هدر تابع شامل امضای اصلی اصلی اصلی () با استدلال ARGS و ARGV است.
اگر برنامه را از طریق خط فرمان اجرا کنید، ممکن است هر گونه اطلاعات را به این برنامه انتقال دهید. برای این، استدلال خط فرمان ARGC و ARGV وجود دارد.
پارامتر ARGC دارای نوع int است و شامل تعداد پارامترهای منتقل شده به عملکرد اصلی است. علاوه بر این، ARGC همیشه حداقل 1 است، حتی زمانی که توابع اصلی توسط هر گونه اطلاعات انتقال نمی یابند، زیرا نام برنامه اولین پارامتر در نظر گرفته شده است.
پارامتر ARGV مجموعه ای از اشاره گرها به رشته ها است. از طریق خط فرمان، تنها نوع رشته می تواند منتقل شود.

هنگامی که برنامه را از طریق خط فرمان ویندوز شروع می کنید، می توانید برخی از اطلاعات را به آن انتقال دهید. در این مورد، خط فرمان به نظر می رسد:
دیسک: \\ path \\ name.exe argument1 argument2 ...

استدلال خط فرمان توسط یک یا چند فضایی جدا شده است.

استدلال ARGV شامل نام کامل برنامه است:

#عبارتند از.
استفاده از Namespace STD؛

جامه<< argv << endl;

بازگشت 0؛
}

نتیجه اجرای

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

#عبارتند از.
استفاده از Namespace STD؛
int strtoint (char * s) (...)
int main (int argc، char * argv) (

int a \u003d 0، b \u003d 0؛

اگر (argc\u003e 1)

a \u003d strtoint (argv)؛

اگر (argc\u003e 2)

b \u003d strtoint (argv)؛

جامه<< a <<«*» << b << «= « << a*b << endl;

بازگشت 0؛
}

شروع برنامه به عنوان

نتیجه اجرای

اشکال زدایی از برنامه با استدلال خط فرمان

برای انتقال استدلال خط فرمان زمانی که اشکال زدایی برنامه، شما باید با منو تماس بگیرید خواص پروژه.


در برگه خواص پیکربندی -\u003e اشکال زدایی انتخاب کنید تیم استدلال و از ارزش های خود بپرسید.

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

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

گزینه های توابع تابع اصلی:
1. int main ()
2. int main (int argc، char ** argv)
3. int main (int argc، char ** argv، char ** env)
4. int main (int argc، char ** argv، char ** env، elfw (auxv_t) auxv)
5. int main (int argc، char ** argv، char ** env، char ** اپل)

argc - تعداد پارامترها
ARGV - آرایه صفر ترمینال از اشاره گرها به رشته های پارامتر خط فرمان
env - صفر ترمینال آرایه از اشاره گرها به ردیف متغیرهای محیطی. هر خط در نام فرمت \u003d ارزش
AUXV - آرایه ای از مقدار کمکی (فقط برای PowerPC موجود است)
اپل - مسیر فایل اجرایی (در MacOS و داروین)
بردار کمکی - یک آرایه با اطلاعات اضافی مختلف، مانند شناسه کاربر کارآمد، نشانه ای از کمی کمی، اندازه صفحه حافظه و غیره

اندازه بخش پشته را می توان در فایل نقشه ها مشاهده کرد:
گربه / proc / 10918 / نقشه

7fffffffa3000-7FFFFFFFFFFF000 RW-P 00000000 00:00 0

قبل از اینکه بوت لودر در اصلی کنترل شود، محتویات آرایه های پارامترهای خط فرمان، متغیرهای محیطی، بردار کمکی را آغاز می کند.
پس از مقداردهی اولیه، قسمت فوقانی پشته به نظر می رسد این برای نسخه 64bit است.
آدرس ارشد از بالا.

1. 0x7ffffffff000 نقطه بالای بخش پشته. درخواست تجدید نظر باعث می شود segfault
0x7ffffffff0f8. خالی خالی * 8 0x00 "
2. نام فایل. چار 1+ "/tmp/a.out"
چار 1 0x00
...
دفن چار 1 0x00
...
چار 1 0x00
3. 0x7FFFFFFFFE5E0. دفن چار 1 ..
چار 1 0x00
...
argv چار 1 0x00
...
چار 1 0x00
4. 0x7FFFFFFFFE5BE. argv چار 1+ "/tmp/a.out"
5. آرایه ای از طول تصادفی
6. داده ها برای AUXV. خالی * 48"
AT_NULL elf64_auxv_t. 16 {0,0}
...
AUXV elf64_auxv_t. 16
7. aUXV elf64_auxv_t. 16 سابق: (0x0e، 0x3E8)
خالی خالی * 8 0x00
...
دفن char * 8
8. 0x7ffffffe308. دفن char * 8 0x7FFFFFFFFE5E0.
خالی خالی * 8 0x00
...
argv char * 8
9. 0x7FFFFFFFFE2F8. argv char * 8 0x7FFFFFFFFE5BE.
10. 0x7FFFFFFFFE2F0. argc طولانی 8" تعداد استدلال + 1
11. متغیرهای محلی و استدلال، توابع ناشی از اصلی
12. متغیرهای محلی اصلی.
13. 0x7ffffffe1fc. argc int 4 تعداد استدلال + 1
0x7FFFFFFFFE1F0. argv char ** 8 0x7FFFFFFFFE2F8.
0x7FFFFFFFFE1E8. دفن char ** 8 0x7ffffffe308.
14. متغیرهای توابع محلی

"- توضیحات زمینه های اسناد را پیدا نکردم، اما تخلیه به وضوح قابل مشاهده است.

برای 32 بیت بررسی نکرد، اما به احتمال زیاد فقط به اندازه کافی برای تقسیم ابعاد به دو است.

1. درخواست تجدید نظر به آدرس، بالاتر از نقطه بالا، سبب Segfault.
2. یک رشته حاوی مسیر به فایل اجرایی.
3. آرایه ای از ردیف ها با متغیرهای محیطی
4. آرایه رشته ها با پارامترهای خط فرمان
5. آرایه ای از طول تصادفی. انتخاب آن را می توان با دستورات غیر فعال کرد.
systl -w kernel.Randomize_va_space \u003d 0
echo 0\u003e / proc / sys / kernel / randomize_va_space
6. داده ها برای بردار کمکی (به عنوان مثال، خط X86_64)
7. بردار کمکی. بیشتر بخوانید
8. آرایه صفر ترمینال از اشاره گرها بر روی ردیف متغیرهای محیطی
9. آرایه صفر ترمینال از اشاره گرها به رشته های پارامتر خط فرمان
10. MEHER WORD حاوی تعداد پارامترهای خط فرمان (یکی از استدلال های عملکرد "ارشد"، پاراگراف 11 را ببینید)
11. متغیرها و استدلال بند، توابع به نام اصلی (_start، __ libc_start_main ..)
12. Invered، در اصل اعلام شده است
13. Airguses of Maint
14. حرکت و استدلال توابع محلی.

بردار کمکی
برای i386 و x86_64، شما نمیتوانید آدرس اول عنصر بردار کمکی را دریافت کنید، اما محتویات این بردار را می توان به روش های دیگر به دست آورد. یکی از آنها این است که به منطقه حافظه مراجعه کنید که شامل آرایه ای از اشاره گرها به ردیف متغیرهای محیطی است.
این باید چیزی شبیه به این باشد:
#عبارتند از. #عبارتند از. int main (int argc، char ** argv، char ** env) (elf64_auxv_t * euxv؛ // x86_64 // elf32_auxv_t * auxv؛ / / i386 در حالی که (* env ++! \u003d null)؛ // ما به دنبال آن هستیم آغاز بردار کمکی برای (euxv \u003d (elf64_auxv_t *) env؛ auxv-\u003e a_type! \u003d at_null؛ auxv ++) (printf ("addr:٪ p نوع:٪ lx: 0x٪ lx \\ n"، auxv ، auxv-\u003e a_type، auxv-\u003e a_un .a_val)؛) printf ("\\ n (void *) (* argv) - (void *) auxv \u003d٪ p -٪ p \u003d٪ ld \\ n (void *) (void *) auxv) - (void *) (و auxv) \u003d٪ p-٪ p \u003d٪ ld \\ n "، (void *) (* argv)، (void *) auxv، (void *) (* argv) - (void * *) auxv، (void *) (void *)، (void *) (و auxv)، (void *) (argv) - (void *) (و auxv))؛ printf ("\\" \\ n argc کپی:٪ d \\ n "، * ((int *) (argv - 1)))؛ بازگشت 0؛)
ELF (32.64) _auxv_t ساختارها در /usr/include/elf.h شرح داده شده است. توابع پر کردن در لینوکس-kernel / fs / binfmt_elf.c

راه دوم برای دریافت محتویات بردار:
hexdump / proc / self / auxv

دیدگاه به یاد ماندنی ترین با تنظیم متغیر محیط LD_SHOW_AUXV به دست می آید.

ld_show_auxv \u003d 1 ls
AT_HWCAP: BFEBFBFF // ویژگی های پردازنده
AT_PARSZ: 4096 // اندازه صفحه حافظه
AT_CLKTCK: 100 // به روز رسانی فرکانس زمان ()
AT_PHDR: 0x400040 // اطلاعات هدر
AT_PHENT: 56.
AT_PHNUM: 9.
AT_BASE: 0x7FD00B5BC000 // آدرس مترجم، منظور من LD.SO
AT_FLAGS: 0x0.
AT_ENTRY: 0x402490 // نقطه ورود در برنامه
AT_UID: 1000 // شناسه های کاربر و گروه ها
AT_EEUID: 1000 // اسمی و کارآمد
AT_GID: 1000.
AT_GID: 1000.
AT_SECURE: 0 // پرچم SETUID افزایش یافته است
AT_RANDOM: 0x7FFFFF0BDC809 // آدرس 16 BYTES تصادفی،
تولید شده در راه اندازی
AT_SYSINFO_EHDR: 0x7FFF2BFF000 // اشاره گر به صفحه مورد استفاده برای
// تماس های سیستم
AT_EXECFN: / bin / ls
AT_PLATFORM: X86_64.
در سمت چپ - نام متغیر، راست به سمت راست. تمام نام های متغیر ممکن و توصیف آنها می تواند در فایل elf.h خراب شود. (ثابت با پیشوند AT_)

بازگشت از Main ()
پس از مقداردهی کردن زمینه فرآیند، کنترل در اصل ()، بلکه به عملکرد _start () منتقل می شود.
اصلی () علل از __libc_start_main. این تابع دوم دارای یک ویژگی جالب است - آن را به یک تابع به یک تابع منتقل می شود که باید پس از اصلی () اجرا شود. و این اشاره گر به طور طبیعی از طریق پشته منتقل می شود.
به طور کلی، استدلال __libc_start_main بر اساس GLIBC-2.11 / Sysdeps / IA64 / ELF / START.S مشاهده می شود
/*
* استدلال برای __libc_start_main:
* OUT0: اصلی
* OUT1: ARGC
* OUT2: ARGV
* OUT3: init
* OUT4: FINI // تابع بعد از اصلی
* OUT5: rtld_fini
* OUT6: Stack_end
*/
کسانی که. برای دریافت آدرس اشاره گر FINI، شما باید به دو کلمه اول از آخرین متغیر محلی تغییر دهید.
این چیزی است که اتفاق افتاده است (عملکرد به نسخه کامپایلر بستگی دارد):
#عبارتند از. void ** ret؛ void * leve؛ void foo () (void (* boo) (void)؛ // اشاره گر به عملکرد printf ("پشته بازنویسی! \\ n")؛ boo \u003d (void (*) (void)) ترک؛ boo ()؛ // fini ()) int main (int argc، char * argv، char * envp) (Unsigned Long int mark \u003d 0xBFBFBFBFBFBFBFBF؛ // برچسب از ما کار ret \u003d (void **) (و مارک + 2)؛ // حذف توابع آدرس پس از اتمام (fini) را ترک کنید \u003d * ret؛ // به یاد داشته باشید * ret \u003d (void *) foo؛ // patch بازگشت 0؛ // فراخوانی تابع foo ())

امیدوارم جالب باشد
موفق باشید

با تشکر از کاربر Xeor برای ارسال مفید.

زنگ.

کسانی هستند که این خبر را قبل از شما خوانده اند.
مشترک شدن برای دریافت مقالات تازه.
پست الکترونیک
نام
نام خانوادگی
چگونه می خواهید زنگ را بخوانید
بدون هرزنامه