2016-09-14 2 views
-2

Os X에서는 다음과 같은 명령으로 C 프로그램을 컴파일했습니다. gcc -o binaryoutName inputfile 결과 바이너리 "Exec"파일에 대해 16 진 덤프를 생성했습니다. 내가 이해 하듯이, Exec 파일은 UNIX 실행 파일이며 UNIX는 실행 파일과 동일합니다. 내가 명령 xxd -b binary을 사용하여 진수 덤프를 실행Unix 실행 파일 'Exec', 16 진수 덤프는 어셈블리가 아닌 C 코드를 보여줍니다.

, 그것은 그러나이 ASCII 내가 처음에 .c 파일을 프로그램 리터럴 C 코드를 표현, 바이너리의 ASCII 내용을 반환

진수 덤프 추출합니다. : 맨 오른쪽 열에서 ASCII 번역 내가 처음에 컴파일 된 .c 파일 내부 코드와 매우 유사하다는 것을

0007c4a: 01101100 01110101 01110011 01101000 00000000 01011111 lush._ 0007c50: 01100110 01101111 01110000 01100101 01101110 00000000 fopen. 0007c56: 01011111 01100110 01110000 01110010 01101001 01101110 _fprin 0007c5c: 01110100 01100110 00000000 01011111 01100111 01100101 tf._ge 0007c62: 01110100 01100011 01101000 01100001 01110010 00000000 tchar. 0007c68: 01011111 01100111 01100101 01110100 01100011 01110111 _getcw 0007c6e: 01100100 00000000 01011111 01100111 01100101 01110100 d._get 0007c74: 01100101 01101110 01110110 00000000 01011111 01101100 env._l 0007c7a: 01101111 01100011 01100001 01101100 01110100 01101001 ocalti 0007c80: 01101101 01100101 00000000 01011111 01101101 01100101 me._me 0007c86: 01101101 01100011 01110000 01111001 00000000 01011111 mcpy._ 0007c8c: 01110000 01110010 01101001 01101110 01110100 01100110 printf 0007c92: 00000000 01011111 01110000 01110101 01110100 01100011 ._putc 0007c98: 01101000 01100001 01110010 00000000 01011111 01110011 har._s 0007c9e: 01100011 01100001 01101110 01100110 00000000 01011111 canf._ 0007ca4: 01110011 01101100 01100101 01100101 01110000 00000000 sleep.

참고. 이것은 컴파일러가 논리적으로 컴파일 할 어셈블리 코드의 ASCII 바이너리가 16 진 덤프에 포함될 것으로 예상했기 때문에 반 직관적입니다.

이것은 컴파일 과정에 대한 이해의 한계에 관한 질문이며 잘못된 몇 가지 세부 사항이있을 것으로 예상됩니다.

내 질문 : 16 진수 덤프가 어셈블리 대신 C 코드의 ASCII를 반환 한 이유는 무엇입니까?

미리 감사드립니다.

+4

우리는 어떻게 가능하게 알 수 있습니까? 아마도 일부 명령이 잘못 실행 된 것일 수 있습니다. 실제 데이터를 표시하지 않으면 아무 것도 확인할 수 없습니다. – kaylum

+2

어떻게'gcc'를 호출 했습니까? – Serge

+0

명령은 'gcc -o BinaryOuputfile FilenameInput'이었습니다. 컴파일하는 동안 명령 구문이 정확했기 때문에 질문을 작성할 때 실수했습니다. 16 진 덤프 추출이 포함되었습니다. – user4493605

답변

0

문자열이 포함 된 실행 파일이나 개체 파일의 섹션 (또는 유사한 섹션)은 .strtab입니다.

#include <stdio.h> 

int main(void) 
{ 
    printf("Hello world!\n"); 
} 

다음 명령을 사용하여 컴파일 :

$ xxd a.out 
... 
00022e0: 0000 0000 0000 0000 0063 7274 7374 7566 .........crtstuf 
00022f0: 662e 6300 5f5f 4a43 525f 4c49 5354 5f5f f.c.__JCR_LIST__ 
0002300: 0064 6572 6567 6973 7465 725f 746d 5f63 .deregister_tm_c 
0002310: 6c6f 6e65 7300 7265 6769 7374 6572 5f74 lones.register_t 
0002320: 6d5f 636c 6f6e 6573 005f 5f64 6f5f 676c m_clones.__do_gl 
... 
: 우리가 그것을 Hexdump에서는, 우리는 같은 것을 발견 할 것이다

gcc -Wall -g -std=c11 c00.c 

다음 C 프로그램의 예를 들어

,

그리고 섹션 관련 정보는

을 통해 알 수 있습니다.
$ readelf -WS a.out 
... 
    [34] .strtab   STRTAB   0000000000000000 0022e8 000235 00  0 0 1 

주의점 .strtab의 오프셋은 0x380093의 출력에서 ​​본 것과 일치하는 0x0022e8입니다.

0

당신이 보는 것은 C 코드가 아니라 실행 파일이나 오브젝트 파일 (심볼 외부 연결 속성을 가진 기호)입니다. 심볼 테이블의 경우, 컴파일러는 링크 가능 파일을 생성하거나 디버그를 쉽게하기 위해 다른 목적으로 심볼 파일을 생성합니다. 예를 들어, 오브젝트 파일 또는 실행 파일은 형식이 지정됩니다 (예 : Linux는 ELF 표준을 사용합니다) : 심볼 테이블, 전역 변수, 코드 등 여러 섹션으로 컴파일됩니다.

실행 파일에서 이러한 기호는 필수는 아니며 명령을 strip으로 쉽게 제거 할 수 있습니다. 개체 파일을 제거하면 링크 할 수 없습니다.

nm과 같은 명령을 사용하여 기호 테이블의 내용을보다 읽기 쉬운 형식으로 표시 할 수 있습니다.당신이 프로그램과 정확한 출력 샘플을 컴파일하는 방법을 우리에게 보여주지 않는 경우 stripnm 명령에 대한

읽기 온라인 설명서, 컴파일러는 객체 파일을 링크하는 방법 ...