// Copyright 2018 The Bazel Authors. All rights reserved. // // 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. // Package mindex writes a minimal dex into a file. // It encodes the minimal necessary fields to pass muster with the android runtime. package mindex import ( "flag" "io/ioutil" "log" "sync" "src/tools/ak/types" ) var ( // Cmd defines the command to run mindex Cmd = types.Command{ Init: Init, Run: Run, Desc: desc, Flags: []string{ "out", }, } // Variables that hold flag values out string initOnce sync.Once // see https://android.googlesource.com/platform/art/+/android-5.0.1_r1/runtime/dex_file.h minDex = []byte{ 0x64, 0x65, 0x78, 0x0A, // 0x00: Dex magic 0x30, 0x33, 0x35, 0x00, // 0x04: Dex version 0x44, 0x0E, 0xC1, 0x0F, // 0x08: Adler32 checksum 0x8B, 0x9B, 0x61, 0xEA, // 0x0C: Sha1 digest 0xC1, 0x7F, 0x94, 0x5A, // 0x10: Sha1 digest cont. 0xE9, 0xC0, 0x8A, 0x70, // 0x14: Sha1 digest cont. 0xFD, 0xED, 0x4F, 0x53, // 0x18: Sha1 digest cont. 0x0F, 0x10, 0x51, 0x75, // 0x1C: Sha1 digest cont. // Header 0x8C, 0x00, 0x00, 0x00, // 0x20: Files size 0x70, 0x00, 0x00, 0x00, // 0x24: Header size 0x78, 0x56, 0x34, 0x12, // 0x28: Endian tag 0x00, 0x00, 0x00, 0x00, // 0x2C: Link size 0x00, 0x00, 0x00, 0x00, // 0x30: Link offset 0x70, 0x00, 0x00, 0x00, // 0x34: Map offset 0x00, 0x00, 0x00, 0x00, // 0x38: String ids size 0x00, 0x00, 0x00, 0x00, // 0x3C: String ids offset 0x00, 0x00, 0x00, 0x00, // 0x40: Type ids size 0x00, 0x00, 0x00, 0x00, // 0x44: Type ids offset 0x00, 0x00, 0x00, 0x00, // 0x48: Proto ids size 0x00, 0x00, 0x00, 0x00, // 0x4C: Proto ids offset 0x00, 0x00, 0x00, 0x00, // 0x50: Field ids size 0x00, 0x00, 0x00, 0x00, // 0x54: Field ids offset 0x00, 0x00, 0x00, 0x00, // 0x58: Method ids size 0x00, 0x00, 0x00, 0x00, // 0x5C: Method ids offset 0x00, 0x00, 0x00, 0x00, // 0x60: Class defs size 0x00, 0x00, 0x00, 0x00, // 0x64: Class defs offset 0x1C, 0x00, 0x00, 0x00, // 0x68: Data size 0x70, 0x00, 0x00, 0x00, // 0x6C: Data offset // Data 0x02, 0x00, 0x00, 0x00, // 0x70: Map list size (header and map list) 0x00, 0x00, 0x00, 0x00, // 0x74: kDexTypeHeaderItem 0x01, 0x00, 0x00, 0x00, // 0x78: HeaderItem count 0x00, 0x00, 0x00, 0x00, // 0x7C: Offset 0x00 0x00, 0x10, 0x00, 0x00, // 0x80: kDexTypeMapList 0x01, 0x00, 0x00, 0x00, // 0x84: MapList count 0x70, 0x00, 0x00, 0x00, // 0x88: Offset 0x70 } ) // Init initializes mindex. func Init() { initOnce.Do(func() { flag.StringVar(&out, "out", "", "Path to output.") }) } func desc() string { return "Mindex writes the smallest possible dex to a file." } // Run is the entry point for mindex. func Run() { if out == "" { log.Fatal("Flags -out must be specified.") } if err := ioutil.WriteFile(out, minDex, 0655); err != nil { log.Fatalf("Error writing minimal dex %v", err) } }