1 // Copyright 2021 Code Intelligence GmbH 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package com.code_intelligence.jazzer.instrumentor 16 17 import org.objectweb.asm.ClassReader 18 import org.objectweb.asm.ClassVisitor 19 import org.objectweb.asm.ClassWriter 20 import org.objectweb.asm.MethodVisitor 21 22 internal class HookInstrumentor(private val hooks: Iterable<Hook>, private val java6Mode: Boolean) : Instrumentor { 23 24 private lateinit var random: DeterministicRandom 25 instrumentnull26 override fun instrument(bytecode: ByteArray): ByteArray { 27 val reader = ClassReader(bytecode) 28 val writer = ClassWriter(reader, ClassWriter.COMPUTE_MAXS) 29 random = DeterministicRandom("hook", reader.className) 30 val interceptor = object : ClassVisitor(Instrumentor.ASM_API_VERSION, writer) { 31 override fun visitMethod( 32 access: Int, 33 name: String?, 34 descriptor: String?, 35 signature: String?, 36 exceptions: Array<String>?, 37 ): MethodVisitor? { 38 val mv = cv.visitMethod(access, name, descriptor, signature, exceptions) ?: return null 39 return if (shouldInstrument(access)) 40 makeHookMethodVisitor(access, descriptor, mv, hooks, java6Mode, random) 41 else 42 mv 43 } 44 } 45 reader.accept(interceptor, ClassReader.EXPAND_FRAMES) 46 return writer.toByteArray() 47 } 48 } 49