[Rev] Assembly 문제 풀이

KBC·2024년 8월 26일

리버싱

목록 보기
2/11

1.

0x0000000000001131 <main+8>:	mov    DWORD PTR [rbp-0x10],0x1
0x0000000000001138 <main+15>:	mov    DWORD PTR [rbp-0xc],0x3
0x000000000000113f <main+22>:	mov    DWORD PTR [rbp-0x8],0x5
0x0000000000001146 <main+29>:	mov    edx,DWORD PTR [rbp-0x10]     
0x0000000000001149 <main+32>:	mov    eax,DWORD PTR [rbp-0xc]      
0x000000000000114c <main+35>:	add    edx,eax                      
0x000000000000114e <main+37>:	mov    eax,DWORD PTR [rbp-0x8]      
0x0000000000001151 <main+40>:	add    eax,edx        

실행 후 eax의 값은?


코드를 한 줄씩 봤을때 초기 메모리 저장 상태는 위와 같다. mov를 통해 각 메모리에 값이 저장된다.

0x000000000000114c <main+35>:	add    edx,eax    

위 명령어는 edx += eax 와 같다.

이후 0x8 주소의 값을 다시 eax에 저장하고


마지막으로 eax += edx를 하게 되면 정답은 9가 된다.

2.

0x0000000000001131 <main+8>:	mov    DWORD PTR [rbp-0x10],0x0
0x0000000000001138 <main+15>:	mov    DWORD PTR [rbp-0xc],0x2
0x000000000000113f <main+22>:	mov    DWORD PTR [rbp-0x8],0x3
0x0000000000001146 <main+29>:	mov    eax,DWORD PTR [rbp-0xc]      
0x0000000000001149 <main+32>:	imul   eax,DWORD PTR [rbp-0x8]      
0x000000000000114d <main+36>:	mov    DWORD PTR [rbp-0x4],eax
0x0000000000001150 <main+39>:	cmp    DWORD PTR [rbp-0x4],0x6      
0x0000000000001154 <main+43>:	jne    0x115f <main+54>             
0x0000000000001156 <main+45>:	mov    DWORD PTR [rbp-0x10],0xff
0x000000000000115d <main+52>:	jmp    0x1166 <main+61>
0x000000000000115f <main+54>:	mov    DWORD PTR [rbp-0x10],0x0
0x0000000000001166 <main+61>:	mov    eax,DWORD PTR [rbp-0x4]      
0x0000000000001169 <main+64>:	and    DWORD PTR [rbp-0x10],eax     
실행 후 DWORD PTR [rbp-0x10] 의 값은? 


초기 각 메모리에 위와 같이 저장된다.

imul 연산을 통해 eax = eax * 0x4의 값을 저장하고, 0x4에 eax의 값을 저장후 cmp를 통해 비교한다. 당연히 값은 같고, jne는 not equal일 경우에만 jump하기 때문에 동작하지 않는다.

여기까지 실행 후

0x000000000000115d <main+52>:	jmp    0x1166 <main+61>

위 명령어에 의해 jmp의 무조건 점프가 동작하여 main+61로 점프


비트 연산자 AND에 의해 최종 0x10의 값은 0x06 즉 6이 저장된다.

3.

0x0000000000001164 <main+27>:	mov    DWORD PTR [rbp-0x30],0x1
0x000000000000116b <main+34>:	mov    DWORD PTR [rbp-0x2c],0x2
0x0000000000001172 <main+41>:	mov    DWORD PTR [rbp-0x28],0x3
0x0000000000001179 <main+48>:	mov    DWORD PTR [rbp-0x24],0x4
0x0000000000001180 <main+55>:	mov    DWORD PTR [rbp-0x20],0x5
0x0000000000001187 <main+62>:	mov    DWORD PTR [rbp-0x1c],0x6
0x000000000000118e <main+69>:	mov    DWORD PTR [rbp-0x18],0x7
0x0000000000001195 <main+76>:	mov    DWORD PTR [rbp-0x14],0x8
0x000000000000119c <main+83>:	mov    DWORD PTR [rbp-0x10],0x9
0x00000000000011a3 <main+90>:	mov    DWORD PTR [rbp-0xc],0xa
0x00000000000011aa <main+97>:	mov    DWORD PTR [rbp-0x38],0x0
0x00000000000011b1 <main+104>:	mov    DWORD PTR [rbp-0x34],0x0
0x00000000000011b8 <main+111>:	jmp    0x11ca <main+129>
0x00000000000011ba <main+113>:	mov    eax,DWORD PTR [rbp-0x34]     
0x00000000000011bd <main+116>:	cdqe                                
0x00000000000011bf <main+118>:	mov    eax,DWORD PTR [rbp+rax*4-0x30]   
0x00000000000011c3 <main+122>:	add    DWORD PTR [rbp-0x38],eax         
0x00000000000011c6 <main+125>:	inc    DWORD PTR [rbp-0x34]
0x00000000000011ca <main+129>:	cmp    DWORD PTR [rbp-0x34],0x9
0x00000000000011ce <main+133>:	jle    0x11ba <main+113>            
실행 후 DWORD PTR [rbp-0x38]의 값은?


초기 상태는 위와 같다. jmp 때문에 main+129로 점프하고 jle 조건 때문에 0x34의 값과 0x9가 보다 클 때까지 main+113으로 돌아가야한다.

0x00000000000011ba <main+113>:	mov    eax,DWORD PTR [rbp-0x34]     
0x00000000000011bd <main+116>:	cdqe                                
0x00000000000011bf <main+118>:	mov    eax,DWORD PTR [rbp+rax*4-0x30]   
0x00000000000011c3 <main+122>:	add    DWORD PTR [rbp-0x38],eax         
0x00000000000011c6 <main+125>:	inc    DWORD PTR [rbp-0x34]
0x00000000000011ca <main+129>:	cmp    DWORD PTR [rbp-0x34],0x9
0x00000000000011ce <main+133>:	jle    0x11ba <main+113>    


중간 단계에서 반복 루프를 떼어보면
eax에 저장되는 값은

여기 저장되어있는 값을 한칸씩 내려오면서 할당이 되게 된다.

0x00000000000011bf <main+118>:	mov    eax,DWORD PTR [rbp+rax*4-0x30]   

그래서 결론적으로는 0x34는 반복 횟수를 체크하는 값, 0x38에는 합산된 결과 값을 저장되게 되고, 9보다 클때까지 반복하니 1부터 10까지의 합이 최종적으로 저장되어 결과물은 55가 된다

4.

0x000000000040110e <+8>:     mov    DWORD PTR [rbp-0x40],0x1
   0x0000000000401115 <+15>:    mov    DWORD PTR [rbp-0x3c],0x3
   0x000000000040111c <+22>:    mov    DWORD PTR [rbp-0x38],0x7
   0x0000000000401123 <+29>:    mov    DWORD PTR [rbp-0x34],0xd
   0x000000000040112a <+36>:    mov    DWORD PTR [rbp-0x30],0x15
   0x0000000000401131 <+43>:    mov    DWORD PTR [rbp-0x2c],0x1
   0x0000000000401138 <+50>:    mov    DWORD PTR [rbp-0x28],0xd
   0x000000000040113f <+57>:    mov    DWORD PTR [rbp-0x24],0x1b
   0x0000000000401146 <+64>:    mov    DWORD PTR [rbp-0x20],0xd
   0x000000000040114d <+71>:    mov    DWORD PTR [rbp-0x1c],0x1
   0x0000000000401154 <+78>:    mov    DWORD PTR [rbp-0x4],0x1e
   0x000000000040115b <+85>:    mov    DWORD PTR [rbp-0x8],0x0
   0x0000000000401162 <+92>:    mov    DWORD PTR [rbp-0xc],0x0
   0x0000000000401169 <+99>:    jmp    0x4011a3 <main+157>
   0x000000000040116b <+101>:   mov    eax,DWORD PTR [rbp-0xc]
   0x000000000040116e <+104>:   cdqe   
   0x0000000000401170 <+106>:   mov    eax,DWORD PTR [rbp+rax*4-0x40]
   0x0000000000401174 <+110>:   cmp    DWORD PTR [rbp-0x4],eax
   0x0000000000401177 <+113>:   jle    0x401185 <main+127>
   0x0000000000401179 <+115>:   mov    eax,DWORD PTR [rbp-0xc]
   0x000000000040117c <+118>:   cdqe   
   0x000000000040117e <+120>:   mov    eax,DWORD PTR [rbp+rax*4-0x40]
   0x0000000000401182 <+124>:   mov    DWORD PTR [rbp-0x4],eax
   0x0000000000401185 <+127>:   mov    eax,DWORD PTR [rbp-0xc]
   0x0000000000401188 <+130>:   cdqe   
   0x000000000040118a <+132>:   mov    eax,DWORD PTR [rbp+rax*4-0x40]
   0x000000000040118e <+136>:   cmp    DWORD PTR [rbp-0x8],eax
   0x0000000000401191 <+139>:   jge    0x40119f <main+153>
   0x0000000000401193 <+141>:   mov    eax,DWORD PTR [rbp-0xc]
   0x0000000000401196 <+144>:   cdqe   
   0x0000000000401198 <+146>:   mov    eax,DWORD PTR [rbp+rax*4-0x40]
   0x000000000040119c <+150>:   mov    DWORD PTR [rbp-0x8],eax
   0x000000000040119f <+153>:   add    DWORD PTR [rbp-0xc],0x1
   0x00000000004011a3 <+157>:   cmp    DWORD PTR [rbp-0xc],0x9
   0x00000000004011a7 <+161>:   jle    0x40116b <main+101>
   0x00000000004011a9 <+163>:   mov    edx,DWORD PTR [rbp-0x4]
   0x00000000004011ac <+166>:   mov    eax,DWORD PTR [rbp-0x8]
   0x00000000004011af <+169>:   add    eax,edx
   0x00000000004011b1 <+171>:   mov    DWORD PTR [rbp-0x10],eax
   실행 후 rbp-0x10에 해당하는 값은?


초기 저장 상태는 위와 같다.


이후 jmp에 의해 157라인으로 점프하고 0xc의 값인 0x0과 0x9을 비교해서 0x9보다 클 때까지 다시 101라인으로 돌아가야 한다.

왼쪽에 있는 주소의 값을 돌면서 0x4보다 작은 값들은 0x4에 저장, 0x8보다 큰 값들은 0x8에 저장된다.

최종적으로는 최솟값과 최대값을 더한 숫자인 27이 0x10에 저장된다.

5.

0x0000000000001164 <+27>:	mov    DWORD PTR [rbp-0x30],0x1
0x000000000000116b <+34>:	mov    DWORD PTR [rbp-0x2c],0x1
0x0000000000001172 <+41>:	mov    DWORD PTR [rbp-0x28],0x1
0x0000000000001179 <+48>:	mov    DWORD PTR [rbp-0x24],0x1
0x0000000000001180 <+55>:	mov    DWORD PTR [rbp-0x20],0x1
0x0000000000001187 <+62>:	mov    DWORD PTR [rbp-0x1c],0x1
0x000000000000118e <+69>:	mov    DWORD PTR [rbp-0x18],0x1
0x0000000000001195 <+76>:	mov    DWORD PTR [rbp-0x14],0x1
0x000000000000119c <+83>:	mov    DWORD PTR [rbp-0x10],0x1
0x00000000000011a3 <+90>:	mov    DWORD PTR [rbp-0xc],0x1
0x00000000000011aa <+97>:	mov    DWORD PTR [rbp-0x34],0x0
0x00000000000011b1 <+104>:	jmp    0x11d6 <main+141>
0x00000000000011b3 <+106>:	mov    eax,DWORD PTR [rbp-0x34]
0x00000000000011b6 <+109>:	and    eax,0x1  0b00001   
0x00000000000011b9 <+112>:	test   eax,eax
0x00000000000011bb <+114>:	jne    0x11d2 <main+137>
0x00000000000011bd <+116>:	mov    eax,DWORD PTR [rbp-0x34]
0x00000000000011c0 <+119>:	cdqe   
0x00000000000011c2 <+121>:	mov    eax,DWORD PTR [rbp+rax*4-0x30]
0x00000000000011c6 <+125>:	lea    edx,[rax+rax*1]
0x00000000000011c9 <+128>:	mov    eax,DWORD PTR [rbp-0x34]
0x00000000000011cc <+131>:	cdqe   
0x00000000000011ce <+133>:	mov    DWORD PTR [rbp+rax*4-0x30],edx
0x00000000000011d2 <+137>:	add    DWORD PTR [rbp-0x34],0x1
0x00000000000011d6 <+141>:	cmp    DWORD PTR [rbp-0x34],0x9
0x00000000000011da <+145>:	jle    0x11b3 <main+106>
실행 후 배열의 값은?


초기 상태는 위와 같다. 0x34의 값과 9를 비교해서 만족할때까지 106라인으로 돌아간다.
1. 코드의 시작 부분에서 rbp-0x30부터 rbp-0xc까지의 메모리 위치에 1이 할당된다. 이 메모리 범위는 배열의 각 요소를 나타낸다.

  1. 루프는 rbp-0x34 값이 0부터 9까지 증가하는 동안 실행된다. 각 루프에서는 조건에 따라 배열의 값을 2배로 변경한다.

  2. rbp-0x34의 값이 짝수일 경우, 해당하는 배열 요소는 rax+rax*1으로 설정되어, 기존 값의 2배가 된다.

  • rbp-0x34 = 0, 짝수이므로, 첫 번째 요소는 2 * 1 = 2
  • rbp-0x34 = 1, 홀수이므로, 두 번째 요소는 그대로 1
  • rbp-0x34 = 2, 짝수이므로, 세 번째 요소는 2 * 1 = 2
  • rbp-0x34 = 3, 홀수이므로, 네 번째 요소는 그대로 1
  • rbp-0x34 = 4, 짝수이므로, 다섯 번째 요소는 2 * 1 = 2
  • rbp-0x34 = 5, 홀수이므로, 여섯 번째 요소는 그대로 1
  • rbp-0x34 = 6, 짝수이므로, 일곱 번째 요소는 2 * 1 = 2
  • rbp-0x34 = 7, 홀수이므로, 여덟 번째 요소는 그대로 1
  • rbp-0x34 = 8, 짝수이므로, 아홉 번째 요소는 2 * 1 = 2
  • rbp-0x34 = 9, 홀수이므로, 마지막 요소는 그대로 1
    최종 배열은 {2,1,2,1,2,1,2,1,2,1}
profile
AI, Security

0개의 댓글