F.R.I.D.A.Y.

[C300] : C003 본문

리버싱/C300

[C300] : C003

F.R.I.D.A.Y. 2018. 9. 25. 11:03
반응형


#include <stdio.h> 

#define  X   1
#define  PI  3.141592

main() 
{ 
	double z;
		 
	z = X + PI;
	
	printf( "%f", z );
} 


 위 코드를 분석한다.

 IDA로 돌리면 아래와 같은 코드가 나온다.

 var_8의 경우에는 IDA가 분석을 실행하며 발생하는 IDA 변수로 바라볼 수 있다.

 movsd 명령어는 DWORD 기준으로 복사를 시행한다. mov 명령어로도 충분이 이동이 가능하지만, CPU에 존재하는 명령어를 통해 속도를 최적화하기 위해 사용한다.

 xmm0은 CPU상에 128bit의 레지스터를 의미한다. 자세한 내용은 다음 참고.

 

 이렇게 데이터를 처리하는 이유은  현재 컴퓨터에서 정수의 저장방식과 실수를 저장할 때 사용하는 부동소수점의 저장방식에 차이가 있기 때문이다. 정수는 단순 연산만으로 가능하지만, 부동 소수점은 처리해야할 예외가 상대적으로 많기 때문에 이러한 방식으로 코드를 작성한다고 생각된다.


 [401018]에서 스택의 크기를 8 빼줌으로써 double 타입을 넣는다.

 그 다음줄의

movsd [esp + 8 + var_8], xmm0

 에서 [esp + 8 + var_8]은 번역시 [esp + 8 + (-8)]로 esp에 xmm0을 넣겠다는것이다. esp + 8 + var_8 의 형식으로 사용하는지는 모르겠다.


     push offset _Format

 을 통해 스택에 "%f"를 넣고 _printf를 호출해 넣는다.


 이후

add esp, 0Ch

xor eax, eax

retn

 을 통해 함수 호출 스택프레임을 삭제한다.


 결론적으로 보면 최종 의사코드는 다음과 같다.



#include <stdio.h>

int main(void) {
	double xmm0 = 4.141592[각주:1];

	printf("%f", xmm0);

	return 0;
}


 이 때, 처음 코드의 #define으로 된 전처리 구문의 경우 컴파일 당시 obj 파일이 만들어지기 전 치환후 치환된 코드가 obj파일로 만들어지기 때문에 obj파일을 기반으로 바이너리 파일을 만드는 현재로서는 전처리 구문으로 생성한 상수와 매크로 함수는 확인이 불가능하다.

  1. 401010 에서 ds:_real@~~~~ 부분에 저장되어있다. [본문으로]
728x90
반응형

'리버싱 > C300' 카테고리의 다른 글

[C300] : C004  (0) 2018.09.28
[C300] : C002  (0) 2018.09.23
[C300] : C001  (0) 2018.09.22
Comments