bugku安卓逆向题目First_Mobile(xman)

参考资料

题目来源

题目来自bugku的First_Mobile(xman)

工具

JADX 反编译apk。

gcc 用来编写还原算法。

简单看一下

拿到题目,看后缀是安卓APP,直接甩到夜神里看看啥样子。

反编译,提取算法

MainActivity UI 逻辑

将APK拖入JADX工具,获取到MainActivity代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class MainActivity extends AppCompatActivity {
    private Button button;
    private EditText editText;
 
    /* JADX INFO: Access modifiers changed from: protected */
    @Override // android.support.v7.app.AppCompatActivity, android.support.v4.app.FragmentActivity, android.support.v4.app.BaseFragmentActivityGingerbread, android.app.Activity
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final EditText editText = (EditText) findViewById(R.id.editText);
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() { // from class: com.example.xman.easymobile.MainActivity.1
            @Override // android.view.View.OnClickListener
            public void onClick(View view) {
                new encode();
                if (encode.check(editText.getText().toString())) {
                    Toast.makeText(MainActivity.this.getApplicationContext(), "correct", 1).show();
                } else {
                    Toast.makeText(MainActivity.this.getApplicationContext(), "failed", 1).show();
                }
            }
        });
    }
}

MainActivity 代码解读

  • 创建Activity时,为button添加click事件。
  • button点击时,获取输入的字符串,传入encode的check函数对字符串检测。
  • encode的check函数,返回true时,显示正确提示!否则提示错误。

提取算法代码

双击enocode的check函数,直接跳转到encode类的实现页面。

可以看到算法如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* loaded from: classes.dex */
public class encode {
    private static byte[] b = {23, 22, 26, 26, 25, 25, 25, 26, 27, 28, 30, 30, 29, 30, 32, 32};
 
    public static boolean check(String str) {
        byte[] input = str.getBytes();
        byte[] temp = new byte[16];
        for (int i = 0; i < 16; i++) {
            temp[i] = (byte) ((input[i] + b[i]) % 61);
        }
        for (int i2 = 0; i2 < 16; i2++) {
            temp[i2] = (byte) ((temp[i2] * 2) - i2);
        }
        String key = new String(temp);
        return key.equals(str);
    }
}

编写逆向还原算法

推导过程

逻辑整理得:

((input[i] + b[i]) % 61) * 2 -i = input[i]

设:input[i] = x

1
2
3
4
5
((input[i] + b[i]) % 61) * 2 -i = input[i]
 
=> (x % 61) * 2 + (b[i] % 61) * 2 = x
 
=> (b[i] % 61) * 2 - i = x - (x % 61) * 2

编写keygen

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <stdlib.h>
 
void main()
{
    unsigned char b[] = {23, 22, 26, 26, 25, 25, 25, 26, 27, 28, 30, 30, 29, 30, 32, 32};
    char input[20] = {0};
    char c;
    for (int i = 0; i < 16; i++)
    {
        c = (b[i] % 61) * 2 - i;
        printf(" b[i] %% 61 * 2 - i = x - x %% 61 * 2  => x - x %% 61 * 2 = %d\n", c);
        for (int j = c; j < 255; j++)
        {
            if ( (j - (j % 61) * 2) == c)
            {
                input[i] = j;
                printf("input[%d]=%c(%d)\n",i,j,j);
                break;
            }       
        }  
    }
    printf(input);
}

获取flag

运行代码获取str

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
b[i] % 61 * 2 - i = x - x % 61 * 2  => x - x % 61 * 2 = 46
input[0]=L(76)
 b[i] % 61 * 2 - i = x - x % 61 * 2  => x - x % 61 * 2 = 43
input[1]=O(79)
 b[i] % 61 * 2 - i = x - x % 61 * 2  => x - x % 61 * 2 = 50
input[2]=H(72)
 b[i] % 61 * 2 - i = x - x % 61 * 2  => x - x % 61 * 2 = 49
input[3]=I(73)
 b[i] % 61 * 2 - i = x - x % 61 * 2  => x - x % 61 * 2 = 46
input[4]=L(76)
 b[i] % 61 * 2 - i = x - x % 61 * 2  => x - x % 61 * 2 = 45
input[5]=M(77)
 b[i] % 61 * 2 - i = x - x % 61 * 2  => x - x % 61 * 2 = 44
input[6]=N(78)
 b[i] % 61 * 2 - i = x - x % 61 * 2  => x - x % 61 * 2 = 45
input[7]=M(77)
 b[i] % 61 * 2 - i = x - x % 61 * 2  => x - x % 61 * 2 = 46
input[8]=L(76)
 b[i] % 61 * 2 - i = x - x % 61 * 2  => x - x % 61 * 2 = 47
input[9]=K(75)
 b[i] % 61 * 2 - i = x - x % 61 * 2  => x - x % 61 * 2 = 50
input[10]=H(72)
 b[i] % 61 * 2 - i = x - x % 61 * 2  => x - x % 61 * 2 = 49
input[11]=I(73)
 b[i] % 61 * 2 - i = x - x % 61 * 2  => x - x % 61 * 2 = 46
input[12]=L(76)
 b[i] % 61 * 2 - i = x - x % 61 * 2  => x - x % 61 * 2 = 47
input[13]=K(75)
 b[i] % 61 * 2 - i = x - x % 61 * 2  => x - x % 61 * 2 = 50
input[14]=H(72)
 b[i] % 61 * 2 - i = x - x % 61 * 2  => x - x % 61 * 2 = 49
input[15]=I(73)
LOHILMNMLKHILKHI

测试如下

根据题目得到flag

XMAN{LOHILMNMLKHILKHI}

上传的附件 First_Mobile(xman).7z

最新回复:
教教我吧~ 2024-03-01 20:21:55

这个地方的推导不成立:(a + b) % c ≠ a % c + b % c(此处求余无法逆向推导吧, 我不是很理解,难道有更好的理解,求分析)




我用的方式是爆破


zhenwo 2024-03-02 13:01:48
教教我吧~ 这个地方的推导不成立:(a + b) % c ≠ a % c + b % c(此处求余无法逆向推导吧, 我不是很理解,难道有更好的理解,求分析)我用的方式是爆破
b[i] 的值是确定的,最后变成了 n = x - (x % 0x61)* 2 
所以 将for(x = n ; ;x++) {if( n == x - (x % 0x61)* 2 ) break;} 就行。
有一些小爆破。