Skip to content

Commit fae73b0

Browse files
Make check_memcopy function compatible with arm
1 parent 5e7c1a5 commit fae73b0

File tree

1 file changed

+115
-29
lines changed

1 file changed

+115
-29
lines changed

src/main/java/golanganalyzerextension/FunctionModifier.java

Lines changed: 115 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,13 @@ enum MEMCPY_FUNC_STAGE {
147147
boolean check_memcopy(Function func) {
148148
Instruction inst=program_listing.getInstructionAt(func.getEntryPoint());
149149
MEMCPY_FUNC_STAGE stage=MEMCPY_FUNC_STAGE.GET_SRC;
150-
String tmp_reg="TMP";
150+
Register dst_reg=null;
151+
Register src_reg=null;
152+
String tmp_reg1="TMP";
153+
String tmp_reg2="TMP";
151154
int size=0;
152155
while(inst!=null) {
153-
if(inst.toString().contains("RET")) {
156+
if(inst.toString().toUpperCase().contains("RET") || inst.toString().equals("add pc,lr,#0x0")) {
154157
break;
155158
}
156159

@@ -165,20 +168,57 @@ boolean check_memcopy(Function func) {
165168
}
166169
switch(stage) {
167170
case GET_SRC:
168-
if(!mnemonic.contains("MOV")) {
169-
return false;
170-
}
171-
tmp_reg=op1[0].toString();
172-
if(!op2[0].toString().equals(pointer_size==8?"RSI":"ESI")) {
173-
return false;
171+
if(mnemonic.contains("MOV")) {
172+
tmp_reg1=op1[0].toString();
173+
if(!(op2[0] instanceof Register) || !compare_register((Register)op2[0], program.getRegister("SI"))) {
174+
return false;
175+
}
176+
src_reg=(Register)op2[0];
177+
stage=MEMCPY_FUNC_STAGE.ADD_SRC;
178+
}else if(mnemonic.equals("ldr")) {
179+
if(op2.length<2) {
180+
return false;
181+
}
182+
if(!(op1[0] instanceof Register) || !compare_register((Register)op1[0], program.getRegister("r0"))) {
183+
return false;
184+
}
185+
if(!(op2[0] instanceof Register) || !compare_register((Register)op2[0], program.getRegister("r1"))) {
186+
return false;
187+
}
188+
if(!(op2[1] instanceof Scalar)) {
189+
return false;
190+
}
191+
src_reg=(Register)op2[0];
192+
tmp_reg1=op1[0].toString();
193+
stage=MEMCPY_FUNC_STAGE.SET_DST;
194+
}else if(mnemonic.equals("ldp")) {
195+
if(inst.getNumOperands()<3) {
196+
return false;
197+
}
198+
Object op3[]=inst.getOpObjects(2);
199+
if(op3.length<1) {
200+
return false;
201+
}
202+
if(!(op1[0] instanceof Register) || !compare_register((Register)op1[0], program.getRegister("x26"))) {
203+
return false;
204+
}
205+
if(!(op2[0] instanceof Register) || !compare_register((Register)op2[0], program.getRegister("x27"))) {
206+
return false;
207+
}
208+
if(!(op3[0] instanceof Register) || !compare_register((Register)op3[0], program.getRegister("x20"))) {
209+
return false;
210+
}
211+
src_reg=(Register)op3[0];
212+
tmp_reg1=op1[0].toString();
213+
tmp_reg2=op2[0].toString();
214+
stage=MEMCPY_FUNC_STAGE.SET_DST;
174215
}
175-
stage=MEMCPY_FUNC_STAGE.ADD_SRC;
176216
break;
177217
case ADD_SRC:
178218
if(!mnemonic.equals("ADD")) {
179219
return false;
180220
}
181-
if(!op1[0].toString().equals(pointer_size==8?"RSI":"ESI")) {
221+
if(!(op1[0] instanceof Register) || !compare_register((Register)op1[0], program.getRegister("SI"))) {
182222
return false;
183223
}
184224
if(!(op2[0] instanceof Scalar)) {
@@ -188,22 +228,62 @@ boolean check_memcopy(Function func) {
188228
stage=MEMCPY_FUNC_STAGE.SET_DST;
189229
break;
190230
case SET_DST:
191-
if(!mnemonic.contains("MOV")) {
192-
return false;
193-
}
194-
if(!op1[0].toString().equals(pointer_size==8?"RDI":"EDI")) {
195-
return false;
196-
}
197-
if(!op2[0].toString().equals(tmp_reg)) {
198-
return false;
231+
if(mnemonic.contains("MOV")) {
232+
if(!(op1[0] instanceof Register) || !compare_register((Register)op1[0], program.getRegister("DI"))) {
233+
return false;
234+
}
235+
if(!op2[0].toString().equals(tmp_reg1)) {
236+
return false;
237+
}
238+
dst_reg=(Register)op1[0];
239+
stage=MEMCPY_FUNC_STAGE.ADD_DST;
240+
}else if(mnemonic.equals("str")) {
241+
if(op2.length<2) {
242+
return false;
243+
}
244+
if(!(op1[0] instanceof Register) || !compare_register((Register)op1[0], program.getRegister(tmp_reg1))) {
245+
return false;
246+
}
247+
if(!(op2[0] instanceof Register) || !compare_register((Register)op2[0], program.getRegister("r2"))) {
248+
return false;
249+
}
250+
if(!(op2[1] instanceof Scalar)) {
251+
return false;
252+
}
253+
dst_reg=(Register)op2[0];
254+
size+=Integer.decode(op2[1].toString());
255+
stage=MEMCPY_FUNC_STAGE.GET_SRC;
256+
}else if(mnemonic.equals("stp")) {
257+
if(inst.getNumOperands()<3) {
258+
return false;
259+
}
260+
Object op3[]=inst.getOpObjects(2);
261+
if(op3.length<1) {
262+
return false;
263+
}
264+
if(!(op1[0] instanceof Register) || !compare_register((Register)op1[0], program.getRegister(tmp_reg1))) {
265+
return false;
266+
}
267+
if(!(op2[0] instanceof Register) || !compare_register((Register)op2[0], program.getRegister(tmp_reg2))) {
268+
return false;
269+
}
270+
if(!(op3[0] instanceof Register) || !compare_register((Register)op3[0], program.getRegister("x21"))) {
271+
return false;
272+
}
273+
dst_reg=(Register)op3[0];
274+
if(op3.length>=2 && op3[1] instanceof Scalar) {
275+
size+=Integer.decode(op3[1].toString());
276+
}else {
277+
size+=0x10;
278+
}
279+
stage=MEMCPY_FUNC_STAGE.GET_SRC;
199280
}
200-
stage=MEMCPY_FUNC_STAGE.ADD_DST;
201281
break;
202282
case ADD_DST:
203283
if(!mnemonic.equals("ADD")) {
204284
return false;
205285
}
206-
if(!op1[0].toString().equals(pointer_size==8?"RDI":"EDI")) {
286+
if(!(op1[0] instanceof Register) || !compare_register((Register)op1[0], program.getRegister("DI"))) {
207287
return false;
208288
}
209289
if(!(op2[0] instanceof Scalar)) {
@@ -219,14 +299,20 @@ boolean check_memcopy(Function func) {
219299
}
220300

221301
List<Parameter> params=new ArrayList<>();
222-
String reg_names[]= {pointer_size==8?"RDI":"EDI", pointer_size==8?"RSI":"ESI"};
223-
for(int i=0;i<reg_names.length;i++) {
224-
try {
225-
DataType data_type=new ByteDataType();
226-
ArrayDataType array_datatype=new ArrayDataType(data_type, size, data_type.getLength());
227-
params.add(new ParameterImpl(String.format("param_%d", i+1), new PointerDataType(array_datatype, pointer_size), program.getRegister(reg_names[i]), func.getProgram(), SourceType.USER_DEFINED));
228-
} catch (InvalidInputException e) {
302+
try {
303+
if(dst_reg==null) {
304+
return false;
229305
}
306+
307+
DataType data_type=new ByteDataType();
308+
ArrayDataType array_datatype=new ArrayDataType(data_type, size, data_type.getLength());
309+
params.add(new ParameterImpl(String.format("param_%d", 1), new PointerDataType(array_datatype, pointer_size), dst_reg, func.getProgram(), SourceType.USER_DEFINED));
310+
311+
if(src_reg!=null) {
312+
array_datatype=new ArrayDataType(data_type, src_reg.getBitLength()/8, data_type.getLength());
313+
params.add(new ParameterImpl(String.format("param_%d", 2), new PointerDataType(array_datatype, pointer_size), src_reg, func.getProgram(), SourceType.USER_DEFINED));
314+
}
315+
} catch (InvalidInputException e) {
230316
}
231317
GolangFunction gofunc=new GolangFunction(this, func, String.format("runtime.duffcopy_%#x_%s", size, func.getName()), params);
232318
gofunc_list.add(gofunc);
@@ -330,10 +416,10 @@ boolean check_memset(Function func) {
330416
if(op3.length<1) {
331417
return false;
332418
}
333-
if(!compare_register((Register)op1[0], program.getRegister("xzr"))) {
419+
if(!(op1[0] instanceof Register) || !compare_register((Register)op1[0], program.getRegister("xzr"))) {
334420
return false;
335421
}
336-
if(!compare_register((Register)op2[0], program.getRegister("xzr"))) {
422+
if(!(op2[0] instanceof Register) || !compare_register((Register)op2[0], program.getRegister("xzr"))) {
337423
return false;
338424
}
339425
if(!(op3[0] instanceof Register) || !compare_register((Register)op3[0], program.getRegister("x20"))) {

0 commit comments

Comments
 (0)