Design application using more confuse code? - android

Recently I had opened some real apps by using this
So I'm getting the source code from that. In those source code, I found that most of the code is designed like this
public class LockActivity extends Activity {
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
if (GlobalDataHolder.m9617e()) {
bm.m8771b(getApplicationContext(), getPackageManager());
finish();
}
}
protected void onResume() {
super.onResume();
if (GlobalDataHolder.m9617e()||this.f4719a.m9124j()) {
bm.m8771b(getApplicationContext(), getPackageManager());
finish();
return;
}
startActivity(new Intent(getApplicationContext(), LaunchActivity.class));
}
public void onPause() {
super.onPause();
}
public void onDestroy() {
super.onDestroy();
}
}
And also the java file named by Garbled text such as
aa.java
bh.java
cj.java
My question is
1) Why those developer create the function named 'm8771b','m9617e'
2) Why most of apps is designed like that?
3) Is this more secure for avoid other to copy their code?
4) Should we also design the application like that?
5) How they can remember where they put the function?

People don't write code like that... unless they are either a savant or inexperienced. Using seemingly random strings of methods/class names is something called Obfuscation, which means to hide the real meaning of something in order to make it difficult to read.
Obfuscation Wiki as it pertains to software development
There are programs out there, like ProGuard which do this for us. Its purpose is to both compact and obscure code. That way it is difficult for someone to decompile and reconstruct the project without pouring over what it does (depending on complexity) endlessly.
Since Java always compiles into bytecode, it is predictable in the way in which it can be decompiled and much more standard that a write-once compile-anywhere language. ProGuard helps protect intellectual property or proprietary software and keep people from just stealing code.

Related

Actual behavior of DevicePolicyManager.setApplicationHidden

Is there anyone knows SDK well enough to tell why after making my app device-owner and executing DevicePolicyManager.setApplicationHidden for a list of apps I can't then find them unless I'd put PackageManager.getInstalledApplications(PackageManager.GET_META_DATA or PackageManager.MATCH_UNINSTALLED_PACKAGES) in the query flags? (meaning just GET_META_DATA won't work and hidden applications would not be unhidden)
I try to find them to unhide them — but no success unless I am looking for uninstalled also.
My theory is that Android doesn't really hide them, but actually marking them uninstalled yet keeping all the data — but I didn't find any information regards it in the documentation. Wonder if someone can clarify this behavior (with source).
Thanks!
The naming is ambiguous but indeed setApplicationHidden effectively uninstalls the app but keeps the APK and data in storage. If you're looking for a way to prevent use of the app without uninstalling it you can try setPackagesSuspended.
You can find the source for setApplicationHidden in PackageManagerService.setApplicationHiddenSettingAsUser() (relevant abstract below). Its logic is simple:
setApplicationHiddenSettingAsUser calls packageSetting.setHidden() to mark the package as hidden for the user,
other methods of PackageManagerService call packageSetting.getHidden() to decide whether the package should be returned.
Code abstract for setApplicationHiddenSettingAsUser:
#Override
public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
int userId) {
PackageSetting pkgSetting;
...
try {
...
synchronized (mPackages) {
pkgSetting = mSettings.mPackages.get(packageName);
...
if (pkgSetting.getHidden(userId) != hidden) {
pkgSetting.setHidden(hidden, userId);
mSettings.writePackageRestrictionsLPr(userId);
...
}
}
...
}
}

Non intrusive logs in Android

Is there a way to have non intrusive logs in Android ?, for example, if I have a method like the following one:
public void aMedthod() {
doSmt();
if (mSomeState) {
if (doSmtElse()) {
Log.v("MyApp","Success")
}
}
}
What I'd like to do is replacing that Log line with something as less intrusive as possible, in order to package the app for production without any trace of the Log library and at the same time, not having to delete nor comment any piece of code.
Jake Wharton made an awesome library that can accomplish exactly that. Take a look here.
just use this to init:
if (BuildConfig.DEBUG) {
Timber.plant(new Timber.DebugTree());
}

Android App Change language functionality code bug

I am creating an app which have functionality for user to choose different language so i created another app to test fuctionality there so idea is to create button in settings and save its Language Value and onclick the language changes and saving its value using shared preference there is no error in my code but the language is not changing. I am unable to figure please guys any help is appreciated. HERE IS CODE FIRST MAIN THEN SETTINGS:
TextView text;
int language;
SharedPreferences sh;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text=(TextView)findViewById(R.id.text);
sh=getSharedPreferences("lang", Context.MODE_PRIVATE);
language=sh.getInt("language",0);
Button Lang=(Button)findViewById(R.id.change);
if(language==0)
{
text.setText("Germany");
}
else
if(language==1)
{
text.setText("English");
}
Lang.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i=new Intent(MainActivity.this,gauravmehra.testastro.Change.class);
startActivity(i);
}
});
}
And change Activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.change);
changeLang=(Button)findViewById(R.id.changeLang);
sh=getSharedPreferences("lang",Context.MODE_PRIVATE);
language=sh.getInt("language",0);
changeLang.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(language==0)
{
language=1;
sh.edit().putInt("language",1);
sh.edit().commit();
}
else if(language==1)
{
language=0;
sh.edit().putInt("language",0);
sh.edit().commit();
}
Intent i=new Intent(Change.this,MainActivity.class);
startActivity(i);
}
});
}
try to use getApplicationContext()
try to use the Context.MODE_MULTI_PROCESS
getApplicationContext().getSharedPreferences("lang",Context.MODE_MULTI_PROCESS)
Update:
if your api level >=23
You must use ContentProvider instead of SharedPreferences in the multi process situation.
public static final int MODE_MULTI_PROCESS
Added in API level 11
This constant was deprecated in API level 23.
MODE_MULTI_PROCESS does not work reliably in some versions of Android, and furthermore does not provide any mechanism for reconciling concurrent modifications across processes. Applications should not attempt to use it. Instead, they should use an explicit cross-process data management approach such as ContentProvider.
ref:http://developer.android.com/reference/android/content/Context.html#MODE_MULTI_PROCESS
[EDITED]
You have what seems to be a copy/paste error.
In your "change Activity", you have this statement in 2 places:
sh.edit().putInt("language",1);
You should instead use this in both places:
sh.edit().putInt("language", language);
Or, even better:
public void onClick(View v) {
language = 1 - language;
sh.edit().putInt("language", language);
sh.edit().commit();
Intent i=new Intent(Change.this,MainActivity.class);
startActivity(i);
}
[OLD ANSWER - might still help others]
When calling getSharedPreferences(String name, int mode), the mode argument determines whether the stored values are private, or globally readable and/or writeable.
MODE_PRIVATE was used in the app that originally stored the data. That means that no other apps have any access to that data.
You should be aware that the other 2 main modes have been deprecated since API Level 17, though, since they open up security holes. Also, MODE_MULTI_PROCESS was deprecated in API level 23 because it did not work reliably. So, there is really no good way to use a SharedPreference between apps.
If you don't really need to share data between apps, you should put both activities in the same app. But, if the 2 activities are in different processes or you really need two apps, then you should consider having the first app implement either a ContentProvider or Service to provide the shared data. For example, you could use a FileProvider.
Or, in general you could just pass the data between the 2 apps as extras in the Intent you pass to startActivity(), and that would not require use of SharedPreferences at all.
I think i figure out what was the problem. I have tried above solutions but i think above methods cannot work in this problem so in my change methods i was previously doing
sh.edit().putInt("language",1);
sh.edit().commit();
but i think this thing doesn't work here so changed the line with this
Editor editor=sh.edit();
editor.putInt("language",1);
editor.commit();
and voila app now doing great. Hope it helps i am beginner in android.

Is DexGuard tamper and Environment detection helpful?

I am very new to DexGuard and Proguard. I was going through their documentation and sample examples. They have dexguard_util which helps you detect if the application is tampered with and also helps in detecting if it is running in the environment it is supposed to run. The document suggests that this tamper and environment detection be encrypted using the following code is dexgaurd-project.txt.
-encryptclasses A$D
-encryptstrings A$D
follwing is the activity
public class A extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
new D().c();
}
private class D
{
public void c()
{
//some code to which detects the tampering and environment and takes action accordingly
}
}
}
What if a hacker inject this line of code.
public class A extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//code commented by hacker
//new D().c();
}
private class D
{
public void c()
{
//some code to which detects the tampering and environment and takes action accordingly
}
}
}
Then my application will run without running those tests which I think is a big problem. Is my understanding of how reverse engineering works wrong or there are better ways of doing this. Please share better methods of doing this if they exist. Thanks in advance. Note that public class A cannot be encrypted as it is an entry point and is kept using this command in progaurd-project.txt
-keep class somepackage.A
When it comes to anti-tampering, it is important to keep in mind that their goal is not to stop any and all potential tampering efforts, but, rather, it's just a matter of raising the security bar of the target high enough to dissuade most attackers.
With that said, the
A bit of a tangent:
The document suggests that this tamper and environment detection be encrypted using the following code is dexgaurd-project.txt.
Class encryption does prevent basic static analysis of the application package, e.g. simply unzipping the package and loading it in jd-gui. However, as this answer shows, it's trivial to circumvent: one only has to hook into the static method that decrypts the apk on load, and dump it. But this allows the security bar to be raised.
Now back to your original question:
What if a hacker inject this line of code.
As an attacker, that would be the next step. However, that would require repackaging the app, and signing it with the hacker's signing key. Therefore, it is necessary to combine Dexguard's anti-tampering measures like checking the apk signature.
Is DexGuard tamper and Environment detection helpful?
In summary, yes, it is helpful in as far as it raises the bar above the vast majority of apps out there. But it's no silver bullet.

LVL licensing in a Live Wallpaper?

Has anybody had success integrating the Licensing Verification Library (LVL) with a Live Wallpaper? If it were just running an Activity, it'd be crystal clear to just extend my Activity from the Licensing Activity, which in turn extends Activity. But Live Wallpapers are a Service, and I'm not sure how the two are intended to interact.
I'm using code derived from this: http://www.droidforums.net/forum/android-app-developers/69899-market-license-easy-implementation-protect-your-apps.html which seems to be the code that nearly everything I can find on the web refers to.
I notice that wallpaper settings are an activity, and I have those working properly, but for some reason I can't grok the Licensing stuff...
It's actually really quite simple, you don't need to use any Activity class to implement licensing into a WallpaperService.
Make sure you've followed the directions carefully at http://developer.android.com/guide/publishing/licensing.html
Here's how I did it:
Your extended Engine class should include something similar to the following... (code not essential to your question has been removed)
class startYourEngines extends Engine {
public startYourEngines() {
super();
licenseStatus(); //custom license check method (for modularity)
//the rest of your engine would go here
}
public void onDestroy() {
super.onDestroy();
licenseChecker.onDestroy(); //we call this to close IPC connections
}
//prep work
private static final String BASE64_PUBLIC_KEY = //OMITTED//;
private LicenseCheckerCallback licenseCallback;
private LicenseChecker licenseChecker;
private byte[] salt = "rAnd0mStr!ng".getBytes();
private AESObfuscator aes;
private String deviceId;
//our custom license check method
private void licenseStatus() {
deviceId = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
aes = new AESObfuscator(salt, getPackageName(), deviceId);
licenseCallback = new licenseVerification();
licenseChecker = new LicenseChecker(context, new ServerManagedPolicy(context, aes), BASE64_PUBLIC_KEY);
licenseChecker.checkAccess(licenseCallback);
}
//our callback method
private class licenseVerification implements LicenseCheckerCallback {
#Override
public void allow() {
//allow full app use
}
#Override
public void dontAllow() {
//prevent or limit app use
}
#Override
public void applicationError(ApplicationErrorCode errorCode) {
//error handling here
}
}
}
Licensing on the Android platform was created with versatility in mind. Just be sure to read through the documentation, and you shouldn't have any issues.
I have only written applications that start activities, but looking at my source code, it seems that the only reason that you would have to have an Activity do the license check is to show dialogs.
In all of the examples available on line, the LicenseCheckerCallback implementation always shows a dialog in the allow() and dontAllow() methods. Why not just show a toast in dontAllow() and exit your wallpaper service (call stopSelf(YourService.this))?
Let me know if you want more information, because I dont think you are limited to only using an activity for license checking. As an aside, make sure that you dont keep whole strings, etc in your app or in the preferences. Anyone with root access can access your preferences and if your app is decompiled, your strings are visible...
I think I've actually got it working now. I'm extending LicenseCheckActivity to my own Activity class that I'm calling in the manifest file with the usual MAIN action and LAUNCH category. I instantiate my class, do the license check, and then either allow the wallpaper to function or not based on that result (though the best way to do that is still something I need to sort out).
It almost seems too easy that I think I must be missing something. I'd appreciate anybody with experience with selling a licensed live wallpaper on the Android Market to share whatever wisdom they care to.

Categories

Resources