Skip to content

Commit

Permalink
Fix integer datatype
Browse files Browse the repository at this point in the history
  • Loading branch information
mooncat-greenpy committed May 21, 2023
1 parent 8dea68b commit 2a6be3b
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 35 deletions.
22 changes: 11 additions & 11 deletions src/main/java/golanganalyzerextension/datatype/GolangDatatype.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,27 +87,27 @@ public static GolangDatatype create_by_parsing(GolangBinary go_bin, Address type
if(go_datatype.kind==Kind.Bool) {
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, new BooleanDataType());
}else if(go_datatype.kind==Kind.Int) {
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_signed_number_datatype(pointer_size));
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_signed_numeric_datatype(pointer_size));
}else if(go_datatype.kind==Kind.Int8) {
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_signed_number_datatype(1));
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_signed_numeric_datatype(1));
}else if(go_datatype.kind==Kind.Int16) {
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_signed_number_datatype(2));
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_signed_numeric_datatype(2));
}else if(go_datatype.kind==Kind.Int32) {
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_signed_number_datatype(4));
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_signed_numeric_datatype(4));
}else if(go_datatype.kind==Kind.Int64) {
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_signed_number_datatype(8));
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_signed_numeric_datatype(8));
}else if(go_datatype.kind==Kind.Uint) {
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_unsigned_number_datatype(pointer_size));
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_unsigned_numeric_datatype(pointer_size));
}else if(go_datatype.kind==Kind.Uint8) {
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_unsigned_number_datatype(1));
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_unsigned_numeric_datatype(1));
}else if(go_datatype.kind==Kind.Uint16) {
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_unsigned_number_datatype(2));
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_unsigned_numeric_datatype(2));
}else if(go_datatype.kind==Kind.Uint32) {
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_unsigned_number_datatype(4));
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_unsigned_numeric_datatype(4));
}else if(go_datatype.kind==Kind.Uint64) {
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_unsigned_number_datatype(8));
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_unsigned_numeric_datatype(8));
}else if(go_datatype.kind==Kind.Uintptr) {
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_unsigned_number_datatype(pointer_size));
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, go_bin.get_unsigned_numeric_datatype(pointer_size));
}else if(go_datatype.kind==Kind.Float32) {
go_datatype=new OtherGolangDatatype(go_bin, type_base_addr, offset, is_go16, new Float4DataType());
}else if(go_datatype.kind==Kind.Float64) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ boolean check_memcopy() {
}
if(dst_reg==null) {
dst_reg=(Register)op2[0];
inner_datatype=go_bin.get_unsigned_number_datatype(((Register)op1[0]).getBitLength()/8);
inner_datatype=go_bin.get_unsigned_numeric_datatype(((Register)op1[0]).getBitLength()/8);
}
size+=Integer.decode(op2[1].toString());
stage=MEMCPY_FUNC_STAGE.GET_SRC;
Expand Down Expand Up @@ -222,7 +222,7 @@ boolean check_memcopy() {
}
if(dst_reg==null) {
dst_reg=(Register)op3[0];
inner_datatype=go_bin.get_unsigned_number_datatype(((Register)op1[0]).getBitLength()/8);
inner_datatype=go_bin.get_unsigned_numeric_datatype(((Register)op1[0]).getBitLength()/8);
}
if(op3.length>=2 && op3[1] instanceof Scalar) {
size+=Integer.decode(op3[1].toString());
Expand Down Expand Up @@ -306,7 +306,7 @@ boolean check_memset() {
start=0;
dst_reg=(Register)op2[0];
src_reg=(Register)op1[0];
inner_datatype=go_bin.get_unsigned_number_datatype(src_reg.getBitLength()/8);
inner_datatype=go_bin.get_unsigned_numeric_datatype(src_reg.getBitLength()/8);
}
size+=Integer.decode(op2[1].toString());
}else if(mnemonic.equals("stp")) {
Expand All @@ -333,7 +333,7 @@ boolean check_memset() {
if(start<0) {
start=0;
dst_reg=(Register)op3[0];
inner_datatype=go_bin.get_unsigned_number_datatype(((Register)op1[0]).getBitLength()/8);
inner_datatype=go_bin.get_unsigned_numeric_datatype(((Register)op1[0]).getBitLength()/8);
}
if(op3.length>=2 && op3[1] instanceof Scalar) {
size+=Integer.decode(op3[1].toString());
Expand All @@ -359,7 +359,7 @@ boolean check_memset() {
params.add(new ParameterImpl(String.format("param_%d", 1), new PointerDataType(inner_datatype, go_bin.get_pointer_size()), dst_reg, get_func().getProgram(), SourceType.USER_DEFINED));

if(src_reg!=null) {
params.add(new ParameterImpl(String.format("param_%d", 2), go_bin.get_unsigned_number_datatype(src_reg.getBitLength()/8), src_reg, get_func().getProgram(), SourceType.USER_DEFINED));
params.add(new ParameterImpl(String.format("param_%d", 2), go_bin.get_unsigned_numeric_datatype(src_reg.getBitLength()/8), src_reg, get_func().getProgram(), SourceType.USER_DEFINED));
}
} catch (InvalidInputException e) {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,9 @@ boolean check_memcopy() {
if(dst_reg==null) {
dst_reg=(Register)op1[0];
if(op2[0].toString().contains("XMM")) {
inner_datatype=go_bin.get_unsigned_number_datatype(4);
inner_datatype=go_bin.get_unsigned_numeric_datatype(4);
}else {
inner_datatype=go_bin.get_unsigned_number_datatype(((Register)op2[0]).getBitLength()/8);
inner_datatype=go_bin.get_unsigned_numeric_datatype(((Register)op2[0]).getBitLength()/8);
}
}
stage=MEMCPY_FUNC_STAGE.ADD_DST;
Expand Down Expand Up @@ -284,7 +284,7 @@ boolean check_memset() {
start=0;
dst_reg=(Register)op1[1];
src_reg=eax_reg;
inner_datatype=go_bin.get_unsigned_number_datatype(src_reg.getBitLength()/8);
inner_datatype=go_bin.get_unsigned_numeric_datatype(src_reg.getBitLength()/8);
}
size+=4;
inst=inst.getNext();
Expand All @@ -307,7 +307,7 @@ boolean check_memset() {
if(start<0) {
dst_reg=(Register)op1[0];
src_reg=(Register)op2[0];
inner_datatype=go_bin.get_unsigned_number_datatype(4);
inner_datatype=go_bin.get_unsigned_numeric_datatype(4);
}
if(op1.length<2) {
if(start<0) {
Expand Down Expand Up @@ -354,7 +354,7 @@ boolean check_memset() {
params.add(new ParameterImpl(String.format("param_%d", 1), new PointerDataType(inner_datatype, go_bin.get_pointer_size()), dst_reg, get_func().getProgram(), SourceType.USER_DEFINED));

if(src_reg!=null) {
params.add(new ParameterImpl(String.format("param_%d", 2), go_bin.get_unsigned_number_datatype(src_reg.getBitLength()/8), src_reg, get_func().getProgram(), SourceType.USER_DEFINED));
params.add(new ParameterImpl(String.format("param_%d", 2), go_bin.get_unsigned_numeric_datatype(src_reg.getBitLength()/8), src_reg, get_func().getProgram(), SourceType.USER_DEFINED));
}
} catch (InvalidInputException e) {
}
Expand Down
25 changes: 11 additions & 14 deletions src/main/java/golanganalyzerextension/gobinary/GolangBinary.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import ghidra.program.model.data.Integer5DataType;
import ghidra.program.model.data.Integer6DataType;
import ghidra.program.model.data.Integer7DataType;
import ghidra.program.model.data.IntegerDataType;
import ghidra.program.model.data.LongLongDataType;
import ghidra.program.model.data.ShortDataType;
import ghidra.program.model.data.SignedByteDataType;
Expand All @@ -40,7 +39,6 @@
import ghidra.program.model.data.UnsignedInteger5DataType;
import ghidra.program.model.data.UnsignedInteger6DataType;
import ghidra.program.model.data.UnsignedInteger7DataType;
import ghidra.program.model.data.UnsignedIntegerDataType;
import ghidra.program.model.data.UnsignedLongLongDataType;
import ghidra.program.model.data.UnsignedShortDataType;
import ghidra.program.model.lang.Register;
Expand Down Expand Up @@ -306,15 +304,17 @@ public void add_datatype(String path, DataType datatype) {
category.addDataType(datatype, null);
}

public DataType get_unsigned_number_datatype(int size) {

public DataType get_unsigned_numeric_datatype(int size) throws InvalidBinaryStructureException {
if(size==1) {
return new ByteDataType();
}else if(size==2) {
return new UnsignedShortDataType();
}else if(size==3) {
return new UnsignedInteger3DataType();
}else if(size==4) {
return new UnsignedIntegerDataType();
// The size of UnsignedIntegerDataType and UnsignedLongDataType depends on the binary.
return new UnsignedInteger4DataType();
}else if(size==5) {
return new UnsignedInteger5DataType();
}else if(size==6) {
Expand All @@ -325,22 +325,21 @@ public DataType get_unsigned_number_datatype(int size) {
return new UnsignedLongLongDataType();
}else if(size==16) {
return new UnsignedInteger16DataType();
}else if(pcheader.get_pointer_size()==8) {
return new UnsignedLongLongDataType();
}else {
return new UnsignedIntegerDataType();
}

throw new InvalidBinaryStructureException("Invalid datatype size");
}

public DataType get_signed_number_datatype(int size) {
public DataType get_signed_numeric_datatype(int size) throws InvalidBinaryStructureException {
if(size==1) {
return new SignedByteDataType();
}else if(size==2) {
return new ShortDataType();
}else if(size==3) {
return new Integer3DataType();
}else if(size==4) {
return new IntegerDataType();
// The size of UnsignedIntegerDataType and UnsignedLongDataType depends on the binary.
return new Integer4DataType();
}else if(size==5) {
return new Integer5DataType();
}else if(size==6) {
Expand All @@ -351,11 +350,9 @@ public DataType get_signed_number_datatype(int size) {
return new LongLongDataType();
}else if(size==16) {
return new Integer16DataType();
}else if(pcheader.get_pointer_size()==8) {
return new LongLongDataType();
}else {
return new IntegerDataType();
}

throw new InvalidBinaryStructureException("Invalid datatype size");
}

public MemoryBlock[] get_memory_blocks() {
Expand Down
108 changes: 108 additions & 0 deletions src/test/java/golanganalyzerextension/gobinary/DataTypeTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package golanganalyzerextension.gobinary;

import static org.junit.Assert.assertEquals;

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import ghidra.program.database.ProgramBuilder;
import ghidra.program.model.listing.Program;
import ghidra.test.AbstractGhidraHeadlessIntegrationTest;
import ghidra.util.task.TaskMonitor;
import golanganalyzerextension.exceptions.InvalidBinaryStructureException;

public class DataTypeTest extends AbstractGhidraHeadlessIntegrationTest {

protected Program program;

protected void initialize(Map<String, String> bytes_map) throws Exception {
ProgramBuilder builder=new ProgramBuilder("test", ProgramBuilder._X86, null);
for(Map.Entry<String, String> entry : bytes_map.entrySet()) {
builder.setBytes(entry.getKey(), entry.getValue());
}
program = builder.getProgram();
}

@ParameterizedTest
@MethodSource("test_get_numeric_datatype_params")
public void test_get_numeric_datatype(int size, int expected_size) throws Exception {
initialize(new HashMap<String, String>(){{
put("0x500000", "fbffffff 00 00 01 04 00000000");
put("0x50000c", "00104000 00200000");
put("0x502000", "00104000");
}});

GolangBinary go_bin=new GolangBinary(program, TaskMonitor.DUMMY);

assertEquals(go_bin.get_signed_numeric_datatype(size).getLength(), expected_size);
assertEquals(go_bin.get_unsigned_numeric_datatype(size).getLength(), expected_size);
}

static Stream<Arguments> test_get_numeric_datatype_params() throws Throwable {
return Stream.of(
Arguments.of(1, 1),
Arguments.of(2, 2),
Arguments.of(3, 3),
Arguments.of(4, 4),
Arguments.of(5, 5),
Arguments.of(6, 6),
Arguments.of(7, 7),
Arguments.of(8, 8),
Arguments.of(16, 16)
);
}

@ParameterizedTest
@MethodSource("test_get_numeric_datatype_exception_params")
public void test_get_numeric_datatype_exception(int size, boolean expected) throws Exception {
initialize(new HashMap<String, String>(){{
put("0x500000", "fbffffff 00 00 01 04 00000000");
put("0x50000c", "00104000 00200000");
put("0x502000", "00104000");
}});

GolangBinary go_bin=new GolangBinary(program, TaskMonitor.DUMMY);
boolean signed_result=true;
try {
go_bin.get_signed_numeric_datatype(size);
} catch(InvalidBinaryStructureException e) {
signed_result=false;
}
assertEquals(signed_result, expected);

boolean unsigned_result=true;
try {
go_bin.get_unsigned_numeric_datatype(size);
} catch(InvalidBinaryStructureException e) {
unsigned_result=false;
}
assertEquals(unsigned_result, expected);
}

static Stream<Arguments> test_get_numeric_datatype_exception_params() throws Throwable {
return Stream.of(
Arguments.of(1, true),
Arguments.of(2, true),
Arguments.of(3, true),
Arguments.of(4, true),
Arguments.of(5, true),
Arguments.of(6, true),
Arguments.of(7, true),
Arguments.of(8, true),
Arguments.of(9, false),
Arguments.of(10, false),
Arguments.of(11, false),
Arguments.of(12, false),
Arguments.of(13, false),
Arguments.of(14, false),
Arguments.of(15, false),
Arguments.of(16, true),
Arguments.of(17, false)
);
}
}

0 comments on commit 2a6be3b

Please sign in to comment.