Reverse Code Engineering

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

Reverse Code Engineering

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

Reverse Code Engineering

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

آخرین نظرات

Reference count یا Load count یک DLL یعنی تعداد دفعاتی که این کتابخانه در داخل پروسس بارگزاری می شود. هر زمان که این DLL (از طریق LoadLibrary) در داخل پروسس بارگزاری شود ,reference count یک واحد افزایش پیدا می کند و هر زمان که این DLL آزاد می شود (از طریق FreeLibrary) از پروسس,reference count یک واحد کاهش پیدا می کند. زمانی که reference count به صفر برسد, کتابخانه بطور کامل از فضای پروسس unmap می شود.

API های ویندوز اطلاعات زیادی در مورد DLL ها ارائه نمی دهند.

DLL injection and Hooking

۳۱
شهریور

در اینجا قصد داریم تا در مورد DLL Injection و استفاده از آن برای انجام Inline Hooking در پروسس راه دور را بصورت تئوری توضیح دهیم.
در ویندوز هر پروسس فضای آدرس مجازی مختص به خودش را دارد که در آن می توان هر DLL را در هر زمانی لود یا آنلود کرد. اما این لود و آنلود شدن DLL توسط خود پروسس انجام می گیرد. گاهی وقت ها ما تمایل داریم یک DLL را بدون اینکه پروسس بفهمد در داخل پروسس لود کنیم.دلایل زیادی برای این کار وجود دارد (قانونی و غیر قانونی) . برای مثال یک بدافزار نویس ممکن است بخواهد تا فعالیت های مخربش را با لود کردن یک DLL در یک پروسس قابل اطمینان مخفی کند یا ممکن است بخواهد دستگاه های امنیتی را bypass کند از طرف دیگر یک شخص ممکن است بخواهد عملکرد های برنامه ای را توسعه دهد.
ما در اینجا راه های تزریق code/DLL در داخل یک پروسس راه دور (Remote process) را نشان می دهیم .سپس ما آنرا برای هوک کردن API خاصی در پروسس هدف توسعه می دهیم تا بتوانیم کارهای خودمان را انجام دهیم.

با سلام خدمت همه دوستان.

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

امروز میخام مبحث جدیدی رو شروع کنیم و جلو بریم :

Windows Internal and Rootkit

خوب ما همزمان چندتا مبحث رو جلو خواهیم برد؛ یکیش تحلیل بدافزار (ZeroAccess) , یکیش همین WI&R هستش. البته لابه لای اینها شاید آموزش های دیگری هم داده بشه:)

مهندسی معکوس یک کار ماهرانه هستش مخصوصا زمانی که ما میخواهیم یک برنامه بزرگ یا فایل های پک شده مثل Malware ها رو آنالیز کنیم.
برخی ازین کارهای رایج شامل:
* پیگیری تخصیصات حافظه
* پیگیری فراخوانی API های خاص
* انپک کردن خانواده ای از Malware ها
* تصمیم گیری هوشمندانه مبتنی بر رویدادهای خاص

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

API Call Tracing یکی از روشهایی است که با آن میتوان یک دید کلی و خلاصه از یک فایل اجرایی بدست آورد.

شاید در برخی موارد بررسی فراخوانی های API را مد نظر ما باشد مخصوصا برای فهمیدن رفتار یک Malware .
در اینجا ما در مورد برخی از این تکنیک ها توضیح می دهیم:

1. آنپک کردن برنامه های پک شده
2. نمایش رفتار برنامه
3. پیدا کردن توابعی که برایمان مفید هستند


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

API Calls Logging with PEfile & PyDbg:


با تکیه بر موارد بالا,ما برای اسکریپتمان به اطلاعات زیر نیازمندیم:
1. آدرس برگشت - از کجا API فراخوانی شده؟
2. نام API - کدام API فراخوانی شده؟

پس ما باید یک breakpoint روی هر فراخوانی تابع قرار بدیم,چونکه به نام API یا آدرس آن احتیاج داریم.اگر ما نام تابع را داشته باشیم از طریق آن میتوانیم آدرس تابع را بدست بیاوریم و نقطه توقف روی آن قرار دهیم, در اینجا, آدرس ما می تواند مستقیما breakpoint روی آن قرار گیرد.اما سوال اینجاست که چطور میتوانیم نام توابع APIرو بدست بیاوریم؟
این مشکل رو ما با PEfile حل کردیم.پس ما اول توابع ورودی رو بدست میاریم و پس از اون با قرار دادن BP روی اینها آدرسهارو نیز بدست میاریم.
اما این روش محدودیت های زیر رو هم دارد:
1. در مورد DLL هایی که از طریق تابع LoadLibrary() لود شوند شکست می خورد.
2. اگر برنامه پک شده باشه پس جدول ورودی در زمان آنپک شدن ایجاد خواهد شد, پس شکست می خورد.

قبل از حل این مشکل اجازه بدید در مورد نحوه ی کار Unpacker Stub یا لودر ها برای ساختن جدول ورودی در هنگام اجرا توضیح مختصر میدم:
به طور معمول آنها از LoadLibrary برای لود کردن DLL و GetProcAddress برای بدست آوردن آدرس API استفاده می کنند.
این 2 تا تابع توسط kernel32.dll اکسپورت شدن, و در داخل هر پروسسی به صورت پیش فرض وجود دارند.
پس اگر ما یک  BP روی GetProcAddress قرار بدیم,نام API از پشته قابل دستبابی است. در ادامه یک BP هم روی آدرس بدست آمده از تابع GetProcAddress قرار می دهیم.
اما روش های دیگری هم برای بازسازی جدول ورودی در هنگام اجرا وجود دارد که توسط بدافزارها مورد استفاده قرار میگیرد.
تو اسمبلی یه چیزی شبیه به کد زیر :


      	push dword ptr fs:[30h] ; PEB
        pop eax
        mov eax,[eax+0ch] ; LDR
        mov ecx,[eax+0ch] ; InLoadOrderModuleList
        mov edx,[ecx]
        push edx
        mov eax,[ecx+30h]

توی مبحث توسعه نرم افزار, مبهم سازی (obfuscation) یک عمل عمدی برای ساخت کدهای مبهم شده است. یعنی سورس کد یا کد ماشینی تولید کنیم که فهمیدن آن برای انسان مشکل باشد. به ابزاری که این عمل رو برای ما انجام میدهد obfuscator  می گویند.بعنوان مثال Obfuscator سورس کد, سورس کد برنامه رو دریافت می کند و سورس کد دیگری با همان عملکرد که درک آن سخت تر است را تولید می کند.

 

مبهم سازی زمانی صورت میگیرد که برنامه نویس نخواهد هدف یا منطق برنامه قابل رویت باشد, جلوگیری از tampering , دلسرد کردن کردن reverser و چیزای دیگه که همگی به خود برنامه نویس مربوط می شود.

البته معماری و خصوصیات یک زبان هم می تواند به مبهم سازی آن کمک کند از جمله زبان های برنامه نویسی مثل C, C++, Perl و...زبانهای راحتی برای مبهم سازی هستند.

 

مبهم سازی می تواند شامل تعویض کلمات کلیدی ساده, استفاده کردن یا نکردن از فضای خالی, برداشتن توضیحات, از بین بردن تورفتگی ها, تغییر نام ثابت ها و شناسه ها (مثل مغییرها, توابع و ...) در سورس فایل و ... باشد.

 

مثال زیر به زبان جاوا اسکریپت است:


تابع call ebp :
این تابع دارای چندین حلقه هستش که دایما دارن محتویات رو تغییر میدن و دستورات جدید رو رمزگشایی میکنن و در آدرسی که بعد از این تابع قرار دارد و قرار است به اون jump زده شود قرار می دهند. اگه دستورات آدرس 401018 رو قبل و بعد از این تابع ببینید خواهید دید که کلی دستور جدید تولید شده.


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

دستور بعد از این تابع یک دستور بی اثر هستش و بعد از اون هم یک پرش.

این همون پرشی هستش که به کدهای رمزگشایی شده انجام میشه.


پکر و آنپکر

۲۹
آبان
با سلام خدمت دوستان.
اول از همه ازتون عذر میخوام که مدتی نبودم.
امروز رو قراره مختصری در مورد پکر ها توضیح بدم.

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

دلایلی که ما از پکرها استفاده می کنیم:
1- برای کاهش سایز فایلمون (البته این مورد با افزایش حافظه و قدرت سخت افزار دیگه دلیل قانع کننده ای نیست)
2- فرار از کشف و آنالیز شدن (این کار هم جنبه مثبت داره و هم جنبه ی منفی. جنبه ی مثبتش استفاده کردن برنامه نویس ها مخصوصا ایرانی ها برای سخت تر کردن مراحل کرک و ... و جنبه ی منفی اون bypass کردن آنتی ویروس و سخت ترکردن تحلیل بدافزار میتونه باشه)

تعریف کلی پکر:
گرفتن یک فایل اجرایی و فشرده سازی آن.
برای سخت تر شدن تحلیل پکر میتونه فایل اجرایی رو رمز کنه یا از تکنیک های anti reversing مثل آنتی دیباگ , آنتی دیس و ... استفاده کنه.
پکر میتونه کل یه فایل اجرایی رو پک کنه یا اینکه فقط یه سری سکشن های خاص مثل سکشن code رو پک کنه.
همه ی اینها به هدف پکر بستگی داره.

خوب همونطور که گفته بودیم دستور int 2dh باعث میشه که از آدرس 413BC0 پرش کنیم و همچین آدرس 413BC1 هم اجرا بشه و در آدرس 413BC2 متوقف بشیم.

pop esi چی کار کرد؟

آدرس 413BB9 که توسط Call در آدرس 413BB4 در پشته پوش شده بود رو پاپ میکنه. پس الان ESI ما محتوی مقدار 413BB9 هستش.

در ادامه از این 9 واحد کم میشه و الان ESI محتوی 413BB0 هستش.

دستور lodsd یا بعبارتی (LODS DWORD PTR DS:[ESI]  ) مقدار آدرس 413BB0 رو به اندازه 4بایت(Dword) در EAX لود میکنه.  پس الان EAX ما مقدار 0 میگیره. و خود ESI هم 4 بایت کاهش پیدا میکنه.

 

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

کاری که شمارو با ابعاد مختلف مهندسی معکوس آشنا می کنه مثل انواع آنتی ها, حقه ها, نحوه ی استفاده از امکانات سیستم عامل, نحوه ی سواستفاده از این امکانات, Zero Day ها و خیلی چیزای دیگه...:)

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

ما قراره سری آموزشی Dr.FU که تحلیل یه نسخه ی قدیمی از بدافزار ZeroAccess که بهش Max++ هم میگن هستش رو اینجا قرار بدیم.

 

ما فرض می کنیم که شما با مسائل پایه مهندسی معکوس مثل X86 asm , Debugging , OS و زبان برنامه نویسی آشنایی مختصری دارید, اگه این اطلاعات رو ندارید میتونید آموزش های قبلی این وبلاگ رو بخونید.

موارد مورد نیاز در طول این آموزش:

1- یک راه انداز ماشین مجازی مثل Virtual Box یا Vmware

2- ویندوز XP سرویس پک 2 برای نصب در VMWare

3- IDA Pro , OllyDbg یا ImmDbg

4- یک هگزادیتور

5- WinDbg

6- Wireshark

7- ZeroAccess (نسخه ای که قراره آنالیز کنیم رو اینجا می تونید دانلود کنید)

 

نکته: ویندوز میزبان ما XP-SP2 هست و VM رو در این ویندوز نصب کردیم و یه ویندوز XP-SP2 مجازی هم راه اندازی کردیم.

نکته دوم: قبل شروع آنالیز حتما یه snapshot از VM خودتون بگیرد.

 

طریقه ی راه اندازی یک ماشین مجازی رو احتمالا باهاش آشنا هستید اگه اینطور نیست می تونید از دکتر Google بپرسید:)

 

 

وقتی فایل رو در IDA باز میکنیم: 



3 تا فایل دیگه برای آنالیز در اینجا قرار میدم.

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


لینک دانلود


این پست با اینکه از روند آموزشی ما خارج هستش ولی چون یکی از دوستان درخواست داده بودن که در مورد Flink و Blink صحبت کنیم  و اینکه یه زنگ تفریحی هم برای وبلاگ باشه قرار داده میشه:)

 

مقدمه:

Flink و Blink دو تا اشاره گر هستند که جزی از یه ساختار بنام _LIST_ENTRY بحساب میان که این ساختار بنوعی لیست پیوندی هستش ولی از نوع مضاعف.

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

خوب من علاوه بر توضیح این ساختار یه توضیحات مختصری هم در مورد پروسس ها و

Enumeration process از طریق LIST_ENTRY رو میدم.

با سلام.

یکی از دوستان توی نظری که داده بودند از نحوه ی تحلیل sample سوم در پست قبل ایراد گرفته بودند. ایشون از جواب خلاصه نشده هم از توضیح ندادن در مورد اعداد شناور و رجیسترها و امکانات CPU برای این منظور ایراد گرفتن.

همونطور که این دوستمون گفتند باید از یک مثال دیگه ای که فعلا این دستورات داخلش نباشه استفاده میکردم. ولی حالا که این اتفاق افتاده توی این پست قصد دارم در مورد Floating point توضیحاتی رو بدم.

 

میخاستم در مورد پکرها و روش های انپک کردن توضیح بدم ولی تصمیمم عوض شد و قرار شد که توی چندتا پست یه سری فایل رو reverse کنیم.

 

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

 

دانلود

 

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


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

دوستان هم میتونند سایت هایی که از نظرشون مفید هست رو معرفی کنند.


برنامه نویسی و سورس کد



http://www.learnpython.org

همونطور که از اسمش مشخصه برای آموزش زبان پایتون هستش(زبان فارسی هم داره)

البته آموزش زبان های دیگه ای هم مثل C , C# , PHP, JS, Java, Shell رو داره,جالبی این سایت داشتن مفسر و کامپایلر آنلاین هستش:)


https://compilr.com

http://www.compileonline.com

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



http://www.sourcecodeonline.com

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



دیس اسمبلر های آنلاین



http://www.onlinedisassembler.com/odaweb

دیس اسمبلر آنلاین با قابلیت پشتیبانی چندین معماری


https://pyms86.appspot.com

یک دیس اسمبلر آنلاین که با پایتون نوشته شده 


http://www.e-tradition.net/bytes/6502/disassembler.html

یک دیس اسمبلر برای 6502/6510 MPU که با جاوا اسکریپت نوشته شده



Deobfuscate آنلاین برای کدهای ماشین



http://opticode.coseinc.com

سایتی که کدهای مبهم شده ( obfuscate) رو Deobfuscate میکنه



Decompiler های آنلاین



http://www.javadecompilers.com

دیکامپایلر آنلاین برای جاوا


http://www.decompileandroid.com

دیکامپایلری برای فایل های APK اندروید


http://www.showmycode.com

دیکامپایلر و decoder آنلاین برای جاوا, dotNet , swf ,php و QR 



با سلام خدمت دوستان.

خوب همونطور که در پست های قبل مشاهده کردید اکثرا به مبحث "تشخیص ساختارهای برنامه نویسی در اسمبلی" پرداخته شده, سعیم بر این بود تا بتونم این سری آموزشی رو به اتمام برسونم و خوشبختانه هم تموم شد. 

همونطور که میدونید اینها مباحث فصل هفتم کتاب Practical Malware Analysis هستش. ولی کامل نیست و برای کامل شدن این قضیه من یه سری فایل اجرایی قرار میدم که نه تنها شامل مباحث گفته شده هستش بلکه ساختارهای دیگه ای رو هم شامل میشه و شما میتونید با آنالیز اونها توانایی خودتون رو توی این زمینه افزایش بدید. این فایل ها course بندی شده از ساده به سخت.

دانلود

یه سری فایل دیگه هم بود که من فراموش کرده بودم, ولی الان لینک دانلودش رو گذاشتم

دانلود2

موفق باشید.


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

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

ازینرو لیست های پیوندی اجازه قرار دادن یا حذف کردن یک گره رو در هر نقطه از لیست را می دهند.

 

به کد زیر توجه کنید:

 

struct node

{

   int x;

   struct node * next;

};

 

typedef struct node pnode;

 

void main()

{

   pnode * curr, * head;

   int i;

 

   head = NULL;

 

   for(i=1;i<=10;i++) (1)

   {

      curr = (pnode *)malloc(sizeof(pnode));

      curr->x = i;

      curr->next  = head;

      head = curr;

   }

 

   curr = head;

 

   while(curr) (2)

   {

      printf("%d\n", curr->x);

      curr = curr->next ;

   }

}


ساختارها (یا بصورت اختصار struct ها) شبیه آرایه ها هستند با این تفاوت که شامل انواع مختلفی از عناصر هستند. بد افزار نویس ها ازین برای اطلاعات گروهی استفاده می کنند. گاهی وقتا استفاده از ساختار ها بجای یه سری از متغیرهای مختلف مفید واقع میشه و کارو راحت می کنه مخصوصا اگه به گروهی از متغیرها برای یه کار نیاز داشته باشیم.توابع API ویندوز هم اکثر اوقات از ساختارها استفاده می کنند.


struct my_structure { 

     int x[5];

     char y;

     double z;

};

 

struct my_structure *gms; 

 

void test(struct my_structure *q)

{

     int i;

     q->y = 'a';

     q->z = 15.6;

     for(i = 0; i<5; i++){

           q->x[i] = i;

     }

}

 

void main()

{

     gms = (struct my_structure *) malloc(

     sizeof(struct my_structure));

     test(gms);

}

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

بد افزارها گاهی اوقات از آرایه برای اشاره به رشته هایی که محتوی چندین hostname که بعنوان گزینه هایی برای ارتباط استفاده می شود, استفاده می کنند.


دو آرایه در مثال زیر تعریف شده که هر دو در هنگام تکرار حلقه تنظیم می شوند.

آرایه a بصورت محلی و آرایه b بصورت عمومی تعریف شده که این تفاوت را در کد دیس اسمبل شده مشاهده خواهید کرد.


int b[5] = {123,87,487,7,978};

void main()

{

   int i;

   int a[5];

 

   for(i = 0; i<5; i++)

   {

      a[i] = i;

      b[i] = i;

   }

}


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


00401006        mov     [ebp+var_18], 0

0040100D        jmp     short loc_401018

0040100F loc_40100F:

0040100F        mov     eax, [ebp+var_18]

00401012        add     eax, 1

00401015        mov     [ebp+var_18], eax

00401018 loc_401018:

00401018        cmp     [ebp+var_18], 5

0040101C        jge     short loc_401037

0040101E        mov     ecx, [ebp+var_18]

00401021        mov     edx, [ebp+var_18]

00401024        mov     [ebp+ecx*4+var_14], edx 1(1)

00401028        mov     eax, [ebp+var_18]

0040102B        mov     ecx, [ebp+var_18]

0040102E        mov     dword_40A000[ecx*4], eax 2(2)

00401035        jmp     short loc_40100F


در اینجا آدرس مبنای آرایه b برابر است با dword_40A000 و آدرس مبنای آرایه a برابر با var_14 میباشد.بخاطر اینکه هر دو آرایه عددی هستند, هر عنصر 4 بایت سایز دارد.

هر چند دستورات (1) و (2) برای دسترسی به دو آرایه متفاوت هستند در هر دو مورد ecx بعنوان اندیس استفاده شده است, که در 4 ضرب می شود تا سایز هر عنصر حساب شود. مقدار نتیجه به آدرس مبنای آرایه برای دسترسی به عنصر آرایه مدنظر جمع می شود.

سوییچ خیلی زیاد توسط برنامه نویس ها (مخصوصا بدافزارنویس ها) برای گرفتن تصمیم هایی مبتنی بر یک کاراکتر یا عدد استفاده می شود.

دستور سوییچ به دو صورت رایج کامپایل می شود: استفاده از استایل if یا جداول پرش.


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

حافظه اصلی یا همون رم سیستم برای یک برنامه به 4 قسمت اصلی زیر تقسیم میشه

قسمتی که برای ما در اینجا مهمه Stack هستش.
پشته به عبارت کلی قطعه ای از حافظه هستش که برای نگهداری اطلاعات تابع از جمله متغیرهای محلی , کنترل جریان و... استفاده میشه. با push میتوان عنصری داخل پشته قرار داد و با pop میتوان عنصری از داخل پشته برداشت کرد یا باصطلاح بازیابی کرد.
همونطور که میدونید ساختار پشته بصورت LIFO است یعنی اگه ما 1 , 2 و 3 رو به ترتیب درون پشته قرار دهیم (push) , اولین عنصری که میتونیم برداشت کنیم pop) 3) خواهد بود پس هر عنصری جدید روی عنصر ماقبل خودش قرار میگیره.
در معماری x86 پشته built-in پشتیانی میشه و رجیسترهایی هم که برای این کار هستند ESP و EBP هستند.
رجیستر ESP به بالای پشته اشاره میکنه یعنی آخرین عنصر, و با push یا pop کردن مقدار این رجیستر تغییر می کند.
از EBP هم بعنوان آدرس مبنا مورد استفاده قرار میگیره , تا از این طریق بشه متغیرهای محلی و پارامترها رو پیدا کرد.
پشته از آدرس های بالا به پایین تخصیص داده میشود به این صورت که آخرین عنصر آدرسش کوچکتر از اولین عنصر هستش.

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

1- مقاله آموزشی در مورد دیباگر Olly هستش که میتونید از این لینک دانلودش کنید.
2- کتاب "کرک و تکنیک های نفوذ به نرم افزار" رو هم پیشنهاد میکنم.البته بهتره که فقط فصل های 2 , 3 , 5 رو فعلا مطالعه کنید فصل 7 هم مفیده ولی بخاطر توضیحات مبهم پیشنهاد نمیکنم. این کتاب رو میتونید از کتاب فروشی ها تهیه کنید یا از اینجا دانلود کنید.

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

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

موفق باشید.

Pcrlth0n

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

یکی ازین حلقه ها FOR هستش که خیلی زیاد استفاده میشه و 4تا قسمت داره:

مقداردهی اولیه

مقایسه

دستورات اجرایی

افزایش یا کاهش

 

یه نمونه از دستور for

int i;

 

for(i=0; i<100; i++)

{

   printf("i equals %d\n", i);

}

توی برنامه نویسی از دستور if برای تغییر روند اجرا مبتنی بر یک شرط خاص استفاده میشه که ما میخوایم اینجا به بررسی کدهای دیس اسمبل تولید شده با دستور if بپردازیم.

در زیر کد زبان سی و همچنین کد دیس اسمبل شده ی اون رو مشاهده میکنید توجه کنید که دستور if در اینجا با پرش شرطی jnz پیاده سازی شده البته توی کدهای دیس اسمبل شده این یادتون باشه که هر پرش شرطی دلیل بر وجود دستور  if نیست.


int x = 1;

int y = 2;

 

if(x == y){

      printf("x equals y.\n");

}

else{

      printf("x is not equal to y.\n");

}

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

00401006        mov     [ebp+var_8], 1

0040100D        mov     [ebp+var_4], 2

00401014        mov     eax, [ebp+var_8]

00401017        cmp     eax, [ebp+var_4]  (1)

0040101A        jnz     short loc_40102B  (2)

0040101C        push    offset aXEqualsY_ ; "x equals y.\n"

00401021        call    printf

00401026        add     esp, 4

00401029        jmp     short loc_401038  (3)

0040102B loc_40102B:

0040102B        push    offset aXIsNotEqualToY ; "x is not equal to y.\n"

00401030        call    printf

با تغییر دادن بعضی از فیلد های فایل های اجرایی (PE) میشه عملکرد بعضی از نرم افزارهای مهندسی معکوس مثل olly رو مختل کرد.



عبارت junk code رو احتمالا توی مباحث مرتبط با مهندسی معکوس مثل مبهم سازی , Anti reversing , کدهای چندریختی و ... باهاش مواجه شدید.

توی این پست قراره در مورد junk code ها به صورت خلاصه توضیح بدم تا یه آشنایی کلی باهاش پیدا کنید.

 

Junk code چیست؟

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

 

دلیل استفاده از junk code ها؟

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

 

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

البته این روش هم دارای یه سری نقاط ضعف هستش,بعنوان مثال کدهای بلااستفاده بیشتر روند مهندسی معکوس روی توی آنالیز ایستا سخت می کنند نه آنالیز پویا, این کدها رو میشه با کمی تجربه تشخیص داد یا میشه با نوشتن اسکریپت هایی برای Olly یا IDA این کارو بصورت اتوماتیک انجام داد.

 

یه سری از دستورات اسمبلی که هیچ کاری انجام نمیدند رو در زیر مشاهده میکنید:


• NOP                       ;No Operation

• PUSH AX POP AX            ;push ax onto the stack and then pop it back off

• XCHG BX,BX                ;trade BX for BX (same as NOP literally in 8086)

• MOV AX,AX                 ;move ax register to AX register

• ROL AX,CL ROR AX,CL       ;rotate register left then rotate right.

• INC CX DEC CX             ;increase CX decrease CX


میتونید از ترکیب دستورات بالا استفاده کنید و یه بلوک کد بلااستفاده همراه با یه سری پرش ایجاد کنید, خلاقیت توی junk code ها حرف اول رو میزنه:)

 

نکته: البته یادتون باشه اگه از دستوراتی استفاده می کنید که روی رجیسترها تاثیر میزارند حتما قبلش رجیسترها رو داخل پشته ذخیره کنید (pushad) و بعد از اتمام کار رجیسترها رو به حالت اول برگردونید (popad)

خوب همونطور که میبینید اینم یه نقطه ضعف هستش و jnuk code هارو لو میده:)

 

توی زبان های سطح بالا, ایجاد junk code ها خلاقیت برنامه نویس رو بیشتر میطلبه. میتونید یه کلاس برای اینکار تعریف کنید و هر از چندگاهی اونرو لابه لایه کدهای برنامتون بکار ببرید ...

 

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

اینم یه نمونه junk code دیس اسمبل شده توی IDA:


میبینید که با دستور pushad شروع شده

پایین هم انتهای این کد رو مشاهده می کنید که با دستور popad تمام رجیسترها به حالت اول برمیگرده.





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

کد برناممون هم بصورت زیر هستش:

int a = 0;

int b = 1;

a = a + 11;

a = a - b;

a--;

b++;

b = a % 3;

این یک کتابخانه ی ویندوزی هستش که وابسته به کتابخانه های پشتیبانی شده نیست. شما می تونید ازش برای خوندن شماره سریال هارد دیسک استفاده کنید,همانطور که می دونید این شماره سریال منفرد هستش و از این شماره سریال می تونید برای ساختنن یک Machine ID یا encrypt number استفاده کنید.

بیشتر زبان های برنامه نویسی رو هم پشتیبانی می کنه.

خصیصه های اصلی:

* Easy to obtain the serial number of hard disk.
* Any operation can not to change the serialnumber of harddisk, include Format and Partition etc.
* Retrieve REAL serial number of hard disk. NOT Partition ID, NOT Volume ID.
* Support reading several physics hard disks.
* Many development languages are supported, such as the Delphi, C++Builder, VC, C#, VB, VB.NET, PowerBuilder, Visual Foxpro, Microsoft VBA, Clarion etc is available.
* Read more parameters, such as Model Number, Revision Number, Buffer Size, Cylinders, Heads, Sectors per track, etc.
* Not require administrator rights in Windows 7/Vista/2003/XP/2000/98.


لینک دانلودش اینجاس , این نسخه trial هستش.


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


ImpREC, CHimpREC, Imports Fixer ... همه اینها ابزارهای خوبی برای بازسازی جداول ورودی (import table) هستند. اما دارای اشکالاتی هم هستند.


Scylla مزایای زیر رو داره:

•x64 and x86 support
•full unicode support
•written in C/C++
•plugin support (ImpREC plugins are supported)
•works great with Windows 7

نویسنده این ابزار پیشنهاد میکنه که اونرو توی ویندوز سون نسخه ی 64بیتی استفاده کنید,چونکه برای این سیستم عامل طراحی شده و ممکنه توی سیستم عامل های دیگه کمی دچار مشکل بشه


قابل دانلود از:

https://github.com/NtQuery/Scylla

PE analysis toolkit

۱۰
بهمن

pev یه پروژه متن باز هستش که برای آنالیز فایل های اجرایی نوشته شده, این toolkit شامل چندین ابزار برای بررسی فایلها هستش که لیستش رو در زیر مشاهده می کنید:


* pehash - calculate PE file hashes
* pedis - PE disassembler
* pepack - packer detector
* pescan - search for suspicious things in PE files, including TLS callbacks
* pesec - check security features in PE files
* pestr - search for unicode and ascii strings in PE files
* readpe - show PE file headers, sections and more
* rva2ofs - convert RVA to raw file offsets
* ofs2rva - convert raw file offsets to RVA


نکات اصلی این toolkit :


- No need for Windows API. We use our own PE library called libpe.
- Tested on Windows, Linux and OS X.
- Support for 32 and 64-bit PE files.
- Written entirely in C, using C99 standard. So, it's multiplatform.
- Fully scriptable. All pev tools uses CLI and produces outputs in clear text and CSV (HTML, XML and JSON in development).


در کل بنظرم ارزش معرفی رو داشت, هرچند که یکم من باهاش مشکل دارم:)
میتونید از اینجا دانلودش کنید.


Enigma Protector

۱۰
بهمن

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

ویژگی های این پروتکتور:

File Protection

    A range of features and technologies to help protect the executable file from hacking, analysis, modification and disassembly. A Virtual Machine technology enables part of the application and protection code to be executed in its own virtual CPU, which makes the code practically impossible to analyze.


 Licensing System

    The licensing system allows prompt integration of registration key verification functions, binding license to a specific computer, limiting the term of license. Rich functionality of the licensing system allows you to create your own key generators and to use the built-in or easily customizable CGI key generators.


 Virtual Box

    The unique technology which allows combining the files used by your application into a single module without loss of efficiency. This function supports all kinds of files, including dll, ocx, mp3, avi, etc. Virtual Box will protect your files and prevent them from being copied and used in third-party products.


محصولات دیگه هم داره که میتونید توی سایتش مشاهده کنید:

http://enigmaprotector.com

آخرین نسخش تا اونجا که می دونستم 9.3.3 بودش, یه دیباگر برای ویندوز7 و ماقبلش هستش, البته نسخه ی 64 بیتی هم داره (نسخه 2.9) که نیاز به NET framework. داره و باهاش میشه برنامه های NET. رو هم دیباگ کرد.البته این دیباگر قابلیت دیباگ سورس کد رو نداره.


میتونید از اینجا هر دو نسخه رو دانلود کنید

نسخه های VB.NET که پشتیبانی میشن:
2003, 2005, 2008, 2010, 2012, 2013 


هر نوع پروژه ای هم قابل تبدیل هستش:
Win Forms, Web, Class Library, Compact Framework, Silverlight و ..

آخرین ویژگی هایی هم که به زبان VB اضافه شده هم پشتیبانی شده مثل:


Await/Async
Multiline Lambdas
Implicit Line Continuation
Auto-Implemented Properties
Collection Initializers
Array Literals
Nullable Optional Parameters
Generic Variance
LINQ
WPF applications
In line XML w/"code holes"
The new "If" operator
Object initializers
Extension methods
Lambda expressions
Nullable data types
Implicit types
Anonymous types

etc...

خصیصه های اصلی:

Support for the latest Visual Studio features - The latest VB.Net / C# features are supported, including Await/Async, Implicit Line Continuation, Multiline Lambdas, Nullable Optional Parameters, LINQ, XML, WPF, Lambda expressions, and extension methods.
Support for All Project Types - Win Forms, Web, Class Library, Compact Framework, Console, etc.
High Accuracy - This release was stress tested on thousands of sample programs. Tested were hundreds of Microsoft sample projects (Visual Studio SDK samples, DirectX SDK projects, Windows 7 SDK samples, etc.), in house and customer projects, third party control samples (Infragistics, ComponentOne, Telerik, etc.), and open source projects from SourceForge and CodePlex.
Ease of Use - While the conversion logic itself is complex, using the converter isn't.  You are guided through each step of the process with easy, clear instructions.
Customization - Not every project is the same.  With dozens of conversion options to choose from, you are in control of the conversion process.
Convert Single Projects or Groups of Projects - You can create lists of programs and convert them with one click.  There's also a command line version included.
Comprehensive Reporting - There are reports showing potential trouble spots in your code, interesting things which happened during the conversion process, and any C# compiler errors which need to be fixed.


خود سایتش ادعا کرده که پروژه 5 میلیون خطی هم باهاش convert کرده و روی حدود 8هزار پروژه هم تست شده.به نظر که عالیه واسه کسایی که قرار یه پروژه مشابه با زبان سی شارپ بنویسن و میتونه کمک زیادی کنه.

میتونید از سایتش این نرم افزار رو دانلود کنید:
که البته رایگان نیست
help ها و مثال هایی هم توی سایت هستش که اگه قصد استفاده ازش رو دارید میتونه بهتون کمک کنه.

jakstab decompiler

۰۹
بهمن

ابزاری برای دیس اسمبل کردن و آنالیز ایستا برروی فایلهای اجرایی و تهیه گرافی از جریان کنترلی آن است. این ابزار به زبان جاوا نوشته شده و multi platform هستش که روی پردازنده های 0x86 برروی فایل های اجرایی PE و ELF قابل استفاده است.
این ابزار کد های ماشین رو به یک زبان میانی ترجمه میکنه و...

اطلاعات بیشتر رو میتونید از سایت اصلیش بدست بیارید:
http://www.jakstab.org/download

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


Process Explorer

۰۹
بهمن

This major Process Explorer release includes heat-map display for process CPU, private bytes, working set and GPU columns, sortable security groups in the process properties security page, and tooltip reporting of tasks executing in Windows 8 Taskhostex processes. It also creates dump files that match the bitness of the target process and works around a bug introduced in Windows 8 disk counter reporting.


دانلود آخرین نسخه

این برنامه می تونه فرآیند تشخیص هویت (authentication process) ویندوز رو bypass کنه, بدون اینکه پسورد قدیمی شمارو بازنویسی کنه.


System Requirements: Pentium III compatible processor, 10MB free space on the hard drive. CD-ROM, Floppy Drive or USB flash drive, keyboard, Internet connection (for product download). Compatible BIOS version. Windows system is required for installer to run. USB flash drive is required for the EFI version to work. Disk encryption is not supported. 

Supported target systems: All Windows systems starting from Windows XP to Windows 8.1 (please note, authorization through domain controller is not officialy supported). Regarding the EFI support only Windows 8/8.1 systems are supported. Kon-Boot is now able to bypass online account authorization on Windows 8/8.1.


خوشبختانه این برنامه نسخه رایگان هم داره که البته روی سیستم های 64 بیتی و ویندوز 7/8 جواب نمیده و برای XP-32bit هستش.

البته Kon-boot برای Mac OSX هم این برنامه رو ارائه کرده ولی چونکه این سیستم عامل جزء مباحث ما نیست بهش کاری نداریم.

آدرس سایتش:
http://kon-boot.com

PeFile

یک ماژول بسیار مفید به زبان پایتون برای آنالیز static فایل اجرایی یا همون PE , که باهاش میشه به هدر ها و عناصر دیگه مثل جدول ورودی و ... دسترسی داشت.
برای کار با این ماژول و ابزارهایی که برای آنالیز ایستاتیک فایل های اجرایی تهیه شده اند, نیاز به آشنایی حدالامکان نسبی با ساختار این فایلها هستش.
میتونید توی همین وبلاگ مقاله آشنایی با فایل های اجرایی رو پیدا کنید.
این ماژول رو می تونید از اینجا دانلود کنید

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

کار اصلی ما:

 

1- لود کردن dll توی حافظه هستش (LoadLibraryA)

نکته:توجه داشته باشید که dll توی مسیر فایل باشه وگرنه نمیتونه لودش کنه

 

2- بدست آوردن آدرس تابعی که میخوایم فراخوانی کنیم(GetProcAddress)

 

3- فراخوانی تابع

 

4- آزاد سازی dll (FreeLibrary)  (این کار الزامی نیست میتونید فقط برای مخفی کاری این کارو انجام بدید)

آخرین فیلد ساختار OptionalHeader یعنی فیلد DataDirectory که 128 بایت فضا اشغال کرده دارای 16 تا ساختار به نام IMAGE_DATA_DIRECTORY هستش و هر کدوم ازین ساختار ها 8 بایت سایز دارن.

این ساختار بشکل زیر هستش:

فایل اجرایی توی ویندوز یا به عبارتی PE با پسوند exe , dll و ... شناخته میشن که قطعا با فایلهایی با پسوند اینجوری روبرو شدید:)

اکثر اینا از یک قالب تعیین شده ای استفاده می کنند (VxDs و DLL های 16 بیتی ازین قالب مستثنی هستند) این قالب اجازه میده که یک فایل اجرایی توی همه نسخه های ویندوز قابل حمل باشه و دیگه ما نیاز به کامپایل دوباره مخصوص نسخه ی ویندوزیمون نداشته باشیم.

 

ساختار فایل اجرایی به شکل زیر هستش

 

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

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

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

 

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

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 بیتی بودن آنهاست.

 

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