예제 #1
0
파일: evensys.cpp 프로젝트: genjix/hypatia
void EventSystem::handleKeyPress(SDL_keysym *keysym, bool down)
{
    std::string evtype(down ? "keydown_" : "keyup_");
    switch (keysym->sym)
    {
  #include "keys.hpp"
    default:
        break;
    }
    Event ev(evtype.c_str());
    events.push(ev);
}
예제 #2
0
파일: events.c 프로젝트: Distrotech/clamav
void cli_event_debug(cli_events_t *ctx, unsigned id)
{
    const char *tstr;
    struct cli_event *ev = get_event(ctx, id);
    if (!ev)
	return;
    tstr = evtype(ev->type);
    if (ev->multiple == multiple_chain && ev->type != ev_data) {
	unsigned i;
	cli_dbgmsg("%s: ev_chain %u %s\n", ev->name, ev->count, tstr);
	for (i=0;i<ev->count;i++)
	    ev_debug(ev->type, &ev->u.v_chain[i], i);
    } else {
	cli_dbgmsg("%s: %s\n", ev->name, tstr);
	ev_debug(ev->type, &ev->u, ev->count);
    }
}
예제 #3
0
void rename_classes(
    Scope& scope,
    std::vector<std::string>& pre_whitelist_patterns,
    std::vector<std::string>& post_whitelist_patterns,
    const std::string& path,
    std::unordered_set<const DexType*>& untouchables,
    ProguardMap& proguard_map,
    bool rename_annotations) {
  unpackage_private(scope);
  int clazz_ident = 0;
  std::map<DexString*, DexString*> aliases;
  for(auto clazz: scope) {
    if (!should_rename(
        clazz, pre_whitelist_patterns, post_whitelist_patterns,
        untouchables, rename_annotations)) {
      continue;
    }
    char clzname[4];
    get_next_ident(clzname, clazz_ident);

    auto dtype = clazz->get_type();
    auto oldname = dtype->get_name();


    // The X helps our hacked Dalvik classloader recognize that a
    // class name is the output of the redex renamer and thus will
    // never be found in the Android platform.
    // The $ indicates that the class was originally an inner class.
    // Some code, most notably android instrumentation runner, uses
    // this information to decide whether or not to classload the class.
    bool inner = strrchr(oldname->c_str(), '$');
    char descriptor[10];
    sprintf(descriptor, "LX%s%s;", inner ? "$" : "", clzname);
    auto dstring = DexString::make_string(descriptor);
    aliases[oldname] = dstring;
    dtype->assign_name_alias(dstring);
    std::string old_str(oldname->c_str());
    std::string new_str(descriptor);
    proguard_map.update_class_mapping(old_str, new_str);
    base_strings_size += strlen(oldname->c_str());
    base_strings_size += strlen(dstring->c_str());
    TRACE(RENAME, 4, "'%s'->'%s'\n", oldname->c_str(), descriptor);
    while (1) {
     std::string arrayop("[");
      arrayop += oldname->c_str();
      oldname = DexString::get_string(arrayop.c_str());
      if (oldname == nullptr) {
        break;
      }
      auto arraytype = DexType::get_type(oldname);
      if (arraytype == nullptr) {
        break;
      }
      std::string newarraytype("[");
      newarraytype += dstring->c_str();
      dstring = DexString::make_string(newarraytype.c_str());
      aliases[oldname] = dstring;
      arraytype->assign_name_alias(dstring);
    }
  }
  /* Now we need to re-write the Signature annotations.  They use
   * Strings rather than Type's, so they have to be explicitly
   * handled.
   */

  /* Generics of the form Type<> turn into the Type string
   * sans the ';'.  So, we have to alias those if they
   * exist.  Signature annotations suck.
   */
  for (auto apair : aliases) {
    char buf[MAX_DESCRIPTOR_LENGTH];
    const char *sourcestr = apair.first->c_str();
    size_t sourcelen = strlen(sourcestr);
    if (sourcestr[sourcelen - 1] != ';') continue;
    strcpy(buf, sourcestr);
    buf[sourcelen - 1] = '\0';
    auto dstring = DexString::get_string(buf);
    if (dstring == nullptr) continue;
    strcpy(buf, apair.second->c_str());
    buf[strlen(apair.second->c_str()) - 1] = '\0';
    auto target = DexString::make_string(buf);
    aliases[dstring] = target;
  }
  walk_annotations(scope, [&](DexAnnotation* anno) {
    static DexType *dalviksig =
      DexType::get_type("Ldalvik/annotation/Signature;");
    if (anno->type() != dalviksig) return;
    auto elems = anno->anno_elems();
    for (auto elem : elems) {
      auto ev = elem.encoded_value;
      if (ev->evtype() != DEVT_ARRAY) continue;
      auto arrayev = static_cast<DexEncodedValueArray*>(ev);
      auto const& evs = arrayev->evalues();
      for (auto strev : *evs) {
        if (strev->evtype() != DEVT_STRING) continue;
        auto stringev = static_cast<DexEncodedValueString*>(strev);
        if (aliases.count(stringev->string())) {
          TRACE(RENAME, 5, "Rewriting Signature from '%s' to '%s'\n",
              stringev->string()->c_str(),
              aliases[stringev->string()]->c_str());
          stringev->string(aliases[stringev->string()]);
        }
      }
    }
  });

  if (!path.empty()) {
    FILE* fd = fopen(path.c_str(), "w");
    if (fd == nullptr) {
      perror("Error writing rename file");
      return;
    }
    for (const auto &it : aliases) {
      // record for later processing and back map generation
      fprintf(fd, "%s -> %s\n",it.first->c_str(),
      it.second->c_str());
    }
    fclose(fd);
  }

  for (auto clazz : scope) {
    clazz->get_vmethods().sort(compare_dexmethods);
    clazz->get_dmethods().sort(compare_dexmethods);
    clazz->get_sfields().sort(compare_dexfields);
    clazz->get_ifields().sort(compare_dexfields);
  }
}
예제 #4
0
/**
 * Walks all the code of the app, finding classes that are reachable from
 * code.
 *
 * Note that as code is changed or removed by Redex, this information will
 * become stale, so this method should be called periodically, for example
 * after each pass.
 */
void recompute_classes_reachable_from_code(const Scope& scope) {
  for (auto clazz : scope) {
    clazz->rstate.clear_if_compute();
  }

  std::unordered_set<DexString*> maybetypes;
  walk_annotations(scope,
                   [&](DexAnnotation* anno) {
                     static DexType* dalviksig =
                         DexType::get_type("Ldalvik/annotation/Signature;");
                     // Signature annotations contain strings that Jackson uses
                     // to construct the underlying types.  We capture the
                     // full list here, and mark them later.  (There are many
                     // duplicates, so de-duping before we look it up as a class
                     // makes sense)
                     if (anno->type() == dalviksig) {
                       auto elems = anno->anno_elems();
                       for (auto const& elem : elems) {
                         auto ev = elem.encoded_value;
                         if (ev->evtype() != DEVT_ARRAY) continue;
                         auto arrayev = static_cast<DexEncodedValueArray*>(ev);
                         auto const& evs = arrayev->evalues();
                         for (auto strev : *evs) {
                           if (strev->evtype() != DEVT_STRING) continue;
                           auto stringev =
                               static_cast<DexEncodedValueString*>(strev);
                           maybetypes.insert((DexString*)stringev->string());
                         }
                       }
                       return;
                     }
                     // Class literals in annotations.
                     //
                     // Example:
                     //    @JsonDeserialize(using=MyJsonDeserializer.class)
                     //                                   ^^^^
                     if (anno->runtime_visible()) {
                       auto elems = anno->anno_elems();
                       for (auto const& dae : elems) {
                         auto evalue = dae.encoded_value;
                         std::vector<DexType*> ltype;
                         evalue->gather_types(ltype);
                         if (ltype.size()) {
                           for (auto dextype : ltype) {
                             mark_reachable_directly(dextype);
                           }
                         }
                       }
                     }
                   });

  // Now we process the strings that were in the signature
  // annotations.
  // Note: We do not mark these as ref'd by string, because
  // these cases are handleable for renaming.
  for (auto dstring : maybetypes) {
    const char* cstr = dstring->c_str();
    int len = strlen(cstr);
    if (len < 3) continue;
    if (cstr[0] != 'L') continue;
    if (cstr[len - 1] == ';') {
      auto dtype = DexType::get_type(dstring);
      mark_reachable_directly(dtype);
      continue;
    }
    std::string buf(cstr);
    buf += ';';
    auto dtype = DexType::get_type(buf.c_str());
    mark_reachable_directly(dtype);
  }

  // Matches methods marked as native
  walk_methods(scope,
               [&](DexMethod* meth) {
                 if (meth->get_access() & DexAccessFlags::ACC_NATIVE) {
                   mark_reachable_by_classname(meth->get_class(), true);
                 }
               });

  walk_code(scope,
            [](DexMethod*) { return true; },
            [&](DexMethod* meth, DexCode* code) {
              auto opcodes = code->get_instructions();
              for (const auto& opcode : opcodes) {
                // Matches any stringref that name-aliases a type.
                if (opcode->has_strings()) {
                  auto stringop = static_cast<DexOpcodeString*>(opcode);
                  DexString* dsclzref = stringop->get_string();
                  DexType* dtexclude =
                      get_dextype_from_dotname(dsclzref->c_str());
                  if (dtexclude == nullptr) continue;
                  mark_reachable_by_classname(dtexclude, true);
                }
                if (opcode->has_types()) {
                  // Matches the following instructions (from most to least
                  // common):
                  // check-cast, new-instance, const-class, instance-of
                  // new-instance should not be on this list, and
                  // we should not allow these to operate on themselves.
                  // TODO(snay/dalves)
                  auto typeop = static_cast<DexOpcodeType*>(opcode);
                  mark_reachable_directly(typeop->get_type());
                }
              }
            });
}