[Rev] Disassemble 문제 풀이

KBC·2024년 8월 26일

리버싱

목록 보기
5/11

1. Handray1

   0x0000000000401136 <+0>:	endbr64 
   0x000000000040113a <+4>:	push   %rbp
   0x000000000040113b <+5>:	mov    %rsp,%rbp
   0x000000000040113e <+8>:	sub    $0x10,%rsp
   0x0000000000401142 <+12>:	movq   $0x402004,-0x8(%rbp)
   0x000000000040114a <+20>:	mov    -0x8(%rbp),%rax
   0x000000000040114e <+24>:	mov    %rax,%rsi
   0x0000000000401151 <+27>:	mov    $0x402015,%edi
   0x0000000000401156 <+32>:	mov    $0x0,%eax
   0x000000000040115b <+37>:	callq  0x401040 <printf@plt>
   0x0000000000401160 <+42>:	mov    $0x0,%eax
   0x0000000000401165 <+47>:	leaveq 
   0x0000000000401166 <+48>:	retq   

위는 handray1 파일을 gdb로 disassemble한 결과이다.

#include <stdio.h>
int main(){
    char* a = "handray is easy!";
    {{guess1}}("%s",{{guess2}});
}
// flag = {{guess1}}{{guess2}} (공백없이) ex)strcmpa

문제의 힌트는 위와 같다.

그럼 어셈블리를 다시 살펴보면 37라인 "printf"함수를 호출하고 있다.
따라서 flag는 printf와 a변수 즉, printfa

2. Handray2

(gdb) disassemble  main
Dump of assembler code for function main:
   0x0000000000401156 <+0>:	endbr64 
   0x000000000040115a <+4>:	push   %rbp
   0x000000000040115b <+5>:	mov    %rsp,%rbp
   0x000000000040115e <+8>:	sub    $0x10,%rsp
   0x0000000000401162 <+12>:	lea    -0x4(%rbp),%rax
   0x0000000000401166 <+16>:	mov    %rax,%rsi
   0x0000000000401169 <+19>:	mov    $0x402004,%edi
   0x000000000040116e <+24>:	mov    $0x0,%eax
   0x0000000000401173 <+29>:	callq  0x401060 <__isoc99_scanf@plt>
   0x0000000000401178 <+34>:	mov    -0x4(%rbp),%eax
   0x000000000040117b <+37>:	and    $0x1,%eax
   0x000000000040117e <+40>:	test   %eax,%eax
   0x0000000000401180 <+42>:	jne    0x401193 <main+61>
   0x0000000000401182 <+44>:	mov    $0x402007,%edi
   0x0000000000401187 <+49>:	mov    $0x0,%eax
   0x000000000040118c <+54>:	callq  0x401050 <printf@plt>
   0x0000000000401191 <+59>:	jmp    0x4011a2 <main+76>
   0x0000000000401193 <+61>:	mov    $0x40200c,%edi
   0x0000000000401198 <+66>:	mov    $0x0,%eax
   0x000000000040119d <+71>:	callq  0x401050 <printf@plt>
   0x00000000004011a2 <+76>:	mov    $0x0,%eax
   0x00000000004011a7 <+81>:	leaveq 
--Type <RET> for more, q to quit, c to continue without paging--
   0x00000000004011a8 <+82>:	retq   
End of assembler dump.
(gdb) disassemble __isoc99_scanf
Dump of assembler code for function __isoc99_scanf@plt:
   0x0000000000401060 <+0>:	endbr64 
   0x0000000000401064 <+4>:	bnd

Hint : ___판별기 (판별기 까지 작성해주세요!)

문제의 힌트는 위와 같다.
코드를 쭉 읽던 중 눈에 들어오는 코드가 있다.

 0x000000000040117b <+37>:	and    $0x1,%eax

eax에 저장되어있는 값과 0x1을 and 조건을 통해 연산한다.
꼴랑 1 들어있는 값과 and 연산시에는 1 또는 0만 남는다. 정확히는 짝수면 0, 홀수면 1이 출력된다.

0x000000000040117e <+40>:	test   %eax,%eax

이후 eax에 들어있는 값이 0인지 확인한다.
이후 각각 0 또는 1일시 지정된 부분으로 점프해서 printf문을 통해 출력하고 있다.

결과적으로 홀수판별기, 짝수판별기 등 많이 입력해본 결과 정답은 홀짝판별기였다.

3. Handray3

(gdb) disassemble main
Dump of assembler code for function main:
   0x0000000000401136 <+0>:	endbr64 
   0x000000000040113a <+4>:	push   %rbp
   0x000000000040113b <+5>:	mov    %rsp,%rbp
   0x000000000040113e <+8>:	sub    $0x10,%rsp
   0x0000000000401142 <+12>:	movq   $0x402004,-0x8(%rbp)
   0x000000000040114a <+20>:	movq   $0x402013,-0x10(%rbp)
   0x0000000000401152 <+28>:	mov    -0x8(%rbp),%rax
   0x0000000000401156 <+32>:	add    $0x1,%rax
   0x000000000040115a <+36>:	movzbl (%rax),%edx
   0x000000000040115d <+39>:	mov    -0x10(%rbp),%rax
   0x0000000000401161 <+43>:	add    $0x1,%rax
   0x0000000000401165 <+47>:	movzbl (%rax),%eax
   0x0000000000401168 <+50>:	cmp    %al,%dl
   0x000000000040116a <+52>:	jne    0x40117b <main+69>
   0x000000000040116c <+54>:	mov    $0x402026,%edi
   0x0000000000401171 <+59>:	mov    $0x0,%eax
   0x0000000000401176 <+64>:	callq  0x401040 <printf@plt>
   0x000000000040117b <+69>:	mov    -0x8(%rbp),%rax
   0x000000000040117f <+73>:	add    $0x4,%rax
   0x0000000000401183 <+77>:	movzbl (%rax),%edx
   0x0000000000401186 <+80>:	mov    -0x10(%rbp),%rax
   0x000000000040118a <+84>:	add    $0x4,%rax
--Type <RET> for more, q to quit, c to continue without paging--c
   0x000000000040118e <+88>:	movzbl (%rax),%eax
   0x0000000000401191 <+91>:	cmp    %al,%dl
   0x0000000000401193 <+93>:	jne    0x4011a4 <main+110>
   0x0000000000401195 <+95>:	mov    $0x402032,%edi
   0x000000000040119a <+100>:	mov    $0x0,%eax
   0x000000000040119f <+105>:	callq  0x401040 <printf@plt>
   0x00000000004011a4 <+110>:	mov    $0x0,%eax
   0x00000000004011a9 <+115>:	leaveq 
   0x00000000004011aa <+116>:	retq   

스택 프레임 설정

0x0000000000401136 <+0>:    endbr64 
0x000000000040113a <+4>:    push   %rbp
0x000000000040113b <+5>:    mov    %rsp,%rbp
0x000000000040113e <+8>:    sub    $0x10,%rsp

스택 프레임 설정: 현재 rbp를 스택에 저장하고, rsp를 rbp로 설정하여 새로운 스택 프레임을 만듦.

문자열 주소 저장

0x0000000000401142 <+12>:   movq   $0x402004,-0x8(%rbp)
0x000000000040114a <+20>:   movq   $0x402013,-0x10(%rbp)

문자열 주소 저장: 첫 번째와 두 번째 문자열의 주소를 각각 -0x8(%rbp)와 -0x10(%rbp)에 저장함.

int main() {
    char *str1 = "ABCD";
    char *str2 = "ABEF";

C 코드: str1과 str2에 문자열 주소를 저장함.

두 번째 문자 비교

0x0000000000401152 <+28>:   mov    -0x8(%rbp),%rax
0x0000000000401156 <+32>:   add    $0x1,%rax
0x000000000040115a <+36>:   movzbl (%rax),%edx
0x000000000040115d <+39>:   mov    -0x10(%rbp),%rax
0x0000000000401161 <+43>:   add    $0x1,%rax
0x0000000000401165 <+47>:   movzbl (%rax),%eax
0x0000000000401168 <+50>:   cmp    %al,%dl
0x000000000040116a <+52>:   jne    0x40117b <main+69>

두 번째 문자 비교: str1[1]과 str2[1]을 비교하고, 같으면 메시지를 출력하는 코드, 다르면 점프

    if (str1[1] != str2[1]) {
        printf("Second characters do not match.\n");
    }

C 코드: 두 번째 문자가 다를 경우 스킵, 같을 경우 같다고 출력

다섯 번째 문자 비교

0x000000000040117b <+69>:   mov    -0x8(%rbp),%rax
0x000000000040117f <+73>:   add    $0x4,%rax
0x0000000000401183 <+77>:   movzbl (%rax),%edx
0x0000000000401186 <+80>:   mov    -0x10(%rbp),%rax
0x000000000040118a <+84>:   add    $0x4,%rax
0x000000000040118e <+88>:   movzbl (%rax),%eax
0x0000000000401191 <+91>:   cmp    %al,%dl
0x0000000000401193 <+93>:   jne    0x4011a4 <main+110>

다섯 번째 문자 비교: str1[4]과 str2[4]을 비교하고, 같으면 메시지를 출력하는 코드, 다르면 점프

    if (str1[4] != str2[4]) {
        printf("Fifth characters do not match.\n");
    }

C 코드: 다섯 번째 문자가 다를 경우 스킵, 같을 경우 같다고 출력

결과적으로 유추한 C코드는 다음과 같다

#include <stdio.h>
#include <string.h>
int main() {
    char str1 = "ABCD";
    charstr2 = "ABEF";
    if (str1[1] == str2[1]) {
        printf("Second character matches.\n");
    }
    if (str1[4] == str2[4]) {
        printf("Fifth character matches.\n");
    }
    return 0;
}
profile
AI, Security

0개의 댓글