1
対象シーン
私は、友人に連絡し、あなたが削除した長い時間前にお互いを見つけるのに長い時間を連絡したくない、あなたが経験していないかわからないが、あなたはについて何も知りません。
私はあなたが他の当事者や友人を思い、それは、本当にあまりにもナイーブ若すぎる、誰もがマイクロチャネルのアドレス帳に、いくつかの「ゾンビパウダー」があることを信じて、彼らはサイレント連絡先リストを築く;実際には、他の側からしなければなりませんフレンドリスト、そしてどのようにこれらの人々が行うフィルタリングするために削除?
それは毎回のマイクロチャネル通信で友達がお互いに「わざわざ」深刻検出するために、録音されたメッセージを送信するのテスト、オンラインツールのゾンビパウダーの多数を検出し、検出時のソフトウェアの別の部分、ウイルスは、いくつかのコードに移植されますブラックボックスの操作は非常に安全なようです。
この記事の目的は、ゾンビパウダーのすべてをフィルタリングする「転送友人にシミュレーション」、およびそれらを除去するためのキーによって、マイクロ手紙アプリケーションを自動化することです。
2
準備
スクリプトを書き始める前に、次の準備を行います
- ルート後のAndroid携帯電話やエミュレータ、根なし機器が推奨されていない場合、網易MUMUシミュレータ
- Androidの開発環境、Androidのメーカー
- sqlcipherグラフィカルツール
- 自動化ツール:Pythonのは、仮想環境下でインストールされているpocoui
3
スクリプティング
全体の動作は、マイクロクラックが、ゾンビパウダー得られたアナログデータを転送するすべてのゾンビ粉末を除去するために、友人を通信チャネルデータベースカタログの友人を選択している、3つのステップに分割されます。
最初のステップは、我々は、マイクロチャネルのAppデータベースをクラックする必要があります。
PS:ここだけの簡単なスピーチは、マイクロチャネルのアドレス帳データを解読するためのキーのように、あなたは、このステップをスキップして、提供品のAPKエンドを使用することができ、プロセスをクラックすることです。
まず、我々は、新しいプロジェクト、プロジェクトの初期設定を作成するアプリケーションの管理者権限を付与し、にマイクロチャネルアクセス権を変更するには、Android Studioを使用します。
// 微信のApp的目录 のpublic static final String型WX_ROOT_PATH = " /data/data/com.tencent.mm/ " 。 / ** * 执行Linuxの指令 * * @paramのparamString * / パブリック静的な無効execRootCmd(文字列のparamString) { しようと { プロセスlocalProcess = Runtime.getRuntime()。EXEC(" SU " )。 オブジェクトlocalObjectに = localProcess.getOutputStream()。 DataOutputStreamをlocalDataOutputStream = 新しいDataOutputStreamを((OutputStreamの)localObjectに)。 文字列str =String.valueOf(のparamString)。 localObjectに = STR + " \ nを" ; localDataOutputStream.writeBytes((String)をlocalObjectに)。 localDataOutputStream.flush(); localDataOutputStream.writeBytes(" 終了\ nを" ); localDataOutputStream.flush(); localProcess.waitFor(); localObjectに = localProcess.exitValue()。 }キャッチ(例外localException) { localException.printStackTrace()。 } } // 获取权限 RootUtils.execRootCmd(" chmodの777 -R " + WX_ROOT_PATH)。
その後、マイクロ文字のパスワードデータベースを取得します。
パスワードデータベースは、生成MD5アルゴリズムを介してマイクロチャネル及びマイクロチャネルUID IMEI供給装置です。
/ ** * IMEIとUIN MD5コード生成、パスワードデータベースへのアクセス(前7つの小文字に) * * @paramのIMEI * @paramのUINの *の@の復帰 * / パブリック静的文字列getDbPassword(IMEI文字列、文字列UIN ) { IF(TextUtils.isEmpty(IMEI)|| TextUtils.isEmpty(UIN)) { Log.d(" XAG "、" 失敗したデータベースのパスワードを初期化する:UID空またはIMEI " ); 戻り " パスワードエラー" ; } ストリングMD5 = MD5Utils.md5(IMEI + UIN); アサート!MD5 = NULL; リターンmd5.substring(0 ,. 7 ).toLowerCase(); } #Pythonの学習交換基631441315
その後、あなたはマイクロチャネルのデータベースを照会するSQLCipher依存ライブラリを使用することができ、我々は、データベースを操作しやすく、プロジェクトのために、次の依存関係を追加する必要があります。
// 私たちは、プロジェクトへの依存増やす必要が 実装「net.zetetic:アンドロイド-データベース-sqlcipherを:3.5.4@aar 」
マイクロチャネル、ニックネーム、ユーザー名やその他のデータ内の微小信号コンタクトのすべての友人のための暗号化されたデータベースとクエリ「rcontact」テーブルを開くためのパスワードで上記で得られました。
/ ** * 接続されたデータベース * <P> * []接触rcontactテーブル、テーブル[メッセージ]メッセージチャット:共有ライブラリの紹介 * * @param DBFILE * / プライベート無効openWxDb(ファイルDBFILE、文字列のdb_pwd) { // すべての情報人々の リスト <名刺> =新しい新しい連絡先のArrayList <> (); SQLiteDatabase.loadLibs(この); SQLiteDatabaseHookフックは = 新しい新しいSQLiteDatabaseHook() { 公共ボイドprekey(SQLiteDatabaseデータベース) { } 公共ボイドpostKey(SQLiteDatabaseデータベース) { atabase.rawExecSQL(" プラグマcipher_migrate; "); //2.0互換性のあるデータベース } }; 試み { // オープンデータベースコネクティビティ SQLiteDatabase DB = SQLiteDatabase.openOrCreateDatabase(DBFILE、db_pwd、ヌル、フック); // クエリすべての連絡先 // 自分自身をフィルタリング、グループチャット、パブリック番号、サービス番号そして、いくつかの連絡先 // verifyFlag =!0:公共番号、サービス番号 //注意ブラックリストユーザー、I -設定-プライバシー- 連絡先がブラックリスト カーソルC1 = db.rawQuery( " = 0 RcontactからSELECT *とWHERE verifyFlag (2,4,8,9,33,35,256,258,512,2051,32768,32770,32776,33024,65536,65792,98304)ではありません入力したユーザー名 \「%の@アプリの\」と名ません\のような「%を好きではありません@qqim \ "ではなくユーザー名\のような" %の@のチャットルーム\ "とencryptUsername = \!" \ " " 、 NULL); 一方、(c1.moveToNext()) { 文字列のuserName = c1.getString(c1.getColumnIndex(" ユーザ名" )); ストリング別名 = c1.getString(c1.getColumnIndex(" エイリアス" ))。 ストリングニックネーム = c1.getString(c1.getColumnIndex(" ニックネーム" ))。 int型 = c1.getInt(c1.getColumnIndex(" タイプ" ))。 contacts.add(新しい連絡先(ユーザ名、エイリアス、ニックネーム)); } Log.d(" XAG "、" 微信通讯录中、联系人数目:"Contacts.size +()+ " 番目" ) のための I ++は、(; Iは、(contacts.sizeを<I = 0の整数)) { Log.d(" XAG " 、contacts.get(I).getNickName())。 } c1.close(); db.Close(); }キャッチ(例外E) { Log.e(" XAG "、" データベース情報を読み取りに失敗しました" + e.toString()); Toast.makeText(この、" 記録されたマイクロチャネルの通信障害を読んで!「Toast.LENGTH_SHORT)が.SHOW(); } Toast.makeText(この、」成功したマイクロチャネルのアドレス帳を読んでください!」、Toast.LENGTH_SHORT).SHOW(); }
それは友人の正常なデータに加えて、友人をブラックリスト、データベーステーブル内のデータがrcontactより厄介なことに留意すべきである、友人がデータを削除し、公共の数、マイクロ文字や他のグループにも含まれている、我々はタイプとverifyFlagフィールドでスクリーニングする必要があります。
操作のPythonを容易にするために、そして最終的に友人のcsvファイルへのデータのクエリを書き込みます。
/*** * 写入数据到csv中 * @param output_path * @param contacts */ public static void writeCsvFile(String output_path, List<Contact> contacts) { try { File file = new File(output_path); //删除之前保存的文件 if (file.exists()) { file.delete(); } BufferedWriter bw = new BufferedWriter(new FileWriter(file, true)); // 添加头部名称 bw.write("userName" + "," + "alias" + "," + "nickName"); bw.newLine(); for (int i = 0; i < contacts.size(); i++) { bw.write(contacts.get(i).getUserName() + "," + contacts.get(i).getAlias() + "," + contacts.get(i).getNickName()); bw.newLine(); } bw.close(); } catch (IOException e) { e.printStackTrace(); } }
第 2 步,我们需要模拟给好友转账,来判断这个好友关系是否正常。
首先,我们需要初始化 Airtest,然后利用 adb 把第 1 步生成的数据从手机里导出到本地。
def __init_airtest(self): """ 初始化Airtest :return: """ device_1 = Android('822QEDTL225T7') # device_1 = Android('emulator-5554') connect_device("android:///") self.poco = AndroidUiautomationPoco(device_1, screenshot_each_action=False) auto_setup(__file__) def export_wx_db_from_phone(target_path): """ 从手机中导出通信录数据 :param target_path: :return: """ # 微信通信录数据 wx_db_source_path = "/data/data/com.xingag.crack_wx/wx_data.csv" # 导出到本地 os.popen('adb pull %s %s' % (wx_db_source_path, target_path))
然后就是一系列自动化操作。
打开微信,遍历好友列表,拿到每一个好友的微信号去搜索好友,跳转到好友的聊天界面。
def __to_friend_chat_page(self, weixin_id): """ 点击到一个好友的聊天界面 :param weixin_id: :param weixin_name: :return: """ # 1、点击搜索 element_search = self.__wait_for_element_exists(self.id_search) element_search.click() print('点击搜索') # 2、搜索框 element_search_input = self.__wait_for_element_exists(self.id_search_input) element_search_input.set_text(weixin_id) # 3、搜索列表 element_search_result_list = self.__wait_for_element_exists(self.id_search_result_list) # 3.1 是否存在对应的联系人,如果存在就在第一个子View布局下 # 注意:可能出现最常用的聊天列表,这里需要进行判断 index_tips = 0 for index, element_search_result in enumerate(element_search_result_list.children()): # 联系人的Tips # if element_search_result_list.children()[0].offspring(self.id_contact_tips).exists(): if element_search_result.offspring(text=self.text_contact_tips).exists(): index_tips = index break # 4、点击第一个联系人进入聊天界面 element_search_result_list.children()[index_tips + 1].click()
接着尝试着给对方转账,如果好友关系正常,就会跳出一个支付页面让输入密码。
def __judge_is_friend(self, weixin_id, weixin_name): """ 判断是不是微信好友 :param weixin_id: 微信号 :return: """ # 尝试给好友转账,设置一个小额度,以防止刷脸直接支付了 # 如果对方是你的好友,接下来会让你输入密码,关掉页面就行了 # 如果对方不是你的好友,会提示不是你的好友,不能继续操作了 # 5、点击好友界面的+按钮 self.poco(self.id_chat_more_button).click() # 6、点击转账按钮 self.poco(self.id_chat_more_container).offspring(text=self.text_chat_transfer_account_text).click() # 7、输入金额 self.poco(self.id_transfer_account_input).set_text(self.money) # 8、点击转账按钮 self.poco(self.id_transfer_account_container).offspring(text=self.text_chat_transfer_account_text).click()
如果是僵尸粉,应用会弹出一个警告对话框,提示你不是收款方好友,没法完成转账的操作。
通过警告对话框是否存在,就可以判断好友关系是否正常。 非正常的好友关系,包含:僵尸粉、对方账号异常等。
# 10.弹出警告对话框 # 弹出好友关系不正常 if element_transfer_account_result_button: # 提示内容 ransfer_account_result_tips = self.poco(self.id_transfer_account_result_tips).get_text() if self.text_friend_no_tips in transfer_account_result_tips: print('注意!%s已经把你拉黑了!!!' % weixin_name) self.friend_black_list.append({ 'id': weixin_id, 'nickName': weixin_name }) write_to_file(self.path_black_list, 'id:%s,nickName:%s' % (weixin_id, weixin_name)) elif self.text_friend_limit_tips in transfer_account_result_tips: print('%s账号收到限制!!!' % weixin_name) write_to_file(self.path_account_limit, 'id:%s,nickName:%s' % (weixin_id, weixin_name)) elif self.text_friend_is_norm in transfer_account_result_tips: print('%s好友关系不正常!!!' % weixin_name) write_to_file(self.path_relationship_unnormal, 'id:%s,nickName:%s' % (weixin_id, weixin_name)) # 点击确认按钮 element_transfer_account_result_button.click() # 返回到主页面 self.__back_to_home() else: # 包含正常好友关系和对方账号限制的情况 print('好友关系正常') self.__back_to_home()
最后,模拟点击手机的返回键,一直回退到微信主界面。
def __back_to_home(self): """ 回退到主界面 :return: """ print('准备回退到主界面') home_tips = ['微信', '通讯录', '发现', '我'] while True: keyevent('BACK') is_home = False # 判断是否到达首页 if self.poco(text=home_tips[0]).exists() and self.poco(text=home_tips[1]).exists() and self.poco( text=home_tips[2]).exists() and self.poco(text=home_tips[3]).exists(): is_home = True if is_home: print('已经回到微信首页~') break
循环上面的操作,就可以判断出哪些是僵尸粉,哪些好友的账号被限制,哪些是正常的好友关系。
第 3 步,删除上面获取到的僵尸粉列表。
拿到上面的僵尸粉数据列表,就可以利用上面的方式进行一系列自动化UI 操作,删除掉这些好友。
def del_friend_black(self, weixin_id): """ 删除黑名单好友 :return: """ # 到好友聊天界面 self.__to_friend_chat_page(weixin_id) # 点击聊天界面右上角,进入到好友的详细信息界面 self.poco(self.id_person_msg_button).click() # 点击好友头像 self.poco(self.id_person_head_url).click() # 点击个人名片的右上角,弹出好友操作菜单 self.poco(self.id_person_manage_menu).click() # 查找删除操作栏 # 注意:对于目前主流的手机,都需要滑动到最底部才能出现【删除】这一操作栏 self.poco.swipe([0.5, 0.9], [0.5, 0.3], duration=0.2) # 点击删除,弹出删除对话框 self.poco(self.id_person_del, text=self.text_person_del).click() #はOK OK友達に削除します #のインターフェースはメインインターフェースに直接戻ります self.poco(self.id_person_del_sure、テキスト= self.text_person_del) .click()
4
の結論結果
APKをコンパイルするか、直接実行するには、Androidプロジェクトは、次の項目のデータ・ファイル・ディレクトリにマイクロ文字の友人のアドレス帳を保存することができます。
そして、マイクロチャネルのアプリケーションを動作させるために、自動化を友人の連絡先データを横断するPythonプログラムを実行し、その後、ローカルファイルにゾンビパウダーの全てを書き込み、そして最後に、あなたはアウトこれらのゾンビパウダーをすべて削除するかを選択することができます。