Skip to content

Commit 0bbac12

Browse files
committed
Added regexp matching, internal storing mechanism update, refactoring, switched to md5 hash algorithm, UI test changes, better support for Lucky Patcher
1 parent 981f3eb commit 0bbac12

File tree

16 files changed

+297
-62
lines changed

16 files changed

+297
-62
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Remember that a skilled hacker will always find a way to crack your code. This l
1919
- 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 Protect and other defense systems.
2020
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 masked lucky patcher installation
2121
- Lucky Patcher (12 March 2018) had a nasty trick which allowed them to show their label normally, [but instread with different charset](https://twitter.com/ACioccarelli/status/1105249064147472385), avoiding normal detction.
22-
BillingProtector 1.1.1 detects that version, the Lucky Patcher emulation server, Installer and the Proxy package to bypass app purchase logic.
22+
BillingProtector 1.3.0 detects that version, the Lucky Patcher emulation server, Installer and the Proxy to bypass app purchase mechanism.
2323

2424

2525
# Setup
@@ -35,7 +35,7 @@ allprojects {
3535
And the dependency to your module build.gradle file:
3636
```gradle
3737
dependencies {
38-
implementation 'com.github.AndreaCioccarelli:BillingProtector:1.2.0'
38+
implementation 'com.github.AndreaCioccarelli:BillingProtector:1.3.0'
3939
}
4040
```
4141

app/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ android {
88
applicationId "com.andreacioccarelli.billingprotectorsample"
99
minSdkVersion 14
1010
targetSdkVersion 28
11-
versionCode 3
12-
versionName "1.0.2"
11+
versionCode 7
12+
versionName "1.3.0"
1313
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
1414
}
1515
buildTypes {

app/src/main/java/com/andreacioccarelli/billingprotectorsample/DetectionActivity.java

+27-3
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@
77
import android.support.design.widget.FloatingActionButton;
88
import android.view.View;
99
import android.widget.TextView;
10+
import android.widget.Toast;
1011

1112
import com.andreacioccarelli.billingprotector.BillingProtector;
1213

14+
import java.util.concurrent.TimeUnit;
15+
1316
public class DetectionActivity extends Activity {
1417

1518
BillingProtector bp;
@@ -18,10 +21,10 @@ public class DetectionActivity extends Activity {
1821
@Override
1922
protected void onCreate(Bundle savedInstanceState) {
2023
super.onCreate(savedInstanceState);
21-
setContentView(R.layout.activity_secondary);
24+
setContentView(R.layout.activity);
2225

2326
bp = new BillingProtector(this);
24-
updateData();
27+
runRefresh();
2528

2629
FloatingActionButton fab = findViewById(R.id.fab);
2730
fab.setOnClickListener(new View.OnClickListener() {
@@ -30,11 +33,32 @@ public void onClick(View v) {
3033
Vibrator vib = (Vibrator) getSystemService(VIBRATOR_SERVICE);
3134
vib.vibrate(100);
3235

33-
updateData();
36+
runRefresh();
3437
}
3538
});
3639
}
3740

41+
void runRefresh() {
42+
new Thread(new Runnable() {
43+
@Override
44+
public void run() {
45+
long mills = System.currentTimeMillis();
46+
updateData();
47+
48+
long millsAfter = System.currentTimeMillis();
49+
long diff = millsAfter - mills;
50+
final long seconds = TimeUnit.MILLISECONDS.toSeconds(diff);
51+
52+
runOnUiThread(new Runnable() {
53+
@Override
54+
public void run() {
55+
Toast.makeText(DetectionActivity.this, "Re-computed. Time: " + seconds + "s", Toast.LENGTH_SHORT).show();
56+
}
57+
});
58+
}
59+
}).run();
60+
}
61+
3862
@SuppressLint("SetTextI18n")
3963
void updateData() {
4064
final TextView mxp = findViewById(R.id.mxp);

library/build.gradle

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ android {
1010
defaultConfig {
1111
minSdkVersion 14
1212
targetSdkVersion 28
13-
versionCode 6
14-
versionName "1.2.0"
13+
versionCode 7
14+
versionName "1.3.0"
1515
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
1616
}
1717

1818
buildTypes {
1919
release {
20-
minifyEnabled false
20+
minifyEnabled true
2121
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
2222
}
2323
}

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

+14-11
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,19 @@ package com.andreacioccarelli.billingprotector
44

55
import android.content.Context
66
import android.content.pm.PackageManager
7+
import com.andreacioccarelli.billingprotector.data.DetectionCause
78
import com.andreacioccarelli.billingprotector.data.PirateApp
89
import com.andreacioccarelli.billingprotector.data.SelectionCriteria
9-
import com.andreacioccarelli.billingprotector.data.createPirateAppsList
1010
import com.andreacioccarelli.billingprotector.extensions.removeDuplicatedPackages
11+
import com.andreacioccarelli.billingprotector.extensions.valueOrNull
1112
import com.andreacioccarelli.billingprotector.utils.RootUtils
13+
import com.andreacioccarelli.billingprotector.utils.assembleAppList
1214

1315

1416
/**
15-
* Created by andrea on 2018/Jul.
16-
* Part of the package com.andreacioccarelli.billingprotector
17+
* Designed and Developed by Andrea Cioccarelli
1718
*/
19+
1820
class BillingProtector(private val context: Context) {
1921

2022
/**
@@ -38,16 +40,16 @@ class BillingProtector(private val context: Context) {
3840
fun getPirateAppsList(): List<PirateApp> {
3941
val foundThreats = mutableListOf<PirateApp>()
4042
val installedApps = context.packageManager.getInstalledApplications(PackageManager.GET_META_DATA)
41-
val pirateApps = createPirateAppsList()
43+
val pirateApps = assembleAppList(DetectionCause.PIRACY)
4244

4345
installedApps.forEach { installedApp ->
4446
pirateApps.forEach {
4547
when (it.criteria) {
46-
SelectionCriteria.SLICE -> {
48+
SelectionCriteria.CONTAINS -> {
4749
if (installedApp.packageName.contains(it.field)) foundThreats.add(it)
4850
}
4951

50-
SelectionCriteria.MATCH_PACKAGE -> {
52+
SelectionCriteria.MATCH -> {
5153
if (it.field == installedApp.packageName) foundThreats.add(it)
5254
}
5355

@@ -57,12 +59,13 @@ class BillingProtector(private val context: Context) {
5759
}
5860
}
5961

60-
SelectionCriteria.LABEL -> {
61-
val label = installedApp.loadLabel(context.packageManager)
62-
val nonLocalizedLabel = installedApp.nonLocalizedLabel
62+
SelectionCriteria.LABEL_REGEXP -> {
63+
val label = installedApp.loadLabel(context.packageManager).valueOrNull()
64+
val nonLocalizedLabel = installedApp.nonLocalizedLabel.valueOrNull()
6365

64-
when (it.field) {
65-
label, nonLocalizedLabel -> foundThreats.add(it)
66+
when {
67+
label.matches(it.field.toRegex())
68+
|| nonLocalizedLabel.matches(it.field.toRegex()) -> foundThreats.add(it)
6669
}
6770
}
6871
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
@file:Suppress("ClassName")
2+
3+
package com.andreacioccarelli.billingprotector.assets
4+
5+
/**
6+
* Designed and Developed by Andrea Cioccarelli
7+
*/
8+
9+
object definitions {
10+
11+
private const val lucky_patcher = "Lucky Patcher"
12+
private const val freedom = "Freedom"
13+
private const val xmodgames = "XModGames"
14+
private const val uret_patcher = "Uret Patcher"
15+
private const val creeplays_patcher = "Creeplays Patcher"
16+
private const val creehack = "Creehack"
17+
private const val playcards = "Leo Playcards"
18+
private const val appsara = "AppSara"
19+
private const val modded_store = "Modded Google Play Store"
20+
21+
22+
object match {
23+
/**
24+
* Lucky Patcher
25+
*/
26+
const val field1 = "com.chelpus.lackypatch"
27+
const val khash1 = "419cb6875f3fa235ed925c28afc44f2e"
28+
const val kname1 = lucky_patcher
29+
30+
const val field2 = "com.dimonvideo.luckypatcher"
31+
const val khash2 = "cd9de8549c3e6e151300734f112091b3"
32+
const val kname2 = lucky_patcher
33+
34+
const val field3 = "com.forpda.lp"
35+
const val khash3 = "c2f5ef59294b96727c061ecc0a792392"
36+
const val kname3 = lucky_patcher
37+
38+
const val field4 = "ru.aaaaaaac.installer"
39+
const val khash4 = "e74010e84eb49bc67f51554c60b8e222"
40+
const val kname4 = lucky_patcher
41+
42+
const val field5 = "com.android.vending.licensing.ILicensingService"
43+
const val khash5 = "238b2cc715459f7b9458e0e0744b15e2"
44+
const val kname5 = lucky_patcher
45+
46+
/**
47+
* Uret patcher
48+
* */
49+
const val field6 = "uret.jasi2169.patcher"
50+
const val khash6 = "7a3a1cdb08b74117b3c20f2e04ba099e"
51+
const val kname6 = uret_patcher
52+
53+
/**
54+
* Creeplays Patcher
55+
* */
56+
const val field7 = "org.creeplays.hack"
57+
const val khash7 = "b30bec898f00f528e382b95856ebb909"
58+
const val kname7 = creeplays_patcher
59+
60+
/**
61+
* CreeHack
62+
* */
63+
const val field8 = "apps.zhasik007.hack"
64+
const val khash8 = "48e3b21aec993834ca0a91f48a7099c6"
65+
const val kname8 = creehack
66+
67+
/**
68+
* Leo Playcards
69+
* */
70+
const val field9 = "com.leo.playcard"
71+
const val khash9 = "9d8a3405cd058e411c224fb680fa103c"
72+
const val kname9 = playcards
73+
74+
/**
75+
* AppSara
76+
* */
77+
const val field10 = "com.appsara.app"
78+
const val khash10 = "a00e921d238bb1b84d104e293313d225"
79+
const val kname10 = appsara
80+
}
81+
82+
83+
object slice {
84+
/**
85+
* Lucky Patcher
86+
*/
87+
const val field1 = "com.android.vending.billing.InAppBillingService."
88+
const val khash1 = "48b19168f8f466638c400c2e8eb8eebe"
89+
const val kname1 = lucky_patcher
90+
91+
const val field2 = "com.android.vending.billing.InAppBillingService."
92+
const val khash2 = "48b19168f8f466638c400c2e8eb8eebe"
93+
const val kname2 = lucky_patcher
94+
95+
/**
96+
* Freedom
97+
* */
98+
const val field3 = "jase.freedom"
99+
const val khash3 = "fde5230b767d93fbc23010f9de757f04"
100+
const val kname3 = freedom
101+
102+
const val field4 = "madkite.freedom"
103+
const val khash4 = "771df92f8cc82ad893bb3378a155338d"
104+
const val kname4 = freedom
105+
106+
/**
107+
* Modded Play Store
108+
* */
109+
const val field5 = "com.android.vendinc"
110+
const val khash5 = "81907933708408ddc91af1f381e65bff"
111+
const val kname5 = modded_store
112+
113+
/**
114+
* XModGames
115+
* */
116+
const val field6 = "com.xmodgame"
117+
const val khash6 = "00d0c2bf72590fd9281bb0d60a408092"
118+
const val kname6 = xmodgames
119+
}
120+
121+
object classname {
122+
/**
123+
* Lucky Patcher
124+
* */
125+
const val field1 = "com.lp"
126+
const val khash1 = "38d21e850edd2a6c6253918770a59b27"
127+
const val kname1 = lucky_patcher
128+
129+
}
130+
131+
object regexp {
132+
/**
133+
* Lucky Patcher
134+
* */
135+
const val field1 = "-*[LІ][uцџ][cс][kкќӄ][yуӳӱӰӯӮУў][-.#@_*/\\+`\"$   ~][PРҎҏр][aаӑӓ][tт][cс][hнһӈҺ][eєёеҽзэҿ][rя][sѕ]?-*"
136+
const val khash1 = "6a730bba41046d0a9a9ec2a24f871380"
137+
const val kname1 = lucky_patcher
138+
}
139+
140+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.andreacioccarelli.billingprotector.crypt
2+
3+
import java.security.MessageDigest
4+
import kotlin.experimental.and
5+
6+
7+
/**
8+
* Designed and Developed by Andrea Cioccarelli
9+
*/
10+
11+
object HashGeneratior {
12+
fun hash(input: String): String {
13+
val md = MessageDigest.getInstance("MD5")
14+
md.update(input.toByteArray())
15+
val digest = md.digest()
16+
val sb = StringBuffer()
17+
for (b in digest) {
18+
sb.append(String.format("%02x", b and 0xff.toByte()))
19+
}
20+
21+
return sb.toString()
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.andreacioccarelli.billingprotector.data
2+
3+
/**
4+
* Designed and Developed by Andrea Cioccarelli
5+
*/
6+
7+
abstract class AppDefinition{
8+
abstract val field: String
9+
abstract val hash: String
10+
abstract val criteria: SelectionCriteria
11+
abstract val name: String
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.andreacioccarelli.billingprotector.data
2+
3+
/**
4+
* Designed and Developed by Andrea Cioccarelli
5+
*/
6+
7+
enum class DetectionCause { PIRACY }

0 commit comments

Comments
 (0)