Virgoan ocD hates it when a message is taken back, especially when the picture is taken down before you can see it, or when the message is taken back before you have a chance to see it. Recently, reverse engineering is very popular, so I simply reverse a wechat for Mac & iOS.

Why not iOSBoth Mac and iOS work together

WeChat APP on iOS doesn’t always run at the front desk, if others in the withdrawal news WeChat phone lock screen, broken network, even in the background may not withdraw the message calling at this moment, even when WeChat to return to the front desk, not received the original message data from the server, but only received a “withdrawal” instruction. Based on the above speculation, I decided to focus on wechat for The Mac. After all, wechat on the COMPUTER always receives messages as long as it is open, and the Mac version of wechat does not run into the background.

PS: It was later said that the Web version of wechat would not have withdrawn messages… Unfortunately, I’ve never used it; Even if iOS wechat is not running when sending and withdrawing messages, it will still receive the original message content when receiving messages from the server. Well, I overestimated wechat…

20160701 the Update:

Today, I was bored at home, and I got iOS wechat done, just a little more trouble than Mac.

Be imaginative and bold

Before looking at some of the reverse tutorial, feel the early work is to install software with the environment, crackling command a knock, the whole quite mysterious, in fact, are to use someone else’s ready-made tools to do something, the United States called “standing on the shoulders of giants,” here no longer repeat. The first really difficult thing in my opinion is a word: “guess”!

It is a skill to guess where you want to go from the names of the functions and classes in the dump header file. It’s a test of imagination, and sometimes luck. Drag wechat from your app into Hopper and search for “REVOKE”. I can immediately guess which method handles the withdrawal logic:

My intuition is that -[MessageService onRevokeMsg:] is the way to go. And I was right. One hit! Take a look at the pseudocode for this method:

Pseudo code contains many layers of complex if judgment logic, it must be the complex business logic here that makes wechat colleagues extremely mad, don’t be afraid, we don’t want the following things to happen, just return and everything will be fine! Press option+A or select Modify -> Assemble Instruction… from the Hopper menu bar. To modify the first line of the assembly statement:

I might think it’s too bold to just return it, but I actually looked at this piece of code in the function. So many if judgments are accompanied by data reporting in various error scenarios. The real core business logic is the following pile:

r12 = [[MessageData alloc] initWithMsgType:0x2710]; rax = [r12 isSendFromSelf]; rsi = @selector(toUsrName); if (LOBYTE(rax) ! = 0x0) { rbx = [[r13 toUsrName] retain]; [r12 setFromUsrName:rbx]; [rbx release]; rbx = [[r13 fromUsrName] retain]; [r12 setToUsrName:rbx]; } else { rbx = [[r13 toUsrName] retain]; [r12 setFromUsrName:rbx]; [rbx release]; rbx = [[r13 fromUsrName] retain]; [r12 setToUsrName:rbx]; } [rbx release]; [r12 setMsgStatus:0x4]; [r12 setMsgContent:var_58]; [r12 setMsgCreateTime:LODWORD([r13 msgCreateTime])]; [r15 AddLocalMsg:var_50 msgData:r12]; rbx = [[NSArray arrayWithObject:r13] retain]; [r15 DelMsg:var_50 msgList:rbx isDelAll:0x0]; r15 = *objc_release; [rbx release]; [r12 release];Copy the code

This code determines if the person who withdrew the message is himself, then updates the UI on a case-by-case basis, and finally generates and updates the data. Since there is nothing important to do, you can safely ignore it haha.

You now need to regenerate the modified assembly into a new executable. Select “File -> Produce New Executable…” from the Hopper menu. After point Yes:

Finally the generated executable file to replace/Applications/WeChat app/Contents/MacOS/WeChat

The only thing that puzzled me was that WeChat still worked without having to sign the new executable. It is my first time to play reverse, and I also ask the elder gods for advice. After a series of attempts to withdraw messages, the phone displayed a retraction, but the Message on the Mac version of wechat was still there. One guess, success!

IOS is a little trickier

If you have an IPA that has been decrypted, either use dumpDecrypted on the jailbreak machine yourself, or simply use a third party tool that has been decrypted (that is, installed on the jailbreak machine). I had some problems with sync assistant at first, then PP assistant.

After decompression, find the WeChat. App inside, and pay attention to verify the signature with codesign-dvvv WeChat. App. The original app signature is Tencent’s…

The first step, guess, um, is -[CMessageMgr onRevokeMsg:] this method. I just changed the class name.

Second, change the assembly code. What needs to be changed here is the Thumb instruction set. It’s actually a mode for newer ARM processors. We’re interested in what the various instructions mean, and in particular how to switch from Thumb back to ARM with bx:

There is a Thumb® 16-bit instruction set quick reference card

Finally, replace the generated executable as before.

Step three, sign your name! Recommend reading code signature analysis, Entitlements and Provisioning. The premise of this step is to have a legal certificate, individuals or enterprises can!

Create a new project (my name is testUIImage, I created it last night when I was working on UIImage), make sure you sign it with a certificate, don’t select None… The target schema is selected correctly and compiled into an IPA file. All we need is the signature information in it.

First use LDID tool on the desktop to generate an authorization file (Entitlements. Plist) :

ldid -e /Users/yangxiaoyu/Library/Developer/Xcode/DerivedData/testUIImage-aoqcifvynorulecqtwqqugleuktf/Build/Products/Debug-ipho neos/testUIImage.app/testUIImage > ~/Desktop/Entitlements.plistCopy the code

PS: I installed ldid using Homebrew

Then copy and paste the Provisioning embedded. Mobileprovision from TestuiImage.app into our WeChat. (Right click to display package contents.)

Finally, sign the WeChat. App with the codesign command, replacing it with your own certificate “Common name” :

codesign -f -s "iPhone Developer: xiaoyu yang (XXXXXXXXX)" --entitlements /Users/yangxiaoyu/Desktop/Entitlements.plist / Users/yangxiaoyu/Desktop/WeChat _v6. 3.22 / content/WeChat appCopy the code

The fourth and final step is to package the new WeChat. Ipa:

Xcrun - SDK iphoneos PackageApplication - v/Users/yangxiaoyu/Desktop/WeChat _v6. 3.22 / content/WeChat app - o ~/Desktop/WeChat.ipaCopy the code

Now you can install the new WeChat. Ipa on your phone!

Verify that after exiting the wechat kill process, the other party sends a message and withdraws. After entering wechat, you can still receive the message of withdrawal. Excited!

Afterword.

In fact, reverse engineering is a very interesting learning, and any learning is easy to get started but difficult to get deep. This example seems easy, but in fact, if faced with a more complex environment, just rely on my poor assembly knowledge is certainly not enough. If you’re working backwards from an APP on iOS, it’s actually a lot harder to prepare. Truly mastered the underlying principles and basic knowledge is the hard truth!

In fact, the Security framework is used to verify the signature inside the app to prevent it from being modified. Of course, on the Mac, it is most convenient for us to use the codesign command. Apple provides documentation for code signing services

I’m finally back to the title party! Aha!