2017-11-22 6 views
0

다양한 클래스의 메소드 구현을 핫 스왑해야합니다 (런타임 중에 어딘지 모를 새 구현은 다시 변경 될 수 있음).``Class`` 인스턴스에서 jimple 표현하기

ByteBuddy은 쉽게 처리 할 수 ​​있지만 차단하는 것을 제외하고는 (분명히) ASM과 함께 제공되는 방법을 많이 사용할 수 없습니다.

기본 사용법은

private static byte[] transformFoo() throws IOException { 
    ClassReader classReader = new ClassReader(Foo.class.getResourceAsStream("Foo.class")); 
    ClassWriter classWriter = new ClassWriter(classReader, 0); 
    MyClassVisitor myClassVisitor = new MyClassVisitor(classWriter); 
    classReader.accept(myClassVisitor, 0); 

    return classWriter.toByteArray(); 
} 

은 ASM을 사용

ByteBuddyAgent.install(); 
    byte[] bytes = transformFoo(); 

    ClassFileLocator classFileLocator = ClassFileLocator.Simple.of(Foo.class.getName(), bytes); 
    new ByteBuddy() 
      .redefine(Foo.class, classFileLocator) 
      .make() 
      .load(Foo.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent()); 

입니다.

그러나 ASM은 더 정교하고 복잡한 것을 읽거나 코딩하기가 지루하고 힘들다. 그래서 if-stmts와 같은 것들을 추상화 할 수 있기 때문에 Jimple을 사용하는 편이 낫습니다.

아이디어는, 그러므로, 어떻게 든,

Class<?> fooClass = Foo.class; 

로 시작되는

SootClass fooSootClass = ... 

로 변환,이 방법을 변환하고, 어떻게 든 byte[]

byte[] ret = ... 
return ret; 
로 다시 컴파일

st ByteBuddy은 클래스를 다시로드 할 수 있습니다. 간단히 말해서

는 :

나는 Class<?>에서 변환 가능한 SootClass를 작성하고 내가 주위를 전달할 수있는 byte[]로 컴파일합니다.

어떻게하면됩니까?

업데이트

ThisSootClass에서 byte[]로 변환을 수행 뜨거운 제안 보이지만, 지금까지, 나는 Class에서 전환에 도움이 될 문서 또는 예를 모든 종류의를 찾을 수 없었다 ~ SootClass. 대부분의 예제는 클래스를로드하기 전에 한 번만 계측하는 것처럼 보입니다.

+0

전체 질문 텍스트를 "* '클래스에서 변환 가능한'SootClass'를 어떻게 만들 수 있으며 금액을 변경하지 않고 * [전달할 수있는 바이트]로 컴파일 할 수 있습니까? 귀하의 질문에 정보. 관련없는 코드 예제 나 ASM에 대한 귀하의 의견도 관련성이있는 내용을 추가하지 않습니다. 대신, "변형 가능한"SootClass "가 무엇인지, 그리고 그것이 보통의'SootClass'와 어떻게 다른지, 그리고 시도한 것과 어디서 문제가 발생했는지 설명하는 데 집중해야합니다. – Holger

+0

@Holger 의견을 주셔서 감사합니다. 동기 부여에 관한 비트를 제거 할 수는 있지만, "왜 이것을하고 싶니?", "하지 마라.", "전혀 상관없는 무언가를 할 수는 없을 것"과 같은 코멘트를 얻을 수 있습니다. > ".그것을 유지하는 것은 "당신은 무엇을하고 있는가?"와 같은 종류의 의견을 피하면서 대안 제안을 제안하고자하는 사람들이 그들의 제안이 실행 가능한 선택이 될 수 있는지 판단하는 것을 허용해야합니다. 내 문제는 클래스를로드 한 후에 그을음으로로드하는 방법에 대한 정보를 찾을 수 없다는 것입니다. 그 비트를 추가하기 위해 질문을 업데이트했습니다. – User1291

+0

Soot 특정 질문이있을 때 ByteBuddy 또는 ASM을 사용하지 않는 이유를 설명 할 필요가 없습니다. 그리고 아무도 왜 * 당신이하고 싶은 것을 이해하지 않는 한 * 왜 * 당신이 그것을하고 싶어하는지 묻지 않을 것입니다. 다시 말하자면, "변형 가능한"SootClass "는 무엇이며, 일반적인"SootClass "와 어떻게 다릅니 까? * Atm, 바이트 코드 처리 도구에서 바이트 코드 배열을 얻는 방법을 묻는 것처럼 보입니다. 해당 도구의 기본 설명서에 포함되지 않은 경우 잘못된 것이 있습니다. 질문이 [튜토리얼을 묻는 질문] (https://stackoverflow.com/help/on-topic)과 다른 점을 설명하십시오. – Holger

답변

0

나는 몇 년 전에 나 자신을 시도했고 실패했다. 나는 그것이 이론적으로 가능하다고 말하기는하지만 쉬운 일이다.

+0

당신이 시도한 것과 실패한 이유를 기억하십니까? – User1291

+0

한 가지 문제는 클래스를 즉석에서 처리하려고 할 때 일반적으로 java.lang.instrument를 사용하여로드 할 때 클래스에서 수행하려고한다는 것입니다. 즉, 클래스로드 프로세스에 필수적으로 참여하기 때문에 한 번에 하나의 클래스 만 보게됩니다. 그러나 Soot가하는 많은 일들에 대해 다른 클래스에 대한 액세스가 필요합니다. 예를 들어, 시그니처와 메소드 바디를 해결해야합니다. 그러면로드 된 클래스 세트와로드 된 순서가 완전히 변경됩니다. 나는 이것이 상당한 문제를 일으킨다는 것을 기억한다. ASM은 그러한 해결책을 제시하지 않습니다. – Eric