| // 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) |
| } |
| } |