리버싱 과제2

전수경·2023년 11월 16일
0

write-up

목록 보기
7/10

Quiz64_1



rbx+8=0x401A40+8->0x401A48
해당 메모리 값은 0x0000000000C0FFEE

Quiz64_2


code2를 실행하면 rax에 'rbx+8'의 연산 후의 값을 저장하는 것이 아니라 주소 0x401A48을 저장하므로 code2를 실행하면 해당 메모리 주소가 나온다.

Quiz64_3


code1
rbx+rcx8=rbx+0x28=0x555555554000+0x10->0x555555554010
0x555555554010에 해당하는 값은 0x0000000000000003
add rax, 0x0000000000000003->rax=0x31337+0x0000000000000003=0x3133A
따라서 code1까지 실행 후에 rax 값은 0x3133A

Quiz64_4 Code를 3까지 실행했을 때, rax에 저장된 값은?(앞 문제와 코드 동일)

code2
add rcx, 2->rcx=0x4
code3
rbx+rcx8=rbx+0x48=0x555555554000+0x20->0x555555554020
'0x555555554020'에 해당하는 값은 0x000000000003133A
sub rax, [rbx+rcx*8]->rax=0x3133A(code1참고)-0x000000000003133A=0

Quiz64_5 Code를 4까지 실행했을 때, rax에 저장된 값은?(앞 문제와 코드 동일)

code4
inc rax->1(code1,2,3 참고)

Quiz64_6


code1
rax = 0xffffffff00000000=1111 1111 1111 1111 1111 1111 0000 0000
rcx = 0x123456789abcdef0=0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 0000
rax= rax AND rcx = 0001 0010 0011 0100 0101 0110 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000= 0x1234567800000000

Quiz64_7 Code를 2까지 실행했을 때, rbx에 저장된 값은?(앞 문제와 코드 동일)

code2
rbx = 0x00000000ffffffff=1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
rcx = 0x123456789abcdef0=0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 rbx= rbx AND rcx=0000 0000 1001 1010 1011 1100 1101 1110 1111 0000 =0x000000009ABCDEF0

Quiz64_8 Code를 3까지 실행했을 때, rax에 저장된 값은?(앞 문제와 코드 동일)

code3
rax=0x1234567800000000=0001 0010 0011 0100 0101 0110 0111 1000 0000 0000 0000 0000 0000 0000 0000 0000
rbx=0x000000009ABCDEF0=0000 0000 1001 1010 1011 1100 1101 1110 1111 0000
rax OR rbx= 0001 0010 1011 1110 1111 1110 1111 1110 1111 0000 0000 0000 0000 0000 0000 0000=0x123456789ABCDEF0

Quiz64_9


code1
rax = 0x35014541=0011 0101 0000 0001 0100 0101 0100 0001
rbx = 0xdeadbeef=1101 1110 1010 1101 1011 1110 1110 1111
rax = rax XOR rbx=1110 1011 1010 1100 1111 1010 1010 1110=0xEBACFAAE

Quiz64_10 Code를 2까지 실행했을 때, rax에 저장된 값은?(앞 문제와 코드 동일)

code2
rax = 0xEBACFAAE=1110 1011 1010 1100 1111 1010 1010 1110
rbx = 0xdeadbeef=1101 1110 1010 1101 1011 1110 1110 1111
rax= rax XOR rbx=0011 0101 0000 0001 0100 0101 0100 0001=0x35014541

Quiz64_11 Code를 3까지 실행했을 때, rax에 저장된 값은?(앞 문제와 코드 동일)

code3
EAX는 32비트 레지스터, RXA는 EAX안에 64비트 레지스터이다. 그리고 NOT는 비트를 반전시키는 연산이다.
eax: 0011 0101 0000 0001 0100 0101 0100 0001
not eax: 1100 1010 1111 1110 1011 1010 1011 1110=0xCAFEBA7E

Quiz64_12

[Register]
rcx = 0
rdx = 0
rsi = 0x400000
=======================
[Memory]
0x400000 | 0x67 0x55 0x5c 0x53 0x5f 0x5d 0x55 0x10
0x400008 | 0x44 0x5f 0x10 0x51 0x43 0x43 0x55 0x5d
0x400010 | 0x52 0x5c 0x49 0x10 0x47 0x5f 0x42 0x5c
0x400018 | 0x54 0x11 0x00 0x00 0x00 0x00 0x00 0x00
=======================
[code]
1: mov dl, BYTE PTR[rsi+rcx]
2: xor dl, 0x30
3: mov BYTE PTR[rsi+rcx], dl
4: inc rcx
5: cmp rcx, 0x19
6: jg end
7: jmp 1

code1
rsi는 0x400000, rcx는 0
따라서 rsi+rcx=0+0x400000이므로 해당 메모리에서 1byte를 참조하면 0x67
dl: 0x67

code2
0x67 xor 0x30=
1100111
0110000
=1010111
01010111->0x57
따라서 dl은 0x57

code3
앞에서 한 것과 같이 rsi+rcx는 0x400000
code2에서 구한 dl(0x57)을 해당 위치에 이동시키며, 이동시킨 값을 1byte 참조함

code4
rcx 값 1증가->rcx=1

code5
rcx와 0x19값 비교-> 1<25
후자가 더 크므로 코드 계속 진행
code7로 인해서 1로 이동

앞서 본 code4로 인해서 rcx값이 1씩 증가해 25가 될 때까지 코드는 계속 반복, 25가 되면 code6과 문제 조건(end 시 종료)으로 인해 코드 종료.

그럼 반복될 때 메모리를 확인해보면,
0x400000=0x57=01010111
0x400001=0x55 XOR 0x30->1010101 ^ 0110000 =1100101
0x400002=0x5c XOR 0x30->1011100 ^ 0110000 =1101100
0x400003=0x53 XOR 0x30->1010011 ^ 0110000 =1100011
...
0x400019=0x11 XOR 0x30 = 0010001 ^ 0110000 =0100001

위의 2진수 값들을 아스키 문자로 변환하면, Welcome to assembly world!

Quiz17은 Quiz64_12와 동일.

Quiz25


main code

  • push rbp: rbp 푸쉬
  • mov rbp, rsp: rbp를 rsp에 복사(저장)
  • mov esi, 0xf: esi에 0xf 값 저장
  • mov rdi, 0x400500: rdi에 0x400500 값 저장
  • call 0x400497 <write_n>:
  • call 0x400497 호출해서 write_n으로 이동함

write_n code

  • push rbp & mov rbp, rsp: 반복
  • mov QWORD PTR [rbp-0x8],rdi: rbp-0x8 위치에 rdi 값 저장(0x400500)를 8byte만큼 저장
  • mov DWORD PTR [rbp-0xc], esi: rbp-0xc 위치에 esi 값 저장(0xf)를 4byte만큼 저장
  • xor rdx, rdx: rdx끼리 XOR 연산, 즉 0
  • mov edx, DWORD PTR [rbp-0xc]: rbp-0xc 저장된 값을 4바이트만큼만 edx에 저장(0xf)
  • mov rsi, QWORD PTR [rbp-0x8]: rbp-0x8에 저장된 값을 8바이트만틈만 rsi에 저장(0x400500)
  • mov rdi, 0x1, mov rax, 0x1: rdi, rax에 각각 0x1 복사
  • syscall: 시스템콜, rax 값1이므로 write 호출됨
    rdi=0x1, rsi=0x400500, rdx=0xf->write(1,0x40050, 0xf) 즉, write sys call함수, 버퍼의 주소: 0x400500, 버퍼의 출력길이: 0xf(십진수로 15)
  • pop rbp: 스택을 꺼내어 rbp에 저장
  • ret: return
  • 메인 함수 이동 Q1. 다음 어셈블리 코드를 실행했을 때 출력되는 결과로 올바른 것은?
    3037207964343372 = 07 yd43r
    003f367562336420 = ?6ub3d
    ->리틀엔디안 방식 이용해야 하므로 'r34dy 07 d3bu6?'으로 출력됨

Reversing Basic Challenge #8(Dreamhack)


문제에서 correct를 출력하는 입력값을 찾으라고 한다.


문제 파일 다운 후 분석을 위해 도구를 이용한다.


문제에서 correct를 출력하느 입력값을 찾으라고 하니 해당 문자열을 찾는다.

correct를 출력하는 곳에 가서 분석을 해보니 test eax, eax를 통해 eax에 값이 있는지 확인한 후에 je jmp를 통해서 'correct' 혹은 'wrong'을 출력하고 있다.
업로드중..
break point를 설정한 후에 f9를 통해 실행해보니, 입력하라고 뜬다.

이 뒤는 분석하다가 화나서 포기했습니다..... 리버싱 공부 다시 열심히 할게요.. 다 까먹었네....

profile
Cyber Security

0개의 댓글