安卓wifi密碼破解工具編寫初探_第1頁(yè)
安卓wifi密碼破解工具編寫初探_第2頁(yè)
安卓wifi密碼破解工具編寫初探_第3頁(yè)
安卓wifi密碼破解工具編寫初探_第4頁(yè)
安卓wifi密碼破解工具編寫初探_第5頁(yè)
已閱讀5頁(yè),還剩12頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、安卓 WIFI工具編寫初探圖/文 非蟲最近,在好幾個(gè)安卓群里面都看到有朋友尋求WIFI工具,在網(wǎng)上經(jīng)過(guò)一番搜索后發(fā)現(xiàn)居然沒(méi)有這樣的,這讓我感到很奇怪,難道這樣的功能實(shí)現(xiàn)起來(lái)很難?思索再三,決定探個(gè)究竟。安卓 WIFI 原理淺析首先看SDK 中查看WIFI 操作的相關(guān)類。WIFI 的支持是在 .wifi 包中提供的。里面有 WifiManager、WifiInfo、WifiConfiguration 與 ScanResult 等幾個(gè)常用到的類,WIFI 的管理通過(guò) WifiManager出來(lái)的方法來(lái)操作,仔細(xì)一看還真讓人郁悶,這個(gè)類沒(méi)有提供連接WIFI 的方法,倒是有 disconnect()方

2、法來(lái)斷開連接,不過(guò)有個(gè) reconnect()方法倒是值得注意,只是該方法 SDK 中卻沒(méi)有詳細(xì)的介紹。在谷歌中搜索安卓連接 WIFI 的代碼又測(cè)試失敗,心里頓時(shí)涼了一截!看來(lái)要想完成這個(gè)功能還得下一番功夫。轉(zhuǎn)念,安卓會(huì)不會(huì)把這樣的接口隱藏了,通過(guò) AIDL 的方式就可以呢?為了驗(yàn)證想法,開始在安卓源代碼的“frameworks”目錄中搜索以 aidl 結(jié)尾的文件,最終鎖定“IWifiManager.aidl”文件,用 Editplus打開它,發(fā)現(xiàn) IWifiManager 接口里面也沒(méi)有提供連接 WIFI 的方法。這條線索也斷了!看來(lái)只能從WIFI 的連接過(guò)程著手了。掏出,進(jìn)入“設(shè)置”-“無(wú)

3、線和網(wǎng)絡(luò)設(shè)置”-“WLAN 設(shè)置”里面打開“WLAN”,這時(shí)所示:會(huì)自動(dòng)搜索附近的 WIFI 熱點(diǎn),點(diǎn)擊任一個(gè)加密的熱點(diǎn)會(huì)彈出輸入框,如圖 1圖 1輸入任意長(zhǎng)度大于或等于 8 位的錯(cuò)誤,請(qǐng)重新輸入正確的后點(diǎn)擊連接按鈕,此時(shí)就會(huì)去連接該熱點(diǎn),如果驗(yàn)證失敗就會(huì)提示“并且再試一次”,如圖 2 所示:圖 2就不會(huì)再該熱點(diǎn)并將該 WLAN 網(wǎng)絡(luò)設(shè)為禁用。既然如果此時(shí)更換后再試一次仍然失敗的話,在設(shè)置里可以連接 WIFI,那么說(shuō)明設(shè)置里面就有連接WIFI 的代碼存在。的一個(gè)包提供的,它的代碼位于安卓源碼的“packagesappsSettings”設(shè)置這一塊是做為安卓目錄 中, 為了弄清楚 操作 流程 ,

4、 我決 定到源碼 中查 看相關(guān)代碼 。 首先根據(jù) 文件名判斷打 開“packagesappsSettingssrccomandroidsettingswifiWifiSettings.java”文件,可以看到 WifiSettings 類繼承自SettingsPreferenceFragment,SettingsPreferenceFragment 類使用一系列的 Preferencreen 作為顯示的列表項(xiàng),現(xiàn)在很多都用它來(lái)作為自身的設(shè)置頁(yè)面,不僅布局更簡(jiǎn)單,而且也很方便。找到 WifiSettings 的構(gòu)造函數(shù)代碼如下:這段代碼了一個(gè)廣播接收者,接收一系列的廣播事件,WIFI_SE_CH

5、ANGED_ACTION 事件當(dāng)WIFI功能開啟或關(guān)閉時(shí)會(huì)收到,SCAN_RESULTS_AVAILABLE_ACTION 事件當(dāng)掃描到有可用的WIFI 連接時(shí)會(huì)收 到 , SUPPLICANT_SE_CHANGED_ACTION 事 件 當(dāng) 連 接 請(qǐng) 求 狀 態(tài) 發(fā) 生 改 變 時(shí) 會(huì) 收 到 ,public WifiSettings() mFilter = newentFilter();mFilter.addAction(WifiManager.WIFI_SE_CHANGED_ACTION); mFilter.addAction(WifiManager.SCAN_RESULTS_AVAI

6、LABLE_ACTION); mFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION); mFilter.addAction(WifiManager.SUPPLICANT_SE_CHANGED_ACTION); mFilter.addAction(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION); mFilter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION); mFilter.addAction(WifiManager.NE

7、TWORK_SE_CHANGED_ACTION); mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); mFilter.addAction(WifiManager.ERROR_ACTION);mReceiver = new BroadcastReceiver() Overridepublic void onReceive(Context context,entent) handleEvent(context,ent);mScanner = new Scanner();NETWORK_SE_CHANGED_ACTION 事件當(dāng)網(wǎng)絡(luò)狀態(tài)發(fā)生變化時(shí)

8、會(huì)收到,對(duì)于其它的事件不用去關(guān)心,廣播接收者中調(diào)用 handleEvent()方法對(duì)所有的事件進(jìn)行判斷并處理,事件處理代碼如下:代碼中分別調(diào)用 updateWifiSe()、updateConnectionSe()、updateAcsPos()等方法進(jìn)行更新操作,同樣憑感覺查看 updateAcsPos()方法,代碼如下:private void updateAcsPos() finalwifiSe = mWifiManager.getWifiSe(); switch (wifiSe) case WifiManager.WIFI_SE_ENABLED:/ AcsPos are automati

9、cally sorted with TreeSet.final Collection acsPos = constructAcsPos(); getPreferencreen().removeAll();if (mInXlSetupWizard) (WifiSettingsForSetupWizardXL)getActivity().onAcsPosUpdated(getPreferencreen(), acsPos); else for (AcsPoacsPo: acsPos) getPreferencreen().addPreference(acsPo);private void hand

10、leEvent(Context context,entent) String action =ent.getAction();if (WifiManager.WIFI_SE_CHANGED_ACTION.equalion) updateWifiSe(ent.getExtra(WifiManager.EXTRA_WIFI_SE,WifiManager.WIFI_SE_UNKNOWN); else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equalion) | WifiManager.CONFIGURED_NETWORKS_CHANGED_ACT

11、ION.equalion) | WifiManager.LINK_CONFIGURATION_CHANGED_ACTION.equalion) updateAcsPos(); else if (WifiManager.SUPPLICANT_SE_CHANGED_ACTION.equalion) if (!mConnected.get() updateConnectionSe(WifiInfo.getDetailedSeOf(SupplicantSe) ent.getParcelableExtra(WifiManager.EXTRA_NEW_SE);if (mInXlSetupWizard) (

12、WifiSettingsForSetupWizardXL)getActivity().onSupplicantSeChanged(ent); else if (WifiManager.NETWORK_SE_CHANGED_ACTION.equalion) NetworkInfo info = (NetworkInfo)ent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); mConnected.set(info.isConnected(); changeNextButtonSe(info.isConnected(); updateAcsP

13、os();updateConnectionSe(info.getDetailedSe();.成功開啟 WIFI,即 getWifiSe()返回為 WIFI_SE_ENABLED 時(shí)首先會(huì)調(diào)用 constructAcsPos(),在這個(gè)方法中調(diào)用 mWifiManager.getConfiguredNetworks()與 mWifiManager.getScanResults()來(lái)分別獲取已保存與可用的 WIFI 熱點(diǎn)網(wǎng)絡(luò),接著判斷 mInXlSetupWizard 并調(diào)用 onAcsPosUpdated()或 addPreference(acsPo),這兩者的操作都是往頁(yè)面添加顯示搜索到的 W

14、IFI 熱點(diǎn)網(wǎng)絡(luò),區(qū)別只是調(diào)用者是不是大屏或平板電腦( mInXlSetupWizard 意思為是否為大屏幕的設(shè)置向?qū)В@個(gè)結(jié)論由長(zhǎng)時(shí)間分析所得!*_*,XL=XLarge )。AcsPos的構(gòu)造函數(shù)有三個(gè),代碼如下:上面的兩個(gè)構(gòu)造函數(shù)分別針對(duì)調(diào)用 mWifiManager.getConfiguredNetworks()與 mWifiManager.getScanResults()得來(lái)的結(jié)果調(diào)用 loadConfig(WifiConfiguration config)與 loadResult(ScanResult result),經(jīng)過(guò)這一步后,AcsPos的成員變量也初始化完了,然后調(diào)用 re

15、fresh()方法進(jìn)行刷新顯示操作,代碼我就不帖了,主要就是設(shè)置顯示,,信號(hào)強(qiáng)度等。顯示工作做完后,的重點(diǎn)應(yīng)用轉(zhuǎn)向 WIFI 熱點(diǎn)網(wǎng)絡(luò)點(diǎn)擊事件的處理。的點(diǎn)擊事件的處理同樣在 WifiSettings.java 文件中,代碼如下:AcsPo(Context context, WifiConfiguration config) super(context); setWidgetLayoutResource(R.layout.preference_widget_wifi_signal); loadConfig(config);refresh();AcsPo(Context context, Scan

16、Result result) super(context);setWidgetLayoutResource(R.layout.preference_widget_wifi_signal); loadResult(result);refresh();AcsPo(Context context, Bundle savedSe) super(context);setWidgetLayoutResource(R.layout.preference_widget_wifi_signal);mConfig = savedSe.getParcelable(KEY_CONFIG); if (mConfig !

17、= null) loadConfig(mConfig);mScanResult = (ScanResult) savedSe.getParcelable(KEY_SCANRESULT); if (mScanResult != null) loadResult(mScanResult);mInfo = (WifiInfo) savedSe.getParcelable(KEY_WIFIINFO); if (savedSe.containsKey(KEY_DETAILEDSE) mSe = DetailedSe.valueOf(savedSe.getString(KEY_DETAILEDSE);up

18、date(mInfo, mSe);break;.這段代碼很簡(jiǎn)單,如果WIFI 沒(méi)有加密,直接調(diào)用 mSelectedAc個(gè)不加密的WifiConfiguration,代碼如下:sPo.generateOpenNetworkConfig()生成一代碼首先new 了一個(gè)WifiConfiguration 賦值給mConfig,然后設(shè)置allowedKeyManagement 為KeyMgmt.NONE表示不使用加密連接,這個(gè)工作做完成后就調(diào)用了 mWifiManager 的 connectNetwork()方法進(jìn)行連接,看這個(gè)方法的父親可以發(fā)現(xiàn)是WifiManager,居然是 WifiManage

19、r,可這個(gè)方法卻沒(méi)有導(dǎo)出!繼續(xù)分析,如果是加密的 WIFI,就調(diào)用 showConfigUi()方法來(lái)顯示輸入框,對(duì)于大屏, 即mInXlSetupWizard 為真時(shí),調(diào)用了 WifiSettingsForSetupWizardXL 類的 showConfigUi()方法,如果為假就直接調(diào)用 showDialog(acsPo, edit)顯示框,代碼如下:private void showDialog(AcsPoacsPo,edit) if (mDialog != null) removeDialog(WIFI_DIALOG_ID); mDialog = null;/ Save the ac

20、s poand edit mode mDlgAcsPo= acsPo; mDlgEdit = edit; showDialog(WIFI_DIALOG_ID);Overrideprotected void generateOpenNetworkConfig() if (security != SECURITY_NONE)throw new IllegalSeException(); if (mConfig != null)return;mConfig = new WifiConfiguration();mConfig.= AcsPo.convertToQuotedString(); mConf

21、ig.allowedKeyManagement.set(KeyMgmt.NONE);OverridepubliconPreferenceTreeClick(Preferencreen screen, Preference preference) if (preference instanceof AcsPo) mSelectedAcsPo= (AcsPo) preference;/* Bypass dialog for unsecured, unsaved networks */if (mSelectedAcsPo.security = AcsPo.SECURITY_NONE & mSelec

22、tedAcsPworkId = INVALID_NETWORK_ID) mSelectedAcsPo.generateOpenNetworkConfig(); mWifiManager.connectNetwork(mSelectedAcsPo.getConfig(); else showConfigUi(mSelectedAcsPo, false); else return super.onPreferenceTreeClick(screen, preference);return true;這段代碼保存 acsPo后就調(diào)用 showDialog(WIFI_DIALOG_ID)了,在 onC

23、reateDialog()初始化方法中判斷 mDlgAcsPo是否為 null,如果為 null 就調(diào)用 AcsPo的第三個(gè)構(gòu)造方法從保存的狀態(tài)中生成一個(gè)AcsPo,最后 new WifiDialog(getActivity(), this, ap, mDlgEdit)生成一個(gè) WifiDialog,這個(gè) WifiDialog 繼承自AlertDialog ,也 就是 它, 最終將 Dialogerface.OnClickListener 的應(yīng)代碼,馬上就到關(guān)鍵啰!框展現(xiàn)在 面前 , WifiDialog 構(gòu)造 函數(shù) 的第二 個(gè)參 數(shù) 為器,設(shè)置為 this 表示類本身對(duì)按鈕點(diǎn)擊事件進(jìn)行響應(yīng),

24、接下來(lái)找找事件響代碼判斷彈出的框是WIFI 熱點(diǎn)拋棄還是WIFI 連接,并做出相應(yīng)的處理,這里看看 submit()方法的代碼:void submit(WifiConfigController configController) networkSetup = configController.chosenNetworkSetupMethod(); switch(networkSetup) case WifiConfigController.WPS_PBC:case WifiConfigController.WPS_DISPLAY:case WifiConfigController.WPS_KE

25、YPAD: mWifiManager.startWps(configController.getWpsConfig(); break;case WifiConfigController.MANUAL:final WifiConfiguration config = configController.getConfig();public void onClick(Dialogerface dialogerface,button) if (mInXlSetupWizard) if (button = WifiDialog.BUTTON_FET & mSelectedAcsPo!= null) fe

26、t(); else if (button = WifiDialog.BUTTON_SUBMIT) (WifiSettingsForSetupWizardXL)getActivity().onConnectButtonPressed(); else if (button = WifiDialog.BUTTON_FET & mSelectedAcsPo!= null) fet(); else if (button = WifiDialog.BUTTON_SUBMIT) submit(mDialog.getController();public Dialog onCreateDialog(dialo

27、gId) AcsPoap = mDlgAcsPo; / For manual launch if (ap = null) / For re-launch from saved seif (mAcsPoSavedSe != null) ap = new AcsPo(getActivity(), mAcsPoSavedSe);/ For repeated orienion changes mDlgAcsPo= ap;/ If its still null, fine, its for Add Network mSelectedAcsPo= ap;mDialog = new WifiDialog(g

28、etActivity(), this, ap, mDlgEdit); return mDialog;關(guān)鍵代碼終于找到了,那個(gè)叫激動(dòng)啊 T_T!按鈕事件首先對(duì) WIFI 網(wǎng)絡(luò)加密類型進(jìn)行判斷,是 WPS 的就調(diào)用mWifiManager.startWps(configController.getWpsConfig(),是手動(dòng)設(shè)置就調(diào)用被點(diǎn)擊 AcsPo項(xiàng)的 getConfig()方法WifiConfiguration 信息,如果不為 null 調(diào)用 connectNetwork(mSelectedAcsPworkId)連接網(wǎng)絡(luò),為 null 說(shuō)明可能是 AcsPosaveNetwork()的代碼

29、:調(diào)用第二個(gè)構(gòu)造函數(shù)使用 ScanResult 生成的,則調(diào)用 saveNetwork(config),看看調(diào)用的 mWifiManager.saveNetwork(config)方法,這個(gè)方法同樣在SDK 中沒(méi)有導(dǎo)出,到源碼中找找,最終在源代碼的“frameworksbasewifijavaandroidnetwifiWifiManager.java”文件中找到是通過(guò)向自身發(fā)送消息的方式調(diào)用了WifiS eMachine.java-WifiConfigStore.java-saveNetwork()方法,最終保存 WIFI 網(wǎng)絡(luò)后發(fā)送了一個(gè)已配置網(wǎng)絡(luò)變更廣播,這里由于篇幅就不再展開了。分析到

30、這里,大概了解了 WIFI 連接的整個(gè)流程,程序無(wú)論是否為加密的 WIFI 網(wǎng)絡(luò),最終調(diào)用 WifiManager的 connectNetwork()方法來(lái)連接網(wǎng)絡(luò)。而這個(gè)方法在 SDK 中卻沒(méi)有導(dǎo)出,馬上回來(lái).該如何解決這個(gè)問(wèn)題,一杯茶后,private void saveNetwork(WifiConfiguration config) if (mInXlSetupWizard) (WifiSettingsForSetupWizardXL)getActivity().onSaveNetwork(config); else mWifiManager.saveNetwork(config);i

31、f (config = null) if (mSelectedAcsPo!= null& !requireKeyStore(mSelectedAcsPo.getConfig()& mSelectedAcsPworkId != INVALID_NETWORK_ID) mWifiManager.connectNetwork(mSelectedAcsPworkId); else if (workId != INVALID_NETWORK_ID) if (mSelectedAcsPo!= null) saveNetwork(config); else if (configController.isEd

32、it() | requireKeyStore(config) saveNetwork(config); else mWifiManager.connectNetwork(config);break;if (mWifiManager.isWifiEnabled() mScanner.resume();updateAcsPos();connectNetwork()方法我始終不明白安卓SDK 中為什么不開放 connectNetwork 這個(gè)接口,但現(xiàn)在需要用到了,也只能接著往下面分析,WifiManager 是 Framework 層的,接下來(lái)的探索移步到安卓源碼“frameworksbasewi

33、fijavaandroidnetwifi”目錄中去,在 WifiManager.java 中搜索“connectNetwork”,代碼如下:注意看注釋部分!“對(duì)于一個(gè)新的網(wǎng)絡(luò),這個(gè)函數(shù)相當(dāng)于陸續(xù)調(diào)用了addNetwork(), enableNetwork(),saveConfiguration() 與 reconnect()”。看到這句話,心里可美了,因?yàn)檫@四個(gè)函數(shù)在 SDK 中都有導(dǎo)出,在代碼中分別調(diào)用它們不就達(dá)到調(diào)用connectNetwork 的目的了么?繼續(xù)分 析代 碼,如 果 config 不為 空, connectNetwork 就通 過(guò) mAsyncChannel 發(fā)送 了一 條

34、“CMD_CONNECT_NETWORK”的消息,mAsyncChannel 的如下:從注釋上理解,這個(gè)東西是用來(lái)與 WifiService 通信的。WifiService 屬于 Framework 底層的服務(wù),位于源碼“frameworksbaseservijavacomandroidserver”目錄,找到代碼如下:Overridepublic void handleMessage(Message msg) switch (msg.what) .case WifiManager.CMD_CONNECT_NETWORK: if (msg.obj != null) mWifiSeMachine

35、.connectNetwork(WifiConfiguration)msg.obj); else mWifiSeMachine.connectNetwork(msg.arg1);break;./* For communication with WifiService */private AsyncChannel mAsyncChannel = new AsyncChannel();/*Connect to a network with the given configuration. The network alsogets added to the supplicant configurat

36、ion.*For a new network, this function is used instead of asequence of addNetwork(), enableNetwork(), saveConfiguration() andreconnect()*param config the set of variablest describe the configuration,contained in a link WifiConfiguration object.hide*/public void connectNetwork(WifiConfiguration config

37、) if (config = null) return;mAsyncChannel.sendMessage(CMD_CONNECT_NETWORK, config);在 handleMessage()方法中有很多消息處理,這里由于篇幅只列出了 CMD_CONNECT_NETWORK,可以看出這 WifiService 就是個(gè)“托”,它只是將“”重新轉(zhuǎn)給 mWifiSeMachine 處理,mWifiSeMachine 為WifiSeMachine 類,代碼和 WifiManager 在同一目錄,找到 connectNetwork 代碼如下:真有才了!還在發(fā)消息,只不過(guò)是給自已發(fā),懷疑這寫 WI

38、FI 模塊的是不是 90 后,這一層層繞的不頭暈?找到處理代碼如下:OverridepublicprosMessage(Message message) .case CMD_CONNECT_NETWORK:netId = message.arg1;WifiConfiguration config = (WifiConfiguration) message.obj;/* We connect to a specific network by iing a selectto the WifiConfigStore. This enables the network,while disabling

39、all other networkshe supplicant.Disabling a connected network will cause a disconnectionfrom the network. Amand() will then initiatea connection to the enabled network.*/if (config != null) netId = WifiConfigStore.selectNetwork(config); else WifiConfigStore.selectNetwork(netId);/* The se tracker han

40、dles enabling networks upon completion/failure */ mSupplicantSeTracker.sendMessage(CMD_CONNECT_NETWORK);Wifand();mLastExplicitNetworkId = netId;mLastNetworkChoiceTime= SystemClock.elapsedRealtime(); mNextWifiActionExplicit = true;if (DBG) log(Setting wifi connect explicit for netid + netId);/* Expec

41、t a disconnection from the old connection */public void connectNetwork(netId) sendMessage(obtaessage(CMD_CONNECT_NETWORK, netId, 0);public void connectNetwork(WifiConfiguration wifiConfig) /* arg1 is used to indicate netId, force a netId value ofWifiConfiguration.INVALID_NETWORK_ID when we are passi

42、nga configuration since the default value of 0 is a valid netId*/sendMessage(obtaessage(CMD_CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID, 0, wifiConfig);注釋中說(shuō):通過(guò) WifiConfigStore 的 selectNetwork()方法連接一個(gè)特定的網(wǎng)絡(luò),當(dāng)禁用 supplicant 中其它所有網(wǎng)絡(luò)時(shí),會(huì)連接網(wǎng)絡(luò),而禁用一個(gè)已經(jīng)連接的網(wǎng)絡(luò),將會(huì)始化并連接已啟用的網(wǎng)絡(luò)。disconnection 操作,mand()方初sel

43、ectNetwork()過(guò)后,mSupplicantSeTracker 發(fā)送了一條 CMD_CONNECT_NETWORK 消息,它其實(shí)只做了一件事,就是將“mNetworksDisabledDuringConnect ”設(shè)為 true。最后 Wif絡(luò)進(jìn)行重新連接,至此,WIFI 的連接過(guò)程就完畢了,下面看看 selectNetwork()代碼:and()對(duì)網(wǎng)代碼都在這里了,不帖了,帖了太多了,這段代碼流程為 addOrUpdateNetworkNative()先保存一個(gè),sicselectNetwork(WifiConfiguration config) if (config != null

44、) NetworkUpdateResult result = addOrUpdateNetworkNative(config); netId = result.getNetworkId();if (netId != INVALID_NETWORK_ID) selectNetwork(netId); else loge(Failed to update network + config);return netId;return INVALID_NETWORK_ID;sic void selectNetwork(netId) / Reset the priority of each network

45、 at start or if it goes too high. if (sLastPriority = -1 | sLastPriority 1000000) synchronized (sConfiguredNetworks) for(WifiConfiguration config : sConfiguredNetworks.values() if (workId != INVALID_NETWORK_ID) config.priority = 0; addOrUpdateNetworkNative(config);sLastPriority = 0;/ Set to the high

46、est priority and save the configuration. WifiConfiguration config = new WifiConfiguration(); workId = netId;config.priority = +sLastPriority;addOrUpdateNetworkNative(config); WifiNamand();enableNetworkWithoutBroadcast(netId, true);transitionTo(mDisconnectingSe); break;.mand()然后對(duì)已保存的網(wǎng)絡(luò)優(yōu)先級(jí)降下來(lái),這是為了讓新網(wǎng)絡(luò)

47、擁有更高的優(yōu)先連接權(quán),接著執(zhí)行將配置信息保存,這里的保存操作在底層是將網(wǎng)絡(luò)信息保存到了“/data/misc/wifi/最后 enableNetworkWithoutBroadcast(netId, true)啟用本網(wǎng)絡(luò)并禁用其它網(wǎng)絡(luò)。_supplicant.conf”文件中,小結(jié)一下connectNetwork 的執(zhí)行步驟為“WifiConfigStore.selectNetwork()”-“addOrUpdateNetworkNative( )” - “其 它網(wǎng)絡(luò) 降級(jí) 并設(shè)置 自已 最高 優(yōu)先 級(jí)” - “ WifiNamand() ” -“enableNetworkWithoutBro

48、adcast(netId, true);”-“Wif或失敗”。既然 connectNetwork 的執(zhí)行步驟現(xiàn)在清楚了,那and()”-“通過(guò)廣播判斷連接成功自己實(shí)現(xiàn)它便可以完成 WIFI動(dòng)連接了,代碼編寫WIFI器的編寫有三種思路:第一種就是上面說(shuō)的自己動(dòng)手實(shí)現(xiàn)connectNetwork,按照 SDK 中常規(guī)步驟連接WIFI,本文采用此方法。第二種就是參看WIFI 的連接代碼,通過(guò)NDK 方式自己實(shí)現(xiàn)WIFI 底層操作的調(diào)用,這種方法本文不介紹。第三種方法同樣通過(guò)NDK 方式,但優(yōu)雅些。在上面的分析中,我沒(méi)有提到安卓 WIFI 的_supplicant,它作為安卓 WIFI 的一個(gè)組件存在

49、,為安卓系統(tǒng)提供了、2 等加密網(wǎng)絡(luò)的連接支持。在系統(tǒng)的“/system/bin”目錄中,有“_supplicant”與“_cli”兩個(gè)文件,前者是一個(gè)服務(wù),客戶端通過(guò)它控制無(wú)線網(wǎng)卡,如發(fā)送 AP 掃描指令、提取掃描結(jié)果、關(guān)聯(lián) AP 操作等。后者是一個(gè)命令行工具,用來(lái)與通信,在正常啟動(dòng)_supplicant 服務(wù)后執(zhí)行下面的指令便可以連接上WIFI 網(wǎng)絡(luò):_supplicant_cli -iwlan0 add_network_cli -iwlan0 set_network 1/ 增加一個(gè)網(wǎng)絡(luò),會(huì)返回一個(gè)網(wǎng)絡(luò)號(hào),假設(shè)為 1/為要連接的網(wǎng)絡(luò)名_cli -iwlan0 set_network 1 ps

50、k _cli -iwlan0 enable_network 1_cli -iwlan0 select_network 1_cli -iwlan0 save_config/psk 為連接的/以下三條與上面 connectNetwork 分析功能一致但實(shí)際上,通過(guò)命令行啟動(dòng)_supplicant 卻不能成功,因?yàn)樾枰燃虞d WIFI 驅(qū)動(dòng),然后才能啟用_supplicant 服務(wù)。在WLAN 設(shè)置中啟用WIFI 后,會(huì)調(diào)用 WifiManager.setWifiEnabled,這個(gè)方依次調(diào)用 WifiNative.loadDriver()-WifiNative.startSupplicant()。

51、在加載成功后會(huì)設(shè)置一個(gè)延遲時(shí)間,到延遲時(shí)間后就會(huì)調(diào)用 WifiNative.stopSupplicant()-WifiNative.unloadDriver()停止_supplicant 服務(wù)并卸載驅(qū)動(dòng),這是為了給設(shè)備省電,因?yàn)?WIFI 驅(qū)動(dòng)長(zhǎng)時(shí)間加載很耗電的。命令行本身無(wú)法直接加載驅(qū)動(dòng),導(dǎo)致了_supplicant 無(wú)法成功開啟,這也是無(wú)法通過(guò)命令行直接連接 WIFI的原因,但并不是沒(méi)有突破方法!可以寫代碼并使用 NDK 方式調(diào)用 WifiNative.loadDriver() ,接著啟用_supplicant 服務(wù),服務(wù)加載成功后執(zhí)行上面的_cli 命令行,就可以輕松連接 WIFI 了。

52、可以直接寫一個(gè)原生的 bin,實(shí)現(xiàn)驅(qū)動(dòng)加載及 WIFI 連接,然后在安卓代碼中直接以創(chuàng)建進(jìn)程的方式啟動(dòng)或者在 s中執(zhí)行等方式運(yùn)行。這些方法都具有可行性,本文不做深入探討,只采用文中介紹的第法來(lái)完成程序的功能。目前 WIFI 加密種類常用的有、2、EAP 等,WifiManager 將與 EAP 做了消化,2 則使用_supplicant 進(jìn)行管理,目前,由于與戶采用的安全性問(wèn)題,使用的人已經(jīng)不多了,一般用與2 方式接入較多,在今天的程序中,也只處理了這兩種加密的情況。按照上面的分析思路,代碼實(shí)現(xiàn)應(yīng)該很明了了,但實(shí)際編碼過(guò)程中還是存在著諸多問(wèn)題,首先是停止掃描的問(wèn)題,在WifiManager 中

53、沒(méi)有提供 stopScan()方法,而是在其中通過(guò)一個(gè)繼承自Handler 的SCanner 來(lái)管理,目前來(lái)說(shuō),我沒(méi)想到解決方案,在開始跑 WIFI的過(guò)程中,WIFI 掃描線程一直還是開著,通過(guò)一個(gè) cracking 的布爾值判斷來(lái)界面的更新,這個(gè)問(wèn)題可能在 SDK 層無(wú)法得到解決。第二個(gè)問(wèn)題是一些類的枚舉值,如 SupplicantSe.AUTHENTICATING、KeyMgmt.2_PSK 等在SDK 中都是沒(méi)導(dǎo)出的,要想使用就需要自己添加。談到2_PSK,很有必要講一下 WifiConfiguration 類的構(gòu)造,連接 WIFI 前需要先構(gòu)造這個(gè)類,然后通過(guò) addNetwork()

54、添加網(wǎng)絡(luò)操作后才能進(jìn)行下一步的連接,在網(wǎng)上搜索到的連接代碼如下:.在測(cè)試初期我是直接搬這代碼來(lái)用的,實(shí)際上這代碼是廢的,根本連接不上任何的 WIFI,狀態(tài)代碼顯示一直停留在關(guān)聯(lián) AP 中,而且這樣設(shè)置 WifiConfiguration 后在設(shè)置中也無(wú)法開啟使用 WIFI 了,當(dāng)時(shí)我也很納悶,你都不能用的代碼,怎么還在網(wǎng)上好多篇帖子里亂竄?后來(lái)如下:WIFI 連接的過(guò)程后,整理出的代碼代碼比上面的些,這不該有的東西啊你堅(jiān)決不能有!啟動(dòng) Eclipse 新建一個(gè)WIFICracker 的工程,OnCreate()方法代碼如下:public void onCreate(Bundle savedIn

55、stane) public void onCreate(Bundle savedInstane) super.onCreate(savedInstan try passwordGetter = nee);sswordGetter(/sdcard/password.txt); catch (FileNotFoundException e) showMessageDialog( 程序初始化失敗, 請(qǐng)將字典放到 SD 卡目錄并更名為.if (security = SECURITY_PSK) mConfig = new WifiConfiguration();mConfig.= AcsPo.conve

56、rtToQuotedString();if (pskType = PskType.) mConfig.allowedProtocols.set(WifiConfiguration.Protocol.);else if (pskType = PskType.2) mConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);mConfig.priority = 1;mConfig.sus = WifiConfiguration.Sus.ENABLED; mConfig.= ;mConfig.preSharedKey = password

57、;netid = wm.addNetwork(mConfig); wm.enableNetwork(netid, false);.mConfig = new WifiConfiguration();mConfig.sus = WifiConfiguration.Sus.ENABLED; mConfig.hidden= false;mConfig.= ; mConfig.preSharedKey = password;mConfig.allowedAulgorithms.set(Aulgorithm.OPEN); mConfig.allowedKeyManagement.set(KeyMgmt.

58、_PSK); mConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN); mConfig.allowedPairwiseCiphers.set(PairwiseCipher.CCMP); mConfig.allowedPairwiseCiphers.set(PairwiseCipher.TKIP); mConfig.allowedGroupCiphers.set(GroupCipher.CCMP); mConfig.allowedGroupCiphers.set(GroupCipher.TKIP);netid = wm.addNe

59、twork(mConfig); wm.enableNetwork(netid, false);.deleteSavedConfigs()方法將已存的 Config 中全部刪除,原因是因?yàn)槿绻呀?jīng)保存了正確的WIFI 連接,程序運(yùn)行會(huì)無(wú)法工作,具體代碼參看附件。然后構(gòu)造一個(gè) PasswordGetter 對(duì)象,它用來(lái)讀取/sdcard/password.txt文件每一行作為 WIFI 的探測(cè),類的完整代碼如下:public class PasswordGetter private String password; private File file;private FileReader read

60、er;private BufferedReader br;public PasswordGetter(String passwordFile) password = null;try /File file = new File(/sdcard/password.txt); file = new File(passwordFile);if (!file.exists()throw new FileNotFoundException(); reader = new FileReader(file);br = new BufferedReader(reader); catch (FileNotFou

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論