바이너리패치, gdb 값 변경

flag_gen함수를 실행시키기 위해 IDA에서

 0x00005555555555aa <+278>:   cmp    DWORD PTR [rbp-0x4],0x5
 0x00005555555555ae <+282>:   jne    0x5555555555fe <main+362> 

이 코드에서 jne를 je로 바꿔서 바이너리패치를 했는데 이상한 형식의 플래그가나오고, gdb에서 동적분석중 해당 코드를 실행할 때 rbp-0x4를 0x5로 바꾸니 제대로된 플래그가 나오네요.. 왜그런지 잘 모르겠는데 힌트좀 주실 수 있을까요?

#reversing
작성자 정보
답변 1

어셈블리를 보면 의도를 어느 정도 알 수 있습니다.

   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가 되어야 겠군"이라는 추측을 할 수 있는 것이죠.

2024.01.30. 21:42
질문에 대한 답을 알고 계신가요?
지식을 나누고 포인트를 획득해보세요.
답변하고 포인트 받기