BUUCTF [Zer0pts2020]easy strcmp
两个考点:
假的strcmp 实则调用的是其他的函数
用C实现反汇编中的_QWORD等
其实关于第一个考点
表层分析:
这个肯定不是flag strcmp也是看似正常的extern strcmp
我们在左边的函数列表中逐一查看
只有这个函数有变换的作用
深层分析:
在init()函数中
可以发现
for ( i = 0LL; i != v4; ++i )
((void (__fastcall *)(_QWORD, __int64, __int64))*(&funcs_889 + i))(a1, a2, a3);
这是从&func_889开始调用了一系列函数
找到funcs_889的位置
逐一查看 在sub_795中
终于看到 strcmp函数的位置被修改为了qword_201090
跟进查看 off_201028
正是 strcmp在plt表中的位置 然后被修改为了sub_6EA
所以调用strcmp实际上调用的是sub_6EA
然后可以查看到qword_201060是5个64位16进制数
这里如果用python写的话很容易错也不好写 因为涉及到了字符串转_QWORD后运算
思路就是 最后的qword_201090肯定是比较判断 而我们已知a2 所以将
字符串 "zer0pts{********CENSORED******.}" 8位8位的加回去就可以了
第二个考点 C关于_DWORD这些的处理方法:
#include<bits/stdc++.h>
using namespace std;
int main(){
char p[] = "zer0pts{********CENSORED********}";
uint64_t qword_202060[] = {0, 0x410A4335494A0942, 0x0B0EF2F50BE619F0, 0x4F0A3A064A35282B, 0};
for(int j=0;j<5;j++)
*(uint64_t *)&(p[8*j]) += qword_202060[j];
cout<<p;
}
C中 _QWORD等价于 uint64_t (__int64也可以)
这里不直接写 p[8*j]是因为要将字符串转成 __int64
所以这里用指针的形式写
最后得到flag