Java, VB.NET, C #, ActionScript 3.0 등과 같은 바이트 코드 기반 가상 머신 언어를 사용하면 인터넷에서 디 컴파일러를 다운로드하고 바이트 코드를 한 번에 실행하는 것이 얼마나 쉬운 지에 대해 종종 듣습니다. 종종 몇 초 만에 원본 소스 코드와 너무 멀지 않은 것을 생각해냅니다. 아마도 이런 종류의 언어는 특히 그것에 취약합니다.
최근에 원래 이진 코드가 원래 작성된 언어 (및 디 컴파일하려는 언어)를 알았을 때 네이티브 이진 코드와 관련하여 더 이상 듣지 못하는 이유가 궁금해졌습니다. 오랫동안 네이티브 머신 언어가 일반적인 바이트 코드보다 훨씬 더 복잡하고 더 복잡하기 때문이라고 생각했습니다.
그러나 바이트 코드는 어떻게 생겼습니까? 다음과 같이 보입니다 :
1000: 2A 40 F0 14
1001: 2A 50 F1 27
1002: 4F 00 F0 F1
1003: C9 00 00 F2
그리고 네이티브 머신 코드는 어떻게 보입니까 (16 진수)? 물론 다음과 같습니다.
1000: 2A 40 F0 14
1001: 2A 50 F1 27
1002: 4F 00 F0 F1
1003: C9 00 00 F2
그리고 지침은 다소 비슷한 마음의 틀에서 나옵니다.
1000: mov EAX, 20
1001: mov EBX, loc1
1002: mul EAX, EBX
1003: push ECX
따라서 C ++과 같이 네이티브 바이너리를 디 컴파일하려고하는 언어가 어떻습니까? 즉시 생각 나는 유일한 두 가지 아이디어는 1) 실제로 바이트 코드보다 훨씬 복잡하다는 것입니다. 또는 2) 운영 체제가 프로그램을 페이지 매김하고 조각을 흩어 버리는 경향이 너무 많은 문제가 있다는 사실에 관한 것입니다. 그러한 가능성 중 하나가 맞다면 설명하십시오. 그러나 어느 쪽이든, 왜 기본적으로 이것을 듣지 못합니까?
노트
답 중 하나를 받아들이려고하지만 먼저 무언가를 언급하고 싶습니다. 거의 모든 사람들이 서로 다른 원본 소스 코드가 동일한 머신 코드에 매핑 될 수 있다는 사실을 다시 언급하고 있습니다. 로컬 변수 이름이 손실되고 원래 사용 된 루프 유형 등을 알 수 없습니다.
그러나 방금 언급 한 두 가지 예는 내 눈에 사소한 것입니다. 그러나 일부 답변은 머신 코드와 원본 소스의 차이가이 사소한 것보다 훨씬 더 크다고 진술하는 경향이 있습니다.
그러나 예를 들어 로컬 변수 이름 및 루프 유형과 같은 경우 바이트 코드에서도이 정보가 손실됩니다 (적어도 ActionScript 3.0의 경우). 전에는 디 컴파일러를 통해 그 내용을 가져 왔으며 변수가 호출되었는지 strMyLocalString:String
또는 인지는 신경 쓰지 않았습니다 loc1
. 나는 여전히 그 작은 지역 범위를 보았고 그것이 큰 문제없이 어떻게 사용되고 있는지 볼 수있었습니다. 그리고 for
루프는while
당신이 그것에 대해 생각하면 루프. 또한 irrFuscator (secureSWF와 달리 멤버 변수 및 함수 이름을 무작위 화하는 것 이상을 수행하지 않음)를 통해 소스를 실행할 때도 특정 변수 및 함수를 더 작은 클래스에서 분리하기 시작할 수있는 것처럼 보입니다. 그들이 어떻게 사용되는지, 그들 자신의 이름을 할당하고 거기서부터 일하십시오.
이것이 큰 문제가 되려면 머신 코드는 그것보다 훨씬 많은 정보를 잃어 버릴 필요가 있으며, 그 중 일부는 이것에 관한 것입니다.