ReverseEngineering
1.25K subscribers
41 photos
10 videos
55 files
666 links
Download Telegram
Tools you should know :

1 - radare2 :
official website :
https://rada.re/n/
github :
https://github.com/radareorg

2 - Ghidra :
official website :
https://ghidra-sre.org/
github :
https://github.com/NationalSecurityAgency/ghidra

3 - IDA Free / IDA Pro (Hex-Rays) :
https://hex-rays.com

4 - Cutter :
official website :
https://cutter.re/
github :
https://github.com/rizinorg/cutter

5 - iaito :
official website :
https://rada.re/n/iaito.html
github :
https://github.com/radareorg/iaito

6 - reflutter :
https://github.com/ptswarm/reFlutter

7 - Blutter :
https://github.com/worawit/blutter

8 - Apktool :
official website :
https://apktool.org/
github :
https://github.com/iBotPeaches/Apktool

9 - Jadx-gui :
https://github.com/skylot/jadx

10 - dnSpy :
https://github.com/dnSpy/dnSpy

11 - Binary Ninja :
https://binary.ninja/

12 - x64dbg :
https://x64dbg.com/
1
وقتی یه برنامه رو بدون Optimization کامپایل کنید همه‌چیز مرتب و واضح میاد بالا:

توابع جدا هستن شرط‌ها همون‌طور که نوشتید دیده میشن

ولی وقتی کامپایلر رو با O2- یا O3- اجرا کنید همه‌چیز به هم می‌ریزه:

بعضی توابع کلاً ناپدید می‌شن Inlining

شرط‌ها ساده میشن یا حتی حذف میشن

متغیرها میرن روی رجیستر و دیگه ردپای Stack کمتر میبینن





Inlining

تابع کوچیک رو کامپایلر میتونه مستقیم بیاره وسط کد
📖 مثال سورس:

inline int square(int x) {
return x * x;
}

int main() {
int a = square(5);
}


📖 دیس‌اسمبلی (تقریبی):

mov eax, 5
imul eax, eax ; به جای call تابع


اینجا دیگه خبری از call square نیست




Constant Folding

وقتی آرگومان ثابت باشه کامپایلر جواب رو از قبل حساب میکنه

📖 مثال سورس:

int a = 5 * 4;


📖 اسمبلی:

mov eax, 20 ; به جای ضرب





Loop Unrolling

برای سرعت بیشتر حلقه‌ها باز میشن
📖 سورس:

for (i=0; i<4; i++) arr[i] = 0;


📖 اسمبلی (ممکنه بشه):

mov [arr], 0
mov [arr+4], 0
mov [arr+8], 0
mov [arr+12], 0



Register Allocation

متغیرها به جای حافظه مستقیم روی رجیستر میرن. یعنی دیگه [ebp-4] یا [esp+8] نمی‌بینید فقط eax, ecx, edx




اثر روی RE:

وقتی یه تابع ناپدید میشه ممکنه فکر کنید سورسش وجود نداره در واقع inline شده

شرطی که تو سورس نوشتید ممکنه توی اسمبلی نباشه چون Compiler مطمئن بوده نتیجه همیشه مثبته

این تغییرات باعث میشه تحلیل سخت‌تر شه چون کد با چیزی که انتظار دارید فرق داره





🔹 تمرین پیشنهادی:

یه برنامه ساده با چند تابع و یه حلقه بنویسید

همون برنامه رو با -O0 بدون optimization و O2- کامپایل کنید

توی IDA/Ghidra هر دو رو مقایسه کنید و ببینید چه بخش‌هایی حذف یا تغییر داده شدن




Compiler Optimizations and Their Impact on Reverse Engineering

When you compile with no optimization (-O0) everything looks clean:

Functions stay separate

Conditions appear exactly as written

Variables live on the stack ([ebp-4], [esp+8])


But with -O2 or -O3 enabled, the compiler rewrites reality:

Some functions disappear completely inlining

Conditions are simplified or removed

Variables move into registers
no stack traces

Loops get transformed beyond recognition





Function Inlining

Small functions may be expanded directly into the caller

C Source:

inline int square(int x) {
return x * x;
}

int main() {
int a = square(5);
}



Disassembly (approx):

mov eax, 5
imul eax, eax ; inlined, no

call square

➡️ The function square() completely disappears!




Constant Folding

Constant expressions are precomputed

C Source:

int a = 5 * 4

;

Assembly:

mov eax, 20 ; compiler did the ma

th




Loop Unrolling

Loops may be expanded for speed.

C Source
:

for (int i=0; i<4; i++) arr[i] =

0;

Assemb
ly:

mov [arr], 0
mov [arr+4], 0
mov [arr+8], 0
mov [arr+1
2], 0

-

Register Allocation

Instead of stack-based variables, registers are used

At -O0 → you see [ebp-4], [esp+8]

At -O2 → just eax, ecx, edx


This removes the "breadcrumbs" that RE analysts love




Reverse Engineering Impact:

Missing functions → inlined, not gone

Missing conditions → compiler proved the result always true/false

Loop transformations → code looks nothing like source

Registers instead of stack → harder to track variables


Optimizations don’t just speed up execution — they also obfuscate code naturally, which makes RE a lot tougher




🔹 Practical Exercise

Write a small C program with multiple functions and a loop.


Compile twice:

gcc -O0 prog.c -o prog_O0

gcc -O2 prog.c -o prog_O2



Open both in IDA/Ghidra


Compare:

What functions got inlined?

Did loops unroll?

Where did conditions vanish?
2