3 xpl0it 2015/11/16 12:15

0 x00 overview


[TOC]

This article mainly introduces several simple examples to reverse analyze SO. Of course, some cracking methods can be directly modified in SMALI, but all of them adopt reverse SO.

0 x01 ARM – HEX transformation

1. To convert the ARM command to Hex, use the Arm_Asm tool, as shown below:

2. Manual conversion can be performed according to the ARM reference manual. For example, the format of the add command is as follows:

When add r0,#1, the Rdn is 0 and imm8 is 1, so the binary is 00110000 00000001, converted to hexadecimal is 3001, so the Hex code is 0130

3. Someone uploaded a set of thumb instructions on Baidu Wenku. If you don’t want to find it in the ARM reference manual, you can have a look at this.

V is immed_value n is Rn m is Rm s is Rs r is register_list c is condition 0100 0001 01mm MDDD -- ADC Rd,Rm 0001 110V VVNN NDDD -- ADD Rd,Rn,# IMMED_3 0011 0DDD VVVV VVVV -- ADD Rd,#immed_8 0001 100m mmnn nddd -- ADD Rd,Rn,Rm 0100 0100 hhmm mddd -- ADD Rd,Rm h1h2,h1 is msb for Rd,h2 is msb for Rm 1010 0ddd vvvv vvvv -- ADD Rd,PC,#immed_8*4 1010 1ddd vvvv vvvv -- ADD Rd,SP,#immed_8*4 1011 0000 0vvv vvvv -- ADD SP,#immed_7*4 0100 0000 00mm mddd -- AND Rd,Rm 0001 0vvv vvmm mddd -- ASR Rd,Rm,#immed_5 0100 0001 00ss sddd -- ASR Rd,Rs 1101 cccc vvvv vvvv -- Bcc signed_immed_8 1110 0vvv vvvv vvvv -- B signed_immed_11 0100 0011 10mm mddd -- BIC Rd,Rm 1011 1110 vvvv vvvv -- BKPT immed_8 111h hvvv vvvv vvvv -- BL(X) immed_11 0100 0111 1hmm mSBZ -- BLX Rm 0100 0111 0Hmm mSBZ -- BX Rm 0100 0010 11mm mnnn -- CMN Rn,Rm 0010 1nnn vvvv vvvv -- CMP Rn,#immed_8 0100 0010 10mm mnnn -- CMP Rn,Rm 0100 0101 hhmm mnnn -- CMP Rn,Rm 0100 0000 01mm mddd -- EOR Rd,Rm 1100 1nnn rrrr rrrr -- LDMIA Rn! ,reg_list 0110 1vvv vvnn nddd -- LDR Rd,[Rn+#immed_5*4] 0101 100m mmnn nddd -- LDR Rd,[Rn,Rm] 0100 1ddd vvvv vvvv -- LDR  Rd,[PC+#immed_5*4] 1001 1ddd vvvv vvvv -- LDR Rd,[SP,#immed_8*4] 0111 1vvv vvnn nmmm -- LDRB Rd,[Rn,#immed_5*4] 0101 110m mmnn nddd -- LDRV Rd,[Rn,Rm] 1000 1vvv vvnn nddd -- LDRH Rd,[Rn,#immed_5*2] 0101 101m mmnn nddd -- LDRH Rd,[Rn,Rm] 0101 011m mmnn nddd -- LDRSB Rd,[Rn,Rm] 0101 111m mmnn nddd -- LDRSH Rd,[Rn,Rm] 0000 0vvv vvmm mnnn -- LSL Rd,Rm,#immed_5 0100 0000 10ss sddd -- LSL Rd,Rs 0000 1vvv vvmm mddd -- LSR Rd,Rm,#immed_5 0100 0000 11ss sddd -- LSR Rd,Rs 0010 0ddd vvvv vvvv -- MOV Rd,#immed_8 0001 1100 00nn nddd -- MOV Rd,Rn 0100 0110 hhmm mddd -- MOV Rd,Rm 0100 0011  01mm mddd -- MUL Rd,Rm 0100 0011 11mm mddd -- MVN Rd,Rm 0100 0010 01mm mddd -- NEG Rd,Rm 0100 0011 00mm mddd -- ORR Rd,Rm 1011 110R rrrr rrrr -- POP reg_list 1011 010R rrrr rrrr -- PUSH reg_list 0100 0001 11ss sddd -- ROR Rd,Rs 0100 0001 10mm mddd -- SBC Rd,Rm 1100 0nnn rrrr rrrr -- STMIA Rn! ,reg_list 0110 0vvv vvnn nddd -- STR Rd,[Rn,#immed_5*4] 0101 000m mmnn nddd -- STR Rd,[Rn,Rm] 1001 0ddd vvvv vvvv -- STR  Rd,[SP,#immed_8*4] 0111 0vvv vvnn nddd -- STRB Rd,[Rn,#immed_5] 0101 010m mmnn nddd -- STRB Rd,[Rn,Rm] 1000 0vvv vvnn nddd -- STRH Rd,[Rn,#immed_5*2] 0101 001m mmnn nddd -- STRH Rd,[Rn,Rm] 0001 111v vvnn nddd -- SUB Rd,Rn,#immed_3 0011 1ddd vvvv vvvv -- SUB Rd,#immed_8 0001 101m mmnn nddd -- SUB Rd,Rn,Rm 1011 0000 1vvv vvvv -- SUB Sp,#immed_7*4 1101 1111 VVVV VVVV -- SWI immed_8 0100 0010 00mm MNNN -- TST Rn,Rm 0000 0VVV VVMM MNNN -- LSL Rd,Rm,# IMMED_5 0000 1VVV VVMM MDDD -- LSR Rd,Rm,# IMMED_5 0001 0VVV VVMM MDDD -- ASR Rd,Rm,#immed_5 0001 100m mmnn nddd -- ADD Rd,Rn,Rm 0001 101m mmnn nddd -- SUB Rd,Rn,Rm 0001 110v vvnn nddd -- ADD Rd,Rn,#immed_3 0001 111v vvnn nddd -- SUB Rd,Rn,#immed_3 0001 1100 00nn nddd -- MOV Rd,Rn 0010 0ddd vvvv vvvv -- MOV Rd,#immed_8 0010 1nnn vvvv vvvv -- CMP Rn,#immed_8 0011 0ddd vvvv vvvv -- ADD Rd,#immed_8 0011 1ddd vvvv vvvv -- SUB Rd,#immed_8 0100 0000 00mm mddd -- AND Rd,Rm 0100 0000 01mm mddd -- EOR Rd,Rm 0100 0000 10ss sddd -- LSL Rd,Rs 0100 0000  11ss sddd -- LSR Rd,Rs 0100 0001 00ss sddd -- ASR Rd,Rs 0100 0001 01mm mddd -- ADC Rd,Rm 0100 0001 10mm mddd -- SBC Rd,Rm 0100 0001 11ss sddd -- ROR Rd,Rs 0100 0010 00mm mnnn -- TST Rn,Rm 0100 0010 01mm mddd -- NEG Rd,Rm 0100 0011 00mm mddd -- ORR Rd,Rm 0100 0010 10mm mnnn -- CMP Rn,Rm 0100 0010 11mm mnnn -- CMN Rn,Rm 0100 0011 01mm mddd -- MUL Rd,Rm 0100 0011 10mm mddd -- BIC Rd,Rm 0100 0011 11mm mddd -- MVN Rd,Rm 0100 0100 hhmm mddd -- ADD Rd,Rm h1h2,h1 is msb for Rd,h2 is msb for Rm 0100 0101 hhmm mnnn -- CMP Rn,Rm 0100 0110 hhmm mddd -- MOV Rd,Rm 0100 0111 0Hmm mSBZ -- BX Rm 0100 0111 1hmm mSBZ -- BLX Rm 0100 1ddd vvvv vvvv -- LDR Rd,[PC+#immed_5*4] 0101 000m mmnn nddd -- STR Rd,[Rn,Rm] 0101 001m mmnn nddd -- STRH Rd,[Rn,Rm] 0101 010m mmnn nddd -- STRB Rd,[Rn,Rm] 0101 011m mmnn nddd -- LDRSB Rd,[Rn,Rm] 0101 100m mmnn nddd -- LDR Rd,[Rn,Rm] 0101 101m mmnn nddd -- LDRH Rd,[Rn,Rm] 0101 110m mmnn nddd -- LDRV Rd,[Rn,Rm] 0101 111m mmnn  nddd -- LDRSH Rd,[Rn,Rm] 0110 0vvv vvnn nddd -- STR Rd,[Rn,#immed_5*4] 0110 1vvv vvnn nddd -- LDR Rd,[Rn+#immed_5*4] 0111 1vvv vvnn nmmm -- LDRB Rd,[Rn,#immed_5*4] 0111 0vvv vvnn nddd -- STRB Rd,[Rn,#immed_5] 1000 0vvv vvnn nddd -- STRH Rd,[Rn,#immed_5*2] 1000 1vvv vvnn nddd -- LDRH Rd,[Rn,#immed_5*2] 1001 0ddd vvvv vvvv -- STR Rd,[SP,#immed_8*4] 1001 1ddd vvvv vvvv -- LDR Rd,[SP,#immed_8*4] 1010 0ddd vvvv vvvv -- ADD Rd,PC,#immed_8*4 1010 1ddd vvvv vvvv -- ADD Rd,SP,#immed_8*4 1011 0000 0vvv vvvv -- ADD SP,#immed_7*4 1011 0000 1vvv vvvv -- SUB Sp,#immed_7*4 1011 010R rrrr rrrr -- PUSH reg_list 1011 110R rrrr rrrr -- POP reg_list 1011 1110 vvvv vvvv -- BKPT immed_8 1100 0nnn rrrr rrrr -- STMIA Rn! ,reg_list 1100 1nnn rrrr rrrr -- LDMIA Rn! ,reg_list 1101 cccc vvvv vvvv -- Bcc signed_immed_8 1101 1111 vvvv vvvv -- SWI immed_8 1110 0vvv vvvv vvvv -- B signed_immed_11 111h hvvv vvvv vvvv -- BL(X) immed_11Copy the code

0 x02 sample


Start by reversing the switch branch from the previous article.

The code for getSwitch() is as follows:

JNIEXPORT jint JNICALL Java_com_example_hellojni_GetSwitch_getSwitch (JNIEnv *, jclass, jint a, jint b, jint i){ switch (i){ case 1: return a + b; break; case 2: return a - b; break; case 3: return a * b; break; case 4: return a / b; break; default: return a + b; break; }}Copy the code

1. Reverse APK, use IDA to open libhellojni. so in libs, Alt +t to find GetSwitch

2. When we pass 4,2,2, yes, we execute a-b, so we return 2

3. Add ro, R2,r3 hex = D018 (hex = D018

4. Then switch to Hex View, change Hex to D018, and then return to graph mode, you can see that SUBS R0,R2,R3 has changed to ADDS R0,R2,R3

5. Use 010Editor, CTRL + G to jump to 104A, change Hex to D018, and save.

6. Recompile to APK, run, find the result has changed to 6.

0x03 Internal purchase Crack


1. Normally, when you buy gold coins, you need to pay, because you are using the simulator, so it shows failure to pay.

2. Find the corresponding SO from SMali and open IDA. GameCoin ::GameCoin = v3 + v1 (ADDS R0,R0,R6

3. We know that R0 is the return value and R6 is the current calculated number of coins, so we change this to ADDS R0,#255, so 255 coins are added each time, and Hex is FF30

4. After modification, the initial gold is 10. After one click, 255 coins are added.

0x04 Encryption and decryption


This article is cracked from my love (www.52pojie.cn/thread-3964…) Seen by AdSLXYZ.

Tools:

  1. IntelliJ IDEA
  2. baksmali
  3. AndroidKiller
  4. IDA6.6
  5. Fiddler
  6. An Android real machine (or emulator)
  7. eclipse

Connect your phone to wifi, connect it to the same LOCAL area network as your computer, and then set up Fiddler without going into details. Open baby Tree Incubation version 6.2.1, enter the login window, enter the account password to log in, and view the package on the computer. Can get the request URL: http://www.babytree.com/api/muser/login

POST: android_id=d77c45cb6182db0e&build_serial=mmmm&local_ts=1438682239&source_channel=pc_pregnancy_tongyong_app_140729&longit Ude = = 35.582332 & 122.535462 & latitude phone_number = f2nvyuucysftx buROv8rMh50AdCj7mYdAZwWv9YEpsIR2mClGrO43QK6E5GHko7aEZwtZMT % 2 %2Bkz1kwpthbRlpZecGXjkbyaaeIE4ocYjolDyLXLduydRCjnG%2Bk9OEfBr3QCShaiJ2Z%2BeDQIeqgTssdlzZqzFfpHzsg3oWpdF3RbMLF3O93RzGWntJg kgvzjzK7BfwvRF8p8o6Se2l7mX7malpYrn35H2kh4mEAaLaBGoj2naCxcSXCn6X6w9za6hofkhogCtB7PpY6pulzY%2BOhejwG1jdoCpqRxcctRcsFPWNz72 SD8Mmqkq6wRVeLYX5ZIoWNafwEJuPobuRtmvhQzg % % 3 d & 3 d version = 6.2.1 & imei = 90000451032112 & secret = b8a310e750c8af5187197c279a7e0241 &email=zLkZURsmEpT8fGCGGNADu2KAZ79zkZI3b%2FMBDh5i1vCAbvFmKoGu7L4nBPsOvnzzsnWtuOJipiITnoRQ5w%2FNTy%2FvEx%2BX%2FO8Ff8jcU2q BAXTzGgd0x1lZ8PsGuan0944ax5n1douoaTC370Hv4A%2F58IhP8rhcQWnO4FzFol8FC%2FXQ%2Fd1%2FoAQOycwdLeBUm0JJ5tRKiaT2nBwD1z7Dn1CShsw WCNN2zDCvYgtJ7Ig3JIQipUahL9OaR%2FQnzUzk%2BmaC%2Fm6iRr1q4wkiz9lexJkXFHf1g5VuFqshCNgxdgeDw%2BZHuagedfj5MakZD96Lj%2BtZtRf6G haLbY29tSL65EdSgsg%3D%3D&password=AhOxbuypr6JYDgpP%2Fw%2BLhVlfzwusSMOaE0137YBOvOAZkk%2BbCHwzfduzqsjasx6zrhZUkZv3aoZ27HDI FAebdgsRS9lh2eeuxXiIxZdkaVPy47UNMdLHo1fFnuUEOCbE144H%2FL%2B2EeY%2BjbE8Ebjg0gXuZ7ziNZ%2Bmrgt4%2FrN8YbizcbyCx7A%2Fue3GD3p5 8GV3ztnlxWp9d4D1IlMT5V%2B8qxi3VDpQMr0Ghi4MaDTkH%2FV8fcRSCBqutHTDsEs%2F5AfBgksHFT6Dcxl3tpBIIfdgEmU4EZ%2BpqLqVxVFLdjPA0MJO hzE36P8NqTPiKEXzTuJcmaaS5qU34d2dHGYP2wc7Dg%3D%3D&client_type=android&app_id=pregnancy&mac=5c%3A51%5A57%3A55%3A26%3A4d&cl ient_baby_status=1&bpreg_brithday=2100-01-01Copy the code

Analysis: phone_number, password, email, secret four parameters for encryption, and other parameters are fixed or geographical location information, etc. So we’re going to aim for these four parameters

  1. First, drag APK into AndroidKiller for analysis, there is no shell.
  2. Based on the previous analysis, we can search the corresponding string in AndroidKiller to find the function search we are interested inmuser\login, we know that the login function is incom.babytree.platform.api.muserIn thelogin.smaliIn the. As you can see from the figure, the parent class of login.java is ApiBase, and you can guess that functions common to all Api requests are generated in this class. Key place to find a line, this analysis is mainly based on dynamic debugging.
  3. Decompile apK into a. Smali file using baksmali
  4. Then open IntelliJ IDEA and create a Java project. Import the smali file decompiled in the previous step into the SRC folder. As shown in figure:

  5. Then open Eclipse, switch to DDMS view, select the phone and view its port, as shown in the picture:

    As shown in the figure, the port of the target application is 8631.

  6. Switch to IntelliJ IDEA and select Run-Configurations.

  7. Then create a new Remote, fill in port 8631, and select Source Using Module’s classpath for the project we created earlier, and click OK

  8. Method protected a()Ljava/lang/String; After the breakpoint is set at the beginning of the function, enter the account password in the mobile phone, click login, and you can see that the breakpoint is successfully broken, as shown in the picture:

    As can be seen from the figure, the lower left corner is the function call stack, from the login button press (OnClick), to api.user.login the entire call process. If you expand p0 in the lower right corner, you can see that three parameters have been generated,

    The parameter is generated before the breakpoint. So we look at each function called by its call stack. Look it up and you’ll find. Method public a(Ljava/lang/String; Ljava/lang/String; Ljava/lang/String;) V method. In the new – the instance where v0, Lcom/babytree/platform/API/muser/Login; Break point and click login button again, as shown in the picture:

    At this time, the v1.v2.v3 registers are respectively encrypted. As can be seen from the above, they correspond to three parameters: phone_number,password and email.

    So the encrypted function should be up there. Go up and down the breakpoint and watch the encryption process again.

    Unknown:

    iget-object v0, p0, Lcom/babytree/apps/pregnancy/activity/LoginActivity; ->u:Ljava/lang/String;Copy the code

    After this function call,v0 is a fixed string.

    invoke-static {p1, v0}, Lcom/babytree/apps/pregnancy/h/a; ->a(Ljava/lang/String; Ljava/lang/String;) Ljava/lang/String;Copy the code

    After the call,v1 is the encrypted result. View a function:

    V0 is encrypted for RSA, so the previous v0 is the RSA pubKey. Use a breakpoint in function A to see what the encryption argument is:

    Everything is in sight. Therefore, the algorithm of phone_number,password and email parameters can be known.

  9. Now let’s look at secret’s algorithm.

    Back to AndroidKiller search keywords, positioning to com/babytree/platform/API/ApiCommonParams; At a glance, this is the class generated by the API’s generic parameters. And load a so: api_encrypt. So look at near the secret key, calls the invoke the so – static {v1, v2}, Lcom/babytree/platform/API/ApiCommonParams; ->nativeGetParam(Landroid/content/Context; Ljava/util/List;) Ljava/lang/String; Methods.

    Let’s make a break point on this to see what arguments are passed to the so function. After the breakpoint is broken, you see that the argument passed to so is a List, and all the arguments in the POST argument except secret. We know the parameters, we know the call point. Analyze the SO to see if dynamic debugging is required. Load IDA and find the function called nativeGetParam. After a quick look, the Java MD5 function was called again, and now the debugging of so is done.

    Go back to IntelliJ IDEA, set breakpoint at getMD5Str and continue debugging:

    Soon we will see that p0 is the md5 parameter.

    Secret is MD5(timestamp + asdf12341dfAS! @#$%()(Ujjlasdflasdfj; asjdf23412313kljajsdflasjdflasjdflajsdf; lajsdf2342234sdfsdfffds)

Conclusion:

Dynamic debugging apK allows us to understand the process of APK operation, through the combination of dynamic and static analysis, quickly find what we want ~

0x05 Signature Verification


Put the key code in so, and get the signature information underneath and verify it. Because the acquisition and verification methods are closed in a more secure SO database, it can play a certain protective role. Examples are as follows:

  1. Search for getSignature in the program and find no place to call this function. Guess in the so file and search for loadLibrary.

  2. You can look it up in the code and find that signaturex.so is called

  3. Open signaturex.so with IDA, and then search getSiganture to find where this function is called. From the code you can see, this function calls the org. Cocos2dx. CPP. AppActivity. GetSignature

  4. Looking at the F5 code, we see that this function is the function that determines the signature, and then we double-click the caller of this function, with the following part of the code.

  5. As you can see from the figure above, you can bypass signature verification by simply changing BEQ loc_11F754 to not jump to JJNI — >error. To view HEX, use 010Editor to jump to 0011F73E and change D0 to D1. Signature verification was successfully bypassed.