本文最后更新于:3 years ago
今天刚好打完省赛,两道re题,只做出来一道,,,希望下次能够尽量都做出来。在吾爱破解上面看到有人一天写一篇关于re题的wp,已经连续记录了有一百多天了。我觉的这样很好,为了防止我可能会懈怠,这里也想模仿一下记录一下自己学习过程,正好省赛结束了,从今天开始,一天一道,到明年省赛应该就将近一年了。 大概学习逆向应该有三十天了,其实是不止的,从暑假我就开始学习逆向了,但是正式做CTF题应该是最近一个月开始的,所以就按照三十天算的。想想我成为reverse大师的那一天,,啧啧。
从BUUCTF开始
================================
0x01 查壳和详细信息 .exe文件,第一想到的就是先运行一下,没想到失败了。
用Exeinfo打开,查看一下信息吧
这个我是真没看到过。。。试了一下,OD无法识别,IDA无法完成反编译(一开始我的理解),就连查壳软件都不觉得他是一个PE文件。
0x02 分析文件 用ida打开之后,发现只有两个函数sub_10030和start
看了一下sub_10030函数,死循环
查看完汇编后,这时直接就没有什么想法了,看了看题目,8086,估计有点关系,猜测可能和处理器类型有关系。(最后发现其实正常打开也一样)
8086第一个反应应该都是80x86,而在汇编语言中有种汇编,是十分基础的,被当作示例给大家讲的汇编语言,就是8086汇编。今天早上的微机原理接口第一节课上,满屏幕的都是8086,整本书应该都与这个神奇的东西有关。上网查了一下,8086汇编的程序通常是一个16位的程序,这就是为什么OD认不出来了。( BUUCTF [BJDCTF 2nd]8086 )
看一下汇编
dseg:0000 ; =========================================================================== dseg:0000 dseg:0000 ; Segment type: Pure data dseg:0000 dseg segment para stack 'DATA' dseg:0000 assume cs:dseg dseg:0000 aUDuTZWjQGjzZWz db ']U[du~|t@{z@wj.}.~q@gjz{z@wzqW~/b;',0 dseg:0023 align 10h dseg:0023 dseg ends dseg:0023
第一段数据段是将这串字符串写入物理地址,并取名aUDuTZWjQGjzZWz。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 seg001:0000 ; =========================================================================== seg001:0000 seg001:0000 ; Segment type: Pure code seg001:0000 seg001 segment byte public 'CODE' seg001:0000 assume cs:seg001 seg001:0000 assume es:nothing, ss:nothing, ds:dseg seg001:0000 seg001:0000 ; =============== S U B R O U T I N E ======================================= seg001:0000 seg001:0000 ; Attributes: noreturn seg001:0000 seg001:0000 sub_10030 proc near ; CODE XREF: sub_10030↓j seg001:0000 ; start+5↓p seg001:0000 jmp short sub_10030 seg001:0000 sub_10030 endp seg001:0000 seg001:0000 ; --------------------------------------------------------------------------- seg001:0002 db 0B9h, 22h, 0, 8Dh, 1Eh, 2 dup(0), 8Bh, 0F9h, 4Fh, 80h seg001:0002 db 31h, 1Fh, 0E2h, 0F8h, 8Dh, 16h, 2 dup(0), 0B4h, 9, 0CDh seg001:0002 db 21h, 0C3h seg001:001A assume ss:dseg, ds:nothing seg001:001A seg001:001A ; =============== S U B R O U T I N E ======================================= seg001:001A seg001:001A ; Attributes: noreturn seg001:001A seg001:001A public start seg001:001A start proc near seg001:001A mov ax, seg dseg seg001:001D mov ds, ax seg001:001F assume ds:dseg seg001:001F call sub_10030 seg001:001F start endp seg001:001F seg001:001F ; --------------------------------------------------------------------------- seg001:0022 db 0B4h, 4Ch, 0CDh, 21h seg001:0022 seg001 ends seg001:0022 seg001:0022 seg001:0022 end start
之后真的不知道怎么做了,和我一起遇到的题目都不一样。。。 后来看了wp,果然是我的盲区。 问题出现在这里
seg001:0000 ; --------------------------------------------------------------------------- seg001:0002 db 0B 9h, 22 h, 0 , 8 Dh, 1 Eh, 2 dup(0 ), 8B h, 0F 9h, 4F h, 80 h seg001:0002 db 31 h, 1F h, 0E2 h, 0F 8h, 8 Dh, 16 h, 2 dup(0 ), 0B 4h, 9 , 0 CDh seg001:0002 db 21 h, 0 C3h seg001:001 A assume ss:dseg, ds:nothing seg001:001 A seg001:001 A ; =============== S U B R O U T I N E =======================================
这一段是代码段,就是刚才的死循环段。但是后面还有一串数据,估计就是真正的代码。选中,按C,选force,强制转换成汇编。(确实不知道。。。)
强制转换之后就是这样的
真的神奇,以前还真没有遇到这样的,还是做少了。。。
分析一下大概意思就是循环0x22次,将 aUDuTZWjQGjzZWz
进行与 0x1F
异或操作,就结束了。 理解不是很难,但是将代码段强制转换成汇编这个知识点我是真的不知道。
0x03 EXP Value = ']U[du~|t@{z@wj.}.~q@gjz{z@wzqW~/b' flag = '' for i in Value: flag += chr(ord(i) ^ 0x1F ) print(flag)
=============================== 参考文章: buucf - re - [BJDCTF 2nd]8086