2010-07-07 4 views
1

프로그램을 표현하고 실행하기위한 저수준 프로세스를 확실하게 이해하고 싶습니다. 개체 파일 정보 (헤더, 섹션 등)를 구문 분석하고 표시하는 프로그램을 작성하여이 작업을 수행하기로 결정했습니다. 나는이 부분을 거의 끝냈다. 자연스러운 확장은 나머지 관련 데이터를 어셈블리 명령어로 디 컴파일하는 것입니다. 처음에는 x86에 초점을 맞 춥니 다.x86 디 컴파일을위한 리소스

이 디 컴파일 (binary -> ASM)과 관련된 리소스는 어디에서 찾을 수 있습니까? 필자는 x86이 ASM과 일대일로 대응한다는 것을 읽었지만, 변환 테이블을 가져 오는 데 가장 적합한 참조를 모르겠습니다.

또한 필자는 제공된 디버깅 정보를 추적하는 데 관심이 있습니다. 이 정보에 사용 된 형식에 대한 참조가 있습니까 (ELF와 GCC를 -g 옵션으로 가정 할 수 있습니까?).

일반적인 조언이 있습니까? 여기서의 목표는 내 이해를 높이는 실습 프로젝트입니다.

답변

1

x86은 명령어 길이가 다양하기 때문에 분해가 매우 어렵습니다. 처음 디스어셈블러 인 경우에는 권장하지 않습니다.

말하기 ... 내가 취하는 접근법은 opcode의 첫 번째 바이트 인 바이트를 식별하고 opcode 또는 데이터의 두 번째 바이트 또는 다른 바이트와 구분해야한다는 것입니다. 바이너리의 시작 부분에서 시작하여 opcode를 디스 어셈블 할 수 있다는 것을 알게되면.

어떻게하면 다른 바이트의 opcode를 찾아 낼 수 있습니까? 가능한 모든 실행 경로를 따라 가야하고, 재귀 문제와 같은 소리가 들릴 수도 있지만 그렇지 않아도됩니다. 인터럽트 벡터 테이블 및/또는 코드의 모든 하드웨어 진입 점을 살펴보십시오. 그러면 opcode 바이트의 짧은 목록을 얻을 수 있습니다. 비 재귀 방식은 opcode로 표시된 각 바이트를보고 바이너리를 여러 번 통과 시키며 소비하는 바이트 수를 알 수있을 정도로만 디코딩합니다. 또한 조건부 분기, 조건부 분기, 복귀, 호출 등이 있는지 여부를 알아야합니다. 조건부 분기 또는 반환이 아닌 경우이 명령어가 다음 명령어의 첫 번째 바이트 인 것으로 가정 할 수 있습니다. 분기 나 호출이있을 때마다 목적지 주소를 계산하고 그 바이트를리스트에 추가하십시오. 목록에 새 바이트를 추가하지 않는 패스를 만들 때까지 계속 패스를 만듭니다. 또한 3 바이트 명령어 인 바이트가 명령어로 표시되었지만 바이트가 발견되면 문제가 있음을 확인해야합니다. 조건부 분기점과 같은 것들은 결코 분기하지 않도록 보장합니다. 바이너리로 컴파일 된 높은 수준의 코드를 사용하는 경우에는이 정도를 보지 못한다.하지만 손으로 ​​작성한 어셈블러 또는 코드 보호를 원하는 사람들이 옛날처럼 이런 일을 할 것이다.

불행히도 당신이 갖고있는 것이 모두 가변 길이의 악기 세트 인 경우에는 완벽하게 분해되지 않습니다. 일부 분기 대상은 런타임에 계산됩니다. 때로는 직접 코딩 된 어셈블리가 반환 할 코드를 변경하기 전에 스택을 수정합니다. 그 코드에 대한 유일한 경로라면 프로그래밍 방식으로 계산하지 않을 것입니다. 코드를 시뮬레이트합니다. 그리고 시뮬레이션으로도 모든 실행 경로를 다루지 않을 것입니다.

예를 들어 ARM과 같이 고정 길이 명령어 세트로 설정하면 (팔과 엄지가 섞여 있지 않은 한) 바이너리의 시작 부분에서 간단히 시작하여 단어가 부족할 때까지 분해 할 수 있습니다. 데이터 단어를 유효하거나 유효하지 않거나 사용하기 쉬운 지시로 분해 할 수는 있지만 괜찮습니다.

엘프 어딘가에 바이너리의 어떤 부분이 실행 가능하고 어떤 부분이 데이터인지 나타내는 것이 있으면 놀랄 것입니다. 어쩌면 그렇게 많은 데이터 경로를 걸어야 할 필요가 없다. objdump가 아마도 elf 파일에서 뭔가를 사용하는 것과 같은 작업을 수행하는지 의심 스럽다.

elf 파일 형식은 여러 곳에서 설명되어 있습니다. 기본 구조가 있고 공급 업체는 공급 업체가 문서화하는 특정 블록 유형을 추가 할 수 있습니다.

+0

대단한 답변입니다! 기여할 시간을 내 주셔서 대단히 감사합니다. –

1

체크 아웃 내 가상 머신 자습서 : 그것은 당신이 단계별로 자신의 가상 머신과 어셈블러를 구축하는 방법을 배울 수 http://www.icemanind.com

합니다. 읽고 튜토리얼에서 프로그램을 완료하면 어떻게 프로그램, 어셈블리 언어와 바이너리 작품

에 더 확고한 이해를해야합니다