본문 바로가기
Study/Reversing

[Reversing] 어셈블리어 C로 변환하기 #2

by Jamie Lim 2020. 9. 22.

주어진 어셈블리어

 

 

 

main의 명령은 0으로 초기화를 한 변수 3개를 선언하는 것이다.

 

int a, b, c = 0;

 

 

 

main에서 L2로 점프하므로 아래 명령으로 이동한다. 그럼 [rbp-12]의 값과 9를 비교하는데 [rbp-12]c이다. jle는 만약 앞의 값이 뒤의 값보다 작거나 같으면 점프하라는 의미다. 그러므로 if문을 사용해 표현할 수 있다. 그런데 C언어에서는 jle를 <= 대신 >으로 표현해야 한다고 한다.

 * http://blog.naver.com/PostView.nhn?blogId=67sooon&logNo=10166748134

 

if (c > 9)

 

 

c9보다 작음으로 조건에 만족해 L5로 점프하게 된다.

 

 

eaxc를 넣어 0으로 만든 다음 cdq를 이용해 eaxedx를 확장한다. 그리고 shr을 통해 edx를 쉬프트 연산을 수행한다. cdq를 이용하면 보통 eax에는 몫이 edx에는 나머지가 저장된다고 한다. 그러므로 현재 edx는 2로 나눈 값의 나머지가 된다. 그리고 add를 통해 나머지와 몫을 더한 다음 and 1연산을 통해 해당 값이 짝수인지 홀수인지 확인한다. 

 

c % 2 != 1

 

* cdq : eax의 부호비트를 edx까지 확장한다. (DWORD -> QWORD) 

      이때, edx는 확장 당했으므로 0으로 설정된다.

      이는 보통 나누기 연산을 했을 때 몫을 eax에 나머지를 edx에 넣기 위해 사용한다.

 

연산을 모두 끝낸 c1을 비교했을 때 같지 않다면 L3로 같다면 명령을 계속 수행한다. c에 [rbp-4] 주소에 있는 값을 더

해 그 자리에 저장하게 되어있다. 그리고 L4로 점프하게 된다.

 

if (c % 2 != 1){

    L3;

}

 
else {
	
    a = a + c;
    
    L4;

}

 

 

그럼 우선 같지 않을 때 L3로 넘어가 수행할 명령을 보겠다.

 

 

위 명령은 현재 [rbp-12] 주소의 값인 c의 값은 eax에 넣어준다. 그리고 그 값을 [rbp-8] 주소의 값인 b에 넣어준다. 이 명령은 다음과 같이 표현할 수 있다.

 

b = b + c;

 


만약
c1이 같아 L4로 오게 된다면 다음 명령어를 수행하게 된다. 아마 0xor 연산 1을 했으므로 해당 명령으로 점프할 것이다. 

 

 

위 명령은 [rbp-12] 주소의 값인 c1을 더한 것이다. 그러므로 다음과 같이 표현할 수 있다.

 

c++;

 

 

그래서 모든 명령을 모으면 아래와 같은 코드가 된다. 

 

#include <stdio.h>

int main(){
    int a, b, c = 0;

    if (c > 9) {
    
        if (c % 2!= 1){
            b = b + c;
        }

        else {
            a = a + c;
            c++;
        }
        
    return 0;
}

 

댓글