Skip to content

Commit 6dff6ae

Browse files
committed
Version 1.1.0
Introduced custom package matching rules, support for LuckyPatcher 8.0.0, removed Kt activity, refactoring
1 parent 9eaedfd commit 6dff6ae

File tree

19 files changed

+101
-145
lines changed

19 files changed

+101
-145
lines changed

README.md

+8-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ That's a violation of the Developer's product and business, since it won't just
1515
I've been implmenting by myself on every app of mine a complex and different security scheme each time. Then I decided to put everything together and to realize this project of crucial importance for someone's business, in parallel with [CryptoPrefs](https://github.com/AndreaCioccarelli/CryptoPrefs).
1616
Remember that a skilled hacker will always find a way to crack your code. This library is a harsh barrier that will stop the 99% of the other kiddies.
1717

18+
### Bulletin
19+
At the end of December 2018, Lucky Patcher 8.0.0 was released, along with the possibility to randomize package name and make the app invisible from google play store and other defense systems.
20+
The 5th of January, BillingProtector 1.1.0 update introduces support for custom package parameter matching and comes along with the ability of detecting every lucky patcher installation
21+
1822
# Setup
1923
BillingProtector uses [jitpack](https://jitpack.io/#AndreaCioccarelli/BillingProtector) as package repository.
2024
To use it you need to add that line to your project build.gradle file:
@@ -28,7 +32,7 @@ allprojects {
2832
And the dependency to your module build.gradle file:
2933
```gradle
3034
dependencies {
31-
implementation 'com.github.AndreaCioccarelli:BillingProtector:1.0.2'
35+
implementation 'com.github.AndreaCioccarelli:BillingProtector:1.1.0'
3236
}
3337
```
3438

@@ -49,7 +53,7 @@ You don't need to destroy any references to that object in `onDestroy()` since i
4953
### Checking Root Access
5054
```kotlin
5155
if (bp.isRootInstalled()) {
52-
finish();
56+
finish()
5357
}
5458
```
5559

@@ -70,10 +74,10 @@ if (bp.arePirateAppsInstalled()) {
7074
}
7175
```
7276
The method `arePirateAppsInstalled()` is a simple `for` cycle that iterates through every installed software to search if one of them matches with the packages bundled in the library.
73-
The method `getPirateAppsList()` instread returns a list of `PirateApp`s, that you can easily show to the user, or open in the default Sytsem Settings App Viewer with the given package name, and asking him to uninstall.
77+
The method `getPirateAppsList()` instread returns a list of `PirateApp`s, that you can easily display to the user, or open in the Sytsem Settings App Viewer with the given package name, and finally prompting to uninstall the selected software.
7478

7579
**Warning:**
76-
- Never store the value of `arePirateAppsInstalled()` in a variable. Always calculate it at runtime, because your app can be easily cracked with lucky patcher otherwise (Also if no user will probably have way know it, he'd have to open e.g. Lucky Patcher, patch your app, launch it, uninstall Lucky Patcher, wait you to get on the purchase page and then install it again to compleate the process).
80+
- Never store the value of `arePirateAppsInstalled()` in a variable. Always calculate it at runtime, because your app can be easily cracked with Lucky Patcher otherwise (Also if no user will probably have way know it, he'd have to open e.g. Lucky Patcher, patch your app, launch it, uninstall Lucky Patcher, wait you to get on the purchase page and then install it again to compleate the process).
7781

7882
### Getting root binary path
7983
```kotlin

app/build.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,6 @@ dependencies {
2626
implementation 'com.android.support:appcompat-v7:28.0.0'
2727
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
2828
implementation 'com.android.support:design:28.0.0'
29+
implementation "com.android.support:support-v4:28.0.0"
2930
implementation project(path: ':library')
3031
}

app/src/main/AndroidManifest.xml

+2-5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
33
package="com.andreacioccarelli.billingprotectorsample">
44

5+
<uses-permission android:name="android.permission.VIBRATE" />
56
<application
67
android:allowBackup="true"
78
android:icon="@mipmap/ic_launcher"
@@ -10,7 +11,7 @@
1011
android:supportsRtl="true"
1112
android:theme="@style/AppTheme">
1213
<activity
13-
android:name=".MainActivity"
14+
android:name=".DetectionActivity"
1415
android:label="@string/app_name"
1516
android:theme="@style/AppTheme.NoActionBar">
1617
<intent-filter>
@@ -19,10 +20,6 @@
1920
<category android:name="android.intent.category.LAUNCHER" />
2021
</intent-filter>
2122
</activity>
22-
<activity
23-
android:theme="@style/AppTheme.NoActionBar"
24-
android:name=".SecondaryActivity"
25-
android:label="@string/title_activity_secondary" />
2623
</application>
2724

2825
</manifest>
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,46 @@
11
package com.andreacioccarelli.billingprotectorsample;
22

33
import android.annotation.SuppressLint;
4-
import android.content.Intent;
54
import android.os.Bundle;
65
import android.app.Activity;
6+
import android.os.Vibrator;
77
import android.support.design.widget.FloatingActionButton;
88
import android.view.View;
99
import android.widget.TextView;
1010

1111
import com.andreacioccarelli.billingprotector.BillingProtector;
12-
import com.andreacioccarelli.billingprotector.data.PirateApp;
1312

14-
import java.util.ArrayList;
15-
import java.util.List;
13+
public class DetectionActivity extends Activity {
1614

17-
public class SecondaryActivity extends Activity {
15+
BillingProtector bp;
1816

1917
@SuppressLint("SetTextI18n")
2018
@Override
2119
protected void onCreate(Bundle savedInstanceState) {
2220
super.onCreate(savedInstanceState);
2321
setContentView(R.layout.activity_secondary);
2422

25-
BillingProtector bp = new BillingProtector(this);
26-
27-
TextView mxp = findViewById(R.id.mxp);
28-
mxp.setText(
29-
"isRootInstalled: " + String.valueOf(bp.isRootInstalled()) +
30-
"\narePirateAppsInstalled: " + bp.arePirateAppsInstalled() +
31-
"\n\npirateAppsList: " + bp.getPirateAppsList()
32-
);
23+
bp = new BillingProtector(this);
24+
updateData();
3325

3426
FloatingActionButton fab = findViewById(R.id.fab);
3527
fab.setOnClickListener(new View.OnClickListener() {
3628
@Override
3729
public void onClick(View v) {
38-
finish();
30+
Vibrator vib = (Vibrator) getSystemService(VIBRATOR_SERVICE);
31+
vib.vibrate(100);
32+
33+
updateData();
3934
}
4035
});
4136
}
4237

43-
@Override
44-
public void onBackPressed() {}
38+
void updateData() {
39+
final TextView mxp = findViewById(R.id.mxp);
40+
mxp.setText(
41+
"isRootInstalled: " + String.valueOf(bp.isRootInstalled()) +
42+
"\narePirateAppsInstalled: " + bp.arePirateAppsInstalled() +
43+
"\n\npirateAppsList: " + bp.getPirateAppsList()
44+
);
45+
}
4546
}

app/src/main/java/com/andreacioccarelli/billingprotectorsample/MainActivity.kt

-49
This file was deleted.
463 Bytes
Loading
313 Bytes
Loading
591 Bytes
Loading
882 Bytes
Loading
1.13 KB
Loading

app/src/main/res/layout/activity_main.xml

-33
This file was deleted.

app/src/main/res/layout/activity_secondary.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
<RelativeLayout
2626
android:layout_width="match_parent"
2727
android:layout_height="match_parent"
28-
tools:context=".SecondaryActivity">
28+
tools:context=".DetectionActivity">
2929

3030
<TextView
3131
android:padding="30dp"
@@ -42,7 +42,7 @@
4242
android:layout_height="wrap_content"
4343
android:layout_gravity="bottom|end"
4444
android:layout_margin="@dimen/fab_margin"
45-
app:srcCompat="@drawable/ic_navigate_next_white_48dp" />
45+
app:srcCompat="@drawable/refresh" />
4646

4747
</android.support.design.widget.CoordinatorLayout>
4848

app/src/main/res/layout/content_main.xml

-19
This file was deleted.

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Top-level build file where you can add configuration options common to all sub-projects/modules.
22

33
buildscript {
4-
ext.kotlin_version = '1.3.0'
4+
ext.kotlin_version = '1.3.11'
55
repositories {
66
google()
77
jcenter()

library/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ android {
1010
defaultConfig {
1111
minSdkVersion 14
1212
targetSdkVersion 28
13-
versionCode 3
14-
versionName "1.0.2"
13+
versionCode 4
14+
versionName "1.1.0"
1515
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
1616
}
1717

library/src/main/java/com/andreacioccarelli/billingprotector/BillingProtector.kt

+30-9
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import android.content.pm.PackageManager
55
import com.andreacioccarelli.billingprotector.data.PirateApp
66
import com.andreacioccarelli.billingprotector.data.SelectionCriteria
77
import com.andreacioccarelli.billingprotector.data.createPirateAppsList
8+
import com.andreacioccarelli.billingprotector.extensions.removeDuplicatedPackages
89
import com.andreacioccarelli.billingprotector.utils.RootUtils
910

1011

@@ -33,15 +34,26 @@ class BillingProtector(private val context: Context) {
3334

3435
installedApps.forEach { installedApp ->
3536
pirateApps.forEach {
36-
when (it.criteria) {
37-
SelectionCriteria.SLICE -> {
38-
if (installedApp.packageName.contains(it.packageName)) return true
39-
}
37+
if (installedApp.packageName == "ru.tQFiUIAj.NfssCFlDV") {
38+
when (it.criteria) {
39+
SelectionCriteria.SLICE -> {
40+
if (installedApp.packageName.contains(it.field)) return true
41+
}
4042

41-
SelectionCriteria.MATCH -> {
42-
if (it.packageName == installedApp.packageName) return true
43+
SelectionCriteria.MATCH -> {
44+
if (it.field == installedApp.packageName) return true
45+
}
46+
47+
SelectionCriteria.CLASS_NAME -> {
48+
if (it.name == installedApp.className) return true
49+
}
50+
51+
SelectionCriteria.LABEL -> {
52+
if (it.name == installedApp.nonLocalizedLabel) return true
53+
}
4354
}
4455
}
56+
4557
}
4658
}
4759
return false
@@ -59,15 +71,24 @@ class BillingProtector(private val context: Context) {
5971
pirateApps.forEach {
6072
when (it.criteria) {
6173
SelectionCriteria.SLICE -> {
62-
if (installedApp.packageName.contains(it.packageName)) foundThreats.add(it)
74+
if (installedApp.packageName.contains(it.field)) foundThreats.add(it)
6375
}
6476

6577
SelectionCriteria.MATCH -> {
66-
if (it.packageName == installedApp.packageName) foundThreats.add(it)
78+
if (it.field == installedApp.packageName) foundThreats.add(it)
79+
}
80+
81+
SelectionCriteria.CLASS_NAME -> {
82+
if (it.name == installedApp.className) foundThreats.add(it)
83+
}
84+
85+
SelectionCriteria.LABEL -> {
86+
if (it.name == installedApp.nonLocalizedLabel) foundThreats.add(it)
6787
}
6888
}
6989
}
7090
}
71-
return foundThreats.toList()
91+
92+
return foundThreats.removeDuplicatedPackages()
7293
}
7394
}

library/src/main/java/com/andreacioccarelli/billingprotector/data/PirateApp.kt

+7-4
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ import android.util.Base64 import android.util.Log
66
* Class representing a pirate app with built-in string sign check
77
* */
88

9-
data class PirateApp(val packageName: String, val encodedPackageName: String, val criteria: SelectionCriteria, val name: String) {
9+
data class PirateApp(val field: String, val encodedField: String, val criteria: SelectionCriteria, val name: String) {
1010
init {
11-
val check = Base64.encodeToString(packageName.toByteArray(), Base64.DEFAULT)
12-
if (check.trim() != encodedPackageName.trim()) {
13-
Log.e("BillingProtector", "Package Name=[$packageName], Sign Check String=[$check], Base64 Encoded Package Name=[$encodedPackageName]")
11+
val check = Base64.encodeToString(field.toByteArray(), Base64.DEFAULT)
12+
if (check.trim() != encodedField.trim()) {
13+
Log.e("BillingProtector", "Field=[$field], Check=[$check], Encoded Field=[$encodedField]")
1414
throw SecurityException("Package names mismatch, apk file damaged or corrupted")
1515
}
1616
}
@@ -21,6 +21,9 @@ internal fun createPirateAppsList() = listOf(
2121
PirateApp("com.dimonvideo.luckypatcher", "Y29tLmRpbW9udmlkZW8ubHVja3lwYXRjaGVy", SelectionCriteria.MATCH, "Lucky Patcher"),
2222
PirateApp("com.forpda.lp", "Y29tLmZvcnBkYS5scA==", SelectionCriteria.MATCH, "4Pda Lucy Patcher"),
2323
PirateApp("com.android.vending.billing.InAppBillingService.", "Y29tLmFuZHJvaWQudmVuZGluZy5iaWxsaW5nLkluQXBwQmlsbGluZ1NlcnZpY2Uu", SelectionCriteria.SLICE, "Lucky Patcher"),
24+
PirateApp("ru.aaaaaaac.installer", "cnUuYWFhYWFhYWMuaW5zdGFsbGVy", SelectionCriteria.MATCH, "Lucky Patcher Installer"),
25+
PirateApp("com.lp.LuckyApp", "Y29tLmxwLkx1Y2t5QXBw", SelectionCriteria.CLASS_NAME, "Lucky Patcher 8"),
26+
PirateApp("Lucky Patcher", "THVja3kgUGF0Y2hlcg==", SelectionCriteria.LABEL, "Lucky Patcher"),
2427
PirateApp("jase.freedom", "amFzZS5mcmVlZG9t", SelectionCriteria.SLICE, "Freedom"),
2528
PirateApp("madkite.freedom", "bWFka2l0ZS5mcmVlZG9t", SelectionCriteria.SLICE, "Freedom"),
2629
PirateApp("uret.jasi2169.patcher", "dXJldC5qYXNpMjE2OS5wYXRjaGVy", SelectionCriteria.MATCH, "Uret Patcher"),

library/src/main/java/com/andreacioccarelli/billingprotector/data/SelectionCriteria.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ package com.andreacioccarelli.billingprotector.data
44
* Created by andrea on 2018/Jul.
55
* Part of the package com.andreacioccarelli.billingprotector.data
66
*/
7-
enum class SelectionCriteria { MATCH, SLICE }
7+
enum class SelectionCriteria { MATCH, SLICE, CLASS_NAME, LABEL }

0 commit comments

Comments
 (0)