web-dev-qa-db-ja.com

ラッキーパッチャー、どうすればそれを防ぐことができますか?

このトピックは何度も公開されており、多くのことを学びましたが、本当にアドバイスが必要な問題に遭遇しました。

LVLを難読化で使用しています。デフォルトのLVL ALOTを変更して、反LVLがそれを壊さないようにしました。しかし、ワンクリックでラッキーパッチャーはそれを壊します!新しい壊れたAPKを見てみました。はい、単に「許可メソッド」と呼ばれていました。

私の質問は、ラッキーパッチャーがそれを壊さないようにする方法を誰かがお勧めできるかどうかです。私はそれを完全に防げるわけにはいかないことを知っています、しかし、それが少なくともワンクリックソフトウェアのためにそれほど簡単ではないことを望みます。

27
Snake

証明書を確認するためのコード

public void checkSignature(final Context context)
{
    try
    {
        Signature[] signatures = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures;

        if (signatures[0].toCharsString() != <YOUR CERTIFICATE STRING GOES HERE>)
        {
            // Kill the process without warning. If someone changed the certificate
            // is better not to give a hint about why the app stopped working
            Android.os.Process.killProcess(Android.os.Process.myPid());
        }
    } 
    catch (NameNotFoundException ex)
    {
        // Must never fail, so if it does, means someone played with the apk, so kill the process
        Android.os.Process.killProcess(Android.os.Process.myPid());
    }
}

そして、どれがあなたの証明書であるかを見つける方法も簡単です。デバッグ証明書は常にリリース証明書とは異なるため、リリースモードでAPKを作成する必要があります。証明書の文字列を一時的なテキストビューに出力してコピーするか、次の呼び出しでテキストファイルに出力します。重要:文字列が長すぎるため、logcatはすべてを表示せず、最後の文字を切り捨てるため、logcatを出力しないでください。キャラクター:

signatures[0].toCharsString();

example: YourTextView.setText(signatures[0].toCharsString());

ここで、デバッグモードに戻ったときに、証明書が再び異なり、ビルドごとに異なる場合があるので、デバッグの問題が発生することに注意してください。次に、次の行を使用して開発を容易にし、証明書のテストを呼び出す直前に配置することをお勧めします。

if ((context.getApplicationContext().getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE) != 0)
{
    return;
}

デバッグモードの場合は、この認証コードを呼び出さないでください

そして今、ラッキーパッチャーチェッカー

このコードはその存在をチェックします。私はすべてのバージョンのラッキーパッチャーを逆コンパイルしましたが、その作成者がすべての領域で2つのパッケージ名を使用していることがわかりました。したがって、新しいバージョンを追跡し、将来のラッキーパッチャーパッケージ名をチェック機能に追加し続けるだけで済みます。

また、推奨事項として、例のようにハードコードするのではなく、パッケージ名の文字列を暗号化します。これにより、ラッキーパッチャーは、パッチを適用する文字列を置き換えるだけの新しいバージョンを出しません。クラッカーを難しくします。

private boolean checkLuckyPatcher()
{
    if (packageExists("com.dimonvideo.luckypatcher"))
    {
        return true;
    }

    if (packageExists("com.chelpus.lackypatch"))
    {
        return true;
    }

    if (packageExists("com.Android.vending.billing.InAppBillingService.LACK"))
    {
        return true;
    }

    return false;
}

private boolean packageExists(final String packageName)
{
    try
    {
         ApplicationInfo info = this.getPackageManager().getApplicationInfo(packageName, 0);

        if (info == null)
        {
            // No need really to test for null, if the package does not
            // exist it will really rise an exception. but in case Google
            // changes the API in the future lets be safe and test it
            return false;
        }

        return true;
    }
    catch (Exception ex)
    {
        // If we get here only means the Package does not exist
    }

    return false;
}
39
PerracoLabs

現在のバージョン(6.4.6)では、Lucky Patcherは非常に短いトークンを生成します。たとえば、実際の購入トークン:

felihnbdiljiajicjhdpcgbb.AO-J1OyQgD6gEBTUHhduDpATg3hLkTYSWyVZUvFwe4KzT3r-O7o5kdt_PbG7sSUuoC1l6dtqsYZW0ZuoEkVUOq5TMi8LO1MvDwdx5Kr7vIHCVBDcjCl3CKP4UigtKmXotCUd6znJ0KfW

そしてそれがラッキートークンです:

kvfmqjhewuojbsfiwqngqqmc

かなり簡単な解決策は、トークンの文字列の長さをチェックすることです

@Override public void onIabPurchaseFinished(IabResult result, Purchase info) {
    if (info.getToken().length < 25) {
        Log.wtf("PIRATE", "PIRATE DETECTED");
        return;
    }
}
5
Dima Rostopira

方法は、ラッキーパッチャーがインストールされているかどうかを確認し、インストールされている場合は、ユーザーにメッセージを表示し、その後プロセスを終了することです。ユーザーが持っている場合、彼はあなたのソフトウェアまたは他の開発者のソフトウェアをクラックしようとしていることを意味します。そのため、アプリがインストールされている電話でアプリを使用できないようにすることをお勧めします。海賊行為と戦います。

0
PerracoLabs

Lucky Patcherがmodd APKファイルを作成するときはいつでも、同じパッケージ名で2つのアプリを実行することはできないため、常に異なるパッケージ名になります。

コードが間違ったパッケージ名で実行されているかどうかを確認する簡単なソリューションを次に示します。

_PackageManager pm = getPackageManager();

try {
    PackageInfo packageInfo = pm.getPackageInfo("YOUR_PACKAGE_NAME",PackageManager.GET_ACTIVITIES);
} catch (PackageManager.NameNotFoundException e){
    finish(); 
    //If you get here, your code is running under a different package name... Kill the process!
}
_

私はアプリでfinish();を呼び出すだけで壊れませんが、@ PerracoLabsが示唆するようにAndroid.os.Process.killProcess(Android.os.Process.myPid());を使用するのが最善の方法です。

0
Epicality

はい、それが私の提案のポイントです。コードで、特定のアクションで呼び出される関数を実装します。これらのアクションでは、ラッキーパッチャーのパッケージがインストールされているかどうかを確認する必要があります。これは非常に簡単で、方法がわからない場合はコードを共有できます。検出した場合は、アプリを停止してください。ユーザーがお金を払ったとしても、それを使用することを許可しないでください。彼の悪いレビューは、10000の違法コピーよりも優れています。また、アプリがクラックされた場合でも、LVL専用であり、ラッキーパッチャーは、そのようなアルゴリズムを備えた市場のすべてのアプリを知ることができず、すべてのアプリをカバーするラッキーパッチャーバージョンを作成することができなくなります。市場では、これまでと同様に、開発者は独自の方法で検出します。したがって、最後にアプリがクラックされてlvl保護が失われる可能性がありますが、携帯電話にラッキーパッチャーがインストールされている場合、アプリを実行することはできません。さらに、フラグを設定ファイルに保存して、アプリを最初に実行したときにラッキーパッチャーが検出されたかどうかを検出します。これにより、ユーザーがluckypatcherをアンインストールした後でも、アプリの実行を停止できる場合でも、ユーザーはクラックされていないアプリを再インストールする必要があります。そして、彼はラッキーパッチャーをいつも非難します。 https://www.androidjungles.com/lucky-patcher-apk/

0
PerracoLabs