From 9c20a14103f87a8a7ad53f7d3e863887ea4e800a Mon Sep 17 00:00:00 2001 From: Alex Light Date: Tue, 23 Aug 2016 15:05:12 -0700 Subject: Get a basic modification of dex file working This allows the modification of a single classes methods through transformation. One must ensure that the provided dex file only contains one function and does not add or remove any methods or fields and does not change the inheritance hierarchy in any way. The provided dex file must verify and there must be no frames of the old code present on any thread. These constraints are not checked or verified. Breaking them might cause undefined behavior in all parts of the runtime. Code that has been inlined in any way might not be replaced. This feature is extremely experimental. Bug: 31455788 Test: ./test/run-test --host 902-hello-transformation Change-Id: I35133d24f6cdafdd2af9dc9863e15ba8493fc50e --- runtime/utils.cc | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'runtime/utils.cc') diff --git a/runtime/utils.cc b/runtime/utils.cc index 6f10aaacaf..b52e2f2bca 100644 --- a/runtime/utils.cc +++ b/runtime/utils.cc @@ -52,6 +52,77 @@ namespace art { +static const uint8_t kBase64Map[256] = { + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, + 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT + 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT + 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT + 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255 +}; + +uint8_t* DecodeBase64(const char* src, size_t* dst_size) { + std::vector tmp; + uint32_t t = 0, y = 0; + int g = 3; + for (size_t i = 0; src[i] != '\0'; ++i) { + uint8_t c = kBase64Map[src[i] & 0xFF]; + if (c == 255) continue; + // the final = symbols are read and used to trim the remaining bytes + if (c == 254) { + c = 0; + // prevent g < 0 which would potentially allow an overflow later + if (--g < 0) { + *dst_size = 0; + return nullptr; + } + } else if (g != 3) { + // we only allow = to be at the end + *dst_size = 0; + return nullptr; + } + t = (t << 6) | c; + if (++y == 4) { + tmp.push_back((t >> 16) & 255); + if (g > 1) { + tmp.push_back((t >> 8) & 255); + } + if (g > 2) { + tmp.push_back(t & 255); + } + y = t = 0; + } + } + if (y != 0) { + *dst_size = 0; + return nullptr; + } + std::unique_ptr dst(new uint8_t[tmp.size()]); + if (dst_size != nullptr) { + *dst_size = tmp.size(); + } else { + *dst_size = 0; + } + std::copy(tmp.begin(), tmp.end(), dst.get()); + return dst.release(); +} + pid_t GetTid() { #if defined(__APPLE__) uint64_t owner; -- cgit v1.2.3-59-g8ed1b