java 바이트 프레임워크 ASM 바이트 조작 방법 분석

4087 단어 asm바이트 코드
앞서 ASM에 대한 자세한 설명을 드렸는데 필요한 분들은 여기를 클릭하시면 됩니다java 바이트 프레임워크 ASM의 깊이 있는 학습
JVM 유형 서명 대조표
Type Signature
Java Type
Z
boolean
B
byte
C
char
S
short
I
int
J
long
F
float
D
double
L
fully-qualified-class ;fully-qualified-class
[ type
type[]
( arg-types ) ret-type
method type
예컨대, 자바 방법은

long f (int n, String s, int[] arr);
대응하는 형식 서명은

f (ILjava/lang/String;[I)J
그리고 예를 들면, 자바 방법은

private void hi(double a, List<String> b);
그럼 대응하는 유형 사인은요.

hi (DLjava/util/List;)V
다음은 ASM을 이용하여 상기 두 유형의 서명이 정확한지 확인할 수 있습니다.

public class Test {

 public static void main(String[] args) throws Exception {
 ClassPrinter printer = new ClassPrinter();
 // Bazhang
 ClassReader cr = new ClassReader("Test$Bazhang");
 cr.accept(printer, 0);

 }

 // 
 static class Bazhang {

 public Bazhang(int a) {
 }

 private long f (int n, String s, int[] arr){
  return 0;
 }

 private void hi(double a, List<String> b){

 }
 }

 static class ClassPrinter extends ClassVisitor {

 public ClassPrinter() {
  super(Opcodes.ASM5);
 }

 @Override
 public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
  super.visit(version, access, name, signature, superName, interfaces);
  // name name
  System.out.println(superName + " " + name);
 }

 @Override
 public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
  // 
  System.out.println(name + " " + desc);
  return super.visitMethod(access, name, desc, signature, exceptions);
 }
 }

}
마지막으로 인쇄된 내용:

java/lang/Object Test$Bazhang
<init> ()V
f (ILjava/lang/String;[I)J
hi (DLjava/util/List;)V
이전의 정확성을 검증하였으며, 기본 구조 함수도 인쇄되어 있음을 볼 수 있다.
그러면 다음에 재미있는 일을 하자. 우리는 Bazhang류에 새로운 방법과 방법을 추가한다.

public void newFunc(String str){
 
}
이 때 ClassWriter를 사용해야 합니다. 바이트 코드를 맞추는 데 사용됩니다. 구체적으로 ClassReader, ClassVisitor, ClassWriter에 관한 글은 이 글을 볼 수 있습니다ASM 원본 학습의 ClassReader, ClassVisitor 및 ClassWriter 상세 정보

public static void main(String[] args) throws Exception {
 ClassReader cr = new ClassReader(Bazhang.class.getName());
 ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);

 cr.accept(cw, Opcodes.ASM5);

 MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "newFunc", "(Ljava/lang/String;)V", null, null);

 mv.visitInsn(Opcodes.RETURN);
 mv.visitEnd();

 //  class 
 byte[] code = cw.toByteArray();
 
 // out/ 
 FileOutputStream fos = new FileOutputStream("out/Bazhang222.class");
 fos.write(code);
 fos.close();

}
이렇게 하면 아웃/폴더 아래에 Bazhang222가 생성됩니다.class:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

import java.util.List;

class Test$Bazhang {
 Test$Bazhang() {
 }

 private long f(int n, String s, int[] arr) {
 return 0L;
 }

 private void hi(double a, List<String> b) {
 }

 public void newFunc(String var1) {
 }
}
이전에 정리한 JVM 명령 집합과 결합하여 ASM을 사용하여 바이트 코드를 직접 조작하는 것도 문제없습니다. 마지막에 ASM 소스 다운로드 주소를 첨부합니다.http://forge.ow2.org/projects/asm/
총결산
이상은 바로 이 글의 전체 내용입니다. 본고의 내용이 여러분의 학습이나 업무에 어느 정도 도움이 되고 의문이 있으면 댓글로 교류하시기 바랍니다.

좋은 웹페이지 즐겨찾기