2014-05-16 3 views
-1

JAD 디 컴파일 된 파일이 100 % 정확합니다. 소스 코드를 얻기 위해 일부 jar 파일을 디 컴파일 할 때 정확한 빌드를 표시하지 않는 java 파일로 프로젝트를 빌드하려고 할 때. 내가 잘못했거나 디 컴파일 된 파일이 원본 파일과 정확히 같지 않은가?JAD 디 컴파일 된 파일이 100 % 정확합니까?

+1

소스 파일이 난독 화 될 수 있습니다. 어쨌든 jd-gui –

+0

을 사용하지 마십시오. 주석이 없습니다. 디버그가없는 경우 지역 변수 이름, 원래 줄 번호, 원래 컴파일 시간 상수, 원래 형식 등이 있습니다. 이들은 모두 바이트가 아니기 때문입니다 암호. –

+1

while() {} 및 for() {}의 바이트 코드를 명확하게 구별 할 수없는 경우 디 컴파일러가 다른 바이트를 대체 할 수 있습니다 (의미는 동일하게 유지됩니다). 일부 바이트 코드는 자바 (예 : 생성 된 코드, 다른 VM 기반 언어 컴파일러에서 생성 된 코드)에 제대로 디 컴파일 할 수 없습니다. – Durandal

답변

3

짧은 대답 : 99 %의 시간, 디 컴파일 된 코드는 원래 코드와 같지 않지만 동일한 방식으로 작동해야합니다. 따라서 디 컴파일러가 실수를하지 않는다고 가정하면 함수에서 정확해야하지만 구현에서는 정확하지 않아야합니다.

긴 대답 : Java 컴파일러가 소스를 바이트 코드로 변환 할 때 코드 작성 방법을 변경하는 특정 연산을 수행합니다. Java 컴파일러의 세부 사항에 대한 전문가는 아니지만 많은 컴파일러에서 수행하는 간단한 최적화는 호출 된 코드의 위치에 작은 메서드를 삽입하는 것입니다.

예를 들어, 우리는이 코드를 컴파일 말할 수 : b는 하나 개의 라인이기 때문에

public class c 
{ 
    public int add(int a, int b) 
    { 
     return a + b; 
    } 

    public static void main(String [] args) 
    { 
     int i = add(1, 2); 
    } 
} 

을하고 안전하게 스마트 컴파일러는 이것으로 주요 방법을 변경할 수 있으며, 내용의로 대체 할 수 있습니다

public static void main(String [] args) 
{ 
    int a = 1, b = 2 
    int i = a + b; 
} 

나이 :

public static void main(String [] args) 
{ 
    int i = 1 + 2; 
} 

이 수행 될 수 있기 때문에 캘러스의 오버 헤드 메소드가 호출 된 장소에 직접 메소드의 내용을 넣는 오버 헤드보다 메소드가 더 나쁩니다.

Java 컴파일러가이 상황에서 어떤 역할을하는지 알지 못하지만이 같은 코드를 변경합니다. 원래 코드와 동일한 작업을 수행하므로 반드시 정확하지는 않습니다. 컴파일러는 이러한 변경 사항에 대한 세부 사항을 .class 파일에 두지 않으므로 디 컴파일러가 코드의 특정 지점에서 최적화가 수행되었는지 여부를 알 수있는 방법이 없습니다.

또한 바이트 코드 (예 : 변수 이름 및 주석) 로의 전환이 지속되지 않는 여러 가지가 있습니다.

그렇습니다. 디 컴파일 된 코드를 보면 .java 파일의 모양이 아닌 .class 파일의 모양을 볼 수 있습니다. 비록 그것이 부정확 한 것처럼 보일지라도, 그것은 똑같이 실행되어야합니다.

+2

자바 컴파일러 자체는 ** 인라인을 수행하지 않습니다 ** 너는 설명했다. 메소드가 private 인 경우 * 이론적으로 * 할 수 있지만 클래스의 구조를 유지해야하기 때문에 변경하지 않습니다 (예 : 메소드가 다음을 통해 액세스되는 경우). 반사).인라인은 JIT에서 수행합니다. – Marco13

+0

그래, 자바 컴파일러를 자세히 공부하지는 않았으므로 예제로 사용할 것을 정확히 모르겠습니다. 설명하기 쉽기 때문에이 코드를 사용하기로 결정했습니다. 다른 플랫폼에서도 사용할 수있는 Java 코드에는 적용 할 수 없더라도 코드 구조에 변경 사항이 적용된다는 점을 알게되었습니다. Java 컴파일러에 대해 더 많이 알고있는 사람이 더 좋은 예가 있다면, 그것을 추가하거나 커뮤니티 위키에 대한 내 대답을 바꾸어 드리겠습니다. – RyNo

+2

가장 많이 볼 수있는 차이점은 분기의 미묘한 변화입니다. 예를 들어 'while (a) {if (! b) f(); }'저자가 원래 작성한 곳'while (a) {if (b) continue; 에프(); }'또는'a = b? c : d' 저자가'if (b) a = c; else = d;'. 더 많은 중간 변수가 소개되고 일부 값은 인라인 될 수 있습니다. 그러나 디 컴파일 된 출력이 원래 코드와 기능적으로 동일하다고 가정하지 마십시오. 그것은 의도 된 것이지만 디 컴파일러는 오류가 없습니다. –

-2

해당 프로그램에 더 많은 개인 클래스가있는 경우. decompiler는 자체 방식으로 코드를 변환하지만 코드가 적 으면 올바른 코드를 표시합니다. xml 파일의 경우 완전히 변환됩니다.

+1

그것은 매우 모호하고 아마도 틀린 대답입니다. 더 자세한 내용이나 주장의 출처를 제공해 주시겠습니까? – lukelazarovic