1818
1919public 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 ) {
0 commit comments