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

Source Code for Module sign

  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  from error import error 
 20   
 21  from analysis import TAINTED_PACKAGE_CREATE, TAINTED_PACKAGE_CALL 
 22   
 23  FIELD_ACCESS = { "R" : 0, "W" : 1 } 
 24  PACKAGE_ACCESS = { TAINTED_PACKAGE_CREATE : 0, TAINTED_PACKAGE_CALL : 1 } 
25 -class Sign :
26 - def __init__(self) :
27 self.levels = {} 28 self.hlevels = []
29
30 - def add(self, level, value) :
31 self.levels[ level ] = value 32 self.hlevels.append( level )
33
34 - def get_level(self, l) :
35 return self.levels[ "L%d" % l ]
36
37 - def get_string(self) :
38 buff = "" 39 for i in self.hlevels : 40 buff += self.levels[ i ] 41 return buff
42
43 -class Signature :
44 - def __init__(self, tainted_information) :
45 self.__tainted = tainted_information 46 47 self._cached_signatures = {} 48 self._cached_fields = {} 49 self._cached_packages = {} 50 51 self.levels = { 52 # Classical method signature with basic blocks, strings, fields, packages 53 "L0" : { 54 0 : ( "_get_strings_a", "_get_fields_a", "_get_packages_a" ), 55 1 : ( "_get_strings_pa", "_get_fields_a", "_get_packages_a" ), 56 2 : ( "_get_strings_a", "_get_fields_a", "_get_packages_pa_1" ), 57 3 : ( "_get_strings_a", "_get_fields_a", "_get_packages_pa_2" ), 58 }, 59 60 # strings 61 "L1" : [ "_get_strings_a1" ], 62 63 # exceptions 64 "L2" : [ "_get_exceptions" ], 65 66 # fill array data 67 "L3" : [ "_get_fill_array_data" ], 68 } 69 70 self._init_caches()
71
72 - def _get_bb(self, analysis_method, functions, options) :
73 l = [] 74 for b in analysis_method.basic_blocks.get() : 75 l.append( (b.start, "B") ) 76 l.append( (b.start, "[") ) 77 78 internal = [] 79 80 if "return" in b.get_last().get_name() : 81 internal.append( (b.end, "R") ) 82 elif "if" in b.get_last().get_name() : 83 internal.append( (b.end, "I") ) 84 elif "goto" in b.get_last().get_name() : 85 internal.append( (b.end, "G") ) 86 87 for f in functions : 88 try : 89 internal.extend( getattr( self, f )( analysis_method, options ) ) 90 except TypeError : 91 internal.extend( getattr( self, f )( analysis_method ) ) 92 93 internal.sort() 94 95 for i in internal : 96 if i[0] >= b.start and i[0] <= b.end : 97 l.append( i ) 98 99 del internal 100 101 l.append( (b.end, "]") ) 102 return l
103
104 - def _init_caches(self) :
105 if self._cached_fields == {} : 106 for f_t, f in self.__tainted["variables"].get_fields() : 107 self._cached_fields[ f ] = f_t.get_paths_length() 108 n = 0 109 for f in sorted( self._cached_fields ) : 110 self._cached_fields[ f ] = n 111 n += 1 112 113 if self._cached_packages == {} : 114 for m_t, m in self.__tainted["packages"].get_packages() : 115 self._cached_packages[ m ] = m_t.get_paths_length() 116 n = 0 117 for m in sorted( self._cached_packages ) : 118 self._cached_packages[ m ] = n 119 n += 1
120
121 - def _get_fill_array_data(self, analysis_method) :
122 buff = "" 123 for b in analysis_method.basic_blocks.get() : 124 for i in b.ins : 125 if i.op_name == "FILL-ARRAY-DATA" : 126 buff_tmp = i.get_operands() 127 for j in range(0, len(buff_tmp)) : 128 buff += "\\x%02x" % ord( buff_tmp[j] ) 129 return buff
130
131 - def _get_exceptions(self, analysis_method) :
132 buff = "" 133 134 method = analysis_method.get_method() 135 handlers = method.get_code().handlers 136 # for try_item in method.get_code().tries : 137 # print "w00t", try_item 138 139 for handler_catch_list in method.get_code().handlers : 140 #print "\t HANDLER_CATCH_LIST SIZE", handler_catch_list.size 141 for handler_catch in handler_catch_list.list : 142 #print "\t\t HANDLER_CATCH SIZE ", handler_catch.size 143 for handler in handler_catch.handlers : 144 buff += analysis_method.get_vm().get_class_manager().get_type( handler.type_idx ) 145 #print "\t\t\t HANDLER", handler.type_idx, a.get_vm().get_class_manager().get_type( handler.type_idx ), handler.add 146 return buff
147
148 - def _get_strings_a1(self, analysis_method) :
149 buff = "" 150 151 strings_method = self.__tainted["variables"].get_strings_by_method( analysis_method.get_method() ) 152 for s in strings_method : 153 for path in strings_method[s] : 154 buff += s.replace('\n', ' ') 155 return buff
156
157 - def _get_strings_pa(self, analysis_method) :
158 l = [] 159 160 strings_method = self.__tainted["variables"].get_strings_by_method( analysis_method.get_method() ) 161 for s in strings_method : 162 for path in strings_method[s] : 163 l.append( (path.get_bb().start + path.get_idx(), "S%d" % len(s) ) ) 164 return l
165 166
167 - def _get_strings_a(self, analysis_method) :
168 l = [] 169 170 strings_method = self.__tainted["variables"].get_strings_by_method( analysis_method.get_method() ) 171 for s in strings_method : 172 for path in strings_method[s] : 173 l.append( (path.get_bb().start + path.get_idx(), "S") ) 174 return l
175
176 - def _get_fields_a(self, analysis_method) :
177 fields_method = self.__tainted["variables"].get_fields_by_method( analysis_method.get_method() ) 178 179 l = [] 180 181 for f in fields_method : 182 for path in fields_method[ f ] : 183 l.append( (path.get_bb().start + path.get_idx(), "F%d" % FIELD_ACCESS[ path.get_access_flag() ]) ) 184 return l
185
186 - def _get_packages_a(self, analysis_method) :
187 packages_method = self.__tainted["packages"].get_packages_by_method( analysis_method.get_method() ) 188 189 l = [] 190 191 for m in packages_method : 192 for path in packages_method[ m ] : 193 l.append( (path.get_bb().start + path.get_idx(), "P%s" % (PACKAGE_ACCESS[ path.get_access_flag() ]) ) ) 194 return l
195
196 - def _get_packages_pa_1(self, analysis_method, include_packages) :
197 packages_method = self.__tainted["packages"].get_packages_by_method( analysis_method.get_method() ) 198 199 l = [] 200 201 for m in packages_method : 202 for path in packages_method[ m ] : 203 present = False 204 for i in include_packages : 205 if m.find(i) == 0 : 206 present = True 207 break 208 209 if present == False : 210 continue 211 212 if path.get_access_flag() == 1 : 213 l.append( (path.get_bb().start + path.get_idx(), "P%s{%s%s%s}" % (PACKAGE_ACCESS[ path.get_access_flag() ], path.get_class_name(), path.get_name(), path.get_descriptor()) ) ) 214 else : 215 l.append( (path.get_bb().start + path.get_idx(), "P%s{%s}" % (PACKAGE_ACCESS[ path.get_access_flag() ], m) ) ) 216 217 return l
218
219 - def _get_packages_pa_2(self, analysis_method, include_packages) :
220 packages_method = self.__tainted["packages"].get_packages_by_method( analysis_method.get_method() ) 221 222 l = [] 223 224 for m in packages_method : 225 for path in packages_method[ m ] : 226 present = False 227 for i in include_packages : 228 if m.find(i) == 0 : 229 present = True 230 break 231 232 if present == True : 233 l.append( (path.get_bb().start + path.get_idx(), "P%s" % (PACKAGE_ACCESS[ path.get_access_flag() ]) ) ) 234 continue 235 236 237 if path.get_access_flag() == 1 : 238 l.append( (path.get_bb().start + path.get_idx(), "P%s{%s%s%s}" % (PACKAGE_ACCESS[ path.get_access_flag() ], path.get_class_name(), path.get_name(), path.get_descriptor()) ) ) 239 else : 240 l.append( (path.get_bb().start + path.get_idx(), "P%s{%s}" % (PACKAGE_ACCESS[ path.get_access_flag() ], m) ) ) 241 242 return l
243
244 - def get_method(self, analysis_method, signature_type, signature_arguments={}) :
245 key = "%s-%s-%s" % (analysis_method, signature_type, signature_arguments) 246 if key in self._cached_signatures : 247 return self._cached_signatures[ key ] 248 249 s = Sign() 250 251 #print signature_type, signature_arguments 252 for i in signature_type.split(":") : 253 # print i, signature_arguments[ i ] 254 if i == "L0" : 255 _type = self.levels[ i ][ signature_arguments[ i ][ "type" ] ] 256 try : 257 _arguments = signature_arguments[ i ][ "arguments" ] 258 except KeyError : 259 _arguments = [] 260 261 value = self._get_bb( analysis_method, _type, _arguments ) 262 s.add( i, ''.join(i[1] for i in value)) 263 264 elif i == "L1" : 265 for f in self.levels[ i ] : 266 value = getattr( self, f )( analysis_method ) 267 s.add( i, value ) 268 269 else : 270 for f in self.levels[ i ] : 271 value = getattr( self, f )( analysis_method ) 272 s.add( i, value ) 273 274 self._cached_signatures[ key ] = s 275 return s
276