CG-ctf in RE Hello, RE and ReadAsm2 ultra-detailed explanations

Hello,RE!

A white github out of time in the experiment (clone really slow Hao Mana!), Forget the time, put a horse to forget the lesson (ask tx no dm), so just brush turned a deaf ear play it, after all, and consequently do not know, problems can quickly brush some knowledge, I went inside looked re cg problem and found a problem hello very suitable for me, so I'll do it! Find their own title on the re cg in order to protect intellectual property rights cg, not here to source code, look at themselves!
Then, after I put the exe download, run, like this drop!
Here Insert Picture Description
Well - looking flag with ida look
Here Insert Picture Description
to find this, those weird numbers behind the top really hard, but is subject to the prompt press r can be turned into a string, and then I thought for a moment and then, in fact, this bunch just eight figures, is defined dw type, that is four bytes, also happens to be four characters, so this should be four char, click r, it has become such:
Here Insert Picture Description
emmm, Flag out However, anti-eh ~ galf go again! After Normally, in turn input is really a flag, but also a correct format flag (nonsense), submitted a flag, I thought for a moment, was found with esp, esp what is? Is the stack pointer ah! For a stack, it is from high address to low address to go, so it should be corresponding
g-> 75h, a-> 74h ... and so on, so these every four anti-click on it;

ReadAsm2

首先题目是这样的,给出了一个主函数,然后不知道的是func这个函数,而给定的是一个asm文件
Here Insert Picture Description
想必大家做题的时候遇到这道题之后就已经看过那个asm文件了,所以我在这里就只放一个我写的带有注释的文件截图了:
带有详细题解的asm文件链接:https://pan.baidu.com/s/1zRPyFTmR9s9SUEnJb6A8TQ 提取码:1z8h
Here Insert Picture Description
为了让大家看着方便,就只能是代码片形式了;
看之前先说明一点,在func第一个参数传入的时候,传入的是数组的首地址,所以后面我是用addinput代表的地址的数组集,就是数组里面存的是地址;

   /*
    存入堆栈目的就是为了保护数据,这个地方是汇编之后的重中之重,因为汇编中,寄存器的数量是有限的,而通过寄存器的的数据传输又是最快的,所以
    为了是速度上不太慢,编译器会尽可能的使用寄存器,特别是32位寄存器,64位寄存器,在一般情况下,对于寄存器的功能已经淡化了,8个、16个寄存器就
    可以随便(也不是太随便)调用,所以把一些数据先保存在堆栈,防止数值丢失,然后释放寄存器,让寄存器发挥更重要的作用,等用到时候再弹出到寄存器中
    当然,存储器也可以,堆栈的作用主要在调用函数的时候显得尤为重要!
   */
  4004e6: 55                    push   rbp                              ;把rbp压入堆栈   ,起到保护作用
  4004e7: 48 89 e5              mov    rbp,rsp                          ;rbp作为辅助使用,好处是用了rbp之后,rsp不会变化,就可以使堆栈平衡
  4004ea: 48 89 7d e8           mov    QWORD PTR [rbp-0x18],rdi         ;rdi存第一个参数  ??为什么??  假设这样,rdi保存到堆栈[rbp-0x18]这个位置    rdi=addinput[] 
;至于为什么,我也想知道,我感觉这地方是和寄存器的功能有关,到底是不是这样,兄弟们给我一点时间,我去查一下(问一下老师和大佬)
  4004ee: 89 75 e4              mov    DWORD PTR [rbp-0x1c],esi         ;rsi(esi)存的第二个参数  ???  假设成立的话,esi存入[rbp-0x1c]这个位置    esi=28
  4004f1: c7 45 fc 01 00 00 00  mov    DWORD PTR [rbp-0x4],0x1          ;给这个存储单元一个数值1,为了好记,我们设这个存储单元(四个字节)为i     i=1
  4004f8: eb 28                 jmp    400522 <func+0x3c>               ;跳转到400522    label1

;for循环开始,i=1
;label2:
  4004fa: 8b 45 fc              mov    eax,DWORD PTR [rbp-0x4]          ;   eax = i 
  4004fd: 48 63 d0              movsxd rdx,eax                          ;   rdx = eax = i (i最大为 0x1c) movsxd是 符号扩展 先扩展符号位,例如  1000 扩展为八位的:1111 1000  
  400500: 48 8b 45 e8           mov    rax,QWORD PTR [rbp-0x18]         ;   rax = addinput[0]   addinput[0] 是 表示的地址 
  400504: 48 01 d0              add    rax,rdx                          ;   rax = rax + rdx      addinput[i] = addinput[0] + i      循环28次,找到当前次数的addinput[i]
  400507: 8b 55 fc              mov    edx,DWORD PTR [rbp-0x4]          ;   edx = i      ??这地方好傻啊,就不能用eax吗?
  40050a: 48 63 ca              movsxd rcx,edx                          ;   rcx = edx = i      这个地方也是傻
  40050d: 48 8b 55 e8           mov    rdx,QWORD PTR [rbp-0x18]         ;   rdx = addinput[0]      这个地方还是傻
  400511: 48 01 ca              add    rdx,rcx                          ;   rdx = rdx + rcx   =  i + addinput[0] = addinput[i]      同上傻
  400514: 0f b6 0a              movzx  ecx,BYTE PTR [rdx]               ;   ecx = addinput[rdx] 对应的值  记为input[i]
  400517: 8b 55 fc              mov    edx,DWORD PTR [rbp-0x4]          ;   edx = i        
  40051a: 31 ca                 xor    edx,ecx                          ;   edx = edx ^ ecx = i ^ input[i]       说来说去,最后只要这个核心代码嘛~前面好多多余的步骤
  40051c: 88 10                 mov    BYTE PTR [rax],dl                ;   rax  addinput[i] 代表的地址取一个字节(char),把dl结果移入进去    变换后结果存入input
  40051e: 83 45 fc 01           add    DWORD PTR [rbp-0x4],0x1          ;   i++    

;label1:
  400522: 8b 45 fc              mov    eax,DWORD PTR [rbp-0x4]          ;  eax = i
  400525: 3b 45 e4              cmp    eax,DWORD PTR [rbp-0x1c]         ;  i <= 28
  400528: 7e d0                 jle    4004fa <func+0x14>
  40052a: 90                    nop
  40052b: 5d                    pop    rbp
  40052c: c3                    ret

所以啊~这道题当你真的认真分析下来之后,你会发现,并不难,只是有一些傻瓜的多余地方,核心功能就这一个,主要还是想让自己静下心来,仔细分析一下汇编语言;然后用Python写一串代码得出 flag{read_asm_is_the_basic}
写好的Python文件:链接:https://pan.baidu.com/s/1SePLofkRpxSGQPW6bZaEDg 提取码:fyq5
Here Insert Picture Description

什么?你不知道rbx啥意思???你怎么能不知道呢?好吧,我也不知道,我是百度之后才知道的,我学的是杨季文老师的新概念汇编,基于x8680的32位汇编,还真不知道这东西就是64位汇编之中的;先看图!
Picture description is valid?
在本道题中,就知道这么多就可以了,就可以去做题了,对于那些movsxd百度一下或者猜一下,就可以知道,sf就是符号标志位,所以应该是带符号的扩展,而且要做ctf二进制的话,汇编还真要有一定的基础,所以不懂的话可以去先学一下汇编基础!

To learn more about the difference between 32-bit and 64-bit, I feel pretty good this blog: https: //blog.csdn.net/qq_29343201/article/details/51278798

Published 29 original articles · won praise 13 · views 2763

Guess you like

Origin blog.csdn.net/zmx2473162621/article/details/103163789