2017-11-23 24 views
1

메소드의 모든 라벨의 오프셋을 가져 오려고합니다.자바 바이트 코드 - ASM - 라벨 오프셋 가져 오기

나는 다음과 같은 코드를 사용하여 시도

:

java.lang.IllegalStateException: Label offset position has not been resolved yet 

어떻게 이러한 위치를 오프셋 해결할 수 있습니다

private static ArrayList<Integer> GetLabelOffsets(MethodNode methodNode) { 
    ArrayList<Integer> labelOffsets = new ArrayList<>(); 

    for (AbstractInsnNode instruction : methodNode.instructions.toArray()) { 
     if (instruction instanceof JumpInsnNode) { 
      JumpInsnNode jumpInsnNode = (JumpInsnNode) instruction; 
      labelOffsets.add(jumpInsnNode.label.getLabel().getOffset());. 
     } 
    } 

    return labelOffsets; 
} 

getOffset() 방법이 Exception을 발생하지만를? 아니면 이것을 달성하기위한 적절한 방법은 무엇입니까? documentation of getOffset()에서

public static HashMap<String, ClassNode> ParseJar(JarFile jar) { 
    HashMap<String, ClassNode> classes = new HashMap<>(); 

    try { 
     Enumeration<?> enumeration = jar.entries(); 
     while (enumeration.hasMoreElements()) { 
      JarEntry entry = (JarEntry) enumeration.nextElement(); 

      if (entry.getName().endsWith(".class")) { 
       ClassReader classReader = new ClassReader(jar.getInputStream(entry)); 
       ClassNode classNode = new ClassNode(); 
       classReader.accept(classNode, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); 
       classes.put(classNode.name, classNode); 
      } 

     } 
     jar.close(); 
     return classes; 
    } catch (Exception ex) { 
     return null; 
    } 
} 

public static void main(String[] args) { 
    JarFile jar = new JarFile(fileName); 
    HashMap<String, ClassNode> classes = JarUtils.ParseJar(jar); 
    for (ClassNode classNode : classes.values()) { 
     for (MethodNode methodNode : classNode.methods) { 
      ArrayList<Integer> offsets = GetLabelOffsets(methodNode); 
      // do more stuff with offsets 
     } 
    } 
} 
+0

[최소, 완료 및 확인 가능한 예] (https://stackoverflow.com/help/mcve)를 제공해주십시오. –

+0

업데이트 해 주셔서 감사합니다! 문제를 재현하기 위해 jar 파일을 프로그램 입력으로 사용해야합니까? –

+0

모든 jar 파일이 수행해야합니다. 바이트 코드에 (비) 조율 점프가 포함되어있는 한. – eKKiM

답변

4

:

이 방법

편집

MethodNode

는 요청에 더 많은 코드를 추가 자바 ASM 라이브러리에서 org.objectweb.asm.tree.MethodNode 객체입니다 속성 하위 CL을위한 것입니다. 엉덩이, 그리고 일반적으로 클래스 생성기 또는 어댑터가 필요하지 않습니다. 지시 목록을 처리 할 때

바이트으로 정의되는 오프셋이 있기 때문에, ASM은 상이한 길이를 가질 수있는 명령의 다른 형태를 추상화 특히 매우 유용하지 않을 바이트 코드.

일반적으로이 명령어 목록을 변경할 수 있으므로 Label은 논리 위치를 나타내며 결과 바이트 코드를 쓸 때 오프셋이 계산되고 실제 숫자는 알려집니다.

명령 목록 내에서 해당 LabelNode이 지침과 동일한 Label을 참조해야합니다.

+0

감사! 내가 이걸 지나치게 복잡하게 만든 것 같아. 이렇게하면 효과적이고 훨씬 쉽습니다. – eKKiM