Android reverse-compile look at the implementation principle of the hand Q password Red envelopes _android

Source: Internet
Author: User
Tags anonymous goto

First as a start, talk about simple decompile. There are several purposes of decompile: learn from each other, borrow and use, Hey Hei (dry you, and divided into small dry dry similar to micro-letter red envelopes, and dry to change others apk help him shelves).

The MBPR screen is too small because the KVM is not coming back, so the environment below is windows.

First, decompile
Let us start from the actual combat, first practice how to decompile a apk, to see some of the implementation of functions. After all, the principle of no practice is bullying.
Here we reserve the mentality of learning from each other, so it is the first purpose of friendliness.

1. Prepare
Tools

    • Apktool
    • JADX (new generation of anti-compiler large kill device)

installation package

Mobile phone QQ 6.2.3 (target is set to see how the password red envelopes do it)
2, the use of Apktool

First make sure that you have Java 7 or more installed and that you can invoke Java directly at the command line.

    • downloads windows with the wrapper script (Mac uses this).
    • Download the latest apktool. The
    • Rename the Apktool jar file downloaded above is Apktool.jar.
    • places Apktool.bat and Apktool.jar in the same directory and joins the PATH environment variable.
    • Now you can call Apktool directly from the command line and see how it is used.
Apktool v2.0.3-a tool for reengineering Android apk files with Smali v2.1.0 and Baksmali v2.1.0
 Ce,--Advanced Prints advance information. -version,--Version Prints the version then exits Usage:apktool if|install-framework [options] <framework.apk> p
 ,--frame-path <dir> Stores framework files into <dir>.

-T,--tag <tag> tag frameworks using <tag>.
 Usage:apktool D[ecode] [options] <file_apk> F,--Force force Delete destination directory. -O,--output <dir> The name of folder that gets written.
 The Default is apk.out-p,--the Frame-path <dir> Uses framework files located in <dir>.
 -R,--No-res does not decode.
 -S,--NO-SRC does not decode sources.

-T,--frame-tag <tag> Uses framework files tagged by <tag>.
 Usage:apktool b[uild] [options] <app_path> f,--force-all Skip changes detection and build all files. -O,--output <dir> the name of APKThat gets written.

 The Default is dist/name.apk-p,--the Frame-path <dir> Uses framework files located in <dir>.

3, the use of JADX

    • Download JADX.
    • Run Gradlew Dist compilation.
    • Jadx\jadx-gui\build\install\jadx-gui\bin with a running GUI
    • Jadx\jadx-cli\build\install\jadx\bin is a command-line program
    • You can all join the PATH environment variable for direct command line invocation.

4, analysis of APK documents
The I-Try

Although we can use JADX directly open apk to look at the source code, but in order to better understand the process and working principle of decompile, in order to encounter some problems (such as shell) when you can solve their own, here we first install force, using Apktool to carry out analysis.

D:\dev\reverse>apktool d-o QQ mobileqq_android_6.2.3.apk i:using apktool 2.0.3 on mobileqq_android_6.2.3.apk i:load
ing Resource table ... Exception in thread ' main ' brut.androlib.AndrolibException:Multiple res specs:attr/name at Brut.androlib.res.data.Re Stypespec.addresspec (restypespec.java:78) at Brut.androlib.res.decoder.ARSCDecoder.readEntry (Arscdecoder.java : 248) at Brut.androlib.res.decoder.ARSCDecoder.readTableType (arscdecoder.java:212) at Brut.androlib.res.decoder.AR Scdecoder.readtabletypespec (arscdecoder.java:154) at Brut.androlib.res.decoder.ARSCDecoder.readTablePackage ( arscdecoder.java:116) at Brut.androlib.res.decoder.ARSCDecoder.readTableHeader (arscdecoder.java:78) at Brut.androl Ib.res.decoder.ARSCDecoder.decode (arscdecoder.java:47) at BRUT.ANDROLIB.RES.ANDROLIBRESOURCES.GETRESPACKAGESFROMAPK (androlibresources.java:544) at brut.androlib.res.AndrolibResources.loadMainPkg (androlibresources.java:63) at Brut.androlib.res.AndrolibReSources.getrestable (androlibresources.java:55) at brut.androlib.Androlib.getResTable (androlib.java:66) at Brut.and Rolib. Apkdecoder.settargetsdkversion (apkdecoder.java:198) at Brut.androlib.ApkDecoder.decode (apkdecoder.java:96) at Brut . Apktool.
 Main.cmddecode (main.java:165) at Brut.apktool.Main.main (main.java:81)

Unexpectedly, multiple res specs:attr/name, looking for information on the Internet, it should be Tencent use Apktool bug to the shell, in addition to add the same name ID also made a number of reinforcement, good, you ruthless, Our next article for Tencent's shell to analyze and modify Apktool, this time first with JADX to try.

Second Try

If you open the QQ apk directly with Jadx-gui, you will find that the card is dead. Yes, it's stuck, because it's too big ...

We open the Jadx-gui file (which is actually a boot script), plus:

Set java_opts=-server-xms1024m-xmx8192m-xx:permsize=256m-xx:maxpermsize=1024m

Just like the way we speed up the As/idea, give us more memory so we can open it successfully (it may take a long time).

5. String Dafa

To find our target, red envelopes, we first try to search by string: In Resources-> RESOURCES.ARSC-> res-> values-> strings.xml find passwords corresponding to the

<string name= "Qb_hbdetail_command_word" > Password red envelopes </string>

Then crtl+shift+f for text Search, the result ... Not found.

We then use the resource ID Dafa to find the RESOURCES.ARSC directly in the

0X7F0A0E5A (2131365466) = String.qb_hbdetail_command_word: Password Red envelopes

Search again, good, you ruthless ... Or not. I lost it in the next one.

6. class/Function name Dafa

We're going to sacrifice the second largest, class/function/variable name Dafa search.

Usually the class name conforms to a smaller range, so only class is used first.
Try the Red envelopes in English: Redpacket (Name of class names so R and P capitals)


OK, we found more than 10, start to check, the first redpacketinfo point into a look is a variety of field of the UI with the Vo class, skip, look at the next, From the package name Com.tencent.mobileqq.data looks, seems to have a chance, qqwalletredpacketmsg:

Package com.tencent.mobileqq.data;

Import Android.text.TextUtils;
Import Com.tencent.mobileqq.hotpatch.NotVerifyClass;
Import Cooperation.qzone.util.WiFiDash;
Import java.io.IOException;
Import Java.io.ObjectInput;
Import Java.io.ObjectOutput;
Import Tencent.im.msg.im_msg_body. Qqwalletaiobody;

/* Compiled From:proguard *
/public class Qqwalletredpacketmsg {public
  String Authkey;
  private int channelid;
  public int conftype;
  Public Qqwallettransfermsgelem Elem;
  Public String EnvelopeName;
  public int Envelopeid;
  public boolean isopened;
  public int msgfrom;
  Public String Redpacketid;
  public int redtype;
  private int Resend;
  public int TemplateID;

... serialization, reading and writing, construction methods, etc., can be ignored.
From the field name, here is still more suspicious, guessing Redtype is not describing the type of red envelopes.

We again use the keyword Redtype to search, this time to select Code, only to search within the codes, the results found seemingly wrong, find the relevant string is "View Details", seemingly to describe the status of red envelopes.

Do not give up, continue to grasp qqwalletredpacketmsg this class to search, see if there is a class that is wrapped in the outside, search qqwalletredpacketmsg, scope use field, excluding the class itself, Only a single result: messageforqqwalletmsg:

public class Messageforqqwalletmsg extends Chatmessage {
  //Oh oh? Command_redpacket? Password red envelope public
  static final int msg_type_command_redpacket = 6;
  public static final int msg_type_common_redpacket = 2;
  public static final int msg_type_common_theme_redpacket = 4;
  public static final int msg_type_individual_redpacket = 2001;
  public static final int msg_type_lucy_redpacket = 3;
  public static final int msg_type_lucy_theme_redpacket = 5;
  public static final int msg_type_public_account_redpacket = 2002;
  public static final int msg_type_transfer = 1;
  ...

We found a constant field, which is the visual description of whether the password is a red envelope. In this class search this field also find

public static Boolean iscommandredpacketmsg (Messagerecord messagerecord) {
  if messagerecord!= null && ( Messagerecord instanceof Messageforqqwalletmsg) && ((messageforqqwalletmsg) messagerecord). MessageType = MSG _type_command_redpacket) {return
    true;
  }
  return false;
}

Sure enough, we went on to look for Msg_type_command_redpacket and iscommandredpacketmsg separately, The result was a reference to the method iscommandredpacketmsg in the Troopmessagemanager code that was not successfully compiled.

L_0X0100:
  r2 = COM.TENCENT.MOBILEQQ.DATA.MESSAGEFORQQWALLETMSG.ISCOMMANDREDPACKETMSG (R25);
  if (r2 = = 0) goto l_0x011e;

If this is a password, the red envelope will continue to go on, and if not, it will jump to l_0x011e.

And from the name of the class, Troopmessagemanager should refer to the group of message managers, should be correct, after all, red envelopes are also a group of messages.

So we can only patiently look at this magical full of goto code. Dizzy after reading, probably see is a variety of logical judgments and call Msgproxyutils.java to deal with message processing logic and caching. And then there's no ... Well, you dick, it's The next loser. I'll try something else.

7. Constant Dafa

Constant Dafa can also be considered as a string search, but not to search the XML, but to use Chinese into Unicode after the string to find. Self-search Unicode encoding conversion can find online convertor.

Password red envelopes correspond to "\u53e3\u4ee4\u7ea2\u5305":

A total of 3 code references were found for 2 classes.

Finally the name of the class is a bit intriguing, passwdredbagmanager, password Red envelope manager, a little meaning:

public void B (String str) {(
  trooptipsmsgmgr) This.f2203a.getManager). A (str, "\u533f\u540d\u4e0d\u80fd\ U62a2\u53e3\u4ee4\u7ea2\u5305\u54e6 ", Netconninfocenter.getservertime (), Baseconstants.default_quick_heartbeat_ TIMEOUT, f);
}

This series of Unicode converted to Chinese is "Anonymous can not Rob password Oh", there is this logic, product manager you are really enough.

Here we re looking at the top of the class, sweeping a sweep, and finding that OnDestroy has a way of playing the log is amazing:

Public long[] m883a (sessioninfo sessioninfo, String str) {if (Qlog.iscolorlevel ()) {QLOG.D (f2197a, (int) h, "open
  Passwdredbagbypassword, passwd = "+ str";
  } long[] Jarr = new long[]{0, 0};
  if (Sessioninfo = = null) {return jarr;
  } if (Textutils.isempty (str)) {return jarr;
  } c ();
  list<string> list = (list) this.f2206a.get (str);
  if (list = = NULL | | list.isempty ()) {return jarr;
  } Passwdredbaginfo Passwdredbaginfo;
  String str2 = A (SESSIONINFO.A) + "_" + sessioninfo.f1757a;
    for (String str3:list) {HashMap HashMap = (HashMap) this.f2209b.get (STR3);
      if (HashMap!= null) {Passwdredbaginfo = (passwdredbaginfo) hashmap.get (STR2); if (!) ( Passwdredbaginfo = = NULL | |
        A (STR3))) {Jarr[g] = Passwdredbaginfo.a.uint64_creator_uin.get ();
            if (!b (STR3)) {if (!c (STR3)) {hashmap.put (str2, passwdredbaginfo);
            JARR[F] = 1;
          Break
    } Jarr[f] = 3;    else {jarr[f] = 2;
  }}} passwdredbaginfo = null;
  if (Passwdredbaginfo = = null) {return jarr;
  B (SESSIONINFO.A, sessioninfo.f1757a, Passwdredbaginfo.a.string_redbag_id.get (). ToStringUtf8 ());
  A (Sessioninfo, passwdredbaginfo);
return Jarr;
 }

Iscolorlevel visual is some kind of debug tag, some users may be open in some environments, and from the log with our usual log habits, this method should be called Openpasswdredbagbypassword, The second parameter is password. Finally found it. Look at the logic is basically from the outside load come in all the red envelope information to this class of various hashmap and list (have a tag, will only load the first time, this method will be called by multiple methods), and then according to password from the inside to find corresponding passwdredbaginfo, Set the result tag, and then call the

B (SESSIONINFO.A, sessioninfo.f1757a, Passwdredbaginfo.a.string_redbag_id.get (). ToStringUtf8 ());
A (Sessioninfo, passwdredbaginfo);

Let's not be anxious to see what these two methods do. Then look down the next way, directly:

Public long[] B (sessioninfo sessioninfo, String str) {
  if (Qlog.iscolorlevel ()) {
    qlog.d (f2197a, (int) h, "Openpa Sswdredbagbyid, id = "+ str";
  }

Openpasswdredbagbyid opens the red envelope with an ID, guessing that the ID is the Redpacketid field in the structure we saw first.

And the method also calls the

B (SESSIONINFO.A, sessioninfo.f1757a, str);
A (Sessioninfo, passwdredbaginfo);

Look at these two ways:

public void A (Sessioninfo sessioninfo, Passwdredbaginfo passwdredbaginfo) {if (Sessioninfo!= null && passwdre Dbaginfo!= null) {Object obj = (sessioninfo.a = 0 | | sessioninfo.a = h | | sessioninfo.a = = Action.action_registnew account_commitsms | | SESSIONINFO.A = = Action.action_login)?
    G:null;
    String str = sessioninfo.f1757a;
    String valueof = string.valueof (Passwdredbaginfo.a.uint64_creator_uin.get ());
    if (obj!= null) {str = valueof.equals (this.f2213d)? sessionInfo.f1757a:this.f2213d; Jsonobject a = QQWALLETMSGITEMBUILDER.A (this.f2203a, Sessioninfo, Passwdredbaginfo.a.string_redbag_id.get (). ToStringUtf8 (), Passwdredbaginfo.a.string_authkey.get (). ToStringUtf8 (), str, "appid#1344242394|bargainor_id#
    1000030201|channel#msg "," GRAPHB ", null);
    Bundle Bundle = new Bundle ();
    Bundle.putstring ("JSON", a.tostring ());
    Bundle.putstring ("CALLBACKSN", JBI.A);
    Intent Intent = new Intent (this.f2200a, Paybridgeactivity.class); InteNt.putextras (bundle);
    Intent.addflags (268435456);
    Intent.putextra ("Pay_requestcode", 5);
  This.f2200a.startActivity (Intent); } public void B (int i, string str, string str2) {if (!
    Textutils.isempty (str2)) {HashMap HashMap = (HashMap) this.f2209b.get (STR2);
      if (HashMap!= null) {Passwdredbaginfo Passwdredbaginfo = (passwdredbaginfo) hashmap.get (A (i) + "_" + str);
        if (passwdredbaginfo!= null &&!passwdredbaginfo.f4810a) {passwdredbaginfo.f4810a = true;
      THREADMANAGER.A (The new KMR (this, str2), H, NULL, true);

 }
    }
  }
}

found that the first method seems to send a direct request, it seems as long as the call here, is to get a red envelope. How did it first come here? We searched for references to these two methods within Passwdredbagmanager to find Basechatpie.java:

Public Passwdredbagmanager f25190a; ... public class Enterforsend implements Onkeylistener, Oneditoractionlistener {...//here, judging from the method name is to call public after each input click Send
    Boolean oneditoraction (TextView TextView, int i, keyevent keyevent) {if (I!= basechatpie.dr) {return false;
    The String obj = This.a.f25220a.gettext (). toString ();
      if (obj.length () > 0) {//calls the following method of the outer class long[] a = THIS.A.A (obj);
      Send Message again sendmsgparams sendmsgparams = new Sendmsgparams ();
      sendmsgparams.b = THIS.A.DL;
      SENDMSGPARAMS.A = THIS.A.DJ;
      SENDMSGPARAMS.C = THIS.A.DN;
      sendmsgparams.f26863c = THIS.A.DL;
    ...
    }
  return true;
  }//This calls the 2 openpasswdredbagxxx methods public long[] M5613A (String str) {long[] Jarr = null; Non-anonymous mode will continue to try to match the password red envelopes, the original inside and outside have made a judgment if (!
      ANONYMOUSCHATHELPER.A (). A (THIS.F25174A.A)) {if (Textutils.isempty (this.f25269d) | |!str.equals (this.f25278e)) {
   Use the password to open Jarr = THIS.F25190A.A (this.f25174a, str); else {///use Redpacketid to directly open Jarr = THIS.F25190A.B (this.f25174a, this.f25269d); }//meaningless log to dot what, gorgeous disregard of the bar if (Jarr!= null && jarr[s] = = 1) {this.f25269d = Qunuppuploadtask.qunupp
      AppId;
      this.f25278e = Qunuppuploadtask.qunuppappid;
      This.f25228a.sendEmptyMessage (DZ);  if (Qlog.iscolorlevel ()) {QLOG.D (PASSWDREDBAGMANAGER.A, U, "passwdredbags result[0]=" + jarr[s] + ", result[1]=" +
      Jarr[t] + ", send str=" + str); }} else if (Qlog.iscolorlevel ()) {QLOG.D (PASSWDREDBAGMANAGER.A, U, "the" is in Anonymous, dont search pas
  Swdredbags ");
return Jarr;

 }

Visible every time we enter the message to send, have a judgment, will go to the query is not a red envelope password, if it is directly sent a request to take red envelopes and then continue, otherwise directly as ordinary message continue to send. So if you want to do the automatic robbery, in fact, as long as the message is received directly, call Passwdredbagmanager open method can, even simulate the UI, generate requests, send messages are not, we no longer have to be ignorant of the conscience of the password. By the way we also saw the mobile phone QQ does like to use activity, here the red envelope bomb box is also a separate activities, and the request is sent to the hand Q red envelope to go over there, it seems also divided into lines of business.

This concludes our purpose, and in fact continue, we can try to dump the current activity, use the activity name to find, or use the hierarchy view to see the view ID try.

After the above toss, we successfully decompile the mobile phone QQ, and traced back to the mobile phone QQ red envelopes data structure and judgment process. It's been a few hard times, but reverse engineering is one thing, in particular, static analysis, if not in time to find other roads, and all the way from a clue to see, it is likely to be more and more deep, this article's tracking process is constantly in the pit when the small drill out, and then to find other paths, Finally, I quickly found what I wanted to see.

The above is the entire content of this article, I hope to help you learn.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.