
ترويسة ماكرو لإخفاء شيفرة C وقت الترجمة (tcc، win x86/x64)

obfus.h هي مكتبة تعتمد على الماكرو فقط لإخفاء تطبيقات C أثناء وقت الترجمة، مصممة خصيصًا لـ Tiny C (tcc) (يمكنك تنزيله من هنا -> Tiny-C-Compiler/releases). وهي مخصصة لمنصات Windows x86 وx64 وتدعم جميع إصدارات المترجم تقريبًا. درع موثوق جدًا لبرامجك بلغة C!
دمج obfus.h في مشروعك عملية بسيطة. ما عليك سوى تضمين السطر التالي في الكود الخاص بك:
#include "obfus.h"
سيؤدي هذا تلقائيًا إلى إخفاء الكود الخاص بك أثناء الترجمة، مما يضمن حماية وسرية ملكيتك الفكرية.
الخيارات المتاحة لتكوين الحماية:
// Advanced code protection (see the "Virtualization" part of the documentation!) #define VIRT 1 // Allows you to use the functions of a math VM // Additional options #define CFLOW_V2 1 // More powerful Control Flow obfuscation (slowly!) #define ANTIDEBUG_V2 1 // Use better dynamic anti-debugging protection #define FAKE_SIGNS 1 // Adds fake signatures of various protectors or packers // Disabling default features #define NO_OBF 1 // Don't obfuscate (for debugging) #define NO_CFLOW 1 // Don't use Control-Flow obfuscation #define NO_ANTIDEBUG 1 // Don't build in debugging protectionأو استخدمها مع وسائط المترجم:
tcc "app.c" -w -D NO_CFLOW -D ANTIDEBUG_V2 -D FAKE_SIGNS -D VIRT
[!WARNING] عند تجميع تطبيق مع الإخفاء، استخدم الوسيط
-wلكتم التحذيرات. وإلا، ستعرض وحدة التحكم العديد من السجلات المخيفة التي لا تأثير لها على النتيجة النهائية. لا داعي للانزعاج منها.
🔐 يتم تفعيل الحماية ضد التصحيح عبر استدعاءات للعديد من دوال MSVCRT الأساسية.
في الأماكن الحرجة من الكود يمكنك استخدام البنية ANTI_DEBUG;. على سبيل المثال:
ANTI_DEBUG;
if (!licenseExpired()) {
// ...
}
تعمل HIDE_STRING(str) على إخفاء السلاسل النصية وتعقيدها بصريًا عبر تحويرها، مما يعقّد اكتشافها وتعديلها في الكود المصدري بشكل كبير. عند التصريح بهذه الطريقة، يتم تجميع السلاسل على الرصة (stack) عبر تعليمات mov بدلاً من تحميلها دفعة واحدة. تضمن هذه الطريقة أن السلاسل غير مُصرَّح بها بشكل ثابت، بل يتم إنشاؤها في وقت التشغيل، مما يجعلها أقل عرضة للتحليل الثابت. ومع ذلك، من المهم ملاحظة أن هذه الميزة لا يمكن استخدامها لإخفاء الحقول الثابتة أثناء التصريح بها، لأنها تتضمن استدعاء دالة.
[!IMPORTANT] قد تظل بعض أدوات التفكيك قادرة على كشفها بسبب التحسينات الثابتة. في مخرجات المفكك، سيبدو الكود معقدًا ومرهقًا، مما قد يثني عن التحليل المباشر لكنه قد لا يمنع تمامًا جهود الهندسة العكسية المُصمَّمة.
مثال على استدعاء دالة printf من المكتبة القياسية مع إخفاء ثابت للرسالة وفك تشفيرها على الرصة:
char *hidden_message = HIDE_STRING("Hello, world!");
// ...
printf(hidden_message);
هذه تقنية حماية تُنفَّذ فيها بعض العمليات الحسابية من خلال آلة افتراضية مدمجة عند الأمر. تجعل تحليل العمليات الرياضية صعبًا جدًا! ستعمل مع تفعيل خيار VIRT (وفقط معه!). وإلا، ستُستبدل جميع أوامر الآلة الافتراضية بعوامل رياضية عادية.
[!WARNING] الافتراضية في المواضع الحرجة قد تؤثر على التحسين. استخدمها بحذر فقط في المناطق التي تكون هناك حاجة فعلية إليها.
لا تدعم الآلة الافتراضية بعض عمليات المقارنة الأساسية الخاصة بـ
double.
يمكنك استخدام العوامل المنطقية التي تعتمد على استدعاءات الآلة الافتراضية لزيادة تعقيد فهم الكود:
| Operator | Description |
|---|---|
VM_IF |
هذا ليس بديلاً كاملاً عن if/else، بل هو مجرد تعقيد للعوامل القياسية.
مثال بسيط على استخدام الافتراضية:
// ...
#define VIRT 1
// ...
// if ((2 + 2) == 4) { ... }
VM_IF (VM_EQU(VM_ADD(2, 2), 4)) {
printf("2 + 2 == 4!");
}
// if (condition1) { ... }
// else if (condition2) { ... }
// else { ... }
VM_IF (condition1) {
// if
} VM_ELSE_IF (condition2) {
// else if
} VM_ELSE {
// else
}
يمكنك العثور على أمثلة لاستخدام جميع دوال الآلة الافتراضية في الملف tests/virtualmachine.c
إذا كنت بحاجة إلى حماية متقدمة ضد خبراء الهندسة العكسية، فاستخدم خياري CFLOW_V2 وANTIDEBUG_V2.
// Let's obfuscate your code!
#include <stdio.h>
#define VIRT 1 // [+] Use math virtual machine
#define CFLOW_V2 1 // [+] ControlFlow v2
#define FAKE_SIGNS 1 // [+] Fake signatures
#define ANTIDEBUG_V2 1 // [+] AntiDebug v2
#define NO_OBF 0 // [-] Don't obfuscate (disable all)
#define NO_CFLOW 0 // [-] Disable ControlFlow
#define NO_ANTIDEBUG 0 // [-] Disable AntiDebug
#include "obfus.h"
void main() {
char *out = malloc(256);
strcpy(out, HIDE_STRING("Hello, world!\n"));
if (out) {
printf(out);
} else {
printf("Error!\n");
}
free(out);
int result = VM_ADD(5, 7); // 5 + 7
VM_IF (VM_EQU(result, 12)) { // (5 + 7) == 12
printf("5 + 7 == 12");
}
}
يُوصى باستخدام أحدث إصدار من Tiny C (0.9.27). لسوء الحظ، لا تدعم بعض إصدارات المترجم الوظائف اللازمة للإخفاء الكامل. Visual C وGCC وClang غير مدعومة ومن غير المرجح أن تحظى بالدعم.
يمكنك استخدام البرنامج النصي الخاص لنظام Windows للحصول على أحدث إصدارات obfus.h عبر تنزيل الحزمة من المستودع الرسمي. وهذا مفيد إذا كنت بحاجة إلى أتمتة التحديثات الأمنية دون استخدام git.
على سبيل المثال، يمكنك استخدامه قبل بناء مشروعك:
+ C:\...> call obfh-update C:\...> tcc app.c -wسيقوم البرنامج النصي بتحديث محتويات ملف obfus.h في الدليل الحالي (وفقًا للتكوين المحدد)
إن الكود البرمجي لأي برنامج (ومنطقه الأصلي الأصلي) المحمي باستخدام obfus.h يكاد يكون من المستحيل استعادته (فك إخفائه). ومع ذلك، فإن استخدام هذا المُخفِي لا يضمن حماية كاملة ضد جميع أنواع التهديدات. من المهم تطوير أنظمة الأمان الداخلية للبرنامج وصيانتها.
كيف سيبدو الكود التخطيطي بعد الإخفاء:
سيرى المهندس العكسي شيئًا كهذا إذا حاول استخدام أداة تفكيك:
هذا ما تبدو عليه جميع السلاسل المخفية عبر ميزة
HIDE_STRINGفي المفكك (بنية x86-64):; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; PROTECTED STRING: ; ORIGINAL STRING: ; mov eax, 48h lea rax, aHelloWorld ; mov [rbp-0Fh], al mov r11, rax ; mov eax, 65h ; . . . ; mov [rbp-0Eh], al ; mov eax, 6Ch ; mov [rbp-0Dh], al ; mov eax, 6Ch ; mov [rbp-0Ch], al ; mov eax, 6Fh ; mov [rbp-0Bh], al ; mov eax, 2Ch ; ; etc . . . ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
شكرًا لكل من ساعد في تطوير هذا المشروع. أقدر ذلك! ❤️
وشكرًا لك 🤝 على اهتمامك بهذا المشروع!
| Function | Type | Op | Description | Example |
|---|
VM_ADD | long | + | يجمع رقمين | VM_ADD(5, 3) = 8 |
VM_SUB | long | - | يطرح رقمين | VM_SUB(5, 3) = 2 |
VM_MUL | long | * | يضرب رقمين | VM_MUL(5, 3) = 15 |
VM_DIV | long | / | يقسم رقمين | VM_DIV(6, 3) = 2 |
VM_MOD | long | % | يحسب باقي قسمة رقمين | VM_MOD(5, 3) = 2 |
VM_EQU | BOOL | == | يتحقق مما إذا كان الرقمان متساويين | VM_EQU(5, 5) = true |
VM_NEQ | BOOL | != | يتحقق مما إذا كان الرقمان غير متساويين | VM_NEQ(5, 3) = true |
VM_LSS | BOOL | < | يتحقق مما إذا كان الرقم الأول أقل من الرقم الثاني | VM_LSS(3, 5) = true |
VM_GTR | BOOL | > | يتحقق مما إذا كان الرقم الأول أكبر من الرقم الثاني | VM_GTR(5, 3) = true |
VM_LEQ | BOOL | <= | يتحقق مما إذا كان الرقم الأول أقل من أو يساوي الرقم الثاني | VM_LEQ(3, 5) = true |
VM_GEQ | BOOL | >= | يتحقق مما إذا كان الرقم الأول أكبر من أو يساوي الرقم الثاني | VM_GEQ(5, 3) = true |
VM_ADD_DBL | long double | + | يجمع رقمين عشريين (double) | VM_ADD_DBL(5.5, 3.2) = ≈8.7 |
VM_SUB_DBL | long double | - | يطرح رقمين عشريين (double) | VM_SUB_DBL(5.5, 3.2) = ≈2.3 |
VM_MUL_DBL | long double | * | يضرب رقمين عشريين (double) | VM_MUL_DBL(5.5, 3.2) = ≈17.6 |
VM_DIV_DBL | long double | / | يقسم رقمين عشريين (double) | VM_DIV_DBL(6.0, 3.0) = ≈2.0 |
VM_LSS_DBL | BOOL | < | يتحقق مما إذا كان الرقم العشري الأول أقل من الرقم العشري الثاني | VM_LSS_DBL(3.5, 5.2) = true |
VM_GTR_DBL | BOOL | > | يتحقق مما إذا كان الرقم العشري الأول أكبر من الرقم العشري الثاني | VM_GTR_DBL(5.5, 3.2) = true |
استخدمها بدلاً من if |
VM_ELSE_IF | استخدمها بدلاً من else if |
VM_ELSE | استخدمها بدلاً من else |