我刚刚开始参加大会,以寻求CTF逆转挑战,并且我玩得很开心。我正在努力的当前挑战让我感到难过 - 希望有人可以帮助解决一些基本的大会问题 - 或者指出我的资源。
我通过Binary Ninja运行了为挑战提供的二进制文件,并确定了关键函数 - 在该函数中跟踪逻辑给我带来了问题。
该功能以一种相当直接的方式开始 - 我已经根据我的理解添加了自己的评论:
08048661 push ebp {__saved_ebp} ;Push old base pointer onto stack
08048662 mov ebp, esp {__saved_ebp} ;Function preamble (?)
08048664 sub esp, 0x18
08048667 sub esp, 0xc
0804866a push dword [ebp+0x8 {arg1}] {var_2c} ;var_2c is user input (arg1)
0804866d call strlen ;Get the string length of user input
08048672 add esp, 0x10 ;??
08048675 mov dword [ebp-0x10 {var_14}], eax ;Assign EAX to var_14
08048678 cmp dword [ebp-0x10 {var_14}], 0x13
;Compares string length to 0x13 (decimal 19) - if it's longer continue
0804867c ja 0x8048688
第一个块似乎得到用户输入的字符串长度 - 如果字符串长度大于19,则继续到下一个块。
下一个区块是我认为我的理解不正确的地方:
08048688 mov eax, dword [ebp+0x8 {arg1}]
;Set EAX to the memory location of the user input (arg1)
0804868b movzx eax, byte [eax]
;Replace EAX with the first byte of EAX (arg1)
0804868e cmp al, 0x61
;Compare the first byte of EAX with 0x61 (decimal 97 / binary 01100001)
;if equal, continue to next block
08048690 je 0x8048699
这意味着正确响应的第一个字节必须是01100001 - 但这似乎与下一个块相矛盾:
08048699 mov eax, dword [ebp+0x8 {arg1}]
;Set EAX to the memory location of the user input (arg1)
0804869c add eax, 0x1
;Add 0x1 to EAX (decimal 1 / binary 00000001)
0804869f movzx eax, byte [eax]
;Replace EAX with only the first byte of EAX (arg1+1)
080486a2 cmp al, 0x71
;Compare the first byte of EAX with 0x71 (decimal 113 / binary 01110001)
;if equal, continue to next block
080486a4 je 0x80486ad
这是我目前卡住的地方 - 如果输入的第一个字节需要十进制97 /二进制01100001才能通过第二个块,那么如何向它添加1可能会导致小数113 /二进制01110001需要传递第三块代码?
我不确定我对代码的理解是不正确的 - 非常感谢任何提示或指示。如果这涵盖了基本知识,请道歉 - 我正在自己解决这些问题。
谢谢!
答案 0 :(得分:1)
好吧,它没有添加应该导致113
的一个。如果你仔细观察,你应该注意到在1
再次读取字符值之前已经eax
添加了eax
。仅将此新加载的值与0x71
进行比较。所以这第一个操作只是作为一个索引增量。
更多解释:
08048699 mov eax, dword [ebp+0x8 {arg1}]
这会将输入缓冲区的地址加载到eax
。
0804869c add eax, 0x1
此eax
指向输入缓冲区中的第二个字符。
0804869f movzx eax, byte [eax]
此行将eax
指向(输入缓冲区)的字符加载到eax
(用零扩展到32位)。
只有在最后一行之后,您才能与0x71
进行比较。所以第二个字符应该是' q'。
如果添加eax,0x1将eax指向输入缓冲区中的第二个字符,这是否意味着movzx eax,byte [eax]没有添加eax,0x1指向缓冲区中的第一个字符?
是的,您在地址下的第一个区块中拥有该代码/模式:08048688
& 0804868b
。没有add eax,1
,其余的都是相同的。
dword [ebp+0x8 {arg1}]
总是表示输入缓冲区,还是仅在这种情况下?
只有在这种情况下 - 这个[ebp+0x8]
基本上指向堆栈上的参数 - 在这种情况下它是输入缓冲区,但它不必像那样。