Reverse Code Engineering

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

Reverse Code Engineering

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

Reverse Code Engineering

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

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

آخرین نظرات

زبان اسمبلی در مهندسی معکوس

يكشنبه, ۲۸ دی ۱۳۹۳، ۰۸:۳۶ ق.ظ

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

OllyDbg و IDA Pro دوتا از ابزارهای رایج دیس اسمبل کردن فایل های باینری برای استخراج دستورات اسمبلی از زبان سطح ماشین هستند. پس عملکرد نرم افزار به زبان اسمبلی ازطریق این ابزارها قابل رویت هستش

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

 

پیش زمینه:

BIT : کوچکترین قسمت داده ای که یا 0 هستش یا 1

مثال: 00000001 = 1       00000010 = 2             00000011 = 3    

 

BYTE: یک بایت حاوی 8 بیت است که می تواند 255 حالت را بسازد.(0 تا 255)

 

WORD: یک WORD حاوی 2 بایت یا 16 بیت است.و بیشترین حالت ممکن آن 0FFFFh (یا 65535) است.

 

DOUBLE WORD: حاوی 2 تا WORD یا به عبارتی 32 بیت است و بیشترین مقدار ممکن آن 0FFFFFFFF (یا 4294967295) است.

 

KILOBYTE: یک کیلوبایت برابر با 1024 بایت (32*32) است.

 

MEGABYTE: محتوی 1024*1024 یا 1,048,578 بایت است.

 

قسمت اول: رجیسترها

 

در IA-32 هشت رجیستر عمومی وجود داره:

EAX:   Extended Accumulator Register

EBX:   Extended Base Register

ECX:   Extended Counter Register

EDX:   Extended Data Register

ESI:    Extended Source Index

EDI:    Extended Destination Index

EBP:   Extended Base Pointer

ESP:   Extended Stack Pointer

 

البته بغیر از اینها رجیسترهای دیگه ای هم وجود داره مثل EIP که حاوی اشاره گری به دستور جاری هستش.البته لازم نیست زیاد نگران باقی رجیسترها باشید.

توجه کنید که همه نام ها با حرف E شروع شده اند که این بمعنی 32 بیتی بودن آنهاست.

 

نکته:همانطور که میبینید در شکل بالا رجیسترهای ESI,EDI,ESP,EBP با باقی رجیسترها متفاوت هستن و حالت 8بیتی ندارند.

 

یکی از رجیسترهای مهم دیگه که بالا در موردش توضیح ندادیم رجیستر FLAGS هستش که به رجیستر وضعیت هم شناخته میشه و ازون برای نگهداری اطلاعاتی درباره وضعیت پردازنده استفاده میشه. توی سیستم های 32 بیتی این رجیستر هم 32 بیت هستش البته لازم نیست به همه پرچم های این رجیستر اهمیت بدید توی مهندسی معکوس 3 تا ازینها خیلی پرکاربرده (ZF-OF-CF) که اغلب اوقات وضعیت پرش ها رو مشخص می کنه.

CF: پرچم نقلی هستش, اگه عملیات رقم نقلی تولید کنه این پرچم 1 میشه

ZF: زمانی که نتیجه عملیات صفر بشه این پرچم 1 میشه

OF: اگه یه عملیات محاسباتی باعث سرزیز شدن بشه این پرچم 1 میشه.


قسمت دوم :دستورات


بیشتر دستورات دو تا عملوند (مثل add EAX, EBX) دارند اما برخی هم یکی (مثل not EAX) یا سه تا (مثل IMUL EAX, EDX, 64) عملوند دارند.

زمانی که شما یک دستور با DWORD PTR [XXX] مشاهده می کنید بمعنی مقدار DWORD در آفست حافظه [XXX] هستش.توجه داشته باشید که بایت ها در حافظه بصورت معکوس (یا Little Endian) ذخیره می شوند.

در زیر راه های استفاده از دستور add رو با دو عملوند می بینید: 

add eax,ebx                                  ;; Register, Register

add eax,123                                  ;; Register, Value

add eax,dword ptr [404000]            ;; Register, Dword Pointer [value] d

add eax,dword ptr [eax]                 ;; Register, Dword Pointer [register]d

add eax,dword ptr [eax+00404000] ;; Register, Dword Pointer [register+value]d

add dword ptr [404000],eax            ;; Dword Pointer [value], Register

add dword ptr [404000],123            ;; Dword Pointer [value], Value

add dword ptr [eax],eax                 ;; Dword Pointer [register], Register

add dword ptr [eax],123                 ;; Dword Pointer [register], Value

add dword ptr [eax+404000],eax    ;; Dword Pointer [register+value], Register

add dword ptr [eax+404000],123     ;; Dword Pointer [register+value], value

 

در ادامه برخی از رایج ترین دستورات رو توضیح میدیم:

 

test arg1, arg2

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

CF, OF, PF, SF, ZF

 

cmp arg1, arg2

این دستور عمل تفریق رو روی دوتا عملوند انجام میده و نتیجه هم در جایی نگهداری نمیشه.فقط اگه نتیجه مقایسه صفر باشه روی پرچم ZF تاثیر میزاره و این پرچم یک میشه.پرچم های دیگه ای که ازین دستور متاثر میشند:

CF, AF, OF, PF, SF

 

 jmp loc

این دستور رجیستر EIP رو با آدرس مشخص شده در این دستور بارگزاری میکنه و در نتیجه ادامه روند اجرا از آدرس loc ادامه پیدا میکنه

 

je loc

اگر دوتا عملوند دستور CMP قبل از je با هم مساوی باشند EIP با آدرس مشخص شده در این دستور بارگزاری میشه و نتیجش پرش کردن به اون آدرس هستش

یا به عبارتی jump if Zero Flag == 1

 

 jne loc

اگه دوتا عملوند دستور CMP قبل از jne با هم مساوی نباشند EIP با آدرس مشخص شده  در این دستور بارگزاری میشه و نتیجش پرش کردن به اون آدرس هستش

یا به عبارتی jump if Zero Flag == 0


jg loc

اگه اولین عملوند دستور CMP قبل از je بزرگتر از دومی باشه پرش انجام میشه

یا به عبارتی jump if ZF=0 and SF=OF

 

 jge loc

اگه اولین عملوند دستور CMP قبل از jge بزرگتر یا مساوی دومی باشه پرش انجام میشه

یا به عبارتی jump if SF=OF

 

ja loc

اگه اولین عملوند دستور CMP قبل از ja بزرگتر از دومی باشه پرش انجام میشه

یا به عبارتی  jump if  CF=0 and ZF=0

 

jae loc

مثل دستور jge, اگه اولین عملوند دستور CMP قبل از jae بزرگتر یا مساوی دومی باشه پرش انجام میشه

یا به عبارتی jump if  CF=0

 

 jl loc

اگه اولین عملوند دستور CMP قبل از jl کوچکتر از دومی باشه پرش انجام میشه

یا به عبارتی jump if SF != OF 

 

 jle loc

اگه اولین عملوند دستور CMP قبل از jle کوچکتر یا مساوی دومی باشه پرش انجام میشه

یا به عبارتی jump if SF != OF or ZF = 1


 jo loc

اگه دستور محاسباتی قبل از jo پرچم OF را یک کنه این پرش انجام میشه

 

jnz loc

اگه دستور محاسباتی قبل از jnz پرچم ZF رو صفر کنه این پرش انجام میشه

 

jz loc

اگه دستور محاسباتی قبل از jz پرچم ZF رو یک کند این پرش انجام میشه

 

call proc

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

 

 ret [val]

این دستور مقدار بعدی روی پشته را داخل رجیستر EIP بارگزاری میکنه برای جزئیات بیشتر در مورد این دستور جستجو کنید.

 

loop arg

این دستور مقدار ECX رو کاهش میده و پرشی به آدرس مشخص شده در arg انجام میده

 

 enter arg

این دستور فضایی روی پشته تخصیص میده و قاب پشته رو میسازه

 

 leave

این دستور قاب پشته جاری رو تخریب میکنه و قاب پشته قبلی رو بازیابی می کنه

hlt

این دستور در پردازنده مکث ایجاد میکنه

 

nop

این دستور هیچ کاری انجام نمیده

 

wait

این دستور منتظر میمونه تا CPU آخرین محاسباتش رو به پایان برسونه

 

MOV arg1 arg2

این دستور دو تا عملوند میگیره و arg2 رو به arg1 انتقال میده

 

ADD arg1 arg2

این دستور arg2 رو به arg1 اضافه میکنه و نتیجه رو داخل arg1 نگهداری میکنه پرچم هایی که روشون تاثیر میزاره:

CF, AF, OF, PF, SF, ZF

 

SUB arg1 arg2

این دستور arg2 رو از arg1 کم میکنه و نتیجه رو داخل arg1 نگهداری میکنه, پرچم هایی که روشون تاثیر میزاره:

CF, AF, OF, PF, SF, ZF

 

MUL arg

این دستور arg رو با مقدار رجیستر EAX ضرب میکنه و نتیجه رو در EDX:EAX نگهداری میکنه که 32 بیت پایینی در EAX و 32 بیت بالایی EDX هستش

 

DIV arg

این دستور مقدار EDX:EAX بر arg تقسیم میکنه و خارج قسمت رو در EAX و باقی مانده رو در EDX نگهداری می کنه

 

SHR Op arg

مقدار OP رو به تعداد arg به راست شیفت می کنه

 

SHL Op arg

مقدار OP رو به تعداد arg به چپ شیفت می کنه



ماشاله دستورات اسمبلی تمومی نداره:)
یه مقاله کمکی که می تونید دانلودش کنید

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

نظرات (۰)

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