Jarvis OJ平台安卓部分解题思路
以下为Jarvis OJ平台安卓逆向部分题目的解题思路,难题攻坚中,后续做出会进行补充。
[61dctf]androideasy
1、利用工具对该apk进行反编译,利用jd查看其java源码中的MainActivity.class下的oncreate方法:
if (MainActivity.this.check()) {
Toast.makeText(jdField_this, "You got the flag!", 1).show();
}
2、通过上述我们定位到check()方法
private byte[] s = { 113, 123, 118, 112, 108, 94, 99, 72, 38, 68, 72, 87, 89, 72, 36, 118, 100, 78, 72, 87, 121, 83, 101, 39, 62, 94, 62, 38, 107, 115, 106 };
public boolean check()
{
boolean bool1 = false;
byte[] arrayOfByte = this.editText.getText().toString().getBytes();
boolean bool2;
if (arrayOfByte.length != this.s.length) {
bool2 = bool1;
}
for (;;)
{
return bool2;
for (int i = 0;; i++)
{
if ((i >= this.s.length) || (i >= arrayOfByte.length)) {
break label75;
}
bool2 = bool1;
if (this.s[i] != (arrayOfByte[i] ^ 0x17)) {
break;
}
}
label75:
bool2 = true;
}
}
3、对上述代码分析后我们得到其flag思路为:
将flag转化为字节数组 --> 对数组中的每一位与0x17进行异或操作 --> 将抑或后的值转为十进制与s数列中的对应位进行比较
DD-Android Easy
1、反编译该APK,利用jd查看其java源码中的FlagActivity.class查看方法名发现该apk可能经过混淆。并怀疑其i()方法即为flag算法
2、通过模拟器安装该apk,点击提交获得关键词“密码错误 Wrong Key”
3、在反编译工具中逐级搜索关键词并确定至FlagActivity.clas中的onClickTest()方法:
public void onClickTest(View paramView)
{
if (this.n.getText().toString().equals(i())) {
this.o.setText(2131099685);
}
for (;;)
{
return;
this.o.setText(2131099683);
}
}
4、并在if判断中调用了i()方法——因此我们确定i()方法为flag的产生算法
rivate static final byte[] p = { -40, -62, 107, 66, -126, 103, -56, 77, 122, -107, -24, -127, 72, -63, -98, 64, -24, -5, -49, -26, 79, -70, -26, -81, 120, 25, 111, -100, -23, -9, 122, -35, 66, -50, -116, 3, -72, 102, -45, -85, 0, 126, -34, 62, 83, -34, 48, -111, 61, -9, -51, 114, 20, 81, -126, -18, 27, -115, -76, -116, -48, -118, -10, -102, -106, 113, -104, 98, -109, 74, 48, 47, -100, -88, 121, 22, -63, -32, -20, -41, -27, -20, -118, 100, -76, 70, -49, -39, -27, -106, -13, -108, 115, -87, -1, -22, -53, 21, -100, 124, -95, -40, 62, -69, 29, 56, -53, 85, -48, 25, 37, -78, 11, -110, -24, -120, -82, 6, -94, -101 };
private static final byte[] q = { -57, -90, 53, -71, -117, 98, 62, 98, 101, -96, 36, 110, 77, -83, -121, 2, -48, 94, -106, -56, -49, -80, -1, 83, 75, 66, -44, 74, 2, -36, -42, -103, 6, -115, -40, 69, -107, 85, -78, -49, 54, 78, -26, 15, 98, -70, 8, -90, 94, -61, -84, 64, 112, 51, -29, -34, 126, -21, -126, -71, -31, -24, -60, -2, -81, 66, -84, 85, -91, 10, 84, 70, -8, -63, 26, 126, -76, -104, -123, -71, -126, -62, -23, 11, -39, 70, 14, 59, -101, -39, -124, 91, -109, 102, -49, 21, 105, 0, 37, -128, -57, 117, 110, -115, -86, 56, 25, -46, -55, 7, -125, 109, 76, 104, -15, 82, -53, 18, -28, -24 };
private TextView n;
private TextView o;
private String i()
{
int i = 0;
byte[] arrayOfByte1 = new byte[p.length];
for (int j = 0; j < arrayOfByte1.length; j++) {
arrayOfByte1[j] = ((byte)(byte)(p[j] ^ q[j]));
}
int k = arrayOfByte1[0];
for (j = 0; arrayOfByte1[(k + j)] != 0; j++) {}
byte[] arrayOfByte2 = new byte[j];
while (i < j)
{
arrayOfByte2[i] = ((byte)arrayOfByte1[(k + i)]);
i++;
}
return new String(arrayOfByte2);
}
5、通过对上述代码的分析我们得到flag的算法思路为:
对p,q数列对应位进行异或并存放至字符串arrayOfByte1 --> 计算得出异或值为0的位j --> 将从k位开始到k+j位结束的值转化位字符串(即为flag)
Smali
在做本题时需要比较熟悉smali语言,否则就是看不懂(快看不懂了/无奈)
1、从上往下查看,我们先看到两个base64加密的字符串,紧接着调用了GetFlag方法并将第一个个加密字符串传进去
2、在getflag中将第一个加密字符串解密并赋值给str2
3、之后通过调用decrypt方法,通过该方法我们发现flag通过AES的ECB加密,并且将第一个字符串的解密值作为AES解密的KEY,由此我们可以得出flag的解密方法。
(4、下面的try … catch … 为异常处理)
DD-Android normal
1、反编译该APK,利用jd查看其java源码中的FMainActivity.class,并未发现相关算法,但看到两个行关键代码System.loadLibrary(“hello-libs”)和public native String stringFromJNI(),说明存在so文件:
public class MainActivity
extends AppCompatActivity
{
private TextView mFlagEntryView;
private TextView mFlagResultView;
static
{
System.loadLibrary("hello-libs");
}
public void onClickTest(View paramView)
{
if (this.mFlagEntryView.getText().toString().equals(stringFromJNI())) {
this.mFlagResultView.setText("Correct");
}
for (;;)
{
return;
this.mFlagResultView.setText("Wrong");
}
}
protected void onCreate(Bundle paramBundle)
{
super.onCreate(paramBundle);
setContentView(2130968602);
this.mFlagEntryView = ((TextView)findViewById(2131427413));
this.mFlagResultView = ((TextView)findViewById(2131427415));
}
public native String stringFromJNI();
}
2、利用IDA加载该so文件,定位到关键函数并反汇编得到其伪C代码:
int __fastcall __aeabi_wind_cpp_pr45(char *a1)
{
char *v1; // r4@1
int v2; // r1@1
int v3; // r3@3
int v4; // r6@4
int v5; // r5@5
int v6; // r2@5
int result; // r0@7
char v8[182]; // [sp+6h] [bp-CAh]@2
int v9; // [sp+BCh] [bp-14h]@1
v1 = a1;
v2 = 0;
v9 = _stack_chk_guard;
do
{
v8[v2] = byte_66C[v2] ^ byte_722[v2]; // R5^R6
++v2; // R1
}
while ( v2 != 182 );
v3 = 0;
do
v4 = (unsigned __int8)*(&v8[(unsigned int)(unsigned __int8)v8[0] >> 1] + v3++);
while ( v4 );
v5 = v3 - 1;
v6 = 0;
if ( v3 - 1 >= 1 )
{
_aeabi_memcpy();
v6 = v5;
}
v1[v6] = 0;
result = _stack_chk_guard - v9;
if ( _stack_chk_guard != v9 )
_stack_chk_fail();
return result;
}
3、通过对上述代码分析我们得到其过程为:
对byte_66C与byte_722起始的数据进行异或处理 --> 输出从第28位开始到值为0所对应的字符即为FLAG(不妨直接输出异或后的所有值)
好久没写了,以上为常规做题方法,有错亦或是有什么新姿势还望留言互相学习