Module vm
[hide private]
[frames] | no frames]

Source Code for Module vm

  1  # This file is part of Androguard. 
  2  # 
  3  # Copyright (C) 2010, Anthony Desnos <desnos at t0t0.org> 
  4  # All rights reserved. 
  5  # 
  6  # Androguard is free software: you can redistribute it and/or modify 
  7  # it under the terms of the GNU Lesser General Public License as published by 
  8  # the Free Software Foundation, either version 3 of the License, or 
  9  # (at your option) any later version. 
 10  # 
 11  # Androguard is distributed in the hope that it will be useful, 
 12  # but WITHOUT ANY WARRANTY; without even the implied warranty of   
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 14  # GNU Lesser General Public License for more details. 
 15  # 
 16  # You should have received a copy of the GNU Lesser General Public License 
 17  # along with Androguard.  If not, see <http://www.gnu.org/licenses/>. 
 18   
 19  import random, string 
 20  from subprocess import Popen, PIPE, STDOUT                                       
 21   
 22  import opaque, jvm  
 23   
 24  from il_reil import MTR, BPTR, MetaPolyREIL, REIL_TO_JAVA, REIL_TYPE_REGISTER, REIL_TYPE_LITERAL 
 25   
26 -class IL_REIL_TO_JAVA :
27 - def __init__(self, orig_class_name, il_reil) :
28 self.__bytecodes = [] 29 30 self.__orig_class_name = orig_class_name 31 self.__vm_name = random.choice( string.letters ) + ''.join([ random.choice(string.letters + string.digits) for i in range(10 - 1) ] ) 32 33 self.__vm_format = None 34 35 self.__RR = {} 36 self.__ORR = {} 37 self.__OP = {} 38 self.__BT = {} 39 40 self.__call_code = [] 41 42 self.__debug = False 43 44 self._analyze( il_reil ) 45 46 print self.__RR 47 print self.__ORR 48 print self.__OP 49 print self.__BT 50 51 print self.__bytecodes 52 53 self._create_methods() 54 self._create_call_code()
55
56 - def _create_methods(self) :
57 fd = open("./VM.java", "w") 58 59 fd.write("class VM {\n") 60 61 fd.write("public ") 62 63 if self.__type_return == "" : 64 fd.write("void ") 65 else : 66 fd.write("%s " % self.__type_return) 67 68 fd.write("%s() {\n" % self.__vm_name) 69 70 self.__VAR_REG = "REG" 71 self.__VAR_IREG = "IREG" 72 self.__VAR_IDX = "idx" 73 self.__VAR_C_IDX = "c_idx" 74 self.__VAR_BC = "BC" 75 76 fd.write("int[] %s = new int[%d];\n" % ( self.__VAR_REG, len(self.__RR) ) ) 77 78 fd.write("int[] %s = {" % self.__VAR_IREG) 79 buff = "" 80 for i in self.__RR : 81 buff += "%d,%s," % (self.__RR[i], self.__ORR[ self.__RR[i] ]) 82 fd.write(buff[:-1]) 83 fd.write("};\n") 84 85 buff = "" 86 fd.write("int[][] %s = {" % self.__VAR_BC) 87 for i in self.__bytecodes : 88 buff += "{%s}," % str(i)[1:-1] 89 fd.write(buff[:-1]) 90 fd.write("};\n") 91 92 fd.write("int %s = 0;\n" % self.__VAR_IDX); 93 fd.write("int %s = -1;\n" % self.__VAR_C_IDX); 94 95 if self.__debug : 96 fd.write("System.out.println(\"================START VM===============\");\n") 97 98 fd.write("while(idx < BC.length) {\n") 99 100 self.__VAR_T = "T" 101 self.__VAR_S = "S" 102 103 fd.write("int[] %s = new int[3];\n" % self.__VAR_T); 104 fd.write("int[] %s = new int[3];\n" % self.__VAR_S); 105 106 fd.write("T[0] = (BC[idx][0] & 0x00FF0000) >> 16;\n") 107 fd.write("T[1] = (BC[idx][0] & 0x0000FF00) >> 8;\n") 108 fd.write("T[2] = (BC[idx][0] & 0x000000FF);\n") 109 110 fd.write("S[0] = (BC[idx][1] & 0x00FF0000) >> 16;\n") 111 fd.write("S[1] = (BC[idx][1] & 0x0000FF00) >> 8;\n") 112 fd.write("S[2] = (BC[idx][1] & 0x000000FF);\n") 113 114 if self.__debug : 115 fd.write("System.out.println( \"IDX \" + idx );\n") 116 fd.write("System.out.println( \"TYPE \" + T[0] + \" \" + T[1] + \" \" + T[2] );\n") 117 fd.write("System.out.println( \"SIZE \" + S[0] + \" \" + S[1] + \" \" + S[2] );\n") 118 fd.write("System.out.println( \"BC \" + BC[idx][3] + \" \" + BC[idx][4] + \" \" + BC[idx][5] );\n") 119 120 #FIXME 121 for i in self.__OP : 122 fd.write("if (BC[idx][2] == %d) {\n" % self.__OP[i]) 123 fd.write( REIL_TO_JAVA( i, self, self.__debug ).get_raw() ) 124 fd.write("}\n") 125 126 if self.__debug : 127 fd.write("System.out.printf(\"REG = \");\n") 128 fd.write("for(int j=0; j < REG.length; j++) {\n") 129 fd.write("System.out.printf(\"%d \", REG[j]);\n") 130 fd.write("}\n") 131 fd.write("System.out.println(\"\");\n") 132 133 fd.write("if (%s != -1) {\n" % self.__VAR_C_IDX) 134 fd.write("%s = %s;\n" % (self.__VAR_IDX, self.__VAR_C_IDX)) 135 fd.write("%s = -1;\n" % (self.__VAR_C_IDX)) 136 fd.write("}\n") 137 138 fd.write("else {\n") 139 fd.write("idx = idx + 1;\n") 140 fd.write("}\n") 141 142 fd.write("}\n") 143 144 if self.__debug : 145 fd.write("System.out.println(\"================STOP VM================\\n\");\n") 146 147 fd.write("return REG[%s];\n" % self.__ORR[ self.__RR[ self.__register_return.get_name() ] ] ) 148 149 fd.write("}\n") 150 151 fd.write("}\n") 152 fd.close() 153 154 compile = Popen([ "/usr/bin/javac", "VM.java" ], stdout=PIPE, stderr=STDOUT) 155 stdout, stderr = compile.communicate() 156 print "COMPILATION RESULTS", stdout, stderr 157 if stdout != "": 158 raise("oops") 159 160 # print "COMPILATION RESULTS", "SWAP ...." 161 162 self.__vm_format = jvm.JVMFormat( open( "VM.class" ).read() )
163
164 - def _create_call_code(self) :
165 self.__call_code.append( [ "aload_0" ] ) 166 167 method_vm = self.__vm_format.get_method(self.__vm_name)[0] 168 self.__call_code.append( [ "invokevirtual", self.__orig_class_name, self.__vm_name, method_vm.get_descriptor() ] )
169
170 - def _analyze(self, il_reil) :
171 self.__type_return = il_reil[0] 172 self.__type_param = il_reil[1] 173 self.__register_return = il_reil[3] 174 175 nb = 0 176 for i in il_reil[2] : 177 print nb, 178 i.view() 179 nb += 1 180 181 information_type = 0 182 information_size = 0 183 184 if i.get_name() not in self.__OP : 185 self.__OP[ i.get_name() ] = self._unique_value( self.__OP ) 186 187 for r in i.get_registers() : 188 if r.get_name() not in self.__RR : 189 self.__RR[ r.get_name() ] = self._unique_value( self.__RR ) 190 self.__ORR[ self.__RR[ r.get_name() ] ] = len( self.__ORR ) 191 192 v0, v0_size, v0_type = self._get_val( i.rcv0 ) 193 v1, v1_size, v1_type = self._get_val( i.rcv1 ) 194 v2, v2_size, v2_type = self._get_val( i.rcvout ) 195 196 information_type = (self._get_type( v0_type ) << 16) + (self._get_type( v1_type ) << 8) + self._get_type( v2_type ) 197 information_size = (v0_size << 16) + (v1_size << 8) + v2_size 198 199 self.__bytecodes.append( [ information_type, information_size, self.__OP[ i.get_name() ], v0, v1, v2 ] )
200
201 - def _get_type(self, v) :
202 if v not in self.__BT : 203 n_v = self._unique_value( self.__BT ) 204 self.__BT[ v ] = n_v 205 206 return self.__BT[ v ]
207
208 - def _get_val(self, r) :
209 if r == None : 210 return 0x0, 0x0, 0x0 211 212 if r.get_type() == REIL_TYPE_REGISTER : 213 return self.__RR[ r.get_name() ], r.get_size(), r.get_type() 214 215 return r.get_value(), r.get_size(), r.get_type()
216
217 - def _random_int(self) :
218 return random.randint( 0, 0xFF )
219
220 - def _unique_value(self, h) :
221 v = self._random_int() 222 for k in h : 223 if k == v : 224 self._unique_value( h ) 225 return v
226
227 - def call_code(self) :
228 return self.__call_code
229
230 - def get_methods(self) :
231 return self.__vm_format.get_method(self.__vm_name)
232
233 - def get_operand(self, pos) :
234 return self.__VAR_BC + "[" + self.__VAR_IDX + "]" + "[" + str(3 + pos - 1) + "]"
235
236 - def get_pos_reg(self, operand, variable) :
237 buff = "for(int j=0; j < %s.length; j+=2) {\n" % self.__VAR_IREG 238 buff += "if (%s[j] == %s){\n" % (self.__VAR_IREG, self.get_operand(operand)) 239 buff += "%s = %s[j + 1];\n" % (variable, self.__VAR_IREG) 240 buff += "break;\n" 241 buff += "}\n" 242 buff += "}\n" 243 244 return buff
245
246 - def get_value(self, operand, variable) :
247 buff = "if (%s[%s] == %d) {\n" % (self.__VAR_T, operand - 1, self.__BT[REIL_TYPE_REGISTER]) 248 buff += "for(int j=0; j < %s.length; j+=2) {\n" % self.__VAR_IREG 249 250 buff += "if (%s[j] == %s){\n" % (self.__VAR_IREG, self.get_operand(operand)) 251 buff += "%s = %s[ %s[j + 1] ];\n" % (variable, self.__VAR_REG, self.__VAR_IREG) 252 buff += "break;\n" 253 buff += "}\n" 254 255 buff += "}\n" 256 buff += "}\n" 257 258 buff += "else {\n" 259 buff += "%s = %s;\n" % (variable, self.get_operand(operand)) 260 buff += "}\n" 261 262 return buff
263
264 - def set_reg(self, pos, variable) :
265 return "%s[%s] = %s;\n" % (self.__VAR_REG, pos, variable)
266
267 - def set_idx(self, operand) :
268 return "%s = %s;\n" % (self.__VAR_C_IDX, self.get_operand(operand))
269
270 -class VM_int(object) :
271 - def patch_code(self) :
272 code = self._code 273 idx = self._idx 274 275 code.remove_at( idx ) 276 277 for new_code in self._irtj.call_code() : 278 code.insert_at( idx, new_code ) 279 idx += 1
280
281 - def get_methods(self) :
282 return self._irtj.get_methods()
283
284 -class VM_int_basic_math_formula(VM_int) :
285 - def __init__(self, orig_class_name, code, idx) :
286 self._code = code 287 self._idx = idx 288 289 i = code.get_at( idx ) 290 print i, i.get_name(), i.get_operands() 291 292 oint = opaque.INT( i.get_operands() ).run() 293 mtir = MTR( oint ) 294 295 mtir = MetaPolyREIL( mtir.get() ) 296 297 self._irtj = IL_REIL_TO_JAVA( orig_class_name, mtir.get() )
298
299 -class VM_int_basic_prng(VM_int) :
300 - def __init__(self, orig_class_name, code, idx) :
301 self._code = code 302 self._idx = idx 303 304 i = code.get_at( idx ) 305 # print i, i.get_name(), i.get_operands() 306 oint = opaque.PRNG( i.get_operands() ).run() 307 atoil = BPTR( oint ) 308 309 atoil = MetaPolyREIL( atoil.get() ) 310 311 self._irtj = IL_REIL_TO_JAVA( orig_class_name, atoil.get() )
312