Reverse Code Engineering

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

Reverse Code Engineering

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

Reverse Code Engineering

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

آخرین نظرات

۳ مطلب در شهریور ۱۳۹۵ ثبت شده است

مهندسی معکوس یک کار ماهرانه هستش مخصوصا زمانی که ما میخواهیم یک برنامه بزرگ یا فایل های پک شده مثل 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 و...زبانهای راحتی برای مبهم سازی هستند.

 

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

 

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