Who stole your message?Don't panic!A Python learning tutorial helps you pull it all out

1. Target Scene
I don't know if you've had any experience. I want to contact a friend who hasn't been in touch for a long time. I find that the other party deleted you a long time ago and you don't know anything about it.

It's so young and naive to believe that everyone has some "zombie powder" in their microphone address book. They lie silently in their contact list. You think they're still friends. In fact, they've already deleted it from their friends list. How can you screen out this group?

I know one way is to transfer money to the other party. Enter the amount first and click OK. If the other party deletes you, it will pop up automatically. You are not a friend of the payee.In this way we can know if the other party has deleted you, but it is impossible for us to verify one by one the hundreds or even thousands of WeChat friends with some partners.

There are a lot of tools on the Internet to detect zombie powder, which will send a detection message to every friend in the WeChat address book, seriously "disturbing" each other; while another part of the software will implant some code viruses during the detection, which makes the operation of the dark box very unsafe.

The purpose of this Python tutorial is to automate the operation of WeChat App, which filters out all the zombie powders through Simulated Transfer to Friends and deletes them with one click.

2. Preparations

Before you can write scripts for the formal Python tutorial, you need to prepare the following

  • An Android phone or simulator behind Root is recommended if there is no Root device
  • Android Development Environment, Android Studio
  • sqlcipher graphical tool
  • Automation Tools: Installing pocoui in a Python virtual environment

3. Scripting

The whole operation is divided into three steps: cracking the WeChat database to filter out the friends in the address book, simulating transfer to the friends to get zombie data, and deleting all zombie powder.

Step 1, we need to crack WeChat App's database.

ps: Just briefly talk about the cracking process here. If you want to crack the WeChat address book data with one click, you can skip this step and use the APK provided at the end of the article directly.

First, we use Android Studio to create a new project that grants application administrator privileges and read and write privileges to modify the WeChat directory when the project is initialized.

//WeChat App Directory
public static final String WX_ROOT_PATH = "/data/data/com.tencent.mm/";
/**
* implement linux instructions
*
* @param paramString
*/
public static void execRootCmd(String paramString)
{
try
{
Process localProcess = Runtime.getRuntime().exec("su");
Object localObject = localProcess.getOutputStream();
DataOutputStream localDataOutputStream = new DataOutputStream((OutputStream) localObject);
String str = String.valueOf(paramString);
localObject = str + "\n";
localDataOutputStream.writeBytes((String) localObject);
localDataOutputStream.flush();
localDataOutputStream.writeBytes("exit\n");
localDataOutputStream.flush();
localProcess.waitFor();
localObject = localProcess.exitValue();
} catch (Exception localException)
{
localException.printStackTrace();
}
}
//Get permissions
RootUtils.execRootCmd("chmod 777 -R " + WX_ROOT_PATH);
//Then, get the password of the WeChat database.
//The password of the WeChat database is generated by the imei of the device and the uid of WeChat passing through the md5 algorithm.
/**
* according to imei and uin Generated md5 Code, get the password of the database (go to the first seven lowercase letters)
*
* @param imei
* @param uin
* @return
*/
public static String getDbPassword(String imei, String uin)
{
if (TextUtils.isEmpty(imei) || TextUtils.isEmpty(uin))
{
Log.d("xag", "Failed to initialize database password: imei or uid Is empty");
return "Password error";
}
String md5 = MD5Utils.md5(imei + uin);
assert md5 != null;
return md5.substring(0, 7).toLowerCase();
}

Next, you can use the SQLCipher dependency library to query the WeChat database. We need to add the following dependencies for the project to facilitate the operation of the database.

//We need to increase our dependency on projects
implementation 'net.zetetic:android-database-sqlcipher:3.5.4@aar'
//Use the password obtained above to open the encrypted database, and then query the "rcontact" table to get the micro-signal, nickname, user name and other data of all the friends in the micro-mail address book.
/**
* Connect to database
* <p>
* Introduction to Common Libraries: [ rcontact]Contact sheet, [ message]Chat Message Table
*
* @param dbFile
*/
private void openWxDb(File dbFile, String db_pwd)
{
//all contacts
List<Contact> contacts = new ArrayList<>();
SQLiteDatabase.loadLibs(this);
SQLiteDatabaseHook hook = new SQLiteDatabaseHook()
{
public void preKey(SQLiteDatabase database)
{
}
public void postKey(SQLiteDatabase database)
{
atabase.rawExecSQL("PRAGMA cipher_migrate;"); //compatible2.0Database
}
};
try
{
//Open database connection
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbFile, db_pwd, null, hook);
//Query all contacts
//Filter out some contacts such as myself, group chat, public number, service number, etc.
//verifyFlag != 0:Public Number, Service Number
//Watch out for blacklisted users, I-Set up-Privacy-Address Book Blacklist
Cursor c1 = db.rawQuery(
"select * from rcontact where verifyFlag =0 and type not in (2,4,8,9,33,35,256,258,512,2051,32768,32770,32776,33024,65536,65792,98304) and username not like \"%@app\" and username not like \"%@qqim\" and username not like \"%@chatroom\" and encryptUsername!=\"\"",
null);
while (c1.moveToNext())
{
String userName = c1.getString(c1.getColumnIndex("username"));
String alias = c1.getString(c1.getColumnIndex("alias"));
String nickName = c1.getString(c1.getColumnIndex("nickname"));
int type = c1.getInt(c1.getColumnIndex("type"));
contacts.add(new Contact(userName, alias, nickName));
}
Log.d("xag", "Number of contacts in the WeChat Address Book:" + contacts.size() + "individual");
for (int i = 0; i < contacts.size(); i++)
{
Log.d("xag", contacts.get(i).getNickName());
}
c1.close();
db.close();
} catch (Exception e)
{
Log.e("xag", "Failed to read database information" + e.toString());
Toast.makeText(this, "Failed to read the WeChat address book!", Toast.LENGTH_SHORT).show();
}
Toast.makeText(this, "Read the WeChat address book successfully!", Toast.LENGTH_SHORT).show();
}

Note that the rcontact table data in the database is very cluttered. In addition to normal friends data, blacklist friends, deleted friends, public numbers, WeChat groups and other data are also included. We need to filter through the type and verifyFlag fields.

To facilitate Python operation, the queried friend data is finally written to the csv file.

/***
* Write data to csv in
* @param output_path
* @param contacts
*/
public static void writeCsvFile(String output_path, List<Contact> contacts)
{
try
{
File file = new File(output_path);
//Delete previously saved files
if (file.exists())
{
file.delete();
}
BufferedWriter bw = new BufferedWriter(new FileWriter(file, true));
// Add Header Name
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();
}
}

Step 2, we need to simulate a transfer to a friend to see if the relationship is working.

First, we need to initialize Airtest and then use adb to export the data generated in step 1 from your mobile phone to your local location.

def __init_airtest(self):
"""
//Initialize 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):
"""
//Export Address Book Data from Mobile Phone
:param target_path:
:return:
"""
# WeChat Address Book Data
wx_db_source_path = "/data/data/com.xingag.crack_wx/wx_data.csv"
# Export to Local
os.popen('adb pull %s %s' % (wx_db_source_path, target_path))

Then there is a series of automated operations.

Open WeChat, traverse the list of friends, get every friend's micro-signal to search for friends, jump to the friend's chat interface

def __to_friend_chat_page(self, weixin_id):
"""
//Click on a friend's chat interface
:param weixin_id:
:param weixin_name:
:return:
"""
# 1. Click Search
element_search = self.__wait_for_element_exists(self.id_search)
element_search.click()
print('Click Search')
# 2. Search box
element_search_input = self.__wait_for_element_exists(self.id_search_input)
element_search_input.set_text(weixin_id)
# 3. Search List
element_search_result_list = self.__wait_for_element_exists(self.id_search_result_list)
# 3.1 Is there a corresponding contact, if it exists, under the first subview layout
# Note: The most commonly used chat lists may appear and need to be judged here
index_tips = 0
for index, element_search_result in enumerate(element_search_result_list.children()):
# Contact 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. Click on the first contact to enter the chat interface
element_search_result_list.children()[index_tips + 1].click()

Then try to transfer the money to the other party. If the relationship is normal, you will jump out of a payment page and enter your password.

def __judge_is_friend(self, weixin_id, weixin_name):
"""
//Determine if you are a WeChat friend
:param weixin_id: Wechat number
:return:
"""
# Try to transfer money to a friend and set a small limit to prevent brushing your face and paying directly
# If the other party is your friend, you will be asked to enter the password next, just close the page
# If the other party is not your friend, you will be prompted that it is not your friend and cannot continue to operate
# 5. Click on the + button of the Friend Interface
self.poco(self.id_chat_more_button).click()
# 6. Click on the transfer button
self.poco(self.id_chat_more_container).offspring(text=self.text_chat_transfer_account_text).click()
# 7. Enter amount
self.poco(self.id_transfer_account_input).set_text(self.money)
# 8. Click on the transfer button
self.poco(self.id_transfer_account_container).offspring(text=self.text_chat_transfer_account_text).click()

If it's zombie powder, the app will pop up a warning dialog box telling you that you're not a friend of the payee and can't complete the transfer.


You can tell if your friendship is normal by using the warning dialog.Abnormal friendship, including zombie powder, abnormal account number, etc.

# 10. Pop-up warning dialog
# Pop-up friendship is not normal
if element_transfer_account_result_button:
# Prompt Content
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('Be careful!%s You've been blackened!!!' % 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 Account receipt restrictions!!!' % 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 Friend relationship is not normal!!!' % weixin_name)
write_to_file(self.path_relationship_unnormal, 'id:%s,nickName:%s' % (weixin_id, weixin_name))
# Click the Confirm button
element_transfer_account_result_button.click()
# Return to Home Page
self.__back_to_home()
else:
# Include normal friends and account restrictions for each other
print('Normal Friendship')
self.__back_to_home()
//Finally, simulate clicking on the return key of the mobile phone and go back to the main interface of WeChat.
def __back_to_home(self):
"""
//Back to Home Interface
:return:
"""
print('Preparing to fall back to the main interface')
home_tips = ['WeChat', 'Mail list', 'find', 'I']
while True:
keyevent('BACK')
is_home = False
# Determine whether to reach the home page
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('Has returned to WeChat Homepage~')
break

Cycle through the operations above to determine which zombie powder is, which friends have restricted accounts, and which are normal friends.

Step 3. Delete the list of zombies you obtained above.

Get the list of zombie powder data above and use it to automate a series of UI operations to remove these friends.

def del_friend_black(self, weixin_id):
"""
//Remove Blacklist Friends
:return:
"""
# Chat with friends
self.__to_friend_chat_page(weixin_id)
# Click on the upper right corner of the chat interface to enter the friend's details interface
self.poco(self.id_person_msg_button).click()
# Click on a friend's Avatar
self.poco(self.id_person_head_url).click()
# Click on the top right corner of your personal business card to pop up the Friends Action menu
self.poco(self.id_person_manage_menu).click()
# Find Delete Action Bar
# Note: For current mainstream mobile phones, you need to slide to the bottom to get the action bar Delete
self.poco.swipe([0.5, 0.9], [0.5, 0.3], duration=0.2)
# Click Delete to bring up the Delete dialog
self.poco(self.id_person_del, text=self.text_person_del).click()
# OK to delete friends
# The interface goes directly back to the main interface
self.poco(self.id_person_del_sure, text=self.text_person_del).click()

4. Conclusion

Compile the Android project or run the APK directly to save the friend data of the WeChat address book to the project file directory.

Then running the Python program will iterate through the address book friends'data, automate the operation of WeChat App, then write all the zombies to the local file, and optionally remove them all.

Want to try your WeChat Friend Address Book has zombie powder No, try it!?More Python tutorials and some tips will be updated periodically.You can look forward to it!

Tags: Database Android Python Mobile

Posted on Wed, 07 Aug 2019 23:17:24 -0700 by captain_scarlet87