الهدف من هذه المكتبة هو جعل التحليل الثابت والديناميكي (تصحيح الأخطاء) أكثر صعوبة.
تستهدف المكتبة بيئات Linux.
تعتمد حاليًا على خدعة ptrace المضادة للتحليل وتوفر الميزات الرئيسية التالية:
الاحتجاج المباشر SYSCALL دون الاعتماد على LIBC (وهذا يجعل آلية الالتفافية LD_PRELOAD غير فعالة) ؛
استدعاء النظام الذي يجعل الهندسة العكسية الثابتة أكثر صعوبة (هذه الميزة مدعومة حاليًا فقط في x86_64 ) ؛
دعوات متعددة ptrace syscall. يجب أن تُرجع كل مكالمة إلى ptrace القيمة المتوقعة (أي ، 0 في الاحتجاج الأول و -1 بعد ذلك) وتساهم في حساب قيمة " offset " التي يجب أن تتطابق في نهاية سلسلة مكالمات PTRACE (انظر هنا) في نهاية سلسلة مكالمات ptrace (انظر هنا). إذا قام PTRACE بإرجاع قيمة غير محدودة أو لا تتطابق قيمة " offset " ، فسيتم إنهاء العملية ؛
"ptrace" يسمى في الحلقات المتداخلة. الحلقات غير مصممة وعدد التكرارات العشوائية في كل تجميع. علاوة على ذلك ، فإن قيمة " offset " يتم إدراجها في كل تكرار ؛
يمكن أن يكون الرمز الذي تم إنشاؤه أكثر من ذلك من خلال تمكين ميزة obfuscate التي تعتمد على قفص جولدبرغ ؛
لاستخدام الصندوق ، أضفه إلى تبعياتك:
[dependencies]
debugoff = { version = "0.2.1, features = ["obfuscate"] }
لتمكين التمكين أيضًا ، استدعاء النظام ، استخدم ميزة syscallobf (هذه ميزة تجريبية وتؤثر فقط على الثنائيات التي تستهدف بنية x86_64 ):
[dependencies]
debugoff = { version = "0.2.1, features = ["obfuscate", "syscallobf"] }
بالنظر إلى أن المكتبة تنشئ رمزًا عشوائيًا في كل مجموعة ، تأكد من إعادة بناء كل شيء في كل مرة. شيء من هذا القبيل:
cargo clean
cargo build --release
يعد تجريد الرموز من بناء الإصدار فكرة جيدة أيضًا:
[profile.release]
debug = false
strip = "symbols"
panic = "abort"
في المثال أدناه ، يتم استخدام debugoff فقط عندما يكون نظام التشغيل المستهدف Linux وفقط لبناء الإصدار (وبهذه الطريقة عندما يتم تجميع الكود في وضع التصحيح ، يمكن تصحيحه دون الحاجة إلى تجاوز debugoff ).
// Include only for Linux and when building in release mode
# [ cfg ( target_os = "linux" ) ]
# [ cfg ( not ( debug_assertions ) ) ]
use debugoff ;
use std :: time :: SystemTime ;
fn main ( ) {
// Call only for Linux and when building in release mode
# [ cfg ( target_os = "linux" ) ]
# [ cfg ( not ( debug_assertions ) ) ]
debugoff :: multi_ptraceme_or_die ( ) ;
println ! (
"Time: {}" ,
SystemTime :: now ( )
. duration_since ( SystemTime :: UNIX_EPOCH )
. unwrap ( )
. as_millis ( )
) ;
// Call only for Linux and when building in release mode
# [ cfg ( target_os = "linux" ) ]
# [ cfg ( not ( debug_assertions ) ) ]
debugoff :: multi_ptraceme_or_die ( ) ;
println ! ( "Example complete!" ) ;
}انظر أمثلة أخرى في دليل الأمثلة التي يمكن بناؤها مع:
cargo build --release --features obfuscate,syscallobf --examples إذا قمت بإنشاء الكود التالي (الذي لا يستخدم DebugOff ) في وضع الإصدار:
use std :: time :: SystemTime ;
fn main ( ) {
println ! (
"Time: {}" ,
SystemTime :: now ( )
. duration_since ( SystemTime :: UNIX_EPOCH )
. unwrap ( )
. as_millis ( )
) ;
println ! ( "Example complete!" ) ;
} هذا هو الرسم البياني للوظيفة المقابلة للوظيفة main :
.
إذا قمنا ببناء نفس الرمز باستخدام DebugOff مع ميزة obfuscate :
# [ cfg ( target_os = "linux" ) ]
# [ cfg ( not ( debug_assertions ) ) ]
use debugoff ;
use std :: time :: SystemTime ;
fn main ( ) {
# [ cfg ( target_os = "linux" ) ]
# [ cfg ( not ( debug_assertions ) ) ]
debugoff :: multi_ptraceme_or_die ( ) ;
println ! (
"Time: {}" ,
SystemTime :: now ( )
. duration_since ( SystemTime :: UNIX_EPOCH )
. unwrap ( )
. as_millis ( )
) ;
# [ cfg ( target_os = "linux" ) ]
# [ cfg ( not ( debug_assertions ) ) ]
debugoff :: multi_ptraceme_or_die ( ) ;
println ! ( "Example complete!" ) ;
} هذا هو الرسم البياني للوظيفة المذهلة للوظيفة main :
.
في هذا المثال بالذات ، تم تثبيت جميع التعليمات البرمجية التي تم إنشاؤها بواسطة DebugOff في الوظيفة main . لا يضمن ذلك أن يكون هذا هو الحال دائمًا لأن الوظائف المضمّنة يمكن أن تتأثر بالعديد من العوامل مثل المواقع التي يتم استدعاء DebugOff وإصدار أدوات الأدوات المستخدمة لبناء المشروع. في حالات أخرى ، يمكن أن يكون الرسم البياني الناتج عن الوظيفة أكثر بساطة من الرسم البياني المذكور في المثال ، ولكن على أي حال ، أكثر تعقيدًا من تلك التي تم إنشاؤها عند عدم استخدام DebugOff .
مرخصة بموجب:
obfuscate ؛obfuscate ؛ x86_64 ) ؛