android,安卓WIFI密码破解工具编写初探,毕业论文设计,课程,ppt,开题翻译

3995
    


来源:
Licence:
联系:
分类:
平台:
环境:
大小:
更新:
标签:
联系方式 :
免费下载 ×

下载APP,支持永久资源免费下载

限免产品服务请联系qq:1585269081

下载APP
免费下载 ×

下载APP,支持永久资源免费下载

下载APP 免费下载
下载 ×

下载APP,资源永久免费


如果出现不能下载的情况,请联系站长,联系方式在下方。

免费下载 ×

下载论文助手APP,资源永久免费

免费获取

如果你已经登录仍然出现不能下载的情况,请【点击刷新】本页面或者联系站长



最近,在好几个安卓手机群里面都看到有朋友寻求WIFI密码破解工具,在网上经过一番搜索后发现居然没有这样的软件,这让我感到很奇怪,难道这样的功能实现起来很难?思索再三,决定探个究竟。

安卓WIFI原理浅析

首先看SDK中查看WIFI操作的相关类。WIFI的支持是在android.net.wifi包中提供的。里面有WifiManagerWifiInfoWifiConfigurationScanResult等几个常用到的类,WIFI的管理通过WifiManager暴露出来的方法来操作,仔细一看还真让人郁闷,这个类没有提供连接WIFI的方法,倒是有disconnect()方法来断开连接,不过有个reconnect()方法倒是值得注意,只是该方法SDK中却没有详细的介绍。在谷歌中搜索安卓连接WIFI的代码又测试失败,心里顿时凉了一截!看来要想完成这个功能还得下一番功夫。

转念一想,安卓会不会把这样的接口隐藏了,通过AIDL的方式就可以访问呢?为了验证我的想法,开始在安卓源代码的“frameworks”目录中搜索以aidl结尾的文件,最终锁定“IWifiManager.aidl”文件,用Editplus打开它,发现IWifiManager接口里面也没有提供连接WIFI的方法。这条线索也断了!

看来只能从手机WIFI的连接过程着手了。掏出手机,进入“设置”->“无线和网络设置”->WLAN设置”里面打开“WLAN”,这时手机会自动搜索附近的WIFI热点,点击任一个加密的热点会弹出密码输入框

如果此时更换密码后再试一次仍然失败的话,手机就不会再访问该热点并将该WLAN网络设为禁用。既然在手机设置里可以连接WIFI,那么说明设置里面就有连接WIFI的代码存在。

手机设置这一块是做为安卓手机的一个软件包提供的,它的代码位于安卓源码的“packages\apps\Settings”目录中,为了弄清楚操作流程,我决定到源码中查看相关代码。首先根据文件名判断打开“packages\apps\Settings\src\com\android\settings\wifi\WifiSettings.java”文件,可以看到WifiSettings类继承自SettingsPreferenceFragmentSettingsPreferenceFragment类使用一系列的PreferenceScreen作为显示的列表项,现在很多软件都用它来作为自身的设置页面,不仅布局更简单,而且也很方便。

找到WifiSettings的构造函数代码如下:

public WifiSettings() {

        mFilter = new IntentFilter();

    mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);

    mFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);

        mFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION);

    mFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);

    mFilter.addAction(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);

    mFilter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);

    mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);

    mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);

    mFilter.addAction(WifiManager.ERROR_ACTION);

 

    mReceiver = new BroadcastReceiver() {

        @Override

        public void onReceive(Context context, Intent intent) {

            handleEvent(context, intent);

        }

    };

    mScanner = new Scanner();

}

这段代码注册了一个广播接收者,接收一系列的广播事件,WIFI_STATE_CHANGED_ACTION事件当WIFI功能开启或关闭时会收到,SCAN_RESULTS_AVAILABLE_ACTION事件当手机扫描到有可用的WIFI连接时会收到,SUPPLICANT_STATE_CHANGED_ACTION事件当连接请求状态发生改变时会收到,NETWORK_STATE_CHANGED_ACTION事件当网络状态发生变化时会收到,对于其它的事件我们不用去关心,广播接收者中调用handleEvent()方法对所有的事件进行判断并处理,事件处理代码如下:

      private void handleEvent(Context context, Intent intent) {

        String action = intent.getAction();

        if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {

            updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,

                    WifiManager.WIFI_STATE_UNKNOWN));

        } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action) ||

                WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(action) ||

                WifiManager.LINK_CONFIGURATION_CHANGED_ACTION.equals(action)) {

                updateAccessPoints();

        } else if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(action)) {

            if (!mConnected.get()) {

                updateConnectionState(WifiInfo.getDetailedStateOf((SupplicantState)

                        intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE)));

            }

            if (mInXlSetupWizard) {

                ((WifiSettingsForSetupWizardXL)getActivity()).onSupplicantStateChanged(intent);

            }

        } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {

            NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(

                    WifiManager.EXTRA_NETWORK_INFO);

            mConnected.set(info.isConnected());

            changeNextButtonState(info.isConnected());

            updateAccessPoints();

            updateConnectionState(info.getDetailedState());

        }

        .....

}

代码中分别调用updateWifiState()updateConnectionState()updateAccessPoints()等方法进行更新操作,同样凭感觉查看updateAccessPoints()方法,代码如下:

private void updateAccessPoints() {

        final int wifiState = mWifiManager.getWifiState();

        switch (wifiState) {

            case WifiManager.WIFI_STATE_ENABLED:

                // AccessPoints are automatically sorted with TreeSet.

                final Collection<AccessPoint> accessPoints = constructAccessPoints();

                getPreferenceScreen().removeAll();

                if (mInXlSetupWizard) {

                    ((WifiSettingsForSetupWizardXL)getActivity()).onAccessPointsUpdated(

                            getPreferenceScreen(), accessPoints);

                } else {

                    for (AccessPoint accessPoint : accessPoints) {

                        getPreferenceScreen().addPreference(accessPoint);

                    }

                }

                break;

               .....

    }

成功开启WIFI,即getWifiState()返回为WIFI_STATE_ENABLED时首先会调用constructAccessPoints(),在这个方法中调用mWifiManager.getConfiguredNetworks()mWifiManager.getScanResults()来分别获取已保存与可用的WIFI热点网络,接着判断mInXlSetupWizard并调用onAccessPointsUpdated()addPreference(accessPoint),这两者的操作都是往页面添加显示搜索到的WIFI热点网络,区别只是调用者是不是大屏手机或平板电脑(mInXlSetupWizard意思为是否为大屏幕的设置向导,这个结论由长时间分析所得!*_*XL=XLarge)。AccessPoints 的构造函数有三个,代码如下:

      AccessPoint(Context context, WifiConfiguration config) {

        super(context);

        setWidgetLayoutResource(R.layout.preference_widget_wifi_signal);

        loadConfig(config);

        refresh();

    }

 

    AccessPoint(Context context, ScanResult result) {

        super(context);

        setWidgetLayoutResource(R.layout.preference_widget_wifi_signal);

        loadResult(result);

        refresh();

    }

 

    AccessPoint(Context context, Bundle savedState) {

        super(context);

        setWidgetLayoutResource(R.layout.preference_widget_wifi_signal);

 

        mConfig = savedState.getParcelable(KEY_CONFIG);

        if (mConfig != null) {

            loadConfig(mConfig);

        }

        mScanResult = (ScanResult) savedState.getParcelable(KEY_SCANRESULT);

        if (mScanResult != null) {

            loadResult(mScanResult);

        }

        mInfo = (WifiInfo) savedState.getParcelable(KEY_WIFIINFO);

        if (savedState.containsKey(KEY_DETAILEDSTATE)) {

            mState = DetailedState.valueOf(savedState.getString(KEY_DETAILEDSTATE));

        }

        update(mInfo, mState);

}

上面的两个构造函数分别针对调用mWifiManager.getConfiguredNetworks()mWifiManager.getScanResults()得来的结果调用loadConfig(WifiConfiguration config)loadResult(ScanResult result),经过这一步后,AccessPoints 的成员变量也初始化完了,然后调用refresh()方法进行刷新显示操作,代码我就不帖了,主要就是设置显示SSID,SSID的加密方式,信号强度等。显示工作做完后,我们的重点应用转向WIFI热点网络点击事件的处理。点击事件的处理同样在WifiSettings.java文件中,代码如下:

    @Override

    public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {

        if (preference instanceof AccessPoint) {

            mSelectedAccessPoint = (AccessPoint) preference;

            /** Bypass dialog for unsecured, unsaved networks */

            if (mSelectedAccessPoint.security == AccessPoint.SECURITY_NONE &&

                    mSelectedAccessPoint.networkId == INVALID_NETWORK_ID) {

                mSelectedAccessPoint.generateOpenNetworkConfig();

                mWifiManager.connectNetwork(mSelectedAccessPoint.getConfig());

            } else {

                showConfigUi(mSelectedAccessPoint, false);

            }

        } else {

            return super.onPreferenceTreeClick(screen, preference);

        }

        return true;

}

这段代码很简单,如果WIFI没有加密,直接调用mSelectedAccessPoint.generateOpenNetworkConfig()生成一个不加密的WifiConfiguration,代码如下:

    protected void generateOpenNetworkConfig() {

        if (security != SECURITY_NONE)

            throw new IllegalStateException();

        if (mConfig != null)

            return;

        mConfig = new WifiConfiguration();

        mConfig.SSID = AccessPoint.convertToQuotedString(ssid);

        mConfig.allowedKeyManagement.set(KeyMgmt.NONE);

}

代码首先new了一个WifiConfiguration赋值给mConfig,然后设置allowedKeyManagementKeyMgmt.NONE表示不使用加密连接,这个工作做完成后就调用了mWifiManagerconnectNetwork()方法进行连接,看这个方法的父亲可以发现是WifiManager,居然是WifiManager,可这个方法却没有导出!!!

继续分析,如果是加密的WIFI,就调用showConfigUi()方法来显示输入密码框,对于大屏手机,即mInXlSetupWizard为真时,调用了WifiSettingsForSetupWizardXL类的showConfigUi()方法,如果为假就直接调用showDialog(accessPoint, edit)显示对话框,代码如下:

    private void showDialog(AccessPoint accessPoint, boolean edit) {

        if (mDialog != null) {

            removeDialog(WIFI_DIALOG_ID);

            mDialog = null;

        }

        // Save the access point and edit mode

        mDlgAccessPoint = accessPoint;

        mDlgEdit = edit;

        showDialog(WIFI_DIALOG_ID);

}

 

@Override

    public Dialog onCreateDialog(int dialogId) {

        AccessPoint ap = mDlgAccessPoint; // For manual launch

        if (ap == null) { // For re-launch from saved state

            if (mAccessPointSavedState != null) {

                ap = new AccessPoint(getActivity(), mAccessPointSavedState);

                // For repeated orientation changes

                mDlgAccessPoint = ap;

            }

        }

        // If it's still null, fine, it's for Add Network

        mSelectedAccessPoint = ap;

        mDialog = new WifiDialog(getActivity(), this, ap, mDlgEdit);

        return mDialog;

    }

这段代码保存accessPoint后就调用showDialog(WIFI_DIALOG_ID)了,在onCreateDialog()初始化方法中判断mDlgAccessPoint是否为null,如果为null就调用AccessPoint的第三个构造方法从保存的状态中生成一个AccessPoint,最后new WifiDialog(getActivity(), this, ap, mDlgEdit)生成一个WifiDialog,这个WifiDialog继承自AlertDialog,也就是它,最终将对话框展现在我们面前,WifiDialog构造函数的第二个参数为DialogInterface.OnClickListener的监听器,设置为this表示类本身对按钮点击事件进行响应,接下来找找事件响应代码,马上就到关键啰!

public void onClick(DialogInterface dialogInterface, int button) {

        if (mInXlSetupWizard) {

            if (button == WifiDialog.BUTTON_FORGET && mSelectedAccessPoint != null) {

                forget();

            } else if (button == WifiDialog.BUTTON_SUBMIT) {

                ((WifiSettingsForSetupWizardXL)getActivity()).onConnectButtonPressed();

            }

        } else {

            if (button == WifiDialog.BUTTON_FORGET && mSelectedAccessPoint != null) {

                forget();

            } else if (button == WifiDialog.BUTTON_SUBMIT) {

                submit(mDialog.getController());

            }

        }

}

代码判断弹出的对话框是WIFI热点抛弃还是WIFI连接,并做出相应的处理,这里看看submit()方法的代码:

void submit(WifiConfigController configController) {

        int networkSetup = configController.chosenNetworkSetupMethod();

        switch(networkSetup) {

            case WifiConfigController.WPS_PBC:

            case WifiConfigController.WPS_DISPLAY:

            case WifiConfigController.WPS_KEYPAD:

                mWifiManager.startWps(configController.getWpsConfig());

                break;

            case WifiConfigController.MANUAL:

                final WifiConfiguration config = configController.getConfig();

                if (config == null) {

                    if (mSelectedAccessPoint != null

                            && !requireKeyStore(mSelectedAccessPoint.getConfig())

                            && mSelectedAccessPoint.networkId != INVALID_NETWORK_ID) {

                        mWifiManager.connectNetwork(mSelectedAccessPoint.networkId);

                    }

                } else if (config.networkId != INVALID_NETWORK_ID) {

                    if (mSelectedAccessPoint != null) {

                        saveNetwork(config);

                    }

                } else {

                    if (configController.isEdit() || requireKeyStore(config)) {

                        saveNetwork(config);

                    } else {

                        mWifiManager.connectNetwork(config);

                    }

                }

                break;

        }

 

        if (mWifiManager.isWifiEnabled()) {

            mScanner.resume();

        }

        updateAccessPoints();

}

关键代码终于找到了,那个叫激动啊T_T!按钮事件首先对WIFI网络加密类型进行判断,是WPS的就调用mWifiManager.startWps(configController.getWpsConfig()),是手动设置就调用被点击AccessPoint 项的getConfig()方法读取WifiConfiguration信息,如果不为null调用connectNetwork(mSelectedAccessPoint.networkId)连接网络,为null说明可能是AccessPoint 调用第二个构造函数使用ScanResult生成的,则调用saveNetwork(config),看看saveNetwork()的代码:

private void saveNetwork(WifiConfiguration config) {

        if (mInXlSetupWizard) {

            ((WifiSettingsForSetupWizardXL)getActivity()).onSaveNetwork(config);

        } else {

            mWifiManager.saveNetwork(config);

        }

}

调用的mWifiManager.saveNetwork(config)方法,这个方法同样在SDK中没有导出,到源码中找找,最终在源代码的“frameworks\base\wifi\java\android\net\wifi\WifiManager.java”文件中找到是通过向自身发送消息的方式调用了WifiStateMachine.java->WifiConfigStore.java->saveNetwork()方法,最终保存WIFI网络后发送了一个已配置网络变更广播,这里由于篇幅就不再展开了。

分析到这里,大概了解了WIFI连接的整个流程,程序无论是否为加密的WIFI网络,最终调用WifiManagerconnectNetwork()方法来连接网络。而这个方法在SDK中却没有导出,我们该如何解决这个问题,一杯茶后,马上回来......


免费下载 ×

下载APP,支持永久资源免费下载

下载APP 免费下载
温馨提示
请用电脑打开本网页,即可以免费获取你想要的了。
扫描加我微信 ×

演示

×
登录 ×


下载 ×
论文助手网
论文助手,最开放的学术期刊平台
							 
回复
来来来,吐槽点啥吧

作者联系方式

×

向作者索要->