"Day Wing Cup Android Two" love encryption shelling Combat

Source: Internet
Author: User
Tags sprintf pprint

Objective

This APK uses love encryption encryption, encryption time is 2017.6 months. This problem is actually a shelling problem, take off immediately see flag. (The person is too lazy to do the quiz)

Title Link: https://gitee.com/hac425/blog_data/blob/master/app02.apk

Shell Introduction

Love encrypted shell at the end of 16 has begun hook dvmResolveClass to pass, when the specific method is called to decrypt the method instruction, and then the dexfile structure of the corresponding method of the direction of the md->insns decryption method instruction data area, and then into the 真正的dvmResolveClass execution of instructions, after execution in the re-encryption instructions, This prevents dexhunter the tool from being used in the in dump dex -memory file.

Flow chart

Photo source

Shelling

As can be known from above, the dvmResolveClass code is restored when the function is executed. Then we go to dump the corresponding instruction is the correct instruction. So modify dvmResolveClass the code, the dump method of the data.
To modify a dvmResolveClass function:

/* Add Dump ... */char key_str[20] = "Jiajiatest";  int Fd=open ("/data/local/tmp/resolve_class_config", o_rdonly,0666);    if (fd!=-1) {int len = read (fd,key_str,19);    Key_str[len-1] = ' \x00 ';    Key_str[len] = ' \x00 ';  Close (FD);  } alogi ("The KEY_STR--->%s----referrer->descriptor--->%s--", key_str, Referrer->descriptor);      if (Strstr (Referrer->descriptor, Key_str)) {char task_name[] = "Task_name";      Char *logbuf = new char[1024];      Char path[50] = {0};      sprintf (Path, "/data/local/tmp/%s_dump_%d", Key_str, Getpid ());      FILE *FPW = fopen (Path, "awb+");        for (int i=0; i < referrer->directmethodcount; i++) {method* MD = &referrer->directMethods[i];        Const char* Mname_d = md->name;        Const U2 inssize_d = md->inssize;        Const u2* Insns_d = md->insns;        Const U2 methodldx_d = md->methodindex; U4 insns_d_size = dvmgetmethodinsnssize (MD);//Alogi ("HACKLH_MD---->%p, i-->%d, dirEctmethodcount-->%d ", MD, I,referrer->directmethodcount); sprintf (Logbuf, "--------------(KL) Resolving [class=%s, method=%s, methodindex=%u, inssize=%u, insns_d=%x, codesize=% D] in PID:%d (name:%s) ", Referrer->descriptor,mname_d,methodldx_d,inssize_d, (U4) Insns_d, Insns_d_size,getpid (),        Task_name);        LOGD ("%s", logbuf);          if (FPW! = NULL) {fwrite (Logbuf,1,strlen (LOGBUF), FPW);          Fflush (FPW);          Fwrite ((u1*) insns_d,1,insns_d_size*2, FPW);        Fflush (FPW);        }else{logd ("-(KL) Open%s fail!", path); }} for (int i=0; i < referrer->virtualmethodcount; i++) {method* mv = &referrer->virtualmeth        Ods[i];        Const char* MNAME_V = mv->name;        Const U2 INSSIZE_V = mv->inssize;        Const u2* Insns_v = mv->insns;        Const U2 METHODIDX_V = mv->methodindex;        U4 insns_v_size = dvmgetmethodinsnssize (mv); sprintf (Logbuf, "--------------(KL) Resolving [class=%s, method=%s, methodindex=%u, inssize=%u, insns_d=%x, codesize=%d] in PID:%d (name:%s) ", Referrer->descriptor,mname_v,        Methodidx_v,inssize_v, (U4) Insns_v, Insns_v_size,getpid (), task_name);        LOGD ("%s", logbuf);          if (FPW! = NULL) {fwrite (Logbuf,1,strlen (LOGBUF), FPW);          Fflush (FPW);          Fwrite ((u1*) insns_v,1,insns_v_size*2, FPW);        Fflush (FPW);      }else{logd ("%s", "-(KL) Open file fail!");}}      if (FPW! = NULL) {fclose (FPW); } Delete logbuf;/* Add end ... */

After dump we need to patch the instructions to the Dex location, there are many ways to patch it, and I choose to patch it using IDA script. I think Ida is a loader of various file formats, we can modify the contents of the file in Ida, and then let IDA apply the changes to the file to complete the patch. So the patch code in Ida is very handy, and it's easy to see the results after the patch. The process for patch code is:

Method instructions for reading the dump---> locating the location of the corresponding method instruction data area in IDA---->patch

The code is as follows:

#! /usr/bin/python#-*-Coding:utf8-*-# The script is used to use the Dump Method command in Ida Patchimport refrom dex_parser import dex# Storage store du MP data Dictionary data_array = [] #用来避免多次patchpatched = []file_data = "" Def parse_meta_data (Data= ""): # print data ret = {} t Okens = Re.findall ("\[class= (. *?),. *?method= (. *?),. *?codesize= (. *?) \] ", data) # Print tokens ret[' class_name ') = Tokens[0][0][1:].replace ('/', '. ').    Replace ('; ', ') ret[' method '] = tokens[0][1] ret[' code_size ') = Int (tokens[0][2]) * 2 #dex文件格式定义, total size is codesize*2 # PRINT RET return ret# comment, used to execute # def patch_byte (A, B) for Ida: # print Hex (b), Def patch (dest, SRC, size): print "dest: : {}, src::{}, size::{} ". Format (dest, SRC, size) for I in range (size): Patch_byte (dest + i, int (file_data[src +         I].encode (' hex '), +) print "\ n" def parse_dump_data (filename): Global file_data with open (filename, "RB") as FP: File_data = Fp.read () #使用正则表达式把说明dump数据的元数据加载到内存 All_item = Re.findall ("--------------\ (kl\) resolvING (. *) in pid:.*?\ (name:task_name\) ", file_data) offset = 0 for meta_data in All_item:try: #使用  Dictionary organization Data #{' class_name ': ' com.example.jiajiatest.MainActivity ', ' code_size ': 306, ' method ': ' Add ', ' Data_offset ':             7175} ret = Parse_meta_data (meta_data) data_addr = File_data.find (' (name:task_name) ', offset) + 17 ret[' data_offset ' = data_addr data_array.append (ret) offset = data_addr except E Xception as E:raise e return data_arraydef get_method_addr (Method_data, SIGNATURE_STR): for Md_name in M Ethod_data:if signature_str in Md_name:return method_data[md_name] return-1def patch_dex (dump_data _file, dex_file): Dump_data = Parse_dump_data (dump_data_file) dex_obj = Dex.dex_parser (dex_file) method_data = de X_obj.get_class_data () for item in DUMP_DATA:SIGNATURE_STR = "{}::{}". Format (item[' class_name '], item[' method ') ) If signature_sTR not in patched: #获取要patch的目标地址 addr = get_method_addr (Method_data, SIGNATURE_STR) if a DDR = = -1:print "{} can ' t get Insns addr". Format (SIGNATURE_STR) Continue #do Pat CH print "Patch" + signature_str, Patch (addr,item[' data_offset '],item[' code_size ') PATC Hed.append (SIGNATURE_STR) # Print patched # for i in patched: # Print Iimport pprintpatch_dex ("F:\CODE_WORKPL ace\ida_script\jiajiatest_dump_20406 "," F:\code_workplace\ida_script\classes.dex ") if __name__ = = ' __main__ ': print" comming main "# Parse_dump_data (" F:\code_workplace\ida_script\jiajiatest_dump_20406 ") # Patch_dex (" F:\code_workplac e\ida_script\jiajiatest_dump_20406 "," F:\code_workplace\ida_script\classes.dex ") # dex_obj = Dex.dex_parser (" f:\ Code_workplace\ida_script\classes.dex ") # Class_data = Dex_obj.get_class_data () # Pprint.pprint (class_data) # par Se_meta_data ("--------------(KL) resolving [Class=lcom/example/jiajiatest/httprunner;, Method=makeimghttpget, methodindex=13, insSize=2, insns_d= 6daf04d8, codesize=270] in pid:20406 (name:task_name) ")

Pre-and post-patch comparisons:

Before patch


After patch

You can already see the main logic of the program. Then look at the string to get the flag ...

I did something stupid.
    • Code loop conditions forgot to write, resulting in a cross-border, an open application on the error.

    • File open failed, seems to be a privilege issue, I direct violence to /data/local/tmp change to 777

Summarize

Analyze Android's underlying code errors, follow the logcat logs, find the offending code point, and then put the signed version of the library into IDA for analysis
To analyze a bug, it depends on the key logic of the code, judging the conditions and so on.

At last

To practice more, please comment below if you have questions.

"Day Wing Cup Android Two" love encryption shelling Combat

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.