Records of Android development experience in those years

Android Studio's new version of Logcat from stunning to giving up

AS has finally updated this logcat. The original logcat is really uncomfortable to use. The filter will fail at every turn, or the log will not be printed. After using the new version of logcat initially, it is very comfortable. Let me upload an interface diagram first



  • At a glance, you can see that there are three main changes:

One is multi-window support , which can open multiple logcat windows at the same time, which is very helpful for analyzing complex logs, and each window can copy multiple sub-windows , which is very helpful for analyzing and comparing logs in different positions of the current window of;

One is the filtering method , which is changed to a search and filter syntax similar to Github, which can be filtered with multiple syntax combinations , and the customization is stronger and more flexible;

One is the printing format , which optimizes the printing of multi-line logs, the log layout is also fresher, and color highlighting is also supported . And the print information can also be customized whether to display

Next, we will introduce the filtering syntax in detail.

filter syntax

package:mine default syntax, the official original explanation: PIDs for the local app project, I don't quite understand this explanation, but according to the usage, it should be the log of the project where the current logcat window is located

package:my-package-ID is to filter according to the package name

tag:my-tag filter according to tag

level: ERROR filter according to the log level

-tag:exclude-this-tag adds a '-' in front to exclude the specified TAG

tag~: regex-tag adds a '~' at the end to support regular filtering

-tag~:exclude-this-regex-tag This naturally supports regular filtering to exclude the specified TAG

-package:exclude-this-package 同上

package~:regex-package Same as above

-package~:exclude-this-regex-package 同上

Summarize

The updated content is pretty good, but some problems still exist, and the logcat is still not displayed from time to time, and the phone needs to be plugged and unplugged again.

Follow up

Give up, the log update is not timely, and the deletion is not timely, some logs have not been captured yet, they are more garbage than the original logcat, the basic problem has not been solved, what is the use of fancy upper-level functions

Back to old version

Settings-> Experimental -> [x] Enable new Logcat tool window Unselect -> Restart Android Studio

Android P and above hidden API (non-SDK interface) reflection restriction solution

For relevant restrictions, please refer to: Restrictions for non-SDK interfaces

FreeReflection github

  • Java layer double reflection (Android P)
  • ClassLoader empty (Android P+) ( will be fixed )
  • The native layer obtains the key structure through the offset and then modifies the check Flag (Android P+)

RestrictionBypass github

  • Java layer double reflection (Android P)
  • Native double reflection (hide unknown callers via AttachCurrentThread) (Android Q+) ( will be fixed )

AndroidHiddenApiBypass github

  • Rewrite reflection code with Unsafe (Android P+)

Summarize

At present, I only use FreeReflection, but it has been deprecated due to frequent reports of crashes in the native layer (it is guessed that it is caused by the empty ClassLoader scheme, double reflection should only take effect in Android P, and the native layer modification Flag is not used), others are not yet available Use, no evaluation, but in theory, I am more optimistic about AndroidHiddenApiBypass, pure Java, compatibility is definitely the best, because Unsafe involves native layer access, I am afraid it is not easy to seal, restricting access to some memory areas? Or directly restrict access to reflection-related structures? The double reflection of the native layer of RestrictionBypass should also be easily detected and repaired

Exploration and solution to the problem that Android 10 and above cannot hide application icons

How to hide before Android 10:

con.getPackageManager().setComponentEnabledSetting(new ComponentName(con,activityAliasName,PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP);

After Android 10, this method of hiding icons becomes invalid. After successful hiding, the icon will still be kept on the desktop, and it will jump to the application details page after clicking. Check the official API update description for details: getActivityList .

Then this is very uncomfortable. In my opinion, the current design is not very reasonable. Whether it can be hidden or not should be decided by the user, rather than being forced to be hidden. However, the official has also set up a control switch, which can be removed by modifying the system settings. This restriction only requires adb or an APP or ROOT permission that can modify the system settings to modify. The next step is specific analysis.

Specific analysis

  • getActivityList
//frameworks/base/core/java/android/content/pm/LauncherApps.java
    public List<LauncherActivityInfo> getActivityList(String packageName, UserHandle user) {
    
    
        logErrorForInvalidProfileAccess(user);
        try {
    
    
            return convertToActivityList(mService.getLauncherActivities(mContext.getPackageName(),
                    packageName, user), user);
        } catch (RemoteException re) {
    
    
            throw re.rethrowFromSystemServer();
        }
    }
  • getLauncherActivities
//frameworks/base/services/core/java/com/android/server/pm/LauncherAppsService.java
@Override
public ParceledListSlice<LauncherActivityInfoInternal> getLauncherActivities(
        String callingPackage, String packageName, UserHandle user) throws RemoteException {
    
    
    //查询包含ACTION_MAIN和CATEGORY_LAUNCHER的activity
    ParceledListSlice<LauncherActivityInfoInternal> launcherActivities =
            queryActivitiesForUser(callingPackage,
                    new Intent(Intent.ACTION_MAIN)
                            .addCategory(Intent.CATEGORY_LAUNCHER)
                            .setPackage(packageName),
                    user);
    //检测系统设置(系统设置控制开关控制是否走新版限制逻辑)
    if (Settings.Global.getInt(mContext.getContentResolver(),
            Settings.Global.SHOW_HIDDEN_LAUNCHER_ICON_APPS_ENABLED, 1) == 0) {
    
    
        return launcherActivities;
    }
    //没有找到入口activity
    if (launcherActivities == null) {
    
    
        // Cannot access profile, so we don't even return any hidden apps.
        return null;
    }

    final int callingUid = injectBinderCallingUid();
    final long ident = injectClearCallingIdentity();
    try {
    
    
        //托管配置文件可以隐藏APP
        if (mUm.getUserInfo(user.getIdentifier()).isManagedProfile()) {
    
    
            // Managed profile should not show hidden apps
            return launcherActivities;
        }
        //设备管理员可以隐藏APP
        if (mDpm.getDeviceOwnerComponentOnAnyUser() != null) {
    
    
            // Device owner devices should not show hidden apps
            return launcherActivities;
        }

        final ArrayList<LauncherActivityInfoInternal> result = new ArrayList<>(
                launcherActivities.getList());
        if (packageName != null) {
    
    
            // If this hidden app should not be shown, return the original list.
            // Otherwise, inject hidden activity that forwards user to app details page.
            //可能是如果大于0,表示有有效的启动入口,则不用注入隐藏的APP详情页入口
            if (result.size() > 0) {
    
    
                return launcherActivities;
            }
            final ApplicationInfo appInfo = mPackageManagerInternal.getApplicationInfo(
                    packageName, /* flags= */ 0, callingUid, user.getIdentifier());
            //根据APP信息进行判断是否注入隐藏APP详情页入口
            if (shouldShowSyntheticActivity(user, appInfo)) {
    
    
                LauncherActivityInfoInternal info = getHiddenAppActivityInfo(packageName,
                        callingUid, user);
                if (info != null) {
    
    
                    result.add(info);
                }
            }
            return new ParceledListSlice<>(result);
        }
        final HashSet<String> visiblePackages = new HashSet<>();
        for (LauncherActivityInfoInternal info : result) {
    
    
            visiblePackages.add(info.getActivityInfo().packageName);
        }
        final List<ApplicationInfo> installedPackages =
                mPackageManagerInternal.getInstalledApplications(/* flags= */ 0,
                        user.getIdentifier(), callingUid);
        for (ApplicationInfo applicationInfo : installedPackages) {
    
    
            if (!visiblePackages.contains(applicationInfo.packageName)) {
    
    
                if (!shouldShowSyntheticActivity(user, applicationInfo)) {
    
    
                    continue;
                }
                LauncherActivityInfoInternal info = getHiddenAppActivityInfo(
                        applicationInfo.packageName, callingUid, user);
                if (info != null) {
    
    
                    result.add(info);
                }
            }
        }
        return new ParceledListSlice<>(result);
    } finally {
    
    
        injectRestoreCallingIdentity(ident);
    }
}
  • shouldShowSyntheticActivity
//frameworks/base/services/core/java/com/android/server/pm/LauncherAppsService.java
private boolean shouldShowSyntheticActivity(UserHandle user, ApplicationInfo appInfo) {
    
    
    //没有app信息,是系统APP或者更新的系统APP,则不添加隐藏详情页入口
    if (appInfo == null || appInfo.isSystemApp() || appInfo.isUpdatedSystemApp()) {
    
    
        return false;
    }
    //是管理员APP也不用添加该入口
    if (isManagedProfileAdmin(user, appInfo.packageName)) {
    
    
        return false;
    }
    final AndroidPackage pkg = mPackageManagerInternal.getPackage(appInfo.packageName);
    if (pkg == null) {
    
    
        // Should not happen, but we shouldn't be failing if it does
        return false;
    }
    // If app does not have any default enabled launcher activity or any permissions,
    // the app can legitimately have no icon so we do not show the synthetic activity.
    return requestsPermissions(pkg) && hasDefaultEnableLauncherActivity(
            appInfo.packageName);
}

According to the above source code, it can be found that this mechanism has a global setting switch, and there are many situations that are not restricted by this mechanism. Therefore, the following solutions are summarized:

  • If your APP has adb permission or ROOT permission, you can directly modify this global switch. The modification command is as follows:
adb shell settings put global show_hidden_icon_apps_enabled 0
  • Or your APP has device administrator permissions
  • Or your APP is a system APP
  • Or your APP does not have any default startup entry
  • Or your APP does not request any permissions
  • Or your APP involves Managed profile (this is not clear how to use it)
  • Or your APP is an Xposed module, you can directly inject system services to intercept related APIs, or inject an APP that can modify system settings (for example: settings) to directly modify this switch
  • Or if you are a system source code developer, you can directly modify the code here
  • Other ways that have not yet been explored (such as exploiting some logic loopholes)...

reference

Android Studio gradle does not rely on success but does not report an error, only when it is called, it will report red

You can run the dependent task separately, and an error message will appear

insert image description here

Empty SMPTE 2094-40 data error reporting problem

Search the source code to locate the print log location: SharedMetadata#151

temporary solution

Borrow AS new version of Logcat filter syntax to filter, the filter syntax is as follows

-tag:gralloc4 

That is, the log with the tag gralloc4 is excluded

[Remote USB] VirtualHere specifies IP (Android remote development elegantly connects to debugging devices)

Generally, our Android remote debugging is usually adb connect ip:port directly, but this is very inconvenient. You also need to configure wifi USB debugging, but the remote USB is different. Connecting a remote device is just like connecting a local device. You can see the device with adb device, no need for adb connect and wifi USB debugging.

As for the remote USB tool, of course, VirtualHere is recommended. VirtualHere is really good to use. In the local area network, it can be installed and run directly without any operation (of course, the trial version is limited to one device at a time, but it is enough for personal use. Yes, you can switch when you need it, and you don’t bind the device anyway), but you can’t do this with the Internet. After all, there are so many IPs on the Internet, how does it know which one is right, so we need to manually specify the IP, and the text begins...



​If the server

Then in the client, right-click on USB Hubs and select Specify Hubs...

​Theninsert image description here
click add to add, enter your ip and port in the new window and
insert image description here
wait for new devices to appear under USB hubs
insert image description here

If problems arise, you can use the

telnet ip port

command to see if it can be connected normally, if not, check whether the firewall blocks it

Frida tips

Command Line

Frida command

  • Specify IP and Port: -H 127.0.0.1:27042
  • Force restart application: -f
  • Run the application directly after restart: --no-pause
  • Inject the specified package name (required): com.xxxxx.xxx
  • Inject the specified process ID (choose one of the above): pid
  • Debug js code: –debug --runtime=v8

For details, refer to Here , where the code mode is not very effective for debugging and testing, and the details need to be analyzed

  • Specify the js file path to load (required): -l path_to_js

Access Google Admob

Official Demo

Here

fill hole

  • 1.The ad request was successful, but no ad was returned due to lack of ad inventory
    参考Here

1. Unlinked application store application, add the application ID in the application settings, that is, the package name, and put it on Google Play, or its supported application store 2. The filling rate is low, and the
intermediary mode is used. For details, refer to Here
2.1. View domestic Supported ad sources, refer to Here

  • 2. You need to get on the car to display the Ad

reference

App payment function realization and pitfalls

Alipay payment realization

1. Realization of formal payment
Preconditions:

1. 企业或个体工商户可申请,且账号通过支付宝实名认证审核
2. 需提供真实有效的营业执照,且支付宝账户名称需与营业执照主体一致;
3. 提供APP名称或产品说明文档,开发者与支付宝账户名称不一致需提供开发合作协议。
(您可以提供产品介绍文档或者手机demo .apk .doc .docx .pdf格式,内容要求包含产品说明、接口使用场景、资费说明等(文件大小不超过5M)如果已经在appstore、googleplay、豌豆荚上架,可不提供文档demo,直接提供应用名称)

Now the processing of enterprises and individual industrial and commercial households can be found on a certain treasure. I consulted the seller and said that they need a public account. What does the
Write picture description here
specific meaning of the public account mean? The seller said that it is the second condition above.
I still don’t quite understand , I went online to Baidu again:
Write picture description here
It seems that Baidu, Baidu can't do anything, try using Google,
Write picture description here
I finally found it, it seems that Google is better, Baidu is really getting more and more rubbish!
It seems that to have a public account is equivalent to applying for a company, so let’s forget it, I’m afraid when I think of the huge pile of documents and procedures! I can only wait for a certain amount of funds in the future, so I can directly find someone to do it for me.

2. Informal implementation
1. Personal payment account is still used, and then the background of the server (or personal computer) constantly monitors the payment record, and when it matches the payment record with a specific note, it will deal with it accordingly!
2. Using a third-party agency payment means handing over the payment to a third-party payment provider that has been certified by Alipay. This is indeed the most convenient way. You can get Alipay’s regular payment function without any processing. The disadvantage is that you will definitely be charged for formalities. Fee, of course, it is normal to charge a service fee. After all, they provide services. Another disadvantage is whether the service provider is credible. After all, you don’t know how they handle it in the background. The same kind of service providers have a common biggest shortcoming. — Unstable, that is, if a developer’s app payment is complained, it will definitely affect the service provider. Alipay is equivalent to the service provider being complained. If there are too many complaints, the service provider will hang up!

Wechat payment realized

1. Formal implementation
Write picture description here
also requires enterprise certification, and its developer certification is not very easy. It
Write picture description here
costs 300 yuan to certify a developer, and it is only one year!
Write picture description here
Still need a business, forget it, give up!
2. Informal implementation
still under study...

reference

1. Alipay collection process

DcseTBS obtains the device ID principle

I won’t talk about this tool, this is not the focus of the article, today we are going to study his principle of obtaining the unique ID of the device.
In fact, its method of obtaining the unique ID of the device is no different from that of others.
The implementation code is:

TelephoneManager tm=TelephoneManager.getSystemService(Context.TELEPHONE_SERVICE);
tm.getDeviceId();

The code is very simple, so it is very simple to crack it, you can modify it with the xposed module hook, or directly decompile and modify it.

But the point is not here, but the situation after cracking, each of its device IDs can only be used for one day without recharging, so the way I crack it is to let him return a random device ID every time, so that it can be cracked, But the fact is not like this, it has not been cracked (in fact, I found out later that it has been cracked), every time I open it, it shows an error, which really makes me tangled for a long time, thinking that he used reflection or other methods to obtain the device ID, or the device The ID is stored in the memory card. After passing my verification, I finally found that there is no such thing. This made me confused. Did I use a method I didn’t know? Just when I was about to give up, I thought of a neglected one. place, that is my network IP address, and I found that sometimes the wrong information is not the same. In the end, I finally found the key point of the problem. It turned out that when it
gets a new device ID, it will not be the first time. Trial information appears, but an error message appears, and you are asked to restart. Normally, if it is not cracked, the trial information will appear when you enter the second time, but after we crack it, every time you get Random device ID, that is, when restarting for the second time, a new device ID is obtained, which requires another restart, but the new device ID is obtained again, and the result is that it will never Trial information appears!
Now that the problem is understood, it is easy to crack, just return a new device ID after each trial period!
What a very clever way to prevent being cracked!

Screenshot after cracking

Write picture description here
Do not reset the ID frequently, once a day is sufficient. After setting a new ID, click "remind me tomorrow", and it will automatically prompt you to change the new ID at this time tomorrow, and then set a new ID at this time.

Cracked APK

Seeing that there are so many people who want it, I will send it directly!
Download address: https://download.csdn.net/download/qq_26914291/10383983
[Note] This Apk is only for research and testing, and I have nothing to do with any loss caused by using it for other purposes!

Summarize

1. If you encounter problems when cracking, you must carefully observe the wrong information, maybe the reason is hidden in those!
2. In fact, things that often seem complicated are actually very simple!

Code obfuscation

primary confusion

Code obfuscation with proGuard

1. Reference tutorial: Android Developer Guide (9) - ProGuard
2. Obfuscation template: Android proguard-rules.pro obfuscation template
3. [Android code obfuscation option description (https://blog.csdn.net/jjwwmlp456/article /details/44977721)

Several commands that can increase the intensity of obfuscation:

#将所有类放到跟目录下
-flattenpackagehierarchy

#使用唯一的类成员名称
-useuniqueclassmembernames

Several dictionaries that can increase the intensity of confusion
1. https://github.com/ihbing/AndroidObfuseDictionary

A few commands that need attention when using:
1. When using -assumenosideeffects, you must not add -dontoptimize to work

# 移除Log类打印各个等级日志的代码,打正式包的时候可以做为禁log使用,这里可以作为禁止log打印的功能使用
# 记得proguard-android.txt中一定不要加-dontoptimize才起作用
-assumenosideeffects class android.util.Log {
   public static int v(...);
   public static int i(...);
   public static int w(...);
   public static int d(...);
   public static int e(...);
}

[Note]
1.eclipse will only confuse the project when exporting the project
2.1 proguard.config=proguard-project.txt//use relative path configuration, directly read the proguard-project.txt file in the root directory of the project
2.2 proguard.config= ${sdk.dir}/tools/proguard/proguard-android.txt//Adopt absolute path

Manual obfuscation with proGuard-GUI

Resource Obfuscation Using AndResGuard

Reference tutorial: AndResGuard integration notes

Added 7z compression

Reference tutorial: Two ways of Android project integration AndResGuard resource confusion
Reference tutorial: https://github.com/shwenzhang/AndResGuard/blob/master/doc/how_to_work.zh-cn.md

important point

1. How to open the Task task in Gradle?
Write picture description here

advanced confusion

Use StringFog to encrypt string Base64

Reference tutorial: https://github.com/MegatronKing/StringFog

Obfuscate strings into byte code

Refer to the tutorial as shown below
Write picture description here
: https://github.com/ihbing/obfuseSmaliText

higher order confusion

Modify the obfuscated characters of the proGuard tool

[Note] AndroidStudio's own proGuard obfuscation tool directory D:\Program Files\Android\Android Studio\gradle\m2repository\net\sf\proguard\proguard-base\orD:\Program Files\Android\Android Studio\gradle\m2repository\net\proguard-base\

Fight jadx & jd-gui with invalid code

 //添加无效代码,对抗jadx & jd-gui
        boolean qwerty21345hjdnjd = false;
        while (qwerty21345hjdnjd) {
            switch (1) {
                case 1:
                    while (qwerty21345hjdnjd) {
                        try {
                            Throwable throwable=new Throwable();
                            Throwable cause = throwable.getCause();
                        } catch (NullPointerException e) {
                        } finally {
                        }
                    }
                    break;
            }
        }

reference

1. Android resource obfuscation tool
2. proGuard obfuscation notes
3. Android code obfuscation technology summary (1)
4. APK online anti-obfuscation

Guess you like

Origin blog.csdn.net/qq_26914291/article/details/132225141
Recommended