PATCHELF(1) User Manuals PATCHELF(1)

patchelf - ویرایش و تغییر فایل‌های ELF

patchelf OPTION FILE ...

ابزار PatchELF یک ابزار ساده برای تغییر و دستکاری فایل‌های اجرایی و کتابخانه‌های ELF موجود است. این ابزار می‌تواند بارگذار پویا («مفسر ELF») فایل‌های اجرایی را تغییر داده و RPATH فایل‌های اجرایی و کتابخانه‌ها را ویرایش کند.

تک‌گزینهٔ داده‌شده روی هر FILE اعمال شده و فایل‌ها درجا (در محل) ویرایش می‌شوند.

هر گزینه‌ای که آرگومان رشته‌ای می‌پذیرد، با قرار دادن نماد @ در ابتدای آرگومان می‌تواند یک فایل را نیز به عنوان ورودی دریافت کند. بخش «مثال‌ها (EXAMPLES)» را ببینید.

به‌جای اندازه پیش‌فرض، از اندازه صفحه (page size) داده‌شده استفاده می‌کند.
بارگذار پویای («مفسر ELF») فایل اجرایی را به INTERPRETER تغییر می‌دهد.
مفسر ELF فایل اجرایی را چاپ می‌کند.
مقدار OS ABI فایل اجرایی (فیلد EI_OSABI فایل ELF) را چاپ می‌کند.
مقدار OS ABI فایل اجرایی (فیلد EI_OSABI فایل ELF) را تغییر می‌دهد. پارامتر ABI بسیار انعطاف‌پذیر است. برای نمونه، می‌توانید آن را به‌صورت "Linux"، "linux" یا حتی "lInUx" مشخص کنید - تمام این نام‌ها فیلد EI_OSABI سرآیند ELF را روی مقدار "3" که متناظر با Linux OS ABI است تنظیم می‌کنند. همین قاعده برای سایر نام‌های ABI نظیر System V، FreeBSD، Solaris و غیره نیز صدق می‌کند.
مدخل DT_SONAME بخش .dynamic را چاپ می‌کند. در صورتی که DT_SONAME وجود نداشته باشد، خطا صادر می‌کند.
مدخل DT_SONAME یک کتابخانه را به SONAME تنظیم می‌کند.
مقدار DT_RUNPATH فایل اجرایی یا کتابخانه را به RUNPATH تغییر می‌دهد.
مقدار RUNPATH را به DT_RUNPATH موجود در فایل اجرایی یا کتابخانه اضافه می‌کند.
مدخل DT_RPATH یا DT_RUNPATH فایل اجرایی یا کتابخانه را حذف می‌کند.
تمام دایرکتوری‌هایی را که شامل هیچ کتابخانه‌ای که توسط فیلدهای DT_NEEDED فایل اجرایی یا کتابخانه ارجاع داده شده است نیستند، از DT_RUNPATH یا DT_RPATH حذف می‌کند.

برای نمونه، اگر یک فایل اجرایی به یک کتابخانه به نام libfoo.so ارجاع دهد، دارای RPATH با مقدار "/lib:/usr/lib:/foo/lib" باشد و libfoo.so تنها در /foo/lib یافت شود، آنگاه RPATH جدید برابر با "/foo/lib" خواهد بود.

در ترکیب با گزینهٔ "--shrink-rpath"، این گزینه می‌تواند برای تنظیم دقیق‌تر rpath استفاده شود. برای نمونه، اگر یک فایل اجرایی دارای RPATH با مقدار "/tmp/build-foo/.libs:/foo/lib" باشد، احتمالاً مطلوب است که ارجاع "/foo/lib" به‌جای مدخل "/tmp" نگه داشته شود.
مقدار DT_RUNPATH یا DT_RPATH را برای یک فایل اجرایی یا کتابخانه چاپ می‌کند.
استفاده از DT_RPATH منسوخ‌شده را در فایل به‌جای DT_RUNPATH اجباری می‌کند. به‌طور پیش‌فرض DT_RPATH به DT_RUNPATH تبدیل می‌شود.
یک وابستگی اعلام‌شده به یک کتابخانه پویا (DT_NEEDED) اضافه می‌کند. این گزینه می‌تواند چندین بار مشخص شود.
یک وابستگی اعلام‌شده به یک کتابخانه پویا را با کتابخانه دیگری جایگزین می‌کند (DT_NEEDED). این گزینه می‌تواند چندین بار مشخص شود.
یک وابستگی اعلام‌شده به LIBRARY را حذف می‌کند (مدخل DT_NEEDED). این گزینه می‌تواند چندین بار مشخص شود.
تمام مدخل‌های DT_NEEDED فایل اجرایی را چاپ می‌کند.
شیء (object) را به گونه‌ای علامت‌گذاری می‌کند که جستجو برای وابستگی‌های این شیء از تمام مسیرهای پیش‌فرض جستجوی کتابخانه صرف‌نظر کند.
هر وابستگی DT_NEEDED را در زمان وصله‌زدن در برابر مسیر اجرای شیء (run path) حل کرده و نتیجه را در یک یادداشت .note.nixos.ldcache ثبت می‌کند، به طوری که یک بارگذار که این یادداشت را درک می‌کند بتواند از جستجوی مسیر اجرا در زمان راه‌اندازی صرف‌نظر کند. دایرکتوری‌هایی که از قبل قابل حل نیستند (مؤلفه‌های خالی یا نسبی، مواردی که حاوی نشانه‌های رشته‌ای پویا مانند $ORIGIN یا یک زیردایرکتوری glibc-hwcaps هستند، و مسیرهایی که در زمان وصله‌زدن به دلیل مفقود بودن، دایرکتوری نبودن، یا عدم دسترسی قابل جستجو نیستند) به‌جای یک مسیر دقیق، به عنوان یک راهنمای جستجو ذخیره می‌شوند. این حافظه موقت یک بار از روی باینری وصله‌نشده ساخته می‌شود؛ این گزینه نمی‌تواند با --force-rpath ترکیب شود.
سرآیندهای برنامه یا سرآیندهای بخش را مرتب نمی‌کند. این ویژگی هنگام اشکال‌زدایی patchelf مفید است، چرا که خواندن تفاوت‌های (diffs) خروجی "readelf -a" را آسان‌تر می‌کند.
در صورتی که برچسب DT_DEBUG هنوز در یک شیء ELF وجود نداشته باشد، آن را به بخش .dynamic اضافه می‌کند. یک کتابخانه اشتراکی (-shared) به‌طور پیش‌فرض برچسب DT_DEBUG را دریافت نمی‌کند. این بدان معناست که وقتی یک کتابخانه اشتراکی دارای یک نقطه ورود باشد (به طوری که بتوان آن را به عنوان یک فایل اجرایی اجرا کرد)، دیباگر به‌درستی به آن متصل نمی‌شود و نمادها حل نمی‌شوند.
وضعیت پرچم قابل اجرا بودن سرآیند برنامه GNU_STACK را (در صورت وجود) چاپ می‌کند.
پرچم قابل اجرا بودن سرآیند برنامه GNU_STACK را پاک می‌کند، یا یک سرآیند جدید اضافه می‌کند.
پرچم قابل اجرا بودن سرآیند برنامه GNU_STACK را تنظیم می‌کند، یا یک سرآیند جدید اضافه می‌کند.
نمادهای پویا را تغییر نام می‌دهد. فایل نگاشت نام باید شامل خطوطی با نام قدیم و نام جدید باشد که با فاصله از هم جدا شده‌اند، مانند این:

old_name new_name

نام‌های نماد شامل مشخص‌کننده‌های نسخه‌ای که در خروجی دستور nm -D از binutils نیز نشان داده می‌شوند، نیستند. بنابراین به جای نام write@GLIBC_2.2.5، تنها مقدار write است.

مقادیر بخش‌های قدیمی را رونویسی (clobber) نمی‌کند.

به‌طور پیش‌فرض patchelf بخش‌های سرآیند جایگزین‌شده را با داده‌های بی‌استفاده رونویسی می‌کند تا اطمینان حاصل شود که به طور تصادفی استفاده نمی‌شوند. این گزینه اجازه می‌دهد تا از این رفتار انصراف داده شود، به طوری که فایل‌های باینری که تلاش می‌کنند سرآیندهای خود را از یک آفست ثابت بخوانند (مانند Firefox) همچنان کار کنند.

به ندرت و با احتیاط استفاده شود.

نام فایل خروجی را تعیین می‌کند. در صورت عدم تعیین، فایل ورودی درجا تغییر می‌یابد.
جزئیات تغییرات ایجادشده در فایل ورودی را چاپ می‌کند.
نسخه patchelf را نمایش می‌دهد.

برای استفاده از محتویات یک فایل خارجی به عنوان پارامتر:

$ patchelf a.out --add-rpath @/tmp/generated-rpath.bin

برای تغییر دادن RPATH یک باینری. توجه داشته باشید که $ORIGIN یک نماد ویژه است که توسط بارگذار استفاده می‌شود، بنابراین باید داخل علامت نقل‌قول قرار گیرد.

patchelf --set-rpath '$ORIGIN/../lib64' a.out

Eelco Dolstra <e.dolstra@tudelft.nl>

elf(5), ld.so(8)

JULY 2022 PATCHELF