PDA

View Full Version : کمک:تنظیمات کامپایلر برای تعیین سکشنهای یک exe



civ0003
دوشنبه 17 اردیبهشت 1386, 11:53 صبح
سلام.
آیا این امکان در تنظیمات دلفی وجود داره که توالی section های کد و داده و رسورس و . . . در فایل اجرایی رو کاربر تعیین کنه. مثلا به جای اینکه دومین سکشن فایل exe با فرمت PE وقتی توسط کامپایلر تولید میشه data نباشه و کد باشه. یا جای اینکه کد اولین سکشن از فایل PE رواشغال کنه آخرین سکشن رو پر کنه و . . .. اگه در دلفی این امکان وجود نداره شما کامپایلر یا لینکر دیگه ای میشناسین که این کاررو بتونه انجام بده.

Inprise
دوشنبه 17 اردیبهشت 1386, 12:21 عصر
- این مسئله مربوط به لینکر است نه کامپایلر .

لینکرهای بورلند و مایکروسافت ( دلفی - بورلند سی - ویژوال سی ) هیچکدام چنین امکانی ندارند و اصولا" کاربرد صنعتی ای هم ندارد که لزومی به وجودشان باشد . ( لینکر GNU را هم بررسی نکردم ) تو البته میتونی با هر PE Editor ای تغییرات مورد نظرت رو انجام بدی ، یا کد یا اسکریپتی بنویسی و در قسمت post-make هر کدام از Make فایلهات بگذاری که بعد از ساخته شدن باینری بصورت خودکار تغییرات مد نظرت انجام بشن .

civ0003
سه شنبه 18 اردیبهشت 1386, 13:54 عصر
از insprise ممنونم.
ولی سوالی که برام پیش اومده اینه که اگه بخوام با یه PE editor سکشن ها رو تغییر بدم آیا آدرسدهی ها دچار مشکل نمیشه؟ مثلا در برنامه در حالتی که هنوز جابجایی سکشنها رو انجام ندادم یه jmp در سکشن 1 در آدرس 1000 وجود داره که کنترل رو به آدرس 1023 منتقل میکنه. حالا وقتی من این سکشن رو منتقل میکنم به سکشن 4 . آدرس دستور 1000 مثلا به 4005 منقل میشه. حالا این jmp اشتباه عمل میکنه. چون هنوز به 1023 اشاره داره نه به 4028. حالا تغییر همهء دستورات شامل آدرسدهی RAM مشخصا با PE editor امکان ناپذیریه اینطور نیست؟ لطفا منو راهنمایی کنید. ممنونم.

Inprise
سه شنبه 18 اردیبهشت 1386, 15:00 عصر
تغییر محل کد در متن باینری ارتباطی به آدرس دهی نداره ، چون اشاره به آدرسها در یک برنامه در حال اجرا ، مربوط به آفستهای حافظه است نه متن باینری فایل که روی دیسک ذخیره شده . البته باید هدر فایل PE رو برای محل صحیح EP و موارد دیگر ویرایش کنی... ممکن است بسته به مورد به تغییرات جزئی دیگری هم نیاز باشه اما بطور کلی جواب سوالت همان هست که گفتم .

بطور کل Loader سیستم عامل با استفاده از هدر PE سکشنهای حافظه - که تناظر یک به یک با سکشن های PE ندارند - را میسازد و سپس محل Entry Point را با استفاده از آدرس Relative ای که در هدر درج شده Resolve میکند و کد اجرا میشود .

فصل هفتم - Memory Management - کتاب Windows Internals رو بخون .

civ0003
چهارشنبه 19 اردیبهشت 1386, 11:58 صبح
ممنونم Inprise.
خوب من منظورم این نیست که فقط محل سکشن رو در فایل عوض کنم. من میخوام کلا محل این سکشن چه در فایل چه در هنگام لود هر دو به جای دیگه ای منتقل بشه.
خوب من میخوام یه مثال بزنم.
فرض میکنیم یه فایل PE داریم. entry point :0x1022 .در هدر, سکشن شماره 1 به صورت زیر معرفی میشه:
سکشن 1 ( code segment ):
address in file : 0x100
offset in ram : 0x1000
length in file : 0x280
length in ram : 0x1000
type : readable,executable
سکشن دوم( data segment ):
address in file : 0x400
offset in ram : 0x2000
length in file : 0x120
length in ram : 0x1000
type : readable,writeable

به این حالت میگیم حالت (1). حالا جای این مقادیر بالا رو تغییر میدیم . یعنی هم مقادیر هدر و هم مقادیر داخلی سکشنها و هم entry point رو و به حالت (2) میرسیم:

entry point : 0x2022

سکشن 1 ( data segment ):
address in file : 0x100
offset in ram : 0x1000
length in file : 0x120
length in ram : 0x1000
type : readable,writable
سکشن دوم( code segment ):
address in file : 0x200
offset in ram : 0x2000
length in file : 0x280
length in ram : 0x1000
type : readable,executable

حالا آیا کد اجرا میشه؟ به نظر من نه.

Inprise
چهارشنبه 19 اردیبهشت 1386, 12:49 عصر
اگر به جواب قبلی دقت کنی سکشن های PE روی دیسک و حافظه متناظر نیستند و مثالی که زدی معادل حقیقی نداره . در مورد محل سکشنها روی دیسک جوابهای قبلی کافی هستند.

برای سوال جدیدت یعنی تغییر محل سکشنها روی حافظه :
تو نمیتونی بطور کامل کنترلی بر روند ایجاد Memory Layout یک پروسه داشته باشی . این مسئله وظیفهء VMM ویندوز است و تا جائیکه من SDK و Undocumented API ها را دیده ام چنین امکانی ارائه نشده ؛ به عنوان مثال تو کنترلی بر مشخصات سکشنی که از ابتدای ImageBase قراره نوشته بشه نداری و ... ؛ تا وقتی در این زمینه API ای وجود نداشته باشه نمیتونی عملکرد Memory Manager را تغییر بدهی ، یا انتظار داشته باشی که تو باینری ای مطابق نظر خودت بسازی و او هم بدون وجود قرارداد از پیش تعیین شده ای بتواند نیت تو را بفهمد و کد را بدرستی اجرا کند . البته من هر چه فکر کردم نفهمیدم که این مسئله چطور میتونه دارای هر نوع کاربردی باشه . تو میتونی مقدار ImageBase رو تعیین کنی ، یا محل شروع کد یا Mapping هر کدام از ماژولهای برنامه و ...نه چیزی بیشتر از این .

ASLR ویندوز ویستا هم صرفا نقطه شروع فراخوانی یا Mapping ماژولهای C Runtime و بعضی از DLL های ویندوز رو بصورت تصادفی مشخص میکنه که باز هم نسبتی با مساله تو نداره .

شاید بهتر باشه که انگیزه ات یا ایده اولیه ای که به ذهنت رسیده است رو بگی

civ0003
چهارشنبه 19 اردیبهشت 1386, 13:14 عصر
بازم متشکرم Inprise .
من از هدف خودم برای این کار میگم. شاید اصلا راه حل من اشتباه باشه و راه دیگه ای براش پیدا بشه.
من برنامه ای نوشتم که از کارهایی که طی اجرا انجام میده تغییر دادن محتویات سگمنت کد خودشه. این تغییر باعث تغییر طول سگمنت میشه. که این تغییر طول اصولا همگرا به سمت مقدار ثابتی پیش میره که این مقدار ثابت از طول از پیش تعیین شده نیست بلکه بر اساس نتیجهء تولید شده از اجرای برنامه در هر مرحله از اجرا بدست میاد. حالا تا وقتی که طول کد در محدودهء طول گرد شده در PE هست ( مثلا طول سگمنت یک در image برابر 1000 ولی طول حقیقی برابر 280 ) مشکلی پیش نمیاد ولی وقتی از این حد بیشتر بشه دو سکشن با هم تداخل پیدا میکنن( سکشن کد و سکشن بعد ). برای حل این مشکل من میخوام سگمنت کد رو به انتهای فایل و image منتقل کنم تا هم در گسترش کد در فایل راحتتر باشم(نیاز به تغییر هدر مربوط به بقیهء سکشنها نباشه ) و هم در گسترش کد در image .

Inprise
چهارشنبه 19 اردیبهشت 1386, 14:22 عصر
هدف تو رو از اینکار نمیدونم اما بین ویروس نویسها به چنین فرآیندی میگن متامورفیسم .

یک قاعدهء ثابت در کدهای متامورفیک هست که باعث میشه توسعهء اونها سخت باشه . برای "ثابت" یا "قابل کنترل" نگه داشتن کدهای موجود و نسل بعدی اش یک موتور Disassembler در Engine وجود داره . Disassembler میتونه یک پیاده سازی کامل از - فرضا - IA32 باشه ، یا میتونه بخشی از اون رو پیاده کرده باشه ، یا فقط یک Length-based Disassembler باشه که بر اساس اندازه Instruction ها تصمیم میگیره . در این زمینه استفاده از LDE بین ویروس نویسها خیلی متداوله

مثلا با استفاده از LDE میتونی کدت رو به Branch هائی تقسیم کنی که حد فاصل اونها JMP یا CALL است ( کامپایلرهای مایکروسافت برای فراخوانی توابع همیشه از CALL استفاده میکنن ولی کامپایلرهای بورلند در مواردی از JMP هم استفاده میکنن ) و بعد تلاش کنی موتور متامورفیکت هر Branch رو طوری تغییر بده که اندازهء اون ثابت بمونه و به CALL یا JMP اش هم آسیبی وارد نشه . روشهای متنوعی برای رسیدن به متامورفیسم هست و اطلاعات من هم در این زمینه چندان جدی نیست .

اگر علاقه مند بودی سری به vxheaven بزن و از نمونه کدهای زیادی که اونجا هست استفاده کن . دنبال کدهای همراه مجله مرحوم 29A هم بگردی به چیزهای خوبی میرسی

oVERfLOW
جمعه 21 اردیبهشت 1386, 19:34 عصر
خوب چرا شما علاقه دارید که حتما توی همون سکشن Code بنویسید؟
اصلا همون سکشن Data رو افزایش بدید و دسترسی‌ش رو هم تغییر بدید و هر کاری که خواستید انجام می‌شه.

civ0003
شنبه 22 اردیبهشت 1386, 10:38 صبح
inprise و oVERfLOW ممنونم از راهنمایی شما.
inprise جان باید بگم که بنده تا حدودی با روشهای به کار رفته در متامورفیکها آشنا هستم و در واقع همین متامورفیکها عامل ایجاد ایده ای در ذهن من بودن که برای به دست آوردنش نیاز به این تغییر دارم. استفاده از چند call یا jmp و توضیع کد وبعد مراقبت از عدم تجاوز اندازه یه قضیه ای رو بسیار بحرانی میکنه. و اون پایداری معنی کده البته نه در متامورفیکها بلکه در ایدهء من !!!.باید خدمت oVERfLOW عرض کنم که مشکل اینجاست که در دلفی بعد از سکشن کد 5 یا 6 یا بیشتر سکشن وجود داره و خود داده ها هم سکشن دوم و سوم رو به نظرم اشغال میکنه به این ترتیب استفاده از این سکشن بی فایدس. بازم از inprise و oVERfLOW ممنونم. راستی اگه به اطلاعاتی در این باب برخوردین ممنون میشم اگه خبرم کنید.

civ0003
دوشنبه 31 اردیبهشت 1386, 12:42 عصر
خوب من دو تا سوال اضافه میکنم.
ایا وجود سکشن ریسورس در PE اجباریه؟
آیا قرار گرفتن سکشن ریسورس در انتهای فایل PE اجباریه؟

Inprise
دوشنبه 31 اردیبهشت 1386, 13:29 عصر
جواب هر دو سوالت منفیه . فروم رو جستجو کن ، قبلا دو تا مطلب نسبتا مفصل در مورد ساختار PE مطرح شدن که بهتره بخونیشون .