福州公交集团网站建设,推荐网站网页,山东网站建设的方案,事业单位门户网站建设评价文章目录前言一、[SWPUCTF 2021 新生赛]re1二、[SWPUCTF 2021 新生赛]re2三、[GFCTF 2021]wordy[花指令]四、[NSSRound#3 Team]jump_by_jump[花指令]五、[NSSRound#3 Team]jump_by_jump_revenge[花指令]前言
心血来潮#xff0c;想接触点Reverse#xff0c;感受下Reverse想接触点Reverse感受下Reverse于是从CTF的简单题目中慢慢入门 提示以下是本篇文章正文内容下面案例可供参考
一、[SWPUCTF 2021 新生赛]re1
1、工具IDA 直接使用IDA将exe反编译得到一堆代码。 使用CtrlX查看编译流程然后使用F5查看代码。 int __cdecl main(int argc, const char **argv, const char **envp)
{char Str2[1008]; // [rsp20h] [rbp-60h] BYREFchar Str1[1000]; // [rsp410h] [rbp390h] BYREFint i; // [rsp7FCh] [rbp77Ch]_main();strcpy(Str2, {34sy_r3v3rs3});printf(please put your flag:);scanf(%s, Str1);for ( i 0; i 665; i ){if ( Str1[i] 101 )Str1[i] 51;}for ( i 0; i 665; i ){if ( Str1[i] 97 )Str1[i] 52;}if ( strcmp(Str1, Str2) )printf(you are wrong,see again!);elseprintf(you are right!);system(pause);return 0;
}将输入的字符ascii为101的变成5197的变成52然后与str2对比一致则成功。 s {34sy_r3v3rs3}
r
for i in s:if ord(i) 51:r chr(101)elif ord(i) 52:r chr(97)else:r i
print(r) 得到flag 二、[SWPUCTF 2021 新生赛]re2
int __cdecl main(int argc, const char **argv, const char **envp)
{char Str2[64]; // [rsp20h] [rbp-90h] BYREFchar Str[68]; // [rsp60h] [rbp-50h] BYREFint v7; // [rspA8h] [rbp-8h]int i; // [rspACh] [rbp-4h]_main();strcpy(Str2, ylqq]aycqyp{);printf(Format);gets(Str);v7 strlen(Str);for ( i 0; i v7; i ){if ( (Str[i] 96 || Str[i] 98) (Str[i] 64 || Str[i] 66) )Str[i] - 2;elseStr[i] 24;}if ( strcmp(Str, Str2) )printf(asc_404024);elseprintf(aBingo);system(pause);return 0;
}s ylqq]aycqyp{
l []
for i in s:l.append(ord(i))
# print(l)
l [121, 108, 113, 113, 93, 97, 121, 99, 113, 121, 112, 123]
r
for i in l:if (i 94 or i 96) and (i 62 or i 64):r chr(i 2)else:r chr(i - 24)
print(r)得到的结果进行caser并且猜一下得到{nss_caesar} 三、[GFCTF 2021]wordy[花指令]
花指令实质就是一串垃圾指令它与程序本身的功能无关并不影响程序本身的逻辑。在软件保护中花指令被作为一种手段来增加静态分析的难度花指令也可以被用在病毒或木马上通过加入花指令改变程序的特征码躲避杀软的扫描从而达到免杀的目的。花指令是让反编译器无法反编译起到混淆租用的指令一般最常见的就是在机器码中加入 E8E8 加入后会将汇编代码改变为 CALL而后续的机器码代表的东西是没有意义的不是一个函数所以 CALL 之后反编译器无法识别。 存在大量jmp跳转导致程序无法正常编译尝试将跳转nop掉即将其转换成空指令。 startaddr 0x1135
endaddr 0x3100for i in range(startaddr,endaddr):if get_wide_byte(i) 0xEB:if get_wide_byte(i1) 0xFF:patch_byte(i,0x90)print([] Addr {} is patched.format(hex(i))) 起始地址是main函数的0x1135到结束通过遍历byte判断是否和EB FF即jmp的机械码是则改成90即nop。 看到flag为GFCTF{u_are2wordy} 四、[NSSRound#3 Team]jump_by_jump[花指令]
先找主函数入口即main 可以看到0041188C处有call并且爆红可以判断为花指令因此要消除即变成nop选中41188C按快捷键D将其转换为数据。 然后将0E8h改成0x90即nop机器码 快捷键C将数据再次转换成指令并将下面黄色的部分依次使用C转换成指令。 最后往上选中main入口快捷键P生成函数然后F5获得函数代码。 int __cdecl main_0(int argc, const char **argv, const char **envp)
{int i; // [espD0h] [ebp-2Ch]char v5[28]; // [espDCh] [ebp-20h] BYREFstrcpy(v5, NSSCTF{Jump_b9_jump!});for ( i 0; i 21; i )v5[i] (v5[i] v5[(i * i 123) % 21]) % 128;sub_4110CD(%s, (char)v5);return 0;
}发现flag根本没被加密直接开始ShiftF12就可以看到字符串。 五、[NSSRound#3 Team]jump_by_jump_revenge[花指令] 跟上面一样将爆红那里改成空指令PF5得到伪代码。 int __cdecl main_0(int argc, const char **argv, const char **envp)
{int i; // [espD0h] [ebp-40h]char Str1[36]; // [espE8h] [ebp-28h] BYREFsub_411037(%s, (char)Str1);for ( i 0; i 29; i )Str1[i] (Str1[i] Str1[(i * i 123) % 21]) % 96 32;if ( !j_strcmp(Str1, ~4G~M:WV7iX,zlViGmu4?hJ0H-Q*) )puts(right!);elseputs(nope!);return 0;
}将flag打乱了并且进行了变换逆向解密。 a [~, 4, G, ~, M, :, , W, V, 7, i, X, ,, z, l, V, i, G, m, u, 4, ?, h,J, 0, H, -, Q, *]for i in range(28, -1, -1):k (i * i 123) % 21for j in range(5):x (ord(a[i]) - 32 j * 96 - ord(a[k]))if 33 x 126:a[i] chr(x)break
print(.join(a))