2017-01-20 12 views
-1

명령 .exe (또는 .dll 또는 .so) 그것은 바이너리 단지 읽을 부분을 인쇄 할 .자바 명령이나 서브 루틴 문자열 I가</p> <pre><code>strings someBinaryfile.exe </code></pre> <p>할 수 <code>bash</code>에서

java에 유사한 라이브러리가 있습니까? 파일을 열고 인쇄하는 방법을 알고 있지만 인간이 읽을 수있는 부분 만 있으면됩니다.

+0

@Inian – RonPringadi

+1

질문을 포맷 해 주셔서 감사합니다. 'strings'는'bash' 명령이 아닙니다. 이것은 자바 프로그램뿐만 아니라'bash' 스크립트에서 실행할 수있는 독립 실행 형 프로그램입니다. – chepner

+0

@chepner를 이해합니다 - 제쳐두고 비슷한 목적을 가진 자바 라이브러리가 있습니까? 예를 들어 아파치 공유 (비록 내가 아파치 공유 라이브러리에서 비슷한 기능을 찾을 수 없지만) – RonPringadi

답변

2

strings의 기능을 완전히 복제하는 기존 Java 라이브러리를 인식하지 못했습니다. GNU 문자열 4 자 이상있는 인쇄 가능한 문자 시퀀스를 인쇄, 주어진 각 파일에 대해

: 당신이 그것을 직접 구현하는 것이 좋습니다 싶은 경우에, 우리는 요구 사항의 더 나은 아이디어를 얻기 위해 Linux man page for strings를 읽을 수 있습니다 (또는 아래 옵션과 함께 에 주어진 숫자) 다음에 인쇄 할 수없는 문자가옵니다.

따라서 순수 자바 코드에서 자신의 솔루션을 구현하기를 원한다면, 당신은 파일의 각 바이트를 읽을 수있는 바이트가 인쇄 할 수 있는지 확인하고, 버퍼에이 바이트의 순서를 저장합니다. 그런 다음 인쇄 할 수없는 문자가 발견되면 버퍼에 적어도 4 바이트가 포함되어 있으면 버퍼의 내용을 인쇄하십시오. 예를 들어 :

strings 기능의 기본 근사치를 포함 할

import java.io.BufferedInputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.FileInputStream; 
import java.io.File; 
import java.io.IOException; 

class Strings { 

    private static final int MIN_STRING_LENGTH = 4; 

    public static void main(String[] args) throws IOException { 
     for (String arg : args) { 
      File f = new File(arg); 
      if (!f.exists()) { 
       System.err.printf("error: no such file or directory: %s%n", arg); 
       continue; 
      } 
      if (!f.canRead()) { 
       System.err.printf("error: permission denied: %s%n", arg); 
       continue; 
      } 
      if (f.isDirectory()) { 
       System.err.printf("error: path is directory: %s%n", arg); 
       continue; 
      } 
      try (BufferedInputStream is = new BufferedInputStream(new FileInputStream(f)); 
         ByteArrayOutputStream os = new ByteArrayOutputStream()) { 
       for (int b = is.read(); b != -1; b = is.read()) { 
        if (b >= 0x20 && b < 0x7F) { 
         os.write(b); 
        } else { 
         if (os.size() >= MIN_STRING_LENGTH) { 
          System.out.println(new String(os.toByteArray(), "US-ASCII")); 
         } 
         os.reset(); 
        } 
       } 
       if (os.size() >= MIN_STRING_LENGTH) { 
        System.out.println(new String(os.toByteArray(), "US-ASCII")); 
       } 
      } 
     } 
    } 
} 
하지만 고려해야 할 자세한 내용이 있습니다 : 기본적으로

, 그것은 단지 초기화 및로드 섹션에서 문자열을 출력 오브젝트 파일들; 다른 유형의 파일의 경우 전체 파일에서 문자열을 인쇄합니다. 당신이 구문 분석 및 ELF 또는 Windows PE 같은 바이너리 파일 형식의 다른 부분을 이해해야하기 때문에

이 부분을 구현하는 것은 더 복잡해진다. --encoding = 부호화가 발견 될 수있는 문자열의 문자 인코딩을 선택

-e 인코딩 :

추가적인 합병증 문자 인코딩이다. 가능한 인코딩 값은 다음과 같습니다. s = 단일 7 비트 바이트 문자 (ASCII, ISO 8859 등), S = 단일 8 비트 문자, b = 16 비트 bigendian, l = 16 비트 리틀 엔디 언, B = 32 비트 bigendian, L = 32 비트 리틀 엔디 언. 와이드 문자열을 찾는 데 유용합니다. (l 및 b는 예를 들어 유니 코드 UTF-16/UCS-2 인코딩에 적용됩니다).

위에서 설명한 간단한 논리는 1 바이트 문자로 가정합니다. 멀티 바이트 문자로 인코딩 된 문자열을 식별해야하는 경우 로직은 버퍼 관리, 인쇄 가능성 검사 및 문자열 길이 검사에 대해 더주의해야합니다.

strings으로 전달할 수있는 다른 많은 인수가 모두 맨 페이지에 설명되어 있습니다. 모든 기능을 완벽하게 재현해야한다면 로직을 더욱 복잡하게 만들 것입니다.

구현하지 않으려면 ProcessBuilder 클래스를 통해 strings을 직접 포크하고 실행하고 출력을 구문 분석 할 수 있습니다. 트레이드 오프는 strings이 설치된 플랫폼에서 코드를 실행해야하며 외부 프로세스를 포크하고 실행하는 데 약간의 오버 헤드가 발생한다는 외부 종속성을 도입한다는 것입니다. 상황에 따라 이러한 상충 관계가 적용될 수도 있고 그렇지 않을 수도 있습니다.

+0

굉장! gnu strings 명령과 매우 일치합니다. 고마워요 @ 크리스 - 나우 로스 – RonPringadi