public class MainActivity extends AppCompatActivity {
EditText input;
static {
System.loadLibrary("native-lib");
}
@Override // androidx.appcompat.app.AppCompatActivity
protected void onCreate(Bundle arg2) {
super.onCreate(arg2);
this.setContentView(0x7F0B001C); // layout:activity_main
Button v2 = (Button)this.findViewById(0x7F080023); // id:button
this.input = (EditText)this.findViewById(0x7F080056); // id:input
v2.setOnClickListener(new View.OnClickListener() {
@Override // android.view.View$OnClickListener
public void onClick(View arg7) {
try {
if(MainActivity.this.input.getText().length() == 42) {
Toast v7_2 = Toast.makeText(MainActivity.this, MainActivity.this.stringFromJNI(MainActivity.this.input.getText().toString(), new hi().getSignatures(arg7)), 1);
v7_2.setGravity(0, 0, -700);
v7_2.show();
return;
}
Toast v7_3 = Toast.makeText(MainActivity.this, "Hello!", 0);
v7_3.setGravity(0, 0, -700);
v7_3.show();
}
catch(PackageManager.NameNotFoundException v7_1) {
v7_1.printStackTrace();
}
catch(NoSuchAlgorithmException v7) {
v7.printStackTrace();
}
}
});
}
public native String stringFromJNI(String arg1, String arg2) {
}
}
按钮onClick事件,点击后判断编辑框内内容长度是否等于42;
验证成功后 进行toast提示
toast提示的内容是native函数stringFromJNI
的返回值
两个参数,一个参数是输入的内容,另一个是new hi().getSignatures(arg7)
的返回值
public String getSignatures(View arg3) throws PackageManager.NameNotFoundException, NoSuchAlgorithmException {
MessageDigest.getInstance("MD5");
Signature[] v3 = arg3.getContext().getPackageManager().getPackageInfo("com.example.hello", 0x40).signatures;
if(v3.length > 0) {
Signature v3_1 = v3[0];
Log.i("hello", v3_1.toCharsString());
return v3_1.toCharsString();
}
return "this_is_your_gift!";
}
可以看到获取的是签名信息
同时有个log打印出该签名
查看log日志得到签名为
"308202e4308201cc020101300d06092a864886f70d010105050030373116301406035504030c0d416e64726f69642044656275673110300e060355040a0c07416e64726f6964310b30090603550406130255533020170d3231303330363134333034385a180f32303531303232373134333034385a30373116301406035504030c0d416e64726f69642044656275673110300e060355040a0c07416e64726f6964310b300906035504061302555330820122300d06092a864886f70d01010105000382010f003082010a0282010100cbf2b09e4308ebb459e8841e5a7b920497fef2b349e80648f7eb35f48d40a75e7ce7945b8b42d197bec0bf177e6c9899ed707dcc4a726cb14c1a69b0c4a02474806fa73cfb10e10f7b1665021c24762b6edad65ca63cea3c72e0d4e4ca3f98301173eec3254337af1f5a11f779ecbe04d1b74d53f5835e011222155a56f97e00d75374cd93080dfa087cd356a99fe1eebf5d6d5e31846aad5252c3a17a4656e2e210ce1c7aa4d147fb8cf440a50add61bbb2ec299a2e0dab0b4504796ac3a899da553ab1d83576691ab23409d18398014b3b5eaf12e83f4d99aa09e1e4e4cae133530730c1133da2b3dee37b58eb1a5795b221ec5a8830731a41167d295f9e1b0203010001300d06092a864886f70d010105050003820101000e4740235e9cf2be33de3e06d777139cbbc5cf0622285c17da04697b8067318aaf8df0fbb4d3166f293ea15aa2592f06eb6929af063722ac9f30ad85e2c087564931d6ac65fcd5fbc864b3dc9841e039c6e1d5fbc5c2f8adf90a547bc4ebc07d387914db24451c2cc89925359bd3bb0750c7aabf9d743b1893e98bbc8ff74b24fc0b4be2dbaaf1c917bba01496d0617ffc3a4a8b7a6e79a3036298a6ebf57bb00001e43a0b242864eebb0fcec9e323144d4447c878430f18e6e358ad97566fa04d1f07b171c1476c9af5a1eba0bf6616e219c0b9e1299d09fecded24a880397f92e0f99d8951228c7770c184fd77adff943bfc8b6aa524c5f0a6d7686fe35486"
查看so文件
导出函数中找到相应函数
导入jni.h,修改前两个参数类型,得到下列伪代码
大致流程是
42位,每一位与sign[327+27*i]异或
之后将二进制八位的低三位,放到高三位。也就是原先的76543210变为21076543
写脚本解
#include <stdio.h>
unsigned char data[42] = {
0xCA, 0xEB, 0x4A, 0x8A, 0x68, 0xE1, 0xA1, 0xEB, 0xE1, 0xEE, 0x6B, 0x84, 0xA2, 0x6D, 0x49, 0xC8,
0x8E, 0x0E, 0xCC, 0xE9, 0x45, 0xCF, 0x23, 0xCC, 0xC5, 0x4C, 0x0C, 0x85, 0xCF, 0xA9, 0x8C, 0xF6,
0xE6, 0xD6, 0x26, 0x6D, 0xAC, 0x0C, 0xAC, 0x77, 0xE0, 0x64
};
char sign[] = "308202e4308201cc020101300d06092a864886f70d010105050030373116301406035504030c0d416e64726f69642044656275673110300e060355040a0c07416e64726f6964310b30090603550406130255533020170d3231303330363134333034385a180f32303531303232373134333034385a30373116301406035504030c0d416e64726f69642044656275673110300e060355040a0c07416e64726f6964310b300906035504061302555330820122300d06092a864886f70d01010105000382010f003082010a0282010100cbf2b09e4308ebb459e8841e5a7b920497fef2b349e80648f7eb35f48d40a75e7ce7945b8b42d197bec0bf177e6c9899ed707dcc4a726cb14c1a69b0c4a02474806fa73cfb10e10f7b1665021c24762b6edad65ca63cea3c72e0d4e4ca3f98301173eec3254337af1f5a11f779ecbe04d1b74d53f5835e011222155a56f97e00d75374cd93080dfa087cd356a99fe1eebf5d6d5e31846aad5252c3a17a4656e2e210ce1c7aa4d147fb8cf440a50add61bbb2ec299a2e0dab0b4504796ac3a899da553ab1d83576691ab23409d18398014b3b5eaf12e83f4d99aa09e1e4e4cae133530730c1133da2b3dee37b58eb1a5795b221ec5a8830731a41167d295f9e1b0203010001300d06092a864886f70d010105050003820101000e4740235e9cf2be33de3e06d777139cbbc5cf0622285c17da04697b8067318aaf8df0fbb4d3166f293ea15aa2592f06eb6929af063722ac9f30ad85e2c087564931d6ac65fcd5fbc864b3dc9841e039c6e1d5fbc5c2f8adf90a547bc4ebc07d387914db24451c2cc89925359bd3bb0750c7aabf9d743b1893e98bbc8ff74b24fc0b4be2dbaaf1c917bba01496d0617ffc3a4a8b7a6e79a3036298a6ebf57bb00001e43a0b242864eebb0fcec9e323144d4447c878430f18e6e358ad97566fa04d1f07b171c1476c9af5a1eba0bf6616e219c0b9e1299d09fecded24a880397f92e0f99d8951228c7770c184fd77adff943bfc8b6aa524c5f0a6d7686fe35486";
int main() {
int i,j;
for (i = 0; i < 42; i++) {
data[i] = (data[i] << 3 | data[i] >> 5 & 0x7) & 0xFF;
}
for (i = 0,j=327; i < 42; i++,j+=27) {
data[i] ^= sign[j] + i;
}
puts((char*)data);
}
得到flag为flag{d5577edd-8211-7a0e-f23a-305b0b10683f}