|

本帖最后由 Breathless 于 2018-10-9 16:25 编辑
先用jeb反编译
- package com.ali.mobisecenhance;
- import android.app.Application;
- import android.content.Context;
- public class StubApplication extends Application {
- static {
- try {
- Class v2 = Class.forName("android.os.SystemProperties");
- Object v1 = v2.getDeclaredMethod("get", String.class).invoke(v2, "ro.product.cpu.abi");
- }
- catch(Exception v3) {
- v3.printStackTrace();
- }
- if(((String)v1).equalsIgnoreCase("x86")) {
- System.loadLibrary("mobisecx");
- }
- else {
- System.loadLibrary("mobisec");
- }
- }
- public StubApplication() {
- super();
- }
- protected native void attachBaseContext(Context arg1) {
- }
- public native void onCreate() {
- }
- }
复制代码
加了壳子~~~~关键代码看不到,那就先用ida脱壳吧
先打开DDMS
获取入口点
一键挂起
用ida附加
在ibdvm的dvmDefineClass下了个断点,通过DvmDex的指针,把odex dump下来,下好断点,点jdb启动
查看r0地址
跟随上面的地址
用脚步dump下来
- static main(void)
- {
- auto fp, dex_addr, end_addr;
- fp = fopen("C:\\dump.dex", "wb");
- end_addr = 0x75512000 + 0x00010000;
- for ( dex_addr = 0x75512000; dex_addr < end_addr; dex_addr ++ )
- fputc(Byte(dex_addr), fp);
- }
复制代码
然后修复,最后用版主的Apktool工具,反编译dex,再回编译,就可以用jeb打开了
下面就是分析java代码了
主要是根据这个表对我们输入的字符串,进行置换
- static {
- e.a = new HashMap();
- e.a("a", ". _");
- e.a("b", "_ . . .");
- e.a("c", "_ . _ .");
- e.a("d", "_ . .");
- e.a("e", ".");
- e.a("f", ". . _ .");
- e.a("g", "_ _ .");
- e.a("h", ". . . .");
- e.a("i", ". .");
- e.a("j", ". _ _ _");
- e.a("k", "_ . _");
- e.a("l", ". _ . .");
- e.a("m", "_ _");
- e.a("n", "_ .");
- e.a("o", "_ _ _");
- e.a("p", ". _ _ .");
- e.a("q", "_ _ . _");
- e.a("r", ". _ .");
- e.a("s", ". . .");
- e.a("t", "_");
- e.a("u", ". . _");
- e.a("v", ". . . _");
- e.a("w", ". _ _");
- e.a("x", "_ . . _");
- e.a("y", "_ . _ _");
- e.a("z", "_ _ . .");
- e.a("2", ". _ _ _ _");
- e.a("1", ". . _ _ _");
- e.a("3", ". . . _ _");
- e.a("4", ". . . . _");
- e.a("0", ". . . . .");
- e.a("6", "_ . . . .");
- e.a("9", "_ _ . . .");
- e.a("8", "_ _ _ . .");
- e.a("7", "_ _ _ _ .");
- e.a("5", "_ _ _ _ _");
- }
- public e() {
- super();
- }
- public String a(String arg8) {
- String v0;
- dn.b(dn.a());
- if(arg8.equals("...___...")) {
- v0 = "sos";
- }
- else {
- StringBuilder v2 = new StringBuilder();
- String[] v3 = arg8.split("\\s+"); //根据空格进行分割
- int v4 = v3.length;
- int v1 = 0;
- while(true) {
- if(v1 < v4) {
- Object v0_1 = e.a.get(v3[v1]); //替换
- if(v0_1 != null) {
- v2.append(((String)v0_1));//连接
- ++v1;
- continue;
- }
- else {
- break;
- }
- }
- else {
- goto label_26;
- }
- return v0;
- }
- throw new IllegalArgumentException();
- label_26:
- v0 = v2.toString();
- }
- return v0;
- }
复制代码
下面这部分代码,根据压缩包里的strings.xml和public.xml可以分析run()返回值为0时,提示成功的字符
- public void handleMessage(Message arg5) {
- dn.b(dn.a());
- int v2 = -65536;
- this.a.b.setEnabled(true);
- switch(arg5.what) {
- case 0: {
- goto label_10;
- }
- case 1: {
- goto label_27;
- }
- case 2: {
- goto label_51;
- }
- case 3: {
- goto label_66;
- }
- }
- return;
- label_66:
- this.a.a.setTextColor(v2);
- TextView v1 = this.a.a;
- int v0 = Main.a(this.a).nextBoolean() ? 2130968582 : 2130968581;
- v1.setText(v0);
- return;
- try {
- label_51:
- this.a.a.setTextColor(-65536);
- }
- catch(Exception v0_1) {
- this.a.a.setTextColor(-7829368);
- }
- this.a.a.setText(2130968580);
- return;
- label_10:
- this.a.a.setTextColor(-16776961);
- try {
- this.a.a.setText(103 / arg5.what);
- }
- catch(Exception v0_1) {
- this.a.a.setText(2130968586);
- }
- return;
- label_27:
- this.a.a.setTextColor(v2);
- switch(Main.a(this.a).nextInt(3)) {
- case 0: {
- goto label_36;
- }
- case 1: {
- goto label_41;
- }
- case 2: {
- goto label_46;
- }
- }
- return;
- label_36:
- this.a.a.setText(2130968583);
- return;
- label_41:
- this.a.a.setText(2130968585);
- return;
- label_46:
- this.a.a.setText(2130968584);
- }
复制代码 下面的run()函数为关键点,只要返回0即可,分析逻辑和上面那个CTF很类似
- b(a arg1, Handler arg2, String arg3) {
- this.d = arg1;
- this.b = arg2;
- this.input = arg3;
- super();
- }
- public void run() {
- int v0_6;
- String v0_5;
- String v1_5;
- byte[] v2_3;
- Cipher v1_1;
- MessageDigest v0_3;
- String str;
- dn.b(dn.a());
- MessageDigest v1 = null;
- if(Build$VERSION.SDK_INT >= 10 && (Debug.isDebuggerConnected())) {
- this.b.sendEmptyMessage(1);
- return;
- }
- try {
- str = new e().a(this.input); //a函数的主要目的,在莫尔斯码表中置换
- }
- catch(Exception v0) {
- this.b.sendEmptyMessage(3);
- return;
- }
- try {
- if(str.equals("sos")) {
- this.b.sendEmptyMessage(2);
- return;
- }
- CRC32 v0_1 = new CRC32(); //crc加密
- v0_1.update(str.getBytes());
- v0_1.getValue();
- str.hashCode();
- try {
- v0_3 = MessageDigest.getInstance("sha1"); //sha1加密
- }
- catch(NoSuchAlgorithmException v0_2) {
- v0_2.printStackTrace();
- v0_3 = v1;
- }
- try {
- v1_1 = Cipher.getInstance("AES");
- }
- catch(NoSuchPaddingException v0_4) {
- v0_4.printStackTrace();
- return;
- }
- catch(NoSuchAlgorithmException v2) {
- v2.printStackTrace();
- }
- if(!b.a && v1_1 == null) {
- throw new AssertionError();
- }
- }
- catch(Exception v0) {
- goto label_26;
- }
- int v2_1 = 2;
- try {
- v1_1.init(v2_1, new SecretKeySpec(Base64.decode("GXiQHT1CZ2elMzwpvvAoPA==".getBytes(), 0), "AES")); //AES设置key
- goto label_69;
- }
- catch(Exception v0) {
- }
- catch(InvalidKeyException v2_2) {
- label_69:
- try {
- new byte[0];
- try {
- v2_3 = v1_1.doFinal(Base64.decode("hjdsUjIT5je69WXIZP7Kzw==".getBytes("UTf-8"), 0)); //AES解密,值固定
- goto label_78;
- }
- catch(UnsupportedEncodingException v1_2) {
- try {
- v1_2.printStackTrace();
- label_78:
- String v6 = new String(v2_3); //上面AES解密的
- v0_3.update(new byte[]{127});
- v0_3.update(str.getBytes());
- v0_3.update(new byte[]{1});
- }
- catch(Exception v0) {
- goto label_26;
- }
- }
- catch(BadPaddingException v1_3) {
- goto label_78;
- }
- catch(IllegalBlockSizeException v1_4) {
- goto label_78;
- }
- }
- catch(Exception v0) {
- goto label_26;
- }
- try {
- v1_5 = new String(Base64.encode(v0_3.digest(), 0)); //
- goto label_99;
- }
- catch(Exception v0) {
- try {
- v0.printStackTrace();
- return;
- label_99:
- if(!str.equals(v6)) {
- goto label_190;
- }
- else if(Arrays.equals(v1_5.getBytes(), "2398lj2n".getBytes())) {
- this.b.sendEmptyMessage(0);
- return;
- }
- else {
- v0_5 = "234";
- }
- goto label_117;
- }
- catch(Exception v0) {
- goto label_26;
- }
- }
- label_190:
- v0_5 = v1_5;
- try {
- label_117:
- if(v0_5.equals("lsdf==")) {
- this.b.sendEmptyMessage(0);
- return;
- }
- char[] v1_6 = str.toCharArray();
- v0_6 = str.substring(0, 2).hashCode();
- if(v0_6 > 3904) {
- this.b.sendEmptyMessage(4);
- return;
- }
- if(v0_6 == 3618) {
- if(v1_6[0] + v1_6[1] != 168) {
- goto label_178;
- }
- do {
- label_144:
- byte[] v5_1 = e.class.getAnnotation(f.class).a() + a.class.getAnnotation(f.class).a().getBytes();
- if(v1_6.length - 2 == v5_1.length) {
- v0_6 = 0;
- while(true) {
- if(v0_6 >= v5_1.length) {
- goto label_188;
- }
- else if(v1_6[v0_6 + 2] != v5_1[v0_6]) {
- v0_6 = 0;
- }
- else {
- ++v0_6;
- continue;
- }
- goto label_170;
- }
- }
- goto label_177;
- }
- while(true);
- }
- goto label_178;
- }
- catch(Exception v0) {
- goto label_26;
- }
- label_188:
- v0_6 = 1;
- try {
- label_170:
- if(v0_6 != 0) {
- this.b.sendEmptyMessage(0);
- return;
- }
- label_177:
- if(v2_3 == null) {
- goto label_144;
- }
- label_178:
- this.b.sendEmptyMessage(1);
- }
- catch(Exception v0) {
- label_26:
- this.b.sendEmptyMessage(1);
- }
- }
- }
复制代码
只有为这个的时候this.b.sendEmptyMessage(0);才会提示成功, label_188: ---label_117:---label_190:,跳转这三个点才能成功,
- label_190:
- v0_5 = v1_5;
- try {
- label_117:
- if(v0_5.equals("lsdf==")) {
- this.b.sendEmptyMessage(0);
- return;
- }
复制代码- v0_3.update(new byte[]{127});
- v0_3.update(str.getBytes());
- v0_3.update(new byte[]{1});
- v1_5 = new String(Base64.encode(v0_3.digest(), 0));
- v0_5 = v1_5;
复制代码 由于前面对v0_3的处理,导致不能相等,所以只剩下label_170:这个独苗,然后看可以谁跳转到label_170:
- char[] v1_6 = str.toCharArray();
- v0_6 = str.substring(0, 2).hashCode();
- if(v0_6 > 3904) {
- this.b.sendEmptyMessage(4);
- return;
- }
- if(v0_6 == 3618) {
- if(v1_6[0] + v1_6[1] != 168) {
- goto label_178;
- }
- do {
- label_144:
- byte[] v5_1 = e.class.getAnnotation(f.class).a() + a.class.getAnnotation(f.class).a().getBytes();
- if(v1_6.length - 2 == v5_1.length) {
- v0_6 = 0;
- while(true) {
- if(v0_6 >= v5_1.length) {
- goto label_188;
- }
- else if(v1_6[v0_6 + 2] != v5_1[v0_6]) {
- v0_6 = 0;
- }
- else {
- ++v0_6;
- continue;
- }
- goto label_170;
- }
- }
- goto label_177;
- }
- while(true);
- }
- goto label_178;
- }
复制代码
分析可知,v0_6 == 3618 和 v1_6[0] + v1_6[1] = 168必须同时成立,v0_6 = str.substring(0, 2).hashCode();,由于前面置换表只有小写字母和数字,所以可以直接遍历
- #include <stdio.h>
- #include <stdlib.h>
- int main()
- {
- int arry[] = { 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122 };
- int n = sizeof(arry) / sizeof(arry[0]);
- for (int i = 0; i < n; i++)
- {
- for (int j = 0; j < n; j++)
- {
- if ((arry[i] * 31 + arry[j]) == 3618)
- {
- printf("%d----%d\n", arry[i],arry[j]);
- }
- }
- }
- system("pause");
- return 0;
- }
复制代码
c语言很垃圾,只能写这个了.........结果有两个113----115和115----53,只有后面的符合要求,转换成acsll为s5,接着往下看
- byte[] v5_1 = e.class.getAnnotation(f.class).a() + a.class.getAnnotation(f.class).a().getBytes(); //获取后面四个字符
- if(v1_6.length - 2 == v5_1.length) {
- v0_6 = 0;
- while(true) {
- if(v0_6 >= v5_1.length) {
- goto label_188;
- }
- else if(v1_6[v0_6 + 2] != v5_1[v0_6]) {
- v0_6 = 0;
- }
- else {
- ++v0_6;
- continue;
- }
- goto label_170;
- }
- }
复制代码
下面就可以看出来是比较了,要长度相等,字符相等,所以后面的为7e1p,加上前面的s5为s57e1p,然后再置换一下就行了,结果为... _____ ____. . ..___ .__.
贴下java的分析代码,很垃圾····························
- import java.io.UnsupportedEncodingException;
- import java.security.InvalidKeyException;
- import java.security.MessageDigest;
- import java.security.NoSuchAlgorithmException;
- import java.util.Base64;
- import java.util.Base64.Decoder;
- import java.util.Base64.Encoder;
- import javax.crypto.BadPaddingException;
- import javax.crypto.Cipher;
- import javax.crypto.IllegalBlockSizeException;
- import javax.crypto.NoSuchPaddingException;
- import javax.crypto.spec.SecretKeySpec;
- public class aestest {
-
- public static void main(String[] args) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException {
- byte[] v2_3;
- Cipher v1_1;
- String v5 = "s57e1p";
- String v1_5;
- int v0_6;
- MessageDigest v0_3;
- char[] v1_6 = v5.toCharArray();
- v0_3 = MessageDigest.getInstance("sha1");
- v1_1 = Cipher.getInstance("AES");
- Decoder decoder = Base64.getDecoder();
- Encoder encode = Base64.getEncoder();
- v1_1.init(2, new SecretKeySpec(decoder.decode("GXiQHT1CZ2elMzwpvvAoPA==".getBytes()), "AES"));
- v2_3 = v1_1.doFinal(decoder.decode("hjdsUjIT5je69WXIZP7Kzw==".getBytes("UTf-8")));
- System.out.println(v2_3);
- v0_3.update(new byte[]{127});
- v0_3.update(v5.getBytes());
- v0_3.update(new byte[]{1});
- String v6 = new String(v2_3);
- v1_5 = new String(encode.encode(v0_3.digest()));
- System.out.println(v1_5);
- v0_6 = v5.substring(0, 2).hashCode();
- System.out.println(v0_6);
- }
- }
复制代码
|
|