diff --git a/tools/simple-force-redefine/Android.bp b/tools/simple-force-redefine/Android.bp
new file mode 100644
index 0000000..871f210
--- /dev/null
+++ b/tools/simple-force-redefine/Android.bp
@@ -0,0 +1,83 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// Build variants {target,host} x {debug,ndebug} x {32,64}
+cc_defaults {
+    name: "forceredefine-defaults",
+    host_supported: true,
+    srcs: ["forceredefine.cc"],
+    defaults: ["art_defaults"],
+
+    // Note that this tool needs to be built for both 32-bit and 64-bit since it requires
+    // to be same ISA as what it is attached to.
+    compile_multilib: "both",
+
+    shared_libs: [
+      "libz",
+      "liblog",
+    ],
+    header_libs: [
+        "libopenjdkjvmti_headers",
+        // Annoyingly you aren't allowed to include even header-only non-ndk libs into an ndk build.
+        // Instead we put the directories this would bring in below in 'include_dirs'
+        // "libnativehelper_header_only",
+    ],
+    include_dirs: [
+        // NDK headers aren't available in platform NDK builds.
+        "libnativehelper/include_jni",
+        "libnativehelper/header_only_include",
+    ],
+    sdk_version: "current",
+    stl: "libc++_static",
+    target: {
+      android: {
+        static_libs: [
+          "slicer_ndk_no_rtti",
+          "libbase_ndk",
+        ],
+      },
+      host: {
+        static_libs: [
+          "slicer_no_rtti",
+        ],
+        shared_libs: [
+          "libbase",
+        ],
+      },
+    },
+    multilib: {
+        lib32: {
+            suffix: "32",
+        },
+        lib64: {
+            suffix: "64",
+        },
+    },
+    symlink_preferred_arch: true,
+}
+
+art_cc_library {
+    name: "libforceredefine",
+    defaults: ["forceredefine-defaults"],
+}
+
+art_cc_library {
+    name: "libforceredefined",
+    defaults: [
+        "art_debug_defaults",
+        "forceredefine-defaults",
+    ],
+}
diff --git a/tools/simple-force-redefine/README.md b/tools/simple-force-redefine/README.md
new file mode 100644
index 0000000..362c704
--- /dev/null
+++ b/tools/simple-force-redefine/README.md
@@ -0,0 +1,33 @@
+# forceredfine
+
+ForceRedefine is a JVMTI agent designed for testing how redefiniton affects running processes. It
+allows one to force classes to be redefined by writing to a fifo or give a process a list of
+classes to try redefining. Currently the redefinition is limited to adding (or removing) a single
+NOP at the beginning of every function in the class.
+
+# Usage
+### Build
+>    `make libforceredefine`
+
+The libraries will be built for 32-bit, 64-bit, host and target. Below examples
+assume you want to use the 64-bit version.
+
+#### ART
+>    `adb shell setenforce 0`
+>
+>    `adb push $ANDROID_PRODUCT_OUT/system/lib64/libforceredefine.so /data/local/tmp/`
+>
+>    `echo java/util/ArrayList > /tmp/classlist`
+>    `echo java/util/Arrays >> /tmp/classlist`
+>    `adb push /tmp/classlist /data/local/tmp/`
+>
+>    `adb shell am attach-agent $(adb shell pidof some.deubggable.app) /data/local/tmp/libforceredefine.so=/data/local/tmp/classlist`
+
+Since the agent has no static state it can be attached multiple times to the same process.
+
+>    `adb shell am attach-agent $(adb shell pidof some.deubggable.app) /data/local/tmp/libforceredefine.so=/data/local/tmp/classlist`
+>    `adb shell am attach-agent $(adb shell pidof some.deubggable.app) /data/local/tmp/libforceredefine.so=/data/local/tmp/classlist2`
+>    `adb shell am attach-agent $(adb shell pidof some.deubggable.app) /data/local/tmp/libforceredefine.so=/data/local/tmp/classlist`
+
+One can also use fifos to send classes interactively to the process. (TODO: Have the agent
+continue reading from the fifo even after it gets an EOF.)
\ No newline at end of file
diff --git a/tools/simple-force-redefine/forceredefine.cc b/tools/simple-force-redefine/forceredefine.cc
new file mode 100644
index 0000000..f96626f
--- /dev/null
+++ b/tools/simple-force-redefine/forceredefine.cc
@@ -0,0 +1,281 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "__mutex_base"
+#include <cstddef>
+#include <fcntl.h>
+#include <fstream>
+#include <memory>
+#include <sstream>
+#include <string>
+#include <unistd.h>
+#include <unordered_set>
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+
+#include <nativehelper/scoped_local_ref.h>
+
+#include <jni.h>
+#include <jvmti.h>
+
+// Slicer's headers have code that triggers these warnings. b/65298177
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-parameter"
+#pragma clang diagnostic ignored "-Wsign-compare"
+#include <slicer/code_ir.h>
+#include <slicer/dex_bytecode.h>
+#include <slicer/dex_ir.h>
+#include <slicer/dex_ir_builder.h>
+#include <slicer/reader.h>
+#include <slicer/writer.h>
+#pragma clang diagnostic pop
+
+namespace forceredefine {
+
+namespace {
+
+struct AgentInfo {
+  std::fstream stream;
+  std::unordered_set<std::string> classes;
+  std::mutex mutex;
+};
+
+// Converts a class name to a type descriptor
+// (ex. "java.lang.String" to "Ljava/lang/String;")
+std::string classNameToDescriptor(const char* className) {
+  std::stringstream ss;
+  ss << "L";
+  for (auto p = className; *p != '\0'; ++p) {
+    ss << (*p == '.' ? '/' : *p);
+  }
+  ss << ";";
+  return ss.str();
+}
+
+// Converts a descriptor (Lthis/style/of/name;) to a jni-FindClass style Fully-qualified class name
+// (this/style/of/name).
+std::string DescriptorToFQCN(const std::string& descriptor) {
+  return descriptor.substr(1, descriptor.size() - 2);
+}
+
+static AgentInfo* GetAgentInfo(jvmtiEnv* jvmti) {
+  AgentInfo* ai = nullptr;
+  CHECK_EQ(jvmti->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&ai)), JVMTI_ERROR_NONE);
+  CHECK(ai != nullptr);
+  return ai;
+}
+
+class JvmtiAllocator : public dex::Writer::Allocator {
+ public:
+  explicit JvmtiAllocator(jvmtiEnv* jvmti) : jvmti_(jvmti) {}
+  void* Allocate(size_t size) override {
+    unsigned char* res = nullptr;
+    jvmti_->Allocate(size, &res);
+    return res;
+  }
+  void Free(void* ptr) override {
+    jvmti_->Deallocate(reinterpret_cast<unsigned char*>(ptr));
+  }
+
+ private:
+  jvmtiEnv* jvmti_;
+};
+
+static void Transform(std::shared_ptr<ir::DexFile> ir) {
+  std::unique_ptr<ir::Builder> builder;
+  for (auto& method : ir->encoded_methods) {
+    // Do not look into abstract/bridge/native/synthetic methods.
+    if ((method->access_flags &
+         (dex::kAccAbstract | dex::kAccBridge | dex::kAccNative | dex::kAccSynthetic)) != 0) {
+      continue;
+    }
+
+    struct AddNopVisitor : public lir::Visitor {
+      explicit AddNopVisitor(lir::CodeIr* cir) : cir_(cir) {}
+
+      bool Visit(lir::Bytecode* bc) override {
+        if (seen_first_inst) {
+          return false;
+        }
+        seen_first_inst = true;
+        auto new_inst = cir_->Alloc<lir::Bytecode>();
+        new_inst->opcode = dex::OP_NOP;
+        cir_->instructions.InsertBefore(bc, new_inst);
+        return true;
+      }
+
+      lir::CodeIr* cir_;
+      bool seen_first_inst = false;
+    };
+
+    lir::CodeIr c(method.get(), ir);
+    AddNopVisitor visitor(&c);
+    for (auto it = c.instructions.begin(); it != c.instructions.end(); ++it) {
+      lir::Instruction* fi = *it;
+      if (fi->Accept(&visitor)) {
+        break;
+      }
+    }
+    c.Assemble();
+  }
+}
+
+static void CbClassFileLoadHook(jvmtiEnv* jvmti,
+                                JNIEnv* env ATTRIBUTE_UNUSED,
+                                jclass classBeingRedefined ATTRIBUTE_UNUSED,
+                                jobject loader ATTRIBUTE_UNUSED,
+                                const char* name,
+                                jobject protectionDomain ATTRIBUTE_UNUSED,
+                                jint classDataLen,
+                                const unsigned char* classData,
+                                jint* newClassDataLen,
+                                unsigned char** newClassData) {
+  std::string desc(classNameToDescriptor(name));
+  std::string fqcn(DescriptorToFQCN(desc));
+  AgentInfo* ai = GetAgentInfo(jvmti);
+  {
+    std::lock_guard<std::mutex> mu(ai->mutex);
+    if (ai->classes.find(fqcn) == ai->classes.end()) {
+      return;
+    }
+  }
+  LOG(INFO) << "Got CFLH for " << name << " on env " << static_cast<void*>(jvmti);
+  JvmtiAllocator allocator(jvmti);
+  dex::Reader reader(classData, classDataLen);
+  dex::u4 index = reader.FindClassIndex(desc.c_str());
+  reader.CreateClassIr(index);
+  std::shared_ptr<ir::DexFile> ir(reader.GetIr());
+  Transform(ir);
+  dex::Writer writer(ir);
+  size_t new_size;
+  *newClassData = writer.CreateImage(&allocator, &new_size);
+  *newClassDataLen = new_size;
+}
+
+static void RedefineClass(jvmtiEnv* jvmti, JNIEnv* env, const std::string& klass_name) {
+  jclass klass = nullptr;
+  if ((klass = env->FindClass(klass_name.c_str())) == nullptr || env->ExceptionCheck()) {
+    LOG(WARNING) << "Failed to find class for " << klass_name;
+    env->ExceptionDescribe();
+    env->ExceptionClear();
+    return;
+  }
+  jvmti->RetransformClasses(1, &klass);
+}
+
+static void AgentMain(jvmtiEnv* jvmti, JNIEnv* jni, void* arg ATTRIBUTE_UNUSED) {
+  AgentInfo* ai = GetAgentInfo(jvmti);
+  std::string klass_name;
+  jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, nullptr);
+  // TODO Replace this with something that can read from a fifo and ignore the 'EOF's.
+  while (std::getline(ai->stream, klass_name, '\n')) {
+    LOG(INFO) << "Redefining class " << klass_name << " with " << static_cast<void*>(jvmti);
+    {
+      std::lock_guard<std::mutex> mu(ai->mutex);
+      ai->classes.insert(klass_name);
+    }
+    RedefineClass(jvmti, jni, klass_name);
+  }
+}
+
+static void CbVmInit(jvmtiEnv* jvmti, JNIEnv* env, jthread thr ATTRIBUTE_UNUSED) {
+  // Create a Thread object.
+  ScopedLocalRef<jobject> thread_name(env, env->NewStringUTF("Agent Thread"));
+  if (thread_name.get() == nullptr) {
+    env->ExceptionDescribe();
+    env->ExceptionClear();
+    return;
+  }
+  ScopedLocalRef<jclass> thread_klass(env, env->FindClass("java/lang/Thread"));
+  if (thread_klass.get() == nullptr) {
+    env->ExceptionDescribe();
+    env->ExceptionClear();
+    return;
+  }
+  ScopedLocalRef<jobject> thread(env, env->AllocObject(thread_klass.get()));
+  if (thread.get() == nullptr) {
+    env->ExceptionDescribe();
+    env->ExceptionClear();
+    return;
+  }
+
+  env->CallNonvirtualVoidMethod(
+      thread.get(),
+      thread_klass.get(),
+      env->GetMethodID(thread_klass.get(), "<init>", "(Ljava/lang/String;)V"),
+      thread_name.get());
+  env->CallVoidMethod(thread.get(), env->GetMethodID(thread_klass.get(), "setPriority", "(I)V"), 1);
+  env->CallVoidMethod(
+      thread.get(), env->GetMethodID(thread_klass.get(), "setDaemon", "(Z)V"), JNI_TRUE);
+
+  jvmti->RunAgentThread(thread.get(), AgentMain, nullptr, JVMTI_THREAD_MIN_PRIORITY);
+}
+
+}  // namespace
+
+template <bool kIsOnLoad>
+static jint AgentStart(JavaVM* vm, char* options, void* reserved ATTRIBUTE_UNUSED) {
+  jvmtiEnv* jvmti = nullptr;
+
+  if (vm->GetEnv(reinterpret_cast<void**>(&jvmti), JVMTI_VERSION_1_1) != JNI_OK ||
+      jvmti == nullptr) {
+    LOG(ERROR) << "unable to obtain JVMTI env.";
+    return JNI_ERR;
+  }
+  std::string sopts(options);
+  AgentInfo* ai = new AgentInfo;
+  ai->stream.open(options, std::ios_base::in);
+  if (!ai->stream.is_open()) {
+    PLOG(ERROR) << "Could not open file " << options << " for triggering class-reload";
+    return JNI_ERR;
+  }
+
+  jvmtiCapabilities caps{
+    .can_retransform_classes = 1,
+  };
+  if (jvmti->AddCapabilities(&caps) != JVMTI_ERROR_NONE) {
+    LOG(ERROR) << "Unable to get retransform_classes capability!";
+    return JNI_ERR;
+  }
+  jvmtiEventCallbacks cb{
+    .ClassFileLoadHook = CbClassFileLoadHook,
+    .VMInit = CbVmInit,
+  };
+  jvmti->SetEventCallbacks(&cb, sizeof(cb));
+  jvmti->SetEnvironmentLocalStorage(reinterpret_cast<void*>(ai));
+  if (kIsOnLoad) {
+    jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, nullptr);
+  } else {
+    JNIEnv* jni = nullptr;
+    vm->GetEnv(reinterpret_cast<void**>(&jni), JNI_VERSION_1_2);
+    jthread thr;
+    jvmti->GetCurrentThread(&thr);
+    CbVmInit(jvmti, jni, thr);
+  }
+  return JNI_OK;
+}
+
+// Late attachment (e.g. 'am attach-agent').
+extern "C" JNIEXPORT jint JNICALL Agent_OnAttach(JavaVM* vm, char* options, void* reserved) {
+  return AgentStart<false>(vm, options, reserved);
+}
+
+// Early attachment
+extern "C" JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM* jvm, char* options, void* reserved) {
+  return AgentStart<true>(jvm, options, reserved);
+}
+
+}  // namespace forceredefine
