Skip to content

Commit f92224d

Browse files
Search arg strings from x86/x64 inst
1 parent 905762a commit f92224d

File tree

2 files changed

+63
-24
lines changed

2 files changed

+63
-24
lines changed

src/main/java/golanganalyzerextension/string/StringExtractor.java

Lines changed: 61 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
public class StringExtractor {
2020

21+
private static final String[] reg_arg_str={"RAX", "RBX", "RCX", "RDI", "RSI", "R8", "R9", "R10", "R11"};
22+
2123
private static final int CHECK_INST_NUM=6;
2224

2325
private GolangBinary go_bin;
@@ -90,10 +92,13 @@ private void search_function(Address addr, int length) {
9092
}
9193

9294
private void check_insts(Instruction inst) {
95+
boolean is_arg_reg=false;
9396
if(inst.getNumOperands()!=2) {
9497
return;
9598
}
96-
if(inst.getOperandType(0)!=OperandType.DYNAMIC || inst.getOperandType(1)!=OperandType.SCALAR) {
99+
if((inst.getOperandType(0)&OperandType.REGISTER)!=0 && inst.getOperandType(1)==OperandType.SCALAR) {
100+
is_arg_reg=true;
101+
} else if ((inst.getOperandType(0)&OperandType.DYNAMIC)==0 || inst.getOperandType(1)!=OperandType.SCALAR) {
97102
return;
98103
}
99104
if(inst.getOperandRefType(0)!=RefType.WRITE || inst.getOperandRefType(1)!=RefType.DATA) {
@@ -102,69 +107,103 @@ private void check_insts(Instruction inst) {
102107

103108
Object[] str_len_inst_op1=inst.getOpObjects(0);
104109
Object[] str_len_inst_op2=inst.getOpObjects(1);
105-
if(str_len_inst_op1.length!=2 || str_len_inst_op2.length!=1) {
106-
return;
110+
if(is_arg_reg) {
111+
if(str_len_inst_op1.length!=1 || str_len_inst_op2.length!=1) {
112+
return;
113+
}
114+
} else {
115+
if(str_len_inst_op1.length!=2 || str_len_inst_op2.length!=1) {
116+
return;
117+
}
107118
}
108119

109-
if(!(str_len_inst_op1[0] instanceof Register) || !(str_len_inst_op1[1] instanceof Scalar) || !(str_len_inst_op2[0] instanceof Scalar)) {
110-
return;
120+
if(is_arg_reg) {
121+
if(!(str_len_inst_op1[0] instanceof Register) || !(str_len_inst_op2[0] instanceof Scalar)) {
122+
return;
123+
}
124+
} else {
125+
if(!(str_len_inst_op1[0] instanceof Register) || !(str_len_inst_op1[1] instanceof Scalar) || !(str_len_inst_op2[0] instanceof Scalar)) {
126+
return;
127+
}
111128
}
112129

113130
String base_reg=((Register)str_len_inst_op1[0]).getName();
114-
long string_len_offset=((Scalar)str_len_inst_op1[1]).getValue();
131+
long string_len_offset=0;
132+
if(is_arg_reg) {
133+
for(int j=0; j<reg_arg_str.length; j++) {
134+
if(((Register)str_len_inst_op1[0]).getBaseRegister().getName().equals(reg_arg_str[j])) {
135+
string_len_offset=j;
136+
break;
137+
}
138+
}
139+
if(string_len_offset==0) {
140+
return;
141+
}
142+
} else {
143+
string_len_offset=((Scalar)str_len_inst_op1[1]).getValue();
144+
}
115145
int string_len=(int)((Scalar)str_len_inst_op2[0]).getValue();
116146
if(string_len<=0) {
117147
return;
118148
}
119149

120150
Instruction check_inst=inst;
121151
for(int i=0; i<CHECK_INST_NUM; i++) {
122-
if(check_inst.getPrevious()==null) {
152+
if(check_inst.getPrevious()==null || check_inst.getPrevious().getFlowType().isCall()) {
123153
break;
124154
}
125155
check_inst=check_inst.getPrevious();
126156
}
127157

128-
Map<Register, Address> reg_map=new HashMap<>();
158+
Map<String, Address> reg_map=new HashMap<>();
129159
for(int i=0; i<CHECK_INST_NUM*2 && check_inst!=null; i++) {
130160
if(is_move_addr_to_reg(check_inst)) {
131161
Object[] op1=check_inst.getOpObjects(0);
132162
Object[] op2=check_inst.getOpObjects(1);
133-
reg_map.put((Register)op1[0], (Address)op2[0]);
134-
check_inst=check_inst.getNext();
135-
continue;
163+
reg_map.put(((Register)op1[0]).getName(), (Address)op2[0]);
136164
} else if (is_move_scalar_to_reg(check_inst)) {
137165
Object[] op1=check_inst.getOpObjects(0);
138166
Object[] op2=check_inst.getOpObjects(1);
139-
reg_map.put((Register)op1[0], go_bin.get_address(((Scalar)op2[0]).getValue()));
140-
check_inst=check_inst.getNext();
141-
continue;
167+
reg_map.put(((Register)op1[0]).getName(), go_bin.get_address(((Scalar)op2[0]).getValue()));
142168
} else if (is_move_reg_to_addr_reg(check_inst)) {
143169
Object[] op1=check_inst.getOpObjects(0);
144170
Object[] op2=check_inst.getOpObjects(1);
145-
Address data=reg_map.get((Register)op2[0]);
171+
Address data=reg_map.get(((Register)op2[0]).getName());
146172
if(data!=null && ((Register)op1[0]).getName().equals(base_reg) && string_len_offset==go_bin.get_pointer_size()) {
147173
try {
148174
GolangString str=GolangString.create_string(go_bin, data, string_len);
149175
string_map.put(data.getOffset(), str);
150-
continue;
151176
} catch (InvalidBinaryStructureException e) {
152177
Logger.append_message(String.format("Failed to get string: %s", e.getMessage()));
153178
}
154179
}
155180
} else if (is_move_reg_to_addr_reg_scalar(check_inst)) {
156181
Object[] op1=check_inst.getOpObjects(0);
157182
Object[] op2=check_inst.getOpObjects(1);
158-
Address data=reg_map.get((Register)op2[0]);
183+
Address data=reg_map.get(((Register)op2[0]).getName());
159184
if(data!=null && ((Register)op1[0]).getName().equals(base_reg) && string_len_offset==((Scalar)op1[1]).getValue()+go_bin.get_pointer_size()) {
160185
try {
161186
GolangString str=GolangString.create_string(go_bin, data, string_len);
162187
string_map.put(data.getOffset(), str);
163-
continue;
164188
} catch (InvalidBinaryStructureException e) {
165189
Logger.append_message(String.format("Failed to get string: %s", e.getMessage()));
166190
}
167191
}
192+
} else if (check_inst.getFlowType().isCall() || check_inst.getFlowType().isTerminal()) {
193+
if(is_arg_reg && string_len_offset>0) {
194+
Address arg_str_addr=reg_map.get(reg_arg_str[(int)string_len_offset-1]);
195+
if(arg_str_addr!=null) {
196+
try {
197+
GolangString str=GolangString.create_string(go_bin, arg_str_addr, string_len);
198+
string_map.put(arg_str_addr.getOffset(), str);
199+
} catch (InvalidBinaryStructureException e) {
200+
Logger.append_message(String.format("Failed to get string: %s", e.getMessage()));
201+
}
202+
}
203+
}
204+
if(is_arg_reg) {
205+
return;
206+
}
168207
} else {
169208
clear_reg_move_any_to_reg(reg_map, check_inst);
170209
}
@@ -173,7 +212,7 @@ private void check_insts(Instruction inst) {
173212
}
174213
}
175214

176-
private boolean clear_reg_move_any_to_reg(Map<Register, Address> reg_map, Instruction inst) {
215+
private boolean clear_reg_move_any_to_reg(Map<String, Address> reg_map, Instruction inst) {
177216
for(int i=0; i<inst.getNumOperands(); i++) {
178217
if((inst.getOperandType(i)&OperandType.REGISTER)==0) {
179218
continue;
@@ -186,7 +225,7 @@ private boolean clear_reg_move_any_to_reg(Map<Register, Address> reg_map, Instru
186225
if(!(op instanceof Register)) {
187226
continue;
188227
}
189-
reg_map.remove((Register)op);
228+
reg_map.remove(((Register)op).getName());
190229
}
191230
}
192231
return false;
@@ -240,7 +279,7 @@ private boolean is_move_reg_to_addr_reg(Instruction inst) {
240279
if(inst.getNumOperands()!=2) {
241280
return false;
242281
}
243-
if(inst.getOperandType(0)!=OperandType.DYNAMIC || (inst.getOperandType(1)|(OperandType.REGISTER))==0) {// mov [rax],rdx ADDR|REG(lea), mov [rax+0x100],rdx REG(mov)
282+
if((inst.getOperandType(0)&OperandType.DYNAMIC)==0 || (inst.getOperandType(1)&OperandType.REGISTER)==0) {// mov [rax],rdx ADDR|REG(lea), mov [rax+0x100],rdx REG(mov)
244283
return false;
245284
}
246285
if(inst.getOperandRefType(0)!=RefType.WRITE || inst.getOperandRefType(1)!=RefType.READ) {
@@ -262,7 +301,7 @@ private boolean is_move_reg_to_addr_reg_scalar(Instruction inst) {
262301
if(inst.getNumOperands()!=2) {
263302
return false;
264303
}
265-
if(inst.getOperandType(0)!=OperandType.DYNAMIC || (inst.getOperandType(1)|(OperandType.REGISTER))==0) {// x64 reg only x86 reg|scalar
304+
if((inst.getOperandType(0)&OperandType.DYNAMIC)==0 || (inst.getOperandType(1)&OperandType.REGISTER)==0) {// x64 reg only x86 reg|scalar
266305
return false;
267306
}
268307
if(inst.getOperandRefType(0)!=RefType.WRITE || inst.getOperandRefType(1)!=RefType.READ) {

src/test/java/golanganalyzerextension/StringExtractorTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ static Stream<Arguments> test_search_inst_params() throws Throwable {
250250
put("0x05001000", "6e616d656e616d65");
251251
}}
252252
),
253-
/*Arguments.of(
253+
Arguments.of(
254254
new HashMap<Long, String>(){{
255255
put((long)0x05001000, "name");
256256
}},
@@ -264,7 +264,7 @@ static Stream<Arguments> test_search_inst_params() throws Throwable {
264264
put("0x05001000", "6e616d656e616d65");
265265
}}
266266
),
267-
Arguments.of(
267+
/*Arguments.of(
268268
new HashMap<Long, String>(){{
269269
put((long)0x05000500, "name");
270270
}},

0 commit comments

Comments
 (0)