aboutsummaryrefslogtreecommitdiff
path: root/src/tools/ak/mindex/mindex.go
blob: 9bdbefa8d5ed3f7bb76908cccb74bd11e7cf44e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// 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)
	}
}