Jar 파일은 zip으로 압축이 되어있습니다. 이 압축을 풀면 많은 .class
파일들이 있습니다.
class 파일은 Java 파일을 바이트코드로 컴파일하면서 생성되는 산출물입니다.
class 파일을 열면 Java 코드가 보이지 않기 때문에, 보고 싶다면 Java로 다시 디컴파일해야 합니다.
decompile하는 방법은 여러가지가 있지만, 여기서는 다음 두가지 방법을 소개하겠습니다.
- IntelliJ IDE에서 디컴파일하는 방법
- jd-cli 툴을 이용하여 디컴파일하는 방법
1. IntelliJ IDE에서 디컴파일하는 방법
.class
파일을 Java 파일로 디컴파일 하는 가장 쉬운 방법 중 하나는 IntelliJ를 이용하는 방법입니다.
IntelliJ를 사용하는 경우 .class
파일을 Drag-and-drop 하여 IDE 창에 올려두기만 하면 자동으로 Java로 디컴파일됩니다.
2. jd-cli 툴을 이용하여 디컴파일하는 방법
class 파일을 Java로 decompile해주는 jd-cli
라는 툴이 있습니다. Jar 파일 안에 있는 모든 class 파일을 Java로 변환해주기 때문에 편리합니다.
jd-cli 툴은 GitHub - Jd-cmd에서 다운받을 수 있습니다.
저는 설치파일을 ~/apps/jd-cli-0.9.2-dist/
경로에 압축을 풀어 저장하였습니다.
그럼 다음과 같이 jd-cli.jar 명령어를 실행할 수 있습니다. 명령어의 인자로 디컴파일하고 싶은 jar 파일과 변환된 파일이 저장되는 위치를 입력하면 됩니다.
$ java -jar jd-cli.jar [jar file] -od [output folder]
저의 경우, 다음과 같은 명령어로 디컴파일 할 수 있습니다. output
폴더를 보시면 java 파일로 디컴파일된 것을 확인할 수 있습니다.
java -jar ~/apps/jd-cli-0.9.2-dist/jd-cli.jar android.jar -od output
$ jd-cli android.jar -od output
09:13:41.923 INFO jd.cli.Main - Decompiling android.jar
09:13:41.925 INFO jd.core.output.DirOutput - Directory output will be initialized for path output
09:13:46.225 INFO jd.core.output.DirOutput - Finished with 4751 class file(s) and 7594 resource file(s) written.
class 파일 1개만 디컴파일
jd-cli는 jar 뿐만 아니라 class파일을 Java로 변환해주는 명령어도 있습니다.
- java -jar jd-cli.jar [class file] : class파일을 java로 변환하여 화면에 출력합니다.
- java -jar jd-cli.jar [class file] -od [output folder] : class파일을 java로 변환하여 ouput folder에 저장합니다.
다음과 같이 사용할 수 있습니다.
$ java -jar jd-cli.jar AbstractCollection.class
09:32:37.885 INFO jd.cli.Main - Decompiling /home/js/Desktop/android/java/util/AbstractCollection.class
package java.util;
import androidx.annotation.RecentlyNonNull;
import androidx.annotation.RecentlyNullable;
public abstract class AbstractCollection<E>
....
alias (For linux user)
매번 명령어를 입력하면 번거롭기 때문에 ~/.bashrc
에 아래처럼 명령어를 alias로 등록할 수 있습니다.
$ alias jd-cli='java -jar ~/apps/jd-cli-0.9.2-dist/jd-cli.jar'
alias를 등록하면 다음과 같이 짧은 명령어로 디컴파일할 수 있습니다.
$ jd-cli android.jar -od output
Related Posts
- Java - Unsupported class file major version 61 에러
- Java - String.matches()로 문자열 패턴 확인 및 다양한 예제 소개
- Java - 문자열 공백제거 (trim, replace)
- Java - replace()와 replaceAll()의 차이점
- Java - ArrayList 초기화, 4가지 방법
- Java - 배열 정렬(Sorting) (오름차순, 내림차순)
- Java - 문자열(String)을 비교하는 방법 (==, equals, compare)
- Java - StringBuilder 사용 방법, 예제
- Java - 로그 출력, 파일 저장 방법 (Logger 라이브러리)
- Java IllegalArgumentException 의미, 발생 이유
- Java - NullPointerException 원인, 해결 방법
- Seleninum의 ConnectionFailedException: Unable to establish websocket connection 해결
- Java - compareTo(), 객체 크기 비교
- Java - BufferedWriter로 파일 쓰기
- Java - BufferedReader로 파일 읽기
- Java charAt() 함수 알아보기
- Java - BigInteger 범위, 비교, 연산, 형변환
- Java contains()로 문자(대소문자 X) 포함 확인
- Java - Set(HashSet)를 배열로 변환
- Java - 문자열 첫번째 문자, 마지막 문자 확인
- Java - 문자열 한글자씩 자르기
- Java - 문자열 단어 개수 가져오기
- Java - 1초마다 반복 실행
- Java - 배열을 Set(HashSet)로 변환
- Java - 여러 Set(HashSet) 합치기
- Java - 명령행 인자 입력 받기
- Java - 리스트 역순으로 순회, 3가지 방법
- Java - 특정 조건으로 리스트 필터링, 3가지 방법
- Java - HashMap 모든 요소들의 합계, 평균 계산
- Java - 특정 조건으로 HashMap 필터링
- Java - 싱글톤(Singleton) 패턴 구현
- Java - 숫자 왼쪽에 0으로 채우기
- Java - String 배열 초기화 방법
- Java - 정렬된 순서로 Map(HashMap) 순회
- Java - HashMap에서 key, value 가져오기