Reverse Code Engineering

逆向工程代码 обратная код машиностроения

Reverse Code Engineering

逆向工程代码 обратная код машиностроения

Reverse Code Engineering

Share what I know............... learn what I don’t

(انجام پروژه های مرتبط، برای اطلاعات بیشتر به صفحه "ارتباط با من" مراجعه کنید)

آخرین نظرات

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

دوشنبه, ۲۹ دی ۱۳۹۳، ۰۸:۵۲ ق.ظ

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

همانطور که میدونید بیشتر نرم افزارها با زبان های سطح بالایی مثل C یا C++ توسعه داده میشند و اگه ما با دستورات اسمبلی تولید شده توسط کامپایلرهای این زبانها برای هر سازه آشنا باشیم پس می تونیم خیلی راحتتر کدهای دیس اسمبل شده ی برنامه های نوشته شده با این زبان هارو بررسی کنیم. -- خودمم نفهمیدم چی گفتم :) (منظورم از سازه همون دستورات برنامه نویسی استفاده شده توی کد هستش,مثل حلقه, عملیات محاسباتی و...)

پس ما قراره که سازه های زبان C رو در اسمبلی مورد بررسی قرار بدیم.مثلا حلقه ها, تعریف انواع متغیرها و... البته به این نکته هم توجه داشته باشید که نسخه کامپایلر و تنظیماتش هم روی کد اسمبلی تولید شدش تاثیر میزاره و همه مشابه هم نیستند.

 

بهتره ادامه بحث رو بصورت عملی پیش ببریم. ما میخوایم در ادامه کد دیس اسمبل شده متغیرهای محلی و متغیرهای عمومی رو بررسی کنیم

 

متغیرهای عمومی (Global variables) میتونند توی هر تابعی در برنامه قابل دسترس باشند اما متغیرهای محلی (Local variables) تنها توی تابعی که تعریف شدن میتونند قابل دسترس باشند.

توی مثال زیر متغیرها بصورت عمومی تعریف شدن:

 

int x = 1;

int y = 2;

 

void main()

{

   x = x + y;

   printf("Total = %d\n", x);

{

اما توی مثال زیر متغیر ها بصورت محلی تعریف شدن:

 

void main()

{

   int x = 1;

   int y = 2;

 

   x = x + y;

   printf("Total = %d\n", x);

{

همانطور که میبینید تفاوت زیادی ایجاد نشده و روی نتیجه هم تاثیری نداره و جواب هر دو مثال یکی هستش. اما در کد دیس اسمبل شده ببینیم چه اتفاقی افتاده.

متغیرهای عمومی در کد دیس اسمبل شده زیر:

 

00401003        mov     eax, dword_40CF60

00401008        add     eax, dword_40C000

0040100E        mov     dword_40CF60, eax

00401013        mov     ecx, dword_40CF60

00401019        push    ecx

0040101A        push    offset aTotalD  ;"total = %d\n"

0040101F        call    printf

 

متغیرهای محلی در کد دیس اسمبل شده زیر:

 

00401006        mov     [ebp+var_4], 0
0040100D        mov     [ebp+var_8], 1
00401014        mov     eax, [ebp+var_4]
00401017        add     eax, [ebp+var_8]
0040101A        mov     [ebp+var_4], eax
0040101D        mov     ecx, [ebp+var_4]
00401020        push    ecx
00401021        push    offset aTotalD  ; "total = %d\n"
00401026        call    printf

تفاوت عمده اینه که متغیرهای عمومی با آدرس های حافظه ارجاع شده اند اما متغیرهای محلی با آدرس های پشته .

حالا کدهای دیس اسبمل شده رو خط به خط توضیح میدم.اول کد دیس اسمبل شده متغیر عمومی:


خط اول:

dword_40CF60 متغیر عمومی X و مکان حافظه ای در 0x40CF60 هستش که به eax انتقال پیدا میکنه.به عبارت کلی متغیر X به eax انتقال پیدا میکنه

 

خط دوم:

dword_40C000 متغیر عمومی Y هستش که در مکان حافظه ی 0x40C000 قرار داره که با دستور add به X اضافه میشه و نتیجه در eax ذخیره میشه.

Eax = X + Y

 

خط سوم:

نتیجه جمع X + Y که در eax هستش به  dword_40CF60 (که همون X) هستش انتقال پیدا میکنه پس یعنی X = X + Y

 

خط چهارم:

برای اینکه تابع printf فراخوانی بشه اول باید آرگومانهاشو روی پشته قرار بدیم تا باهاشون فراخوانی بشه (البته یادتون باشه که آرگومانهای این تابع از راست به چپ روی پشته قرار میگیرند).پس ابتدا نتیجه جمع روی به ecx انتقال میدیم.

 

خط پنجم:

سپس ecx رو روی پشته قرار میدیم (که همون جواب جمع یعنی X هستش).

 

خط ششم:

آفست رشته روی پشته قرار میگیره

 

خط هفتم:

توی این خط تابع printf با دوتا آرگومانی که بهش فرستادیم فراخوانی میشه


خوب حالا کد دیس اسمبل شده متغیر محلی رو بررسی میکنیم ولی قبلش یه نکته رو بگم اونم اینه که کد دیس اسمبل شده متغیر محلی بالا حالت labeling برنامه IDA Pro هستش و این کد بدون labeling بشکل زیر هستش:

 

00401006        mov     dword ptr [ebp-4], 0

0040100D        mov     dword ptr [ebp-8], 1

00401014        mov     eax, [ebp-4]

00401017        add     eax, [ebp-8]

0040101A        mov     [ebp-4], eax

0040101D        mov     ecx, [ebp-4]

00401020        push    ecx

00401021        push    offset aTotalD  ; "total = %d\n"

00401026       call    printf

 

البته تفاوت چندانی نداره فقط خوانایی حالت labeling بیشتره.

 

خط اول:

بخاطر اینکه متغیرهای محلی توی پشته قرار دارند پس میتونیم با استفاده از ebp که مبنای قاب پشته هستش و آفست منفی, به متغیرهای محلی دسترسی پیدا کنیم.اگه از آفست مثبت استفاده کنیم به آرگومانها و چیزهای دیگه ای که خارج از مبحث ما هستش میرسیم.

پس به عبارت کلی با استفاده از [ebp-4] میتونیم به متغیر محلی اول دسترسی داشته باشیم. و در این خط میبینیم که مقدار 0 به متغیر اول یعنی X انتقال پیدا میکنه

 

خط دوم:

برای دسترسی به متغیرهای بعدی در پشته باید 4 بایت دیگه به آفست قبلی اضافه کنیم پس یعنی متغیر محلی دوم [ebp-8] هستش. و در اینجا مقدار 1 به متغیر دوم یعنی Y انتقال داده میشه

 

خط سوم:

متغیر X که حاوی مقدار 0 هستش به eax انتقال پیدا میکنه

 

خط چهارم:

متغیر Y که حاوی مقدار 1 هستش به مقدار eax که حاوی مقدار 0 هستش اضافه میشه و نتیجه توی eax ذخیره میشه پس یعنی eax = X + Y

 

خط پنجم:

مقدار eax به متغیر X انتقال داده میشه یعنی X = X + Y

 

خط ششم:

متغیر X که حاوی جمع X + Y هستش به ecx انتقال داده میشه

 

خط هفتم:

ecx روی پشته قرار میگیره تا در ادامه به تابع printf ارسال بشه

 

خط هشتم:

آفست رشته روی پشته قرار میگیره

 

خط نهم:

تابع printf با دو آرگومان بالا که روی پشته هستن فراخوانی میشه


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

کدهای دیس اسمبل بالا خروجی IDA Pro هستش امکان داره همین توی دیس اسمبلرهای دیگه مثل Olly , Win32DSM و ... این خروجی متفاوت باشه

میتونید برای اطلاعات بیشتر فصل 7 کتاب کرک و تکنیک های نفوذ انتشارات ناقوس رو بخونید بدک نیست لینک این فصلشو اینجا میزارم






نظرات (۰)

هیچ نظری هنوز ثبت نشده است
ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
تجدید کد امنیتی