如果瞎输入的话,就是会报错的
可以发现,字符串是没有交叉引用的
不过既然函数不是很多,可以手动 F5 去看特征
所以,我们换一种思路,从QEMU源码的角度来分析,QEMU是把该二进制文件rebase到了哪里呢?
https://github.com/qemu/qemu
[url=https://github.com/qemu/qemu/tree/master/hw/arm]https://github.com/qemu/qemu/tree/master/hw/arm[/url]
[url=https://github.com/qemu/qemu/blob/master/hw/arm/boot.c]https://github.com/qemu/qemu/blob/master/hw/arm/boot.c[/url]
[url=https://github.com/qemu/qemu/blob/master/hw/arm/vexpress.c]https://github.com/qemu/qemu/blob/master/hw/arm/vexpress.c[/url]
|
当没有 entry 的时候,IDA 里的字符串没有交叉引用的
顺着这个流程图,明显就能找到题中的 main 了
length = 0x28 = 40
长度不够,后续添加字符 'a',加上之前的 TEA 算法,就很容易搞明白程序的流程和逻辑了
该函数为输入flag后的程序函数,其首先会对输入的flag进行分组,每组两个int一共5组。
对key进行分组,每组4个int,一共3组。
并对flag做5次tea加密。
#include <bits/stdc++.h>
using namespace std;
#define UINT unsigned int
#define DELTA 0x9e3779b9
void tea_decrypt(UINT* v, UINT* key) {
UINT l = v[0], r = v[1], sum = 0;
sum = DELTA * 32;
for (size_t i = 0; i < 32; i++) {
r -= (((l << 4) ^ (l >> 5)) + l) ^ (sum + key[(sum >> 11) & 3]);
sum -= DELTA;
l -= (((r << 4) ^ (r >> 5)) + r) ^ (sum + key[sum & 3]);
}
v[0] = l;
v[1] = r;
}
UINT str2int(char* str){
UINT ret = 0;
for (int i = 0; i < 4; i++)
ret += pow(0x100, i) * str[i];
return ret;
}
void int2str(int num, char* str1){
char ch;
for (int i = 0; i < 4; i++) {
ch = num & 0xff;
num = num >> 8;
str1[i] = ch;
}
return;
}
int main(){
char flag[100] = { 0 }, key[] = "dddwwawwwwaasdsasawawdwaaasawassssdwdsddssasddwa";
UINT keys[12], tea_cry[2], tea_key[4], cry[] = {3179062266, 2936962595, 3754839610, 2425968462, 1458506693, 3303317055, 1294083110, 1674144741, 1029754371, 3863932833};
for (int i = 0; i < 12; i++){
char newkey[4] = { 0 };
memcpy(newkey, key + i * 4, 4);
keys[i] = str2int(newkey);
}
for (int i = 0; i < 5; i++){
tea_cry[0] = cry[i * 2], tea_cry[1] = cry[i * 2 + 1];
for (int j = 0; j < 4; j++)
tea_key[j] = keys[(i * 4 + j) % 12];
tea_decrypt(tea_cry, tea_key);
cry[i * 2] = tea_cry[0], cry[i * 2 + 1] = tea_cry[1];
}
for (int i = 0; i < 10; i++)
cout << "0x" << hex << cry[i]<< " ";
cout << endl;
for (int i = 0; i < 10; i++)
int2str(cry[i], flag + i * 4);
cout << flag << endl;
return 0;
}