Obfuscator একটি টুল যা সোর্স কোডকে তার কার্যকারিতা পরিবর্তন না করেই পড়তে কঠিন আকারে রূপান্তর করে। Obfuscator বৌদ্ধিক সম্পত্তি রক্ষা, কোড বিশ্লেষণ জটিল করতে এবং রিভার্স ইঞ্জিনিয়ারিং প্রতিরোধ করতে ব্যবহৃত হয়। Android Developers Documentation অনুসারে, R8 এবং ProGuard এর মাধ্যমে অবফাসকেশন Android অ্যাপ্লিকেশনের প্রোডাকশন বিল্ডের একটি মানক ধাপ।
মূল পয়েন্ট
Obfuscator একটি প্রোগ্রাম যা অবফাসকেশন সম্পাদন করে: পঠনযোগ্য কোডকে কার্যকরীভাবে সমতুল্য কিন্তু মানুষের জন্য অপঠনযোগ্য কোডে রূপান্তর করা। একটি অবফাসকেটরের প্রধান কাজগুলি হল শনাক্তকারী বিকৃতি (identifier mangling), ডিবাগ তথ্য অপসারণ, কন্ট্রোল ফ্লো অবফাসকেশন এবং স্ট্রিং এনক্রিপশন।
অবফাসকেশন এনক্রিপশন নয়। এনক্রিপ্টেড কোড ডিক্রিপশন ছাড়া এক্সিকিউট করা যায় না। অবফাসকেটেড কোড সরাসরি JVM, ART বা JavaScript ইঞ্জিনে চলে, কিন্তু মানুষের পক্ষে এটি বোঝা অত্যন্ত কঠিন। অবফাসকেশন সম্পূর্ণ সুরক্ষা প্রদান করে না — একজন দৃঢ়প্রতিজ্ঞ বিশেষজ্ঞ সর্বদা ডিঅবফাসকেটর বা রানটাইম ডিবাগিংয়ের মাধ্যমে লজিক পুনরুদ্ধার করতে পারে।
প্রথম বাণিজ্যিক অবফাসকেটর ProGuard 2002 সালে Java অ্যাপলেটের জন্য একটি টুল হিসেবে আবির্ভূত হয়। Android (2008) এর বৃদ্ধির সাথে, ProGuard মোবাইল ডেভেলপমেন্টের জন্য মানক হয়ে ওঠে। 2018 সালে, Google Android Gradle Plugin 3.4-এর জন্য ProGuard-এর প্রতিস্থাপন হিসেবে R8 প্রকাশ করে। R8 ProGuard-এর চেয়ে 2-3 গুণ দ্রুত এবং SSA (Static Single Assignment) স্তরে গভীর অপ্টিমাইজেশনের কারণে আরও কমপ্যাক্ট বাইটকোড উৎপন্ন করে — একটি মধ্যবর্তী উপস্থাপনা ফর্ম্যাট যা ডেটা প্রবাহ বিশ্লেষণের অনুমতি দেয়।
ওয়েব ডেভেলপমেন্টে, অবফাসকেশন সরল মিনিফায়ার (YUI Compressor, 2007) থেকে জটিল AST ট্রান্সফর্মার (Obfuscator.io, 2016) পর্যন্ত বিবর্তিত হয়েছে। আধুনিক JavaScript অবফাসকেটররা কন্ট্রোল ফ্লো ফ্ল্যাটনিং, অস্বচ্ছ পূর্বাভাস (শর্ত যা সর্বদা সত্য বা মিথ্যা কিন্তু বিশ্লেষকের কাছে স্পষ্ট নয়) এবং রানটাইমে স্ব-ডিক্রিপশন সহ স্ট্রিং এনক্রিপশন ব্যবহার করে। Jscrambler (2012) অবফাসকেশনকে ডিবাগার সুরক্ষা এবং DRM প্রক্রিয়ার সাথে সংহত করে।
ব্যবহারের ক্ষেত্র অবফাসকেশনের বিস্তৃত। মোবাইল ডেভেলপমেন্টে, অবফাসকেটররা APK ডিকম্পাইলার (jadx, APKTool, dex2jar) এর মাধ্যমে কোড চুরি থেকে রক্ষা করে। ওয়েব ডেভেলপমেন্টে, JavaScript অবফাসকেশন অ্যালগরিদম, API কী এবং ক্লায়েন্ট-সাইড ব্যবসায়িক লজিক রক্ষা করে। লাইব্রেরি এবং SDK-তে, অবফাসকেশন প্রতিযোগীদের কোড ব্যবহার করতে বাধা দেয়।
| কৌশল | অবফাসকেশনের আগে | অবফাসকেশনের পরে |
|---|---|---|
| ক্লাসের নাম পরিবর্তন | NetworkManager | a |
| মেথডের নাম পরিবর্তন | sendRequest() | b() |
| স্ট্রিং এনক্রিপশন | "API_KEY" | decrypt("x9fK2p") |
| শর্তের বিভ্রান্তি | if (a > b) | if (a > b ? true : false) |
Identifier Mangling সবচেয়ে সাধারণ পদ্ধতি। ক্লাস, মেথড, ফিল্ড এবং ভেরিয়েবলের নাম ছোট, অ-তথ্যমূলক স্ট্রিং দিয়ে প্রতিস্থাপিত হয়: a, b, c, aa, ab। এটি কোডের প্রতিটি উপাদানের উদ্দেশ্য বোঝা কঠিন করে তোলে। ProGuard এবং R8 বিভিন্ন প্রকারের (ক্লাস A, ফিল্ড A, মেথড A) জন্য অভিন্ন নাম ব্যবহার করে, বিশ্লেষণকে আরও জটিল করে তোলে।
Control Flow Obfuscation কোড গঠন এমনভাবে পরিবর্তন করে যে রৈখিক ক্রম অস্পষ্ট হয়ে যায়। মৃত শাখা যোগ করা হয়, শর্ত উল্টে দেওয়া হয় (if (a) এর পরিবর্তে if (!a)), goto-সদৃশ অপারেটর (লেবেল সহ break/continue) সন্নিবেশ করা হয়। এটি ডিকম্পাইলার এবং ডিবাগারের মাধ্যমে বিশ্লেষণকে অত্যন্ত সময়সাপেক্ষ করে তোলে।
// সোর্স কোড
function authenticate(token) {
const url = "https://api.example.com/auth";
const headers = { Authorization: "Bearer " + token };
return fetch(url, { method: "POST", headers });
}// Obfuscator.io-এর পর হাই মোডে
const _0x4f2e = ["https://api.example.com/auth",
"Authorization", "Bearer ", "POST"];
(function(_0x5a3b, _0x4f2e) {
const _0x1c2d = function(_0x3e4f) {
while (--_0x3e4f) {
_0x5a3b["push"](_0x5a3b["shift"]());
}
};
_0x1c2d(++_0x4f2e);
}(_0x4f2e, _0x1c2d));
function _0x1c2d(_0x5a3b, _0x4f2e) {
return _0x4f2e[_0x5a3b];
}
function _0x3e4f(_0x1c2d) {
const _0x5a3b = _0x1c2d(0, "https://api.example.com/auth");
const _0x4f2e = { Authorization: "Bearer " + _0x1c2d };
return fetch(_0x5a3b, { method: "POST", headers: _0x4f2e });
}Obfuscator.io স্ট্রিং অ্যারে, অ্যারে এলোমেলো করার জন্য একটি স্ব-আহ্বানকারী ফাংশন যোগ করেছে, সমস্ত শনাক্তকারীর নাম পরিবর্তন করেছে এবং স্ট্রিংগুলিকে অ্যারে সূচক দিয়ে প্রতিস্থাপন করেছে। কোডের মূল 5 লাইন 20+ অপঠনযোগ্য লাইনে পরিণত হয়েছে, কিন্তু authenticate(token) কার্যকারিতা সম্পূর্ণরূপে সংরক্ষিত আছে। AST বিশ্লেষণের মাধ্যমে ডিঅবফাসকেশন সম্ভব, কিন্তু সময় প্রয়োজন।
ProGuard Java এবং Android-এর জন্য একটি ক্লাসিক অবফাসকেটর, 2002 সাল থেকে ব্যবহৃত হচ্ছে। ProGuard তিনটি কাজ সম্পাদন করে: কম্প্রেশন (অব্যবহৃত ক্লাস এবং মেথড অপসারণ), অপ্টিমাইজেশন (বাইটকোড অপ্টিমাইজেশন) এবং অবফাসকেশন (শনাক্তকারীর নাম পরিবর্তন)। ProGuard লাইব্রেরির জন্য ব্যতিক্রম নিয়ম সহ proguard-rules.pro ফাইলের মাধ্যমে Android Gradle Plugin-এ সংহত হয়।
R8 একটি আরও আধুনিক অবফাসকেটর যা AGP 3.4 থেকে Android Gradle Plugin-এ অন্তর্ভুক্ত। R8 ProGuard-এর মতো একই কাজ করে কিন্তু দ্রুত (স্ক্র্যাচ থেকে Kotlin-এ লেখা) এবং আরও দক্ষ (ART Runtime-এর জন্য ভাল বাইটকোড অপ্টিমাইজেশন)। R8 ProGuard-এর মতো একই proguard-rules.pro ফাইল ব্যবহার করে কনফিগার করা হয়। R8 সক্ষম করতে, build.gradle-এ minifyEnabled true সেট করা যথেষ্ট।
Mapping ফাইল R8/ProGuard-এর আউটপুট যা ক্লাস, মেথড এবং ফিল্ডের মূল এবং অবফাসকেটেড নামের মধ্যে ম্যাপিং ধারণ করে। ক্র্যাশ রিপোর্ট বিশ্লেষণের জন্য mapping ফাইল গুরুত্বপূর্ণ: এটি ছাড়া, স্ট্যাক ট্রেসে com.example.app.MainActivity.onCreate-এর পরিবর্তে a.a.b থাকবে। Firebase Crashlytics এবং Sentry স্বয়ংক্রিয়ভাবে mapping ফাইল আপলোড করে এবং রিপোর্টে মূল নাম পুনরুদ্ধার করে।
প্রতিটি নতুন অ্যাপ্লিকেশন রিলিজের সাথে mapping ফাইলগুলি Firebase বা Sentry-তে আপলোড করা আবশ্যক। যদি mapping ফাইল হারিয়ে যায় বা আপলোড না করা হয়, তাহলে অবফাসকেশনের পরে সমস্ত ক্র্যাশ রিপোর্ট অপঠনযোগ্য হয়ে যায়। Android Gradle Plugin স্বয়ংক্রিয়ভাবে build/outputs/mapping/release/mapping.txt-এ mapping ফাইল সংরক্ষণ করে। Firebase রিলিজ বিল্ডের সময় mapping আপলোড করতে Crashlytics Gradle Plugin ব্যবহার করে।
// app/build.gradle — R8 এর মাধ্যমে অবফাসকেশন
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile(
"proguard-android-optimize.txt"),
"proguard-rules.pro"
}
}
}# proguard-rules.pro — সংরক্ষণের নিয়ম
# Gson-এর জন্য ডেটা মডেল সংরক্ষণ করুন
-keep class com.example.model.** { *; }
# Retrofit ইন্টারফেসের জন্য ক্লাস সংরক্ষণ করুন
-keep,allowobfuscation interface com.example.api.*
# পাবলিক অ্যাক্টিভিটি অবফাসকেট করবেন না
-keep class * extends android.app.Activity {
public protected *;
}
# প্রোডাকশনে লগ সরান
-assumenosideeffects class android.util.Log {
public static boolean isLoggable(...);
public static int v(...);
public static int d(...);
}proguard-rules.pro-এ -keep নিয়ম গুরুত্বপূর্ণ — এগুলি ছাড়া, R8 রিফ্লেকশন (Gson, Retrofit, Room) এর মাধ্যমে ব্যবহৃত ক্লাস এবং মেথড সরিয়ে ফেলবে বা নাম পরিবর্তন করবে। assumentSideEffects প্রোডাকশন কোড থেকে Log.v এবং Log.d কল সরিয়ে দেয়। Gson, Retrofit এবং OkHttp-এর মতো লাইব্রেরি AAR-এর ভিতরে proguard.txt-এ তৈরি নিয়ম সরবরাহ করে।
Obfuscator.io সবচেয়ে জনপ্রিয় ওপেন-সোর্স JavaScript অবফাসকেটর যা শনাক্তকারীর নাম পরিবর্তন, স্ট্রিং এনক্রিপশন, কন্ট্রোল ফ্লো ফ্ল্যাটনিং এবং ডিবাগ সুরক্ষা সমর্থন করে। কনফিগারেশন JSON কনফিগ বা CLI এর মাধ্যমে করা হয়। বিনামূল্যের সংস্করণ মৌলিক পদ্ধতি সমর্থন করে; Enterprise সংস্করণ পলিমরফিক কোড এবং আত্ম-সুরক্ষা যোগ করে।
Jscrambler একটি বাণিজ্যিক JavaScript অবফাসকেটর যা উন্নত সুরক্ষা সহ: পলিমরফিক ট্রান্সফর্মেশন (প্রতিটি রান নতুন অবফাসকেটেড কোড তৈরি করে), ডিবাগার সুরক্ষা (DevTools সনাক্তকরণ), স্ক্রিনশট সুরক্ষা (self-defending) এবং মেয়াদ শেষ হওয়ার প্রক্রিয়া (একটি নির্দিষ্ট তারিখের পরে কোড কাজ করা বন্ধ করে দেয়)। Jscrambler ব্যাংকিং অ্যাপ্লিকেশন এবং DRM সিস্টেমে ব্যবহৃত হয়।
// obfuscate.js — Obfuscator.io কনফিগারেশন
const JavaScriptObfuscator = require("javascript-obfuscator");
const fs = require("fs");
const code = fs.readFileSync("app.js", "utf8");
const result = JavaScriptObfuscator.obfuscate(code, {
compact: true,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 0.75,
numbersToExpressions: true,
simplify: false,
stringArray: true,
stringArrayThreshold: 0.8,
debugProtection: true,
disableConsoleOutput: true,
});
fs.writeFileSync("app.obfuscated.js", result.code);প্যারামিটার Obfuscator.io-এর: controlFlowFlattening: 0.75 75% ব্লকে কন্ট্রোল ফ্লো বিভ্রান্ত করে; stringArray: true স্ট্রিংগুলিকে অ্যারেতে স্থানান্তর করে; debugProtection DevTools খোলা প্রতিরোধ করে; disableConsoleOutput console.log সরিয়ে দেয়। সীমা যত বেশি হবে, অবফাসকেশন সময় এবং কোড আকার তত বেশি হবে, কিন্তু বিশ্লেষণ তত কঠিন হবে।
অবফাসকেশন রানটাইম বিশ্লেষণ থেকে রক্ষা করে না। একজন আক্রমণকারী ডিবাগারে (Frida, Objection, Xposed) অ্যাপ্লিকেশন চালাতে পারে এবং রিয়েল টাইমে মেথডগুলি আটকাতে পারে। অবফাসকেশন স্ট্যাটিক বিশ্লেষণ (APK ডিকম্পাইলেশন, বাইটকোড পড়া) থেকে রক্ষা করে, কিন্তু ডায়নামিক বিশ্লেষণ থেকে নয়। রানটাইম সুরক্ষার জন্য অতিরিক্ত ব্যবস্থা প্রয়োজন: SSL Pinning, Root Detection, Integrity Verification।
অ্যাপ্লিকেশনের আকার অবফাসকেশনের পরে 20-50% পর্যন্ত বাড়তে পারে। কন্ট্রোল ফ্লো অবফাসকেশন মৃত শাখা যোগ করে এবং শর্ত ডুপ্লিকেট করে — এটি বাইটকোড আকার বাড়ায়। স্ট্রিং এনক্রিপশন ছোট স্ট্রিং লিটারেলকে decrypt() কল দিয়ে প্রতিস্থাপন করে, যা আকারও বাড়ায়। মোবাইল অ্যাপ্লিকেশনের জন্য এটি গুরুত্বপূর্ণ, কারণ APK আকার সরাসরি Google Play-তে রূপান্তরকে প্রভাবিত করে।
কর্মক্ষমতাও প্রভাবিত হয়। কন্ট্রোল ফ্লো অবফাসকেশন অতিরিক্ত চেক এবং শাখা যোগ করে, মেথড এক্সিকিউশন সময় 5-15% বাড়িয়ে দেয়। স্ট্রিং এনক্রিপশন প্রতিটি স্ট্রিং অ্যাক্সেসে decrypt কল যোগ করে। কর্মক্ষমতা-সংবেদনশীল ফাংশনের জন্য (Android-এ onDraw, React-এ render), -keep নিয়মের মাধ্যমে অবফাসকেশন নিষ্ক্রিয় করা উচিত।
সচরাচর জিজ্ঞাসিত প্রশ্ন
এনক্রিপশন কোডকে ডিক্রিপশন ছাড়া অকার্যকর করে তোলে — এক্সিকিউশনের জন্য একটি ডিক্রিপ্টর প্রয়োজন। অবফাসকেশন কোডকে অপঠনযোগ্য করে কিন্তু সরাসরি এক্সিকিউটেবল রাখে। এনক্রিপশন শক্তিশালী সুরক্ষা প্রদান করে কিন্তু একটি ডিক্রিপ্টর লোডার প্রয়োজন, যা নিজেই বিশ্লেষণ করা যেতে পারে।
ডিঅবফাসকেশন সম্ভব কিন্তু শ্রমসাধ্য। jadx, JEB Decompiler এবং UnConfuser-এর মতো টুলগুলি আংশিক ডিঅবফাসকেশন সহ বাইটকোড পুনরুদ্ধার করে। মূল নাম সহ মূল সোর্স কোডের সম্পূর্ণ পুনরুদ্ধার অসম্ভব — নামগুলি অপূরণীয়ভাবে হারিয়ে যায়। আধুনিক অবফাসকেটররা (R8, ProGuard) স্বয়ংক্রিয় ডিঅবফাসকেশন প্রতিরোধী।
Google Play অবফাসকেশন প্রয়োজন করে না কিন্তু build.gradle-এ minifyEnabled-এর মাধ্যমে এটি দৃঢ়ভাবে সুপারিশ করে। অবফাসকেশন ছাড়া অ্যাপ্লিকেশনগুলি APKTool এবং jadx-এর মাধ্যমে সহজেই ডিকম্পাইল করা যায়, যা এগুলিকে API কী চুরি, পরিবর্তন এবং পাইরেসির জন্য ঝুঁকিপূর্ণ করে তোলে। অধিকাংশ বড় অ্যাপ্লিকেশন R8 বা ProGuard ব্যবহার করে।
ক্র্যাশ রিপোর্ট অবফাসকেশনের পরে অবফাসকেটেড নাম (com.example.app.MainActivity-এর পরিবর্তে a.b.c) ধারণ করে। পুনরুদ্ধারের জন্য R8/ProGuard দ্বারা উৎপন্ন mapping ফাইল ব্যবহার করা হয়। স্বয়ংক্রিয় স্ট্যাক ট্রেস ডিঅবফাসকেশনের জন্য mapping ফাইলটি Firebase Crashlytics বা Sentry-তে আপলোড করা আবশ্যক।
স্ট্রিং এনক্রিপশন স্ট্রিং লিটারেল (API কী, URL, বার্তা) এনক্রিপ্টেড ডেটা এবং রানটাইমে decrypt ফাংশন কল দিয়ে প্রতিস্থাপন করে। এটি সংবেদনশীল স্ট্রিংগুলিকে ডিকম্পাইল করা কোডে সাধারণ অনুসন্ধানের মাধ্যমে পড়া থেকে রক্ষা করে। R8/ProGuard -encryptstrings নিয়মের মাধ্যমে স্ট্রিং এনক্রিপশন সমর্থন করে।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন