APK স্বাক্ষরিত বা "ডিবাগ বিল্ড" আছে কি করে তা পরীক্ষা করবেন?


121

আমি যতদূর জানি, অ্যান্ড্রয়েডে "রিলিজ বিল্ড" স্বাক্ষরিত হয়েছে APK এ। কোড থেকে এটি কীভাবে চেক করবেন বা গ্রহনের কোনও ধরণের গোপন সংজ্ঞা রয়েছে?

ওয়েব সার্ভিস ডেটা থেকে তালিকাভিট আইটেমগুলি পপুলিং করতে আমার এটি দরকার (না, লগক্যাট কোনও বিকল্প নয়)।

আমার চিন্তা:

  • অ্যাপ্লিকেশানের android:debuggable , তবে এমন কোনও কারণে যা নির্ভরযোগ্য দেখাচ্ছে না।
  • হার্ড-কোডিং ডিভাইস আইডি ভাল ধারণা নয়, কারণ আমি স্বাক্ষরিত APK গুলি পরীক্ষার জন্য একই ডিভাইসটি ব্যবহার করছি।
  • কোডের কোথাও ম্যানুয়াল পতাকা ব্যবহার করছেন? বোধগম্য, তবে অবশ্যই কিছু সময় পরিবর্তন করতে ভুলবেন না, প্লাস সমস্ত প্রোগ্রামার অলস।

রোল-ব্যাকড ফিলের সম্পাদনা। প্রোগ্রামটি বাজারে আইনত বিতরণ করা হচ্ছে বা হবে না নিয়ে প্রশ্নই আসে না। এটি সম্পর্কে প্রশ্নটি এখনও "ডিবাগ মোডে" প্রোগ্রাম।
im0rtality

এটি করার পক্ষে এই উপায়টি
এমবিএইচ

উত্তর:


80

ডিবাগ বা প্রকাশের শংসাপত্র ব্যবহার করে অ্যাপ্লিকেশনটি তৈরি হচ্ছে কিনা তা যাচাই করার বিভিন্ন উপায় রয়েছে তবে নীচের উপায়টি আমার কাছে সেরা বলে মনে হচ্ছে।

আপনার অ্যাপ্লিকেশনটিতে স্বাক্ষর করে অ্যান্ড্রয়েড ডকুমেন্টেশনের তথ্য অনুসারে , ডিবাগ কীতে নিম্নলিখিত বিষয় বিশিষ্ট নাম ধারণ করে: " সিএন = অ্যান্ড্রয়েড ডিবাগ, ও = অ্যান্ড্রয়েড, সি = ইউএস "। আমাদের কোডটিতে হার্ডবডিং ডিবাগ কী স্বাক্ষর ছাড়াই প্যাকেজটি ডিবাগ কী দিয়ে স্বাক্ষরিত হয়েছে কিনা তা পরীক্ষার জন্য আমরা এই তথ্যটি ব্যবহার করতে পারি।

প্রদত্ত:

import android.content.pm.Signature;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

আপনি এইভাবে একটি ডিজেব্যাগেবল পদ্ধতি প্রয়োগ করতে পারেন:

private static final X500Principal DEBUG_DN = new X500Principal("CN=Android Debug,O=Android,C=US");
private boolean isDebuggable(Context ctx)
{
    boolean debuggable = false;

    try
    {
        PackageInfo pinfo = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(),PackageManager.GET_SIGNATURES);
        Signature signatures[] = pinfo.signatures;

        CertificateFactory cf = CertificateFactory.getInstance("X.509");

        for ( int i = 0; i < signatures.length;i++)
        {   
            ByteArrayInputStream stream = new ByteArrayInputStream(signatures[i].toByteArray());
            X509Certificate cert = (X509Certificate) cf.generateCertificate(stream);       
            debuggable = cert.getSubjectX500Principal().equals(DEBUG_DN);
            if (debuggable)
                break;
        }
    }
    catch (NameNotFoundException e)
    {
        //debuggable variable will remain false
    }
    catch (CertificateException e)
    {
        //debuggable variable will remain false
    }
    return debuggable;
}

6
একাধিক ইম্পোর্ট matchings সমাধানে সহায়তা করতে, ক্লাস এখানে ব্যবহৃত হয় java.security.cert.X509Certificate, java.security.cert.CertificateExceptionএবং android.content.pm.Signature। অন্যান্য সমস্ত ক্লাস আমার পক্ষে একাধিক ম্যাচ উপস্থাপন করে না
খ্রিস্টান গার্সিয়া

1
এই আমদানিগুলির সাথে সম্পাদিত উত্তর। ধন্যবাদ!
Cory পেটস্কি

অ্যাপ্লিকেশন ক্লাসের অনক্রিট পদ্ধতিতে চালানো কি যথেষ্ট দক্ষ?
অ্যান্ড্রয়েড বিকাশকারী

আমি মৃত্যুদন্ড কার্যকর করার সময়টি লক্ষ্য করি নি, তবে আমি এটি আমার অ্যাপ্লিকেশনটিতে ব্যবহার করছি এবং দক্ষতার সাথে কোনও সমস্যা নেই।
ওমর রেহমান

দক্ষতা জন্য ফলাফল ক্যাশে করা যেতে পারে।
ftvs

138

ডিবাজিযোগ্য পতাকাটি পরীক্ষা করতে, আপনি এই কোডটি ব্যবহার করতে পারেন:

boolean isDebuggable =  ( 0 != ( getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE ) );

Kotlin:

val isDebuggable = 0 != applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE

আরও তথ্যের জন্য, দয়া করে অ্যান্ড্রয়েড এলভিএল অ্যাপ্লিকেশনগুলি সুরক্ষিত দেখুন ।

বিকল্পভাবে, আপনি যদি গ্রেডল সঠিকভাবে ব্যবহার করছেন, আপনি BuildConfig.DEBUGসত্য বা মিথ্যা কিনা তা পরীক্ষা করতে পারেন ।


দেখে মনে হচ্ছে এটি এখনও ম্যানিফেস্টের অ্যান্ড্রয়েড চেক করে না:
ডিবাজিযোগ্য

2
ম্যানিফেস্টের ডিবাজেবলের জন্য প্রথম একটি পরীক্ষা, এটি হ্রাস করা হয়। দ্বিতীয়টি গ্রন্থাগারগুলির পক্ষে সম্ভব নয়, লিবের নিজস্ব বিল্ডকনফিগ থাকবে - এটি অ্যাপটির বিল্ডকনফিগ আমদানি করতে সক্ষম নয়, যা লিব ব্যবহার করছে। এর জন্য চিহ্নিত উত্তরটি হ'ল "ঠিক আছে"
ক্রিস্টোফ

এই উত্তরটি লাইব্রেরি প্রকল্প বা অ্যাপ্লিকেশন প্রকল্প নির্বিশেষে সব ক্ষেত্রেই কাজ করবে।
লাভেকুশ অগ্রওয়াল

131

উত্তর দিয়েছেন মার্ক মারফি

সবচেয়ে সহজ এবং সর্বোত্তম দীর্ঘমেয়াদী সমাধানটি হ'ল ব্যবহার করা BuildConfig.DEBUG। এটি একটি booleanমান যা trueডিবাগ বিল্ডের জন্য হবে , falseঅন্যথায়:

if (BuildConfig.DEBUG) {
  // do something for a debug build
}

8
এই পদ্ধতির একমাত্র ব্যর্থতা হ'ল এটি গ্রন্থাগার প্রকল্পগুলিতে (আআর এর) কাজ করবে না। লাইব্রেরিগুলি তৈরি করা হলে, এটি ফলস্বরূপ ফলিত হবে, সুতরাং গ্রন্থাগারটি ব্যবহার করে এমন কোনও অ্যাপ্লিকেশন ডিবাগ মোডে থাকলেও এই চেকটি লাইব্রেরি কোডের মধ্যেই মিথ্যা হয়ে যাবে।
ভিটো আন্দোলিনি

24

আপনি যদি কোনও APKস্থিতি পরীক্ষা করতে চান তবে আপনি এটি ব্যবহার করতে পারেন

aapt dump badging /path/to/apk | grep -c application-debuggable

0যদি APKডিবাজিযোগ্য না হয় এবং 1যদি হয় তবে এই ফলাফলগুলি ।


3
এটিই একমাত্র সমাধান, চূড়ান্ত অ্যাপকে যাচাই করার জন্য। অন্যান্য প্রতিক্রিয়াগুলি মনে করে যে আপনার উত্স আছে।
গিলারমো টোবার

1
aaptএখানে থাকুন/Users/USER_NAME/library/Android/sdk/build-tools/28.0.3/aapt
কেসি

21

হতে পারে দেরী, কিন্তু iosched ব্যবহার BuildConfig.DEBUG


এটি কি এখন ব্যবহার করা নিরাপদ? এখানে একটি নিবন্ধ আছে যা বলছে এতে কিছু সমস্যা রয়েছে: digipom.com/be- careful
অ্যান্ড্রয়েড বিকাশকারী

এটাই সেরা উত্তর!
পিটার ফোর্টুইন

আপনি যদি কোনও তৃতীয় পক্ষের লাইব্রেরি লিখছেন এবং সংকলনের সময় বিল্ডকনফিগের প্যাকেজটি জানেন না not
স্যাম ডোজর

স্যাম, আপনি এই সম্পর্কে বিস্তারিত বলতে পারেন?
আগামেমনস

10

প্রথমে এটি আপনার বিল্ড.gradle ফাইলটিতে যুক্ত করুন, এটি ডিবাগ এবং রিলিজ বিল্ডগুলি পাশাপাশি চালানোর অনুমতি দেবে:

buildTypes {
    debug {
        applicationIdSuffix ".debug"
    }
}

এই পদ্ধতিটি যুক্ত করুন:

public static boolean isDebug(Context context) {
    String pName = context.getPackageName();
    if (pName != null && pName.endsWith(".debug")) {
        return true;
    } else {
        return false;
    }
}

1
আমি এই উত্তরটি পছন্দ করি কারণ এটি নির্ভরযোগ্য। যদিও আমার গুগল ম্যাপস এপিআই কী তে আমার নতুন "অনুমোদিত অ্যান্ড্রয়েড অ্যাপ্লিকেশন" এন্ট্রি যুক্ত করা দরকার (যদিও অ্যাপ্লিকেশন আইডি আলাদা)।
বাজ

5

একটি ডিবাগ বিল্ডও স্বাক্ষর করা হয়েছে, ঠিক অন্য কী দিয়ে। এটি Eclipse দ্বারা স্বয়ংক্রিয়ভাবে উত্পন্ন হয়েছে এবং এর শংসাপত্রটি কেবল এক বছরের জন্য বৈধ। সমস্যা কি android:debuggable? কোড ব্যবহার করে আপনি এই মানটি পেতে পারেন PackageManager


3

আরেকটি বিকল্প, উল্লেখ করার মতো। আপনি যদি ডিবাগারটি সংযুক্ত থাকে কেবল তখনই কিছু কোড কার্যকর করতে হয় তবে এই কোডটি ব্যবহার করুন:

if (Debug.isDebuggerConnected() || Debug.waitingForDebugger()) { 
    //code to be executed 
}

0

সঙ্গে সমাধান android:debuggable। এটি আইটেমটি পড়ার ক্ষেত্রে বাগ ছিল যেখানে কিছু ক্ষেত্রে আইটেমের ডিবাগ পতাকা রেকর্ডে if (m.debug && !App.isDebuggable(getContext()))সর্বদা মূল্যায়ন করার জন্য সংরক্ষণ করা হত না false। আমার খারাপ।


13
আমি বুঝতে পারি এটি এক বছরেরও বেশি পুরানো, তবে আপনার @ ওমর রেহমানের উত্তরটি গ্রহণ করা উচিত, এটির একটি নয়। আপনি যা পোস্ট করেছেন তা হ'ল শেষ পর্যন্ত আপনি যা করেছেন, এটি আপনার জিজ্ঞাসা করা প্রশ্নের উত্তর দেয় না, যদিও ওমরের সমাধান এটি করতে দেখা যায়, মানে তিনি স্বীকৃত creditণের প্রাপ্য।
মাহ

7
@ মাহ - তারা নিজের সমস্যার সমাধানের প্রায় এক বছর পরে পোস্ট করা উত্তরটি গ্রহণ না করার জন্য কাউকে বকাঝকা করা একেবারেই অনুচিত ! এবং এটি এমনকি যে আপনি যে উত্তরটি মনোনীত করেছেন তার চেয়ে যে জটিলতার সাথে তারা গেছে তার থেকেও আরও বেশি জটিলতার বিষয়টি উপেক্ষা করা হচ্ছে - যা আসলে জিজ্ঞাসিত প্রশ্নটির উত্তর দেয়, কারণ প্রশ্নটি একটি বাগ দ্বারা প্রেরিত হয়েছিল যেহেতু পতাকাটি বিশ্বাসযোগ্য নয় is ।
ক্রিস স্ট্রাটন

4
@ ক্রিসট্রেটটন যদি আপনি ভাবেন যে আমার প্রতিক্রিয়া হুমকি দিয়েছিল, আমার মনে হয় আপনি ইন্টারনেট খুব বেশি পড়েন না। আপনি যেমনটি করেছিলেন তেমনভাবে একটি মন্তব্যে আপনার বিরোধী দৃষ্টিভঙ্গি পোস্ট করার অধিকারকে আমি সমর্থন করি এবং ফলস্বরূপ আমি আমার মন্তব্য এবং এই প্রশ্নের অন্যান্য পোস্টগুলি পর্যালোচনা করেছি এবং আমি আমার মূল মন্তব্যে দাঁড়িয়ে আছি: পোস্টারটি এমন প্রশ্ন জিজ্ঞাসা করেছে যা বৈধভাবে ছিল এবং সঠিকভাবে কেউ উত্তর দিয়েছেন। তার নিজের "উত্তর" এর উপর ভিত্তি করে, তার আসল প্রশ্নটি নয় যে তিনি প্রথম স্থানে জিজ্ঞাসা করতে চেয়েছিলেন ... একটি APK এর স্বাক্ষর (প্রকাশ বা ডিবাগ) এর ম্যানিফেস্টে ঠিক শূন্য রয়েছে।
মাহ

3
@ মম - এটি আপনার জিজ্ঞাসকের উপর নির্ভর করে যে আপনি কীভাবে তাদের উত্থাপিত পার্থক্যকে গুরুত্ব সহকারে এক্ষেত্রে তাদের প্রকৃত প্রয়োগের প্রয়োজনটিকে সন্তুষ্ট করে তা সিদ্ধান্ত নেবেন না - বা এই ক্ষেত্রে আপাতদৃষ্টিতে তা নয়। আরও গুরুত্বপূর্ণ, আপনি সম্পূর্ণরূপে উপেক্ষা করবেন যে আপনি যে উত্তরটি মনোনীত করবেন সেগুলি তাদের আসল প্রয়োজন সন্তুষ্ট হওয়ার প্রায় এক বছর পরে পোস্ট করা হয়েছিল । এটি কাউকে শাস্তি দিচ্ছে এক বছর পরে তাদের গ্রহণযোগ্যতা পরিবর্তন করতে ফিরে না আসার জন্য, যা হুমকি দেয়।
ক্রিস স্ট্রাটন

3
@ ক্রিসট্রেটটন প্রকৃত প্রশ্ন জিজ্ঞাসা করাও প্রশ্নকারীর উপর নির্ভর করে / সে এর উত্তর চায় - এমন কিছু যা এই ক্ষেত্রে করা হয়নি। আপনারা ঠিক বলেছেন যে আমি যখন যা পোস্ট করেছি সেটার উত্তরটি যখন দেওয়া হয়েছিল ঠিক তখনই তা অগ্রাহ্য করেছিলাম, তবে কোনও শাস্তি নেই, আমার মতের কেবল যুক্তিসঙ্গত প্রকাশ আছে। আপনি যদি ভাবেন যে আমি এখানে বোকা কাজ করছি, আমি দৃ strongly়ভাবে অনুরোধ করব আপনি আপত্তিজনক মন্তব্য করার জন্য আমার মন্তব্যটি পতাকাঙ্কিত করুন। যাইহোক এটি করার আগে, আপনি এখানে নিজের পোস্টিং পরীক্ষা করতে ইচ্ছুক হতে পারেন।
মাহ

0

কোটলিনে সমাধান যা আমি এই মুহুর্তে ব্যবহার করছি:

@SuppressLint("PackageManagerGetSignatures")
@Suppress("DEPRECATION")
fun isSigned(context: Context?): Boolean {
    return (context?.packageManager?.getPackageInfo(context.packageName, PackageManager.GET_SIGNATURES)?.signatures?.firstOrNull()?.toByteArray()
            ?.let {
                return@let CertificateFactory.getInstance("X.509").generateCertificate(ByteArrayInputStream(it))
            } as? X509Certificate)
            ?.issuerDN
            ?.name
            ?.contains("O=Android", ignoreCase = false) ?: true
}

আমি এখনও ডিবাগ এ সাইন ইন করতে পারি এবং সেগুলি ক্র্যাশলাইটিক্সে রিপোর্ট করা হবে (উদাহরণস্বরূপ, কিউএ প্রক্রিয়াটির জন্য)

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.