天天看点

Android WIFI密码查看器实例(在获取Root权限下查看系统文件)Android WIFI密码查看器实例

Android WIFI密码查看器实例

实现原理:使用shell命令查看保存WIFI密码的系统文件

涉及的知识

  1. 界面展示
  2. 基本的Shell命令
  3. shell查看WIFI密码
  4. ShellUtil的使用
  5. 正则表达式解析字符串
  6. ExpandableListView的使用

界面展示

主界面只包含一个

ExpandableListView

Android WIFI密码查看器实例(在获取Root权限下查看系统文件)Android WIFI密码查看器实例

基本的Shell命令

1.shel由

adb shell

进入,基本命令于Linux下的命令相同,这边演示几个常用的命令

Android WIFI密码查看器实例(在获取Root权限下查看系统文件)Android WIFI密码查看器实例
Android WIFI密码查看器实例(在获取Root权限下查看系统文件)Android WIFI密码查看器实例

因为是在手机的系统文件下操作,所以部分命令不方便演示,下面直接进入查看wifi密码的命令

首先执行

su

获取root权限
Android WIFI密码查看器实例(在获取Root权限下查看系统文件)Android WIFI密码查看器实例
执行

cat /data/misc/wifi/wpa_supplicant.conf

来查看本地的WIFI信息
Android WIFI密码查看器实例(在获取Root权限下查看系统文件)Android WIFI密码查看器实例

在应用内部执行shell命令

此处我们用到是ShellUtil的java文件,来源于网络,封装了一写方法用于执行shell命令,代码如下

注释都在代码内部,此处不多加解释

package com.brioal.poswermanager;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

public class ShellUtils {

    public static final String COMMAND_SU = "su"; // 获取root权限的命令
    public static final String COMMAND_SH = "sh"; // 执行sh文件的命令
    public static final String COMMAND_EXIT = "exit\n"; // 退出的命令
    public static final String COMMAND_LINE_END = "\n"; // 执行命令必须加在末尾

    private ShellUtils() {
        throw new AssertionError();
    }
    //检测root状态
    public static boolean checkRootPermission() {
        return execCommand("echo root", true, false).result == ;
    }
    //执行单行命令,实际还是调用的执行多行 ,传入命令和是否需要root
    public static CommandResult execCommand(String command, boolean isRoot) {
        return execCommand(new String[]{command}, isRoot, true);
    }
    //执行List<String>中的命令 , 传入List和是否需要root
    public static CommandResult execCommand(List<String> commands, boolean isRoot) {
        return execCommand(commands == null ? null : commands.toArray(new String[]{}), isRoot, true);
    }
    //执行多行命令
    public static CommandResult execCommand(String[] commands, boolean isRoot) {
        return execCommand(commands, isRoot, true);
    }

    public static CommandResult execCommand(String command, boolean isRoot, boolean isNeedResultMsg) {
        return execCommand(new String[]{command}, isRoot, isNeedResultMsg);
    }

    public static CommandResult execCommand(List<String> commands, boolean isRoot, boolean isNeedResultMsg) {
        return execCommand(commands == null ? null : commands.toArray(new String[]{}), isRoot, isNeedResultMsg);
    }
    //执行命令,获得返回的信息
    public static CommandResult execCommand(String[] commands, boolean isRoot, boolean isNeedResultMsg) {
        int result = -;
        if (commands == null || commands.length == ) {
            return new CommandResult(result, null, null);
        }

        Process process = null;
        BufferedReader successResult = null;
        BufferedReader errorResult = null;
        StringBuilder successMsg = null;
        StringBuilder errorMsg = null;
        DataOutputStream os = null;
        try {
            process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH);
            os = new DataOutputStream(process.getOutputStream());
            for (String command : commands) {
                if (command == null) {
                    continue;
                }
                os.write(command.getBytes());
                os.writeBytes(COMMAND_LINE_END);
                os.flush();
            }
            os.writeBytes(COMMAND_EXIT);
            os.flush();

            result = process.waitFor();
            // get command result
            if (isNeedResultMsg) {
                successMsg = new StringBuilder();
                errorMsg = new StringBuilder();
                successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
                errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
                String s;
                while ((s = successResult.readLine()) != null) {
                    successMsg.append(s);
                }
                while ((s = errorResult.readLine()) != null) {
                    errorMsg.append(s);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (successResult != null) {
                    successResult.close();
                }
                if (errorResult != null) {
                    errorResult.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            if (process != null) {
                process.destroy();
            }
        }
        return new CommandResult(result, successMsg == null ? null : successMsg.toString(), errorMsg == null ? null
                : errorMsg.toString());
    }
    //封装了返回信息
    public static class CommandResult {

        public int result;
        public String successMsg; //成功信息
        public String errorMsg; // 错误信息

        public CommandResult(int result) {
            this.result = result;
        }

        public CommandResult(int result, String successMsg, String errorMsg) {
            this.result = result;
            this.successMsg = successMsg;
            this.errorMsg = errorMsg;
        }
    }
}
           

在应用内部执行

cat /data/misc/wifi/wpa_supplicant.conf

命令

到了这一步就很简单了,直接看代码

strings = new ArrayList<>();
strings.add("cd data/" + ShellUtils.COMMAND_LINE_END);
strings.add("cd misc/" + ShellUtils.COMMAND_LINE_END);
strings.add("cd wifi/" + ShellUtils.COMMAND_LINE_END);
strings.add("ls" + ShellUtils.COMMAND_LINE_END);
strings.add("cat wpa_supplicant.conf" + ShellUtils.COMMAND_LINE_END);
ShellUtils.CommandResult result = ShellUtils.execCommand(strings, true, true);
//获取返回的结果
String wifis = result.successMsg;
           

此时返回的信息就包含了

wpa_supplicant.conf

文件内部的所有信息,此时我们需要做的就是解析WIFI名称和密码然后显示到界面

利用正则表达式解析返回的数据

首先查看我们获取到的返回信息,其中wifi的名称格式是

ssid="......"

密码的格式是

psk="......"

,这样我们就可以用正则表达式来截取名称和密码

注:部分机型中文的wifi名称会显示为字母和数字的组合,且没有双引号,另开放的网络没有wifi密码,密码一栏的显示是这样的

key_mgmt=NONE

,所以第一步执行的是讲其中的

key_mgmt=NONE

替换为

key_mgmt="无密码"

.这样就不会出现名称的个数和密码的个数不相符的问题

解析wifi的名称

Pattern pattern = null;
        Matcher matcher = null;
        listID = new ArrayList<>();
        listPass = new ArrayList<>();
        //获取用户名
        String rexId = "ssid=[\\S]+[\\s]";
        pattern = Pattern.compile(rexId);
        matcher = pattern.matcher(wifis);

        while (matcher.find()) {
            listID.add(matcher.group());
        }
           

解析wifi的密码

//获取密码
        String rexPass = "psk=\"[^\"]+\"";
        pattern = Pattern.compile(rexPass);
        matcher = pattern.matcher(wifis);
        while (matcher.find()) {
            listPass.add(matcher.group());
        }
           
经过这两步之后我们就获取到了两个包含wifi名称和wifi密码的LIst
封装一个保存wifi信息的base类
package com.brioal.wifipassword.base;

/**
 * Created by Brioal on 2016/3/21.
 */
public class WifiItem {
    private String mId ;
    private String mPass ;

    public WifiItem(String mId, String mPass) {
        this.mId = mId;
        this.mPass = mPass;
    }

    public String getmId() {
        return mId;
    }

    public void setmId(String mId) {
        this.mId = mId;
    }

    public String getmPass() {
        return mPass;
    }

    public void setmPass(String mPass) {
        this.mPass = mPass;
    }
}
           
获取

List<WifiItem>

for (int i = ; i < listID.size(); i++) {
            String mId = listID.get(i);
            String mPass = listPass.get(i);
            mId = mId.substring(, mId.length() - );
            mPass = mPass.substring(, mPass.length() - );
            WifiItem item = new WifiItem(mId, mPass);
            wifiList.add(item);
        }
           

接下来就是最后一步,将wifi信息显示到ExpandableListView当中

显示wifi信息

这一部分比较简单,就直接上代码吧

创建Adapter

private class MyAdapter implements ExpandableListAdapter {


        @Override
        public void registerDataSetObserver(DataSetObserver observer) {

        }

        @Override
        public void unregisterDataSetObserver(DataSetObserver observer) {

        }

        @Override
        public int getGroupCount() {
            return listID.size();
        }

        @Override
        public int getChildrenCount(int groupPosition) {
            return ;
        }

        @Override
        public Object getGroup(int groupPosition) {
            return listID.get(groupPosition);
        }

        @Override
        public Object getChild(int groupPosition, int childPosition) {
            return listPass.get(groupPosition);
        }

        @Override
        public long getGroupId(int groupPosition) {
            return groupPosition;
        }

        @Override
        public long getChildId(int groupPosition, int childPosition) {
            return groupPosition;
        }

        @Override
        public boolean hasStableIds() {
            return false;
        }

        @Override
        public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
            TextView textView = new TextView(MainActivity.this);
            textView.setTextSize();

            textView.setGravity(Gravity.CENTER_VERTICAL);
            textView.setText("     "+wifiList.get(groupPosition).getmId());
            textView.setSingleLine();
            textView.setMaxWidth();
            textView.setTypeface(Typeface.SANS_SERIF);
            textView.setEllipsize(TextUtils.TruncateAt.END);
            return textView;
        }

        @Override
        public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
            TextView textView = new TextView(MainActivity.this);
            textView.setTextSize();
            textView.setGravity(Gravity.CENTER_VERTICAL);
            textView.setText("      "+wifiList.get(groupPosition).getmPass());
            textView.setTypeface(Typeface.SANS_SERIF);

            return textView;
        }

        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return false;
        }

        @Override
        public boolean areAllItemsEnabled() {
            return false;
        }

        @Override
        public boolean isEmpty() {
            return false;
        }

        @Override
        public void onGroupExpanded(int groupPosition) {

        }

        @Override
        public void onGroupCollapsed(int groupPosition) {

        }

        @Override
        public long getCombinedChildId(long groupId, long childId) {
            return ;
        }

        @Override
        public long getCombinedGroupId(long groupId) {
            return ;
        }
    }
           

ExpandableLIstView

设置

Adapter

adapter = new MyAdapter();
        listView.setAdapter(adapter);
           

至此大功告成

源码已分享到Github,有兴趣的同学欢迎下载查看

欢迎联系作者交流,作者QQ:821329382