mirror of
https://github.com/NationalSecurityAgency/ghidra
synced 2024-10-13 05:33:02 +00:00
GP-2012_James_java_attribute_improvements
This commit is contained in:
parent
f2510e4dc8
commit
7d8b222183
|
@ -720,6 +720,26 @@ public class JavaAnalyzer extends AbstractJavaAnalyzer implements AnalysisWorker
|
||||||
explicitParams.get(i), function.getProgram());
|
explicitParams.get(i), function.getProgram());
|
||||||
params.add(currentParam);
|
params.add(currentParam);
|
||||||
}
|
}
|
||||||
|
MethodParametersAttribute methodParamsAttr = methodInfo.getMethodParameters();
|
||||||
|
if (methodParamsAttr != null) {
|
||||||
|
MethodParameters[] methodParams = methodParamsAttr.getMethodParameters();
|
||||||
|
int indexAdjust = methodInfo.isStatic() ? 0 : 1;
|
||||||
|
if (methodParams.length == (params.size() - indexAdjust)) {
|
||||||
|
for (int i = 0; i < methodParams.length; ++i) {
|
||||||
|
int nameIndex = methodParams[i].getNameIndex();
|
||||||
|
if (nameIndex == 0) {
|
||||||
|
continue; // no name
|
||||||
|
}
|
||||||
|
String name = ((ConstantPoolUtf8Info) constantPool[nameIndex]).getString();
|
||||||
|
params.get(i + indexAdjust).setName(name, SourceType.ANALYSIS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Msg.warn(this, "methodParams/params size mismatch for " + function.getName());
|
||||||
|
Msg.warn(this,
|
||||||
|
"methodParams: " + methodParams.length + "; params: " + params.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
function.replaceParameters(params, FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS, true,
|
function.replaceParameters(params, FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS, true,
|
||||||
SourceType.ANALYSIS);
|
SourceType.ANALYSIS);
|
||||||
|
|
||||||
|
|
|
@ -223,9 +223,11 @@ public class MethodInfoJava implements StructConverter {
|
||||||
stringBuffer.append(", ");
|
stringBuffer.append(", ");
|
||||||
}
|
}
|
||||||
ConstantPoolUtf8Info parameterName =
|
ConstantPoolUtf8Info parameterName =
|
||||||
(ConstantPoolUtf8Info) constantPool[localVariables[i].getNameIndex()];
|
(ConstantPoolUtf8Info) constantPool[localVariables[i]
|
||||||
|
.getNameIndex()];
|
||||||
ConstantPoolUtf8Info parameterDescriptor =
|
ConstantPoolUtf8Info parameterDescriptor =
|
||||||
(ConstantPoolUtf8Info) constantPool[localVariables[i].getDescriptorIndex()];
|
(ConstantPoolUtf8Info) constantPool[localVariables[i]
|
||||||
|
.getDescriptorIndex()];
|
||||||
|
|
||||||
stringBuffer.append(DescriptorDecoder.getTypeNameFromDescriptor(
|
stringBuffer.append(DescriptorDecoder.getTypeNameFromDescriptor(
|
||||||
parameterDescriptor.getString(), false, true));
|
parameterDescriptor.getString(), false, true));
|
||||||
|
@ -247,8 +249,8 @@ public class MethodInfoJava implements StructConverter {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (int k = 0; k < exceptionsAttribute.getNumberOfExceptions(); k++) {
|
for (int k = 0; k < exceptionsAttribute.getNumberOfExceptions(); k++) {
|
||||||
ConstantPoolClassInfo exceptionClass =
|
ConstantPoolClassInfo exceptionClass =
|
||||||
(ConstantPoolClassInfo) constantPool[exceptionsAttribute.getExceptionIndexTableEntry(
|
(ConstantPoolClassInfo) constantPool[exceptionsAttribute
|
||||||
k)];
|
.getExceptionIndexTableEntry(k)];
|
||||||
ConstantPoolUtf8Info exceptionClassName =
|
ConstantPoolUtf8Info exceptionClassName =
|
||||||
(ConstantPoolUtf8Info) constantPool[exceptionClass.getNameIndex()];
|
(ConstantPoolUtf8Info) constantPool[exceptionClass.getNameIndex()];
|
||||||
String className = exceptionClassName.getString();
|
String className = exceptionClassName.getString();
|
||||||
|
@ -306,6 +308,15 @@ public class MethodInfoJava implements StructConverter {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MethodParametersAttribute getMethodParameters() {
|
||||||
|
for (AbstractAttributeInfo attributeInfo : attributes) {
|
||||||
|
if (attributeInfo instanceof MethodParametersAttribute) {
|
||||||
|
return (MethodParametersAttribute) attributeInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||||
String name =
|
String name =
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.io.IOException;
|
||||||
import ghidra.app.util.bin.BinaryReader;
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
import ghidra.javaclass.format.constantpool.AbstractConstantPoolInfoJava;
|
import ghidra.javaclass.format.constantpool.AbstractConstantPoolInfoJava;
|
||||||
import ghidra.javaclass.format.constantpool.ConstantPoolUtf8Info;
|
import ghidra.javaclass.format.constantpool.ConstantPoolUtf8Info;
|
||||||
|
import ghidra.util.Msg;
|
||||||
|
|
||||||
public class AttributeFactory {
|
public class AttributeFactory {
|
||||||
|
|
||||||
|
@ -61,6 +62,10 @@ public class AttributeFactory {
|
||||||
return new LocalVariableTableAttribute(reader, constantPool);
|
return new LocalVariableTableAttribute(reader, constantPool);
|
||||||
case AttributesConstants.LocalVariableTypeTable:
|
case AttributesConstants.LocalVariableTypeTable:
|
||||||
return new LocalVariableTypeTableAttribute(reader);
|
return new LocalVariableTypeTableAttribute(reader);
|
||||||
|
case AttributesConstants.MethodParameters:
|
||||||
|
return new MethodParametersAttribute(reader);
|
||||||
|
case AttributesConstants.Module:
|
||||||
|
return new ModuleAttribute(reader);
|
||||||
case AttributesConstants.ModuleMainClass:
|
case AttributesConstants.ModuleMainClass:
|
||||||
return new ModuleMainClassAttribute(reader);
|
return new ModuleMainClassAttribute(reader);
|
||||||
case AttributesConstants.ModulePackages:
|
case AttributesConstants.ModulePackages:
|
||||||
|
@ -87,10 +92,11 @@ public class AttributeFactory {
|
||||||
return new StackMapTableAttribute(reader);
|
return new StackMapTableAttribute(reader);
|
||||||
case AttributesConstants.Synthetic:
|
case AttributesConstants.Synthetic:
|
||||||
return new SyntheticAttribute(reader);
|
return new SyntheticAttribute(reader);
|
||||||
case AttributesConstants.Module:
|
|
||||||
return new ModuleAttribute(reader);
|
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException("Unknown attribute type: " + utf8.getString());
|
Msg.warn(AttributeFactory.class, "Unknown attribute type: " + utf8.getString() +
|
||||||
|
" at index " + (reader.getPointerIndex() - 2));
|
||||||
|
return new UnsupportedAttributeInfo(reader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ public final class AttributesConstants {
|
||||||
"RuntimeInvisibleParameterAnnotations";
|
"RuntimeInvisibleParameterAnnotations";
|
||||||
public final static String AnnotationDefault = "AnnotationDefault";
|
public final static String AnnotationDefault = "AnnotationDefault";
|
||||||
public final static String BootstrapMethods = "BootstrapMethods";
|
public final static String BootstrapMethods = "BootstrapMethods";
|
||||||
|
public final static String MethodParameters = "MethodParameters";
|
||||||
public final static String Module = "Module";
|
public final static String Module = "Module";
|
||||||
public final static String ModulePackages = "ModulePackages";
|
public final static String ModulePackages = "ModulePackages";
|
||||||
public final static String ModuleMainClass = "ModuleMainClass";
|
public final static String ModuleMainClass = "ModuleMainClass";
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package ghidra.javaclass.format.attributes;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
|
import ghidra.app.util.bin.StructConverter;
|
||||||
|
import ghidra.program.model.data.DataType;
|
||||||
|
import ghidra.program.model.data.StructureDataType;
|
||||||
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class stores information about a single method parameter
|
||||||
|
*/
|
||||||
|
public class MethodParameters implements StructConverter {
|
||||||
|
|
||||||
|
private final static int ACC_FINAL_INDEX = 0x10;
|
||||||
|
private final static int ACC_SYNTHETIC_INDEX = 0x1000;
|
||||||
|
private final static int ACC_MANDATED_INDEX = 0x8000;
|
||||||
|
|
||||||
|
private int name_index;
|
||||||
|
private int access_flags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@code MethodParameters} object from the current index of {@code reader}
|
||||||
|
* and advances the index.
|
||||||
|
* @param reader source of bytes
|
||||||
|
* @throws IOException thrown if problem reading bytes
|
||||||
|
*/
|
||||||
|
public MethodParameters(BinaryReader reader) throws IOException {
|
||||||
|
name_index = Short.toUnsignedInt(reader.readNextShort());
|
||||||
|
access_flags = Short.toUnsignedInt(reader.readNextShort());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name index. If the index is 0, then this formal parameter
|
||||||
|
* does not have a name. Otherwise, the constant pool entry at the index
|
||||||
|
* is a {@code CONSTANT_Utf8_Info} structure encoding the name of the
|
||||||
|
* parameter.
|
||||||
|
* @return index or 0
|
||||||
|
*/
|
||||||
|
public int getNameIndex() {
|
||||||
|
return name_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a integer whose bits are treated as flags to encode various properties
|
||||||
|
* of the parameter
|
||||||
|
* @return access flags
|
||||||
|
*/
|
||||||
|
public int getAcccessFlags() {
|
||||||
|
return access_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a {@code boolean} representing whether or not the parameter was declared
|
||||||
|
* {@code final}
|
||||||
|
* @return true if final
|
||||||
|
*/
|
||||||
|
public boolean isFinal() {
|
||||||
|
return (access_flags & ACC_FINAL_INDEX) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a {@code boolean} representing whether or not the parameter is synthetic, i.e.,
|
||||||
|
* a compiler artifact rather than being explicitly or implicitly declared in the source.
|
||||||
|
* @return true if synthetic
|
||||||
|
*/
|
||||||
|
public boolean isSynthetic() {
|
||||||
|
return (access_flags & ACC_SYNTHETIC_INDEX) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a {@code boolean} representing whether or not the parameter is mandated, i.e.,
|
||||||
|
* implicitly declared in source code and forced to be emitted by all compilers.
|
||||||
|
* @return true if synthetic
|
||||||
|
*/
|
||||||
|
public boolean isMandated() {
|
||||||
|
return (access_flags & ACC_MANDATED_INDEX) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||||
|
StructureDataType structure = new StructureDataType("method_parameters", 0);
|
||||||
|
structure.add(WORD, "name_index", null);
|
||||||
|
structure.add(WORD, "access_flags", null);
|
||||||
|
return structure;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package ghidra.javaclass.format.attributes;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
|
import ghidra.program.model.data.DataType;
|
||||||
|
import ghidra.program.model.data.StructureDataType;
|
||||||
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This attribute records info about the (formal) parameters of a method,
|
||||||
|
* such as parameter names.
|
||||||
|
*/
|
||||||
|
public class MethodParametersAttribute extends AbstractAttributeInfo {
|
||||||
|
|
||||||
|
private byte parameters_count;
|
||||||
|
private MethodParameters[] parameters;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@code MethodParametersAttribute} object from the current index of
|
||||||
|
* {@code reader} and advances index.
|
||||||
|
* @param reader source of bytes
|
||||||
|
* @throws IOException if problem reading bytes
|
||||||
|
*/
|
||||||
|
protected MethodParametersAttribute(BinaryReader reader) throws IOException {
|
||||||
|
super(reader);
|
||||||
|
parameters_count = reader.readNextByte();
|
||||||
|
int size = Byte.toUnsignedInt(parameters_count);
|
||||||
|
parameters = new MethodParameters[size];
|
||||||
|
for (int i = 0; i < size; ++i) {
|
||||||
|
parameters[i] = new MethodParameters(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns information about the parameters of the method
|
||||||
|
* @return parameter info
|
||||||
|
*/
|
||||||
|
public MethodParameters[] getMethodParameters() {
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||||
|
StructureDataType structure = getBaseStructure("MethodParameters_attribute");
|
||||||
|
structure.add(BYTE, "num_parameters", null);
|
||||||
|
for (int i = 0; i < parameters.length; ++i) {
|
||||||
|
structure.add(parameters[i].toDataType(), "parameter" + i, null);
|
||||||
|
}
|
||||||
|
return structure;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package ghidra.javaclass.format.attributes;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
|
import ghidra.program.model.data.*;
|
||||||
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class in an artificial attribute (i.e., not defined in the JVM specification)
|
||||||
|
* whose purpose is to consume attributes that are not (yet) supported by Ghidra
|
||||||
|
* so that class file parsing can proceed.
|
||||||
|
*/
|
||||||
|
public class UnsupportedAttributeInfo extends AbstractAttributeInfo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@code UnsupportedAttributeInfo} object from the current index of
|
||||||
|
* {@code reader} and advances the index.
|
||||||
|
* @param reader source of bytes
|
||||||
|
* @throws IOException thrown if problem reading bytes
|
||||||
|
*/
|
||||||
|
protected UnsupportedAttributeInfo(BinaryReader reader) throws IOException {
|
||||||
|
super(reader);
|
||||||
|
reader.setPointerIndex(reader.getPointerIndex() + getAttributeLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||||
|
StructureDataType structure = getBaseStructure("Unsupported_attribute");
|
||||||
|
structure.add(new ArrayDataType(BYTE, getAttributeLength(), BYTE.getLength()));
|
||||||
|
return structure;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue