flag_gen함수를 실행시키기 위해 IDA에서
0x00005555555555aa <+278>: cmp DWORD PTR [rbp-0x4],0x5
0x00005555555555ae <+282>: jne 0x5555555555fe <main+362>
이 코드에서 jne를 je로 바꿔서 바이너리패치를 했는데 이상한 형식의 플래그가나오고, gdb에서 동적분석중 해당 코드를 실행할 때 rbp-0x4를 0x5로 바꾸니 제대로된 플래그가 나오네요.. 왜그런지 잘 모르겠는데 힌트좀 주실 수 있을까요?
어셈블리를 보면 의도를 어느 정도 알 수 있습니다.
0x00000000000015a4 <+272>: jg 0x14c5 <main+49>
0x00000000000015aa <+278>: cmp DWORD PTR [rbp-0x4],0x5
0x00000000000015ae <+282>: jne 0x15fe <main+362>
0x00000000000015b0 <+284>: lea rax,[rip+0xa5f] # 0x2016
0x00000000000015b7 <+291>: mov rdi,rax
0x00000000000015ba <+294>: call 0x1090 <puts@plt>
0x00000000000015bf <+299>: mov eax,DWORD PTR [rbp-0x4]
0x00000000000015c2 <+302>: mov DWORD PTR [rbp-0x8],eax
0x00000000000015c5 <+305>: mov edx,DWORD PTR [rbp-0x8]
0x00000000000015c8 <+308>: lea rcx,[rbp-0xa0]
0x00000000000015cf <+315>: lea rax,[rbp-0x50]
0x00000000000015d3 <+319>: mov rsi,rcx
0x00000000000015d6 <+322>: mov rdi,rax
0x00000000000015d9 <+325>: call 0x11c9 <flag_gen>
질문 주신 부분의 어셈 코드입니다.
flag_gen을 실행시키는 것이 문제의 목표입니다.
이 때, flag_gen을 실행시키는 것에 더해서 올바르게 인자가 전달되어야 합니다.
어셈을 해석해보면, [rbp-0x4]
와 0x5
가 일치하지 않으면 <main+362>
로 jmp하게 되면서 flag_gen함수 실행 없이 main함수가 종료되게 됩니다.
이는, flag_gen을 실행시키기 위해서는 [rbp-0x4]
값이 0x5가 되어야 flag_gen이 실행되는 것으로 이해할 수 있습니다.
물론, jne branch도 패치로 강제로 넘길 수 있는 부분입니다만, flag_gen함수를 실행시키는 것 만으로는 올바른 flag를 얻을 수 없습니다. flag_gen 함수를 디컴파일 해보시면 인자가 3개 들어가는 것을 확인할 수 있습니다. flag_gen함수의 인자 3개도 정확하게 전달해야지 올바른 flag를 생성할 수 있습니다.
flag_gen에게 인자를 전달하는 어셈 코드를 살펴보시면,
0x00000000000015bf <+299>: mov eax,DWORD PTR [rbp-0x4]
0x00000000000015c2 <+302>: mov DWORD PTR [rbp-0x8],eax
0x00000000000015c5 <+305>: mov edx,DWORD PTR [rbp-0x8]
0x00000000000015c8 <+308>: lea rcx,[rbp-0xa0]
0x00000000000015cf <+315>: lea rax,[rbp-0x50]
0x00000000000015d3 <+319>: mov rsi,rcx
0x00000000000015d6 <+322>: mov rdi,rax
0x00000000000015d9 <+325>: call 0x11c9 <flag_gen>
첫 번째 인자에 해당하는 rdi
에는 [rbp-0x50]
의 주소가 들어가고, 두 번째 인자에 해당하는 rsi
에는 [rbp-0xa0]
의 주소가 들어가고 세 번째 인자에 해당하는 rdx
(flag_gen의 경우 세 번째 인자의 자료형이 int이므로 edx
)에는 [rbp-0x4]
의 값이 들어가게 됩니다.
즉, [rbp-0x4]
값에 따라 flag_gen의 실행 결과가 달라질 수 있다는 것을 의미하게 됩니다. 그러면, [rbp-0x4]
에는 어떤 값이 들어가야 하냐? 이에 대한 정보가 위의 jne 분기문에 적혀 있었던 것입니다.
로직 상 jne 분기문에서 [rbp-0x4]
값이 0x5와 일치하지 않으면 flag_gen이 실행되지 않기 때문에 "올바르게 실행되는 flag_gen에서 [rbp-0x4]
값은 0x5가 되어야 겠군"이라는 추측을 할 수 있는 것이죠.