1// Copyright 2018 The Bazel Authors. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15// Package mindex writes a minimal dex into a file. 16// It encodes the minimal necessary fields to pass muster with the android runtime. 17package mindex 18 19import ( 20 "flag" 21 "io/ioutil" 22 "log" 23 "sync" 24 25 "src/tools/ak/types" 26) 27 28var ( 29 // Cmd defines the command to run mindex 30 Cmd = types.Command{ 31 Init: Init, 32 Run: Run, 33 Desc: desc, 34 Flags: []string{ 35 "out", 36 }, 37 } 38 39 // Variables that hold flag values 40 out string 41 initOnce sync.Once 42 43 // see https://android.googlesource.com/platform/art/+/android-5.0.1_r1/runtime/dex_file.h 44 45 minDex = []byte{ 46 0x64, 0x65, 0x78, 0x0A, // 0x00: Dex magic 47 0x30, 0x33, 0x35, 0x00, // 0x04: Dex version 48 0x44, 0x0E, 0xC1, 0x0F, // 0x08: Adler32 checksum 49 0x8B, 0x9B, 0x61, 0xEA, // 0x0C: Sha1 digest 50 0xC1, 0x7F, 0x94, 0x5A, // 0x10: Sha1 digest cont. 51 0xE9, 0xC0, 0x8A, 0x70, // 0x14: Sha1 digest cont. 52 0xFD, 0xED, 0x4F, 0x53, // 0x18: Sha1 digest cont. 53 0x0F, 0x10, 0x51, 0x75, // 0x1C: Sha1 digest cont. 54 55 // Header 56 0x8C, 0x00, 0x00, 0x00, // 0x20: Files size 57 0x70, 0x00, 0x00, 0x00, // 0x24: Header size 58 0x78, 0x56, 0x34, 0x12, // 0x28: Endian tag 59 0x00, 0x00, 0x00, 0x00, // 0x2C: Link size 60 0x00, 0x00, 0x00, 0x00, // 0x30: Link offset 61 0x70, 0x00, 0x00, 0x00, // 0x34: Map offset 62 0x00, 0x00, 0x00, 0x00, // 0x38: String ids size 63 0x00, 0x00, 0x00, 0x00, // 0x3C: String ids offset 64 0x00, 0x00, 0x00, 0x00, // 0x40: Type ids size 65 0x00, 0x00, 0x00, 0x00, // 0x44: Type ids offset 66 0x00, 0x00, 0x00, 0x00, // 0x48: Proto ids size 67 0x00, 0x00, 0x00, 0x00, // 0x4C: Proto ids offset 68 0x00, 0x00, 0x00, 0x00, // 0x50: Field ids size 69 0x00, 0x00, 0x00, 0x00, // 0x54: Field ids offset 70 0x00, 0x00, 0x00, 0x00, // 0x58: Method ids size 71 0x00, 0x00, 0x00, 0x00, // 0x5C: Method ids offset 72 0x00, 0x00, 0x00, 0x00, // 0x60: Class defs size 73 0x00, 0x00, 0x00, 0x00, // 0x64: Class defs offset 74 0x1C, 0x00, 0x00, 0x00, // 0x68: Data size 75 0x70, 0x00, 0x00, 0x00, // 0x6C: Data offset 76 77 // Data 78 0x02, 0x00, 0x00, 0x00, // 0x70: Map list size (header and map list) 79 0x00, 0x00, 0x00, 0x00, // 0x74: kDexTypeHeaderItem 80 0x01, 0x00, 0x00, 0x00, // 0x78: HeaderItem count 81 0x00, 0x00, 0x00, 0x00, // 0x7C: Offset 0x00 82 0x00, 0x10, 0x00, 0x00, // 0x80: kDexTypeMapList 83 0x01, 0x00, 0x00, 0x00, // 0x84: MapList count 84 0x70, 0x00, 0x00, 0x00, // 0x88: Offset 0x70 85 } 86) 87 88// Init initializes mindex. 89func Init() { 90 initOnce.Do(func() { 91 flag.StringVar(&out, "out", "", "Path to output.") 92 }) 93} 94 95func desc() string { 96 return "Mindex writes the smallest possible dex to a file." 97} 98 99// Run is the entry point for mindex. 100func Run() { 101 if out == "" { 102 log.Fatal("Flags -out must be specified.") 103 } 104 105 if err := ioutil.WriteFile(out, minDex, 0655); err != nil { 106 log.Fatalf("Error writing minimal dex %v", err) 107 } 108} 109