@futpib/parser 1.0.3 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +24 -0
- package/.github/workflows/main.yml +1 -0
- package/build/androidPackageParser.js +30 -32
- package/build/arbitraryDalvikBytecode.d.ts +3 -3
- package/build/arbitraryDalvikBytecode.js +33 -27
- package/build/arbitraryDalvikExecutable.js +55 -17
- package/build/arbitraryJava.d.ts +31 -0
- package/build/arbitraryJava.js +532 -0
- package/build/arbitraryJavaScript.d.ts +3 -0
- package/build/arbitraryJavaScript.js +263 -0
- package/build/arbitraryJavascript.d.ts +3 -0
- package/build/arbitraryJavascript.js +263 -0
- package/build/arbitraryZig.d.ts +3 -0
- package/build/arbitraryZig.js +240 -0
- package/build/arbitraryZipStream.d.ts +1 -1
- package/build/arrayParser.js +72 -13
- package/build/backsmali.d.ts +4 -3
- package/build/backsmali.js +26 -6
- package/build/bash.d.ts +89 -0
- package/build/bash.js +1 -0
- package/build/bashParser.d.ts +6 -0
- package/build/bashParser.js +335 -0
- package/build/bashParser.test.d.ts +1 -0
- package/build/bashParser.test.js +343 -0
- package/build/bashParserEdgeCases.test.d.ts +1 -0
- package/build/bashParserEdgeCases.test.js +117 -0
- package/build/dalvikBytecodeParser/addressConversion.d.ts +110 -0
- package/build/dalvikBytecodeParser/addressConversion.js +334 -0
- package/build/dalvikBytecodeParser/formatParsers.d.ts +7 -6
- package/build/dalvikBytecodeParser/formatParsers.js +13 -14
- package/build/dalvikBytecodeParser.d.ts +60 -31
- package/build/dalvikBytecodeParser.js +92 -35
- package/build/dalvikBytecodeParser.test-d.d.ts +1 -0
- package/build/dalvikBytecodeParser.test-d.js +268 -0
- package/build/dalvikBytecodeUnparser/formatUnparsers.d.ts +9 -8
- package/build/dalvikBytecodeUnparser/formatUnparsers.js +13 -12
- package/build/dalvikBytecodeUnparser.d.ts +2 -2
- package/build/dalvikBytecodeUnparser.js +23 -23
- package/build/dalvikBytecodeUnparser.test.js +7 -7
- package/build/dalvikExecutable.d.ts +3 -3
- package/build/dalvikExecutable.test-d.d.ts +1 -0
- package/build/dalvikExecutable.test-d.js +59 -0
- package/build/dalvikExecutableParser/typedNumbers.d.ts +18 -0
- package/build/dalvikExecutableParser/typedNumbers.js +3 -0
- package/build/dalvikExecutableParser.d.ts +2 -1
- package/build/dalvikExecutableParser.js +96 -77
- package/build/dalvikExecutableParser.test.js +24 -3
- package/build/dalvikExecutableParserAgainstSmaliParser.test.js +3 -0
- package/build/dalvikExecutableUnparser/poolScanners.d.ts +2 -2
- package/build/dalvikExecutableUnparser/sectionUnparsers.d.ts +3 -3
- package/build/dalvikExecutableUnparser/sectionUnparsers.js +26 -11
- package/build/dalvikExecutableUnparser.d.ts +2 -2
- package/build/dalvikExecutableUnparser.test.js +2 -1
- package/build/disjunctionParser.d.ts +5 -3
- package/build/disjunctionParser.js +79 -17
- package/build/disjunctionParser.test-d.d.ts +1 -0
- package/build/disjunctionParser.test-d.js +72 -0
- package/build/elementSwitchParser.d.ts +4 -0
- package/build/{exactElementSwitchParser.js → elementSwitchParser.js} +3 -4
- package/build/elementSwitchParser.test-d.d.ts +1 -0
- package/build/elementSwitchParser.test-d.js +44 -0
- package/build/exactSequenceParser.d.ts +4 -2
- package/build/exactSequenceParser.test-d.d.ts +1 -0
- package/build/exactSequenceParser.test-d.js +36 -0
- package/build/fetchCid.js +2 -66
- package/build/index.d.ts +25 -2
- package/build/index.js +23 -1
- package/build/index.test.js +16 -1
- package/build/inputReader.d.ts +10 -0
- package/build/inputReader.js +36 -0
- package/build/java.d.ts +502 -0
- package/build/java.js +2 -0
- package/build/javaKeyStoreParser.js +14 -17
- package/build/javaParser.d.ts +51 -0
- package/build/javaParser.js +1538 -0
- package/build/javaParser.test.d.ts +1 -0
- package/build/javaParser.test.js +1287 -0
- package/build/javaScript.d.ts +35 -0
- package/build/javaScript.js +1 -0
- package/build/javaScriptParser.d.ts +9 -0
- package/build/javaScriptParser.js +34 -0
- package/build/javaScriptUnparser.d.ts +3 -0
- package/build/javaScriptUnparser.js +4 -0
- package/build/javaScriptUnparser.test.d.ts +1 -0
- package/build/javaScriptUnparser.test.js +24 -0
- package/build/javaUnparser.d.ts +2 -0
- package/build/javaUnparser.js +519 -0
- package/build/javaUnparser.test.d.ts +1 -0
- package/build/javaUnparser.test.js +24 -0
- package/build/javascript.d.ts +35 -0
- package/build/javascript.js +1 -0
- package/build/javascriptParser.d.ts +9 -0
- package/build/javascriptParser.js +34 -0
- package/build/javascriptUnparser.d.ts +3 -0
- package/build/javascriptUnparser.js +4 -0
- package/build/javascriptUnparser.test.d.ts +1 -0
- package/build/javascriptUnparser.test.js +24 -0
- package/build/jsonParser.js +2 -12
- package/build/lazyMessageError.d.ts +3 -0
- package/build/lookaheadParser.js +60 -3
- package/build/negativeLookaheadParser.js +70 -11
- package/build/nonEmptyArrayParser.js +72 -13
- package/build/objectParser.d.ts +12 -0
- package/build/objectParser.js +31 -0
- package/build/objectParser.test-d.d.ts +1 -0
- package/build/objectParser.test-d.js +112 -0
- package/build/objectParser.test.d.ts +1 -0
- package/build/objectParser.test.js +55 -0
- package/build/optionalParser.js +69 -10
- package/build/parser.d.ts +4 -0
- package/build/parser.js +3 -1
- package/build/parser.test.js +114 -1
- package/build/parserConsumedSequenceParser.js +66 -7
- package/build/parserContext.d.ts +6 -0
- package/build/parserContext.js +20 -11
- package/build/parserError.d.ts +119 -27
- package/build/parserError.js +16 -8
- package/build/regexpParser.d.ts +2 -0
- package/build/regexpParser.js +101 -0
- package/build/regexpParser.test.d.ts +1 -0
- package/build/regexpParser.test.js +114 -0
- package/build/regularExpression.d.ts +63 -0
- package/build/regularExpression.js +1 -0
- package/build/regularExpressionParser.d.ts +3 -0
- package/build/regularExpressionParser.js +600 -0
- package/build/regularExpressionParser.test.d.ts +1 -0
- package/build/regularExpressionParser.test.js +89 -0
- package/build/separatedArrayParser.js +73 -14
- package/build/separatedNonEmptyArrayParser.js +73 -14
- package/build/sliceBoundedParser.js +62 -5
- package/build/smaliParser.d.ts +7 -7
- package/build/smaliParser.js +185 -268
- package/build/smaliParser.test.js +58 -0
- package/build/stringEscapes.d.ts +5 -0
- package/build/stringEscapes.js +244 -0
- package/build/symbolicExpression.d.ts +29 -0
- package/build/symbolicExpression.js +1 -0
- package/build/symbolicExpressionParser.d.ts +4 -0
- package/build/symbolicExpressionParser.js +123 -0
- package/build/symbolicExpressionParser.test.d.ts +1 -0
- package/build/symbolicExpressionParser.test.js +289 -0
- package/build/terminatedArrayParser.js +113 -38
- package/build/terminatedArrayParser.test.js +4 -2
- package/build/tupleParser.d.ts +7 -15
- package/build/tupleParser.js +1 -0
- package/build/unionParser.d.ts +5 -3
- package/build/unionParser.js +7 -2
- package/build/unionParser.test-d.d.ts +1 -0
- package/build/unionParser.test-d.js +72 -0
- package/build/unionParser.test.js +10 -11
- package/build/zig.d.ts +280 -0
- package/build/zig.js +2 -0
- package/build/zigParser.d.ts +3 -0
- package/build/zigParser.js +1119 -0
- package/build/zigParser.test.d.ts +1 -0
- package/build/zigParser.test.js +1590 -0
- package/build/zigUnparser.d.ts +2 -0
- package/build/zigUnparser.js +460 -0
- package/build/zigUnparser.test.d.ts +1 -0
- package/build/zigUnparser.test.js +24 -0
- package/build/zipParser.js +19 -32
- package/build/zipUnparser.js +19 -7
- package/build/zipUnparser.test.js +1 -1
- package/node_modules-@types/s-expression/index.d.ts +5 -0
- package/package.json +25 -6
- package/src/androidPackageParser.ts +33 -60
- package/src/arbitraryDalvikBytecode.ts +39 -31
- package/src/arbitraryDalvikExecutable.ts +65 -20
- package/src/arbitraryJava.ts +804 -0
- package/src/arbitraryJavaScript.ts +410 -0
- package/src/arbitraryZig.ts +380 -0
- package/src/arrayParser.ts +1 -3
- package/src/backsmali.ts +35 -4
- package/src/bash.ts +127 -0
- package/src/bashParser.test.ts +590 -0
- package/src/bashParser.ts +498 -0
- package/src/dalvikBytecodeParser/addressConversion.ts +496 -0
- package/src/dalvikBytecodeParser/formatParsers.ts +19 -29
- package/src/dalvikBytecodeParser.test-d.ts +310 -0
- package/src/dalvikBytecodeParser.ts +194 -69
- package/src/dalvikBytecodeUnparser/formatUnparsers.ts +27 -26
- package/src/dalvikBytecodeUnparser.test.ts +7 -7
- package/src/dalvikBytecodeUnparser.ts +31 -30
- package/src/dalvikExecutable.test-d.ts +132 -0
- package/src/dalvikExecutable.ts +3 -3
- package/src/dalvikExecutableParser/typedNumbers.ts +11 -0
- package/src/dalvikExecutableParser.test.ts +37 -3
- package/src/dalvikExecutableParser.test.ts.md +163 -2
- package/src/dalvikExecutableParser.test.ts.snap +0 -0
- package/src/dalvikExecutableParser.ts +121 -139
- package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +4 -0
- package/src/dalvikExecutableUnparser/poolScanners.ts +6 -6
- package/src/dalvikExecutableUnparser/sectionUnparsers.ts +38 -14
- package/src/dalvikExecutableUnparser.test.ts +3 -2
- package/src/dalvikExecutableUnparser.ts +4 -4
- package/src/disjunctionParser.test-d.ts +105 -0
- package/src/disjunctionParser.ts +18 -15
- package/src/elementSwitchParser.test-d.ts +74 -0
- package/src/elementSwitchParser.ts +51 -0
- package/src/exactSequenceParser.test-d.ts +43 -0
- package/src/exactSequenceParser.ts +13 -8
- package/src/fetchCid.ts +2 -76
- package/src/index.test.ts +22 -1
- package/src/index.ts +119 -2
- package/src/inputReader.ts +53 -0
- package/src/java.ts +708 -0
- package/src/javaKeyStoreParser.ts +18 -32
- package/src/javaParser.test.ts +1592 -0
- package/src/javaParser.ts +2640 -0
- package/src/javaScript.ts +36 -0
- package/src/javaScriptParser.ts +57 -0
- package/src/javaScriptUnparser.test.ts +37 -0
- package/src/javaScriptUnparser.ts +7 -0
- package/src/javaUnparser.test.ts +37 -0
- package/src/javaUnparser.ts +640 -0
- package/src/jsonParser.ts +6 -27
- package/src/lookaheadParser.ts +2 -6
- package/src/negativeLookaheadParser.ts +1 -3
- package/src/nonEmptyArrayParser.ts +1 -3
- package/src/objectParser.test-d.ts +152 -0
- package/src/objectParser.test.ts +71 -0
- package/src/objectParser.ts +69 -0
- package/src/optionalParser.ts +1 -3
- package/src/parser.test.ts +151 -4
- package/src/parser.ts +11 -1
- package/src/parserConsumedSequenceParser.ts +2 -4
- package/src/parserContext.ts +26 -11
- package/src/parserError.ts +17 -3
- package/src/regexpParser.test.ts +264 -0
- package/src/regexpParser.ts +126 -0
- package/src/regularExpression.ts +24 -0
- package/src/regularExpressionParser.test.ts +102 -0
- package/src/regularExpressionParser.ts +920 -0
- package/src/separatedArrayParser.ts +1 -3
- package/src/separatedNonEmptyArrayParser.ts +1 -3
- package/src/sliceBoundedParser.test.ts +2 -2
- package/src/sliceBoundedParser.ts +15 -19
- package/src/smaliParser.test.ts +64 -0
- package/src/smaliParser.test.ts.md +12 -12
- package/src/smaliParser.test.ts.snap +0 -0
- package/src/smaliParser.ts +246 -534
- package/src/stringEscapes.ts +253 -0
- package/src/symbolicExpression.ts +17 -0
- package/src/symbolicExpressionParser.test.ts +466 -0
- package/src/symbolicExpressionParser.ts +190 -0
- package/src/terminatedArrayParser.test.ts +9 -6
- package/src/terminatedArrayParser.ts +25 -29
- package/src/tupleParser.ts +21 -18
- package/src/unionParser.test-d.ts +105 -0
- package/src/unionParser.test.ts +18 -17
- package/src/unionParser.ts +28 -16
- package/src/zig.ts +411 -0
- package/src/zigParser.test.ts +1693 -0
- package/src/zigParser.ts +1745 -0
- package/src/zigUnparser.test.ts +37 -0
- package/src/zigUnparser.ts +615 -0
- package/src/zipParser.ts +20 -56
- package/src/zipUnparser.test.ts +1 -1
- package/src/zipUnparser.ts +22 -7
- package/tsconfig.json +2 -2
- package/build/exactElementSwitchParser.d.ts +0 -3
- package/src/exactElementSwitchParser.ts +0 -41
package/build/smaliParser.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import invariant from 'invariant';
|
|
2
|
-
import {
|
|
2
|
+
import { rawDalvikBytecodeOperationCompanion } from './dalvikBytecodeParser.js';
|
|
3
|
+
import { getOperationSizeInCodeUnits } from './dalvikBytecodeParser/addressConversion.js';
|
|
3
4
|
import { dalvikExecutableAccessFlagsDefault, dalvikExecutableFieldEquals, dalvikExecutableMethodEquals, isDalvikExecutableField, isDalvikExecutableMethod, } from './dalvikExecutable.js';
|
|
4
5
|
import { createExactSequenceParser } from './exactSequenceParser.js';
|
|
6
|
+
import { createObjectParser } from './objectParser.js';
|
|
5
7
|
import { cloneParser, setParserName } from './parser.js';
|
|
6
8
|
import { promiseCompose } from './promiseCompose.js';
|
|
7
9
|
import { createTupleParser } from './tupleParser.js';
|
|
@@ -14,37 +16,17 @@ import { createNegativeLookaheadParser } from './negativeLookaheadParser.js';
|
|
|
14
16
|
import { createSeparatedArrayParser } from './separatedArrayParser.js';
|
|
15
17
|
import { smaliMemberNameParser, smaliTypeDescriptorParser } from './dalvikExecutableParser/stringSyntaxParser.js';
|
|
16
18
|
import { createDisjunctionParser } from './disjunctionParser.js';
|
|
17
|
-
import { formatSizes } from './dalvikBytecodeParser/formatSizes.js';
|
|
18
|
-
import { operationFormats } from './dalvikBytecodeParser/operationFormats.js';
|
|
19
19
|
import { createSeparatedNonEmptyArrayParser } from './separatedNonEmptyArrayParser.js';
|
|
20
20
|
import { parserCreatorCompose } from './parserCreatorCompose.js';
|
|
21
21
|
import { createElementParser } from './elementParser.js';
|
|
22
22
|
import { createParserAccessorParser } from './parserAccessorParser.js';
|
|
23
|
+
import { createRegExpParser } from './regexpParser.js';
|
|
23
24
|
function shortyFromLongy(longy) {
|
|
24
25
|
if (longy.startsWith('[')) {
|
|
25
26
|
return 'L';
|
|
26
27
|
}
|
|
27
28
|
return longy.slice(0, 1);
|
|
28
29
|
}
|
|
29
|
-
function getOperationFormatSize(operation) {
|
|
30
|
-
if (operation.operation === 'packed-switch-payload') {
|
|
31
|
-
return (operation.branchOffsetIndices.length * 2) + 4;
|
|
32
|
-
}
|
|
33
|
-
if (operation.operation === 'sparse-switch-payload') {
|
|
34
|
-
return (operation.branchOffsetIndices.length * 4) + 2;
|
|
35
|
-
}
|
|
36
|
-
if (operation.operation === 'fill-array-data-payload') {
|
|
37
|
-
const dataSize = operation.data.length; // in bytes
|
|
38
|
-
const paddingSize = dataSize % 2; // 1 if odd, 0 if even
|
|
39
|
-
const totalBytes = 8 + dataSize + paddingSize; // header (8 bytes) + data + padding
|
|
40
|
-
return totalBytes / 2; // Convert to code units (1 code unit = 2 bytes)
|
|
41
|
-
}
|
|
42
|
-
const operationFormat = operationFormats[operation.operation];
|
|
43
|
-
invariant(operationFormat, 'Unknown operation format for "%s" (operation: %o)', operation.operation, operation);
|
|
44
|
-
const operationSize = formatSizes[operationFormat];
|
|
45
|
-
invariant(operationSize, 'Unknown operation size for format %s of operation %s', operationFormat, operation.operation);
|
|
46
|
-
return operationSize;
|
|
47
|
-
}
|
|
48
30
|
// Helper function to convert raw annotation element values to tagged encoded values
|
|
49
31
|
function convertToTaggedEncodedValue(wrappedValue) {
|
|
50
32
|
const { kind, value } = wrappedValue;
|
|
@@ -141,22 +123,8 @@ const smaliSingleIndentationParser = createExactSequenceParser(' ');
|
|
|
141
123
|
const smaliIndentationParser = promiseCompose(createArrayParser(smaliSingleIndentationParser), _indentation => undefined);
|
|
142
124
|
export const smaliCommentParser = promiseCompose(createTupleParser([
|
|
143
125
|
createExactSequenceParser('#'),
|
|
144
|
-
(
|
|
145
|
-
|
|
146
|
-
while (true) {
|
|
147
|
-
const character = await parserContext.peek(0);
|
|
148
|
-
parserContext.invariant(character !== undefined, 'Unexpected end of input');
|
|
149
|
-
invariant(character !== undefined, 'Unexpected end of input');
|
|
150
|
-
if (character !== '\n') {
|
|
151
|
-
characters.push(character);
|
|
152
|
-
parserContext.skip(1);
|
|
153
|
-
continue;
|
|
154
|
-
}
|
|
155
|
-
parserContext.skip(1);
|
|
156
|
-
break;
|
|
157
|
-
}
|
|
158
|
-
return characters.join('');
|
|
159
|
-
}),
|
|
126
|
+
promiseCompose(createRegExpParser(/[^\n]*/), match => match[0]),
|
|
127
|
+
createExactSequenceParser('\n'),
|
|
160
128
|
]), ([_hash, comment,]) => comment);
|
|
161
129
|
const smaliIndentedCommentParser = promiseCompose(createTupleParser([
|
|
162
130
|
createNonEmptyArrayParser(smaliSingleIndentationParser),
|
|
@@ -174,46 +142,18 @@ const smaliLineEndPraser = promiseCompose(createTupleParser([
|
|
|
174
142
|
smaliCommentParser,
|
|
175
143
|
]),
|
|
176
144
|
]), ([_optionalWhitespace, newlineOrComment,]) => newlineOrComment);
|
|
177
|
-
const smaliIdentifierParser =
|
|
178
|
-
const characters = [];
|
|
179
|
-
while (true) {
|
|
180
|
-
const character = await parserContext.peek(0);
|
|
181
|
-
parserContext.invariant(character !== undefined, 'Unexpected end of input');
|
|
182
|
-
invariant(character !== undefined, 'Unexpected end of input');
|
|
183
|
-
if (character === '_'
|
|
184
|
-
|| (character >= 'a' && character <= 'z')
|
|
185
|
-
|| (character >= 'A' && character <= 'Z')
|
|
186
|
-
|| (character >= '0' && character <= '9')) {
|
|
187
|
-
parserContext.skip(1);
|
|
188
|
-
characters.push(character);
|
|
189
|
-
continue;
|
|
190
|
-
}
|
|
191
|
-
parserContext.invariant(characters.length > 0, 'Expected at least one character');
|
|
192
|
-
break;
|
|
193
|
-
}
|
|
194
|
-
return characters.join('');
|
|
195
|
-
};
|
|
145
|
+
const smaliIdentifierParser = promiseCompose(createRegExpParser(/[a-zA-Z0-9_]+/), match => match[0]);
|
|
196
146
|
setParserName(smaliIdentifierParser, 'smaliIdentifierParser');
|
|
197
|
-
const
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
createExactSequenceParser('0x'),
|
|
201
|
-
createArrayParser(parserCreatorCompose(() => elementParser, character => async (parserContext) => {
|
|
202
|
-
parserContext.invariant(((character >= '0' && character <= '9')
|
|
203
|
-
|| (character >= 'a' && character <= 'f')
|
|
204
|
-
|| (character >= 'A' && character <= 'F')), 'Expected "0" to "9", "a" to "f", "A" to "F", got "%s"', character);
|
|
205
|
-
return character;
|
|
206
|
-
})()),
|
|
207
|
-
createOptionalParser(createExactSequenceParser('L')),
|
|
208
|
-
]), ([optionalMinus, _0x, valueCharacters, optionalL,]) => {
|
|
209
|
-
const value = valueCharacters.join('');
|
|
147
|
+
const smaliHexNumberParser = promiseCompose(createRegExpParser(/-?0x([0-9a-fA-F]+)(L)?/), match => {
|
|
148
|
+
const hexDigits = match[1];
|
|
149
|
+
const optionalL = match[2];
|
|
210
150
|
// If the 'L' suffix is present, use BigInt for long values
|
|
211
151
|
if (optionalL) {
|
|
212
|
-
const sign =
|
|
213
|
-
return sign * BigInt('0x' +
|
|
152
|
+
const sign = match[0].startsWith('-') ? -1n : 1n;
|
|
153
|
+
return sign * BigInt('0x' + hexDigits);
|
|
214
154
|
}
|
|
215
|
-
const sign =
|
|
216
|
-
return sign * Number.parseInt(
|
|
155
|
+
const sign = match[0].startsWith('-') ? -1 : 1;
|
|
156
|
+
return sign * Number.parseInt(hexDigits, 16);
|
|
217
157
|
});
|
|
218
158
|
const smaliNumberParser = createUnionParser([
|
|
219
159
|
promiseCompose(createTupleParser([
|
|
@@ -361,13 +301,11 @@ const smaliClassDeclarationParser = promiseCompose(createTupleParser([
|
|
|
361
301
|
class: classPath,
|
|
362
302
|
}));
|
|
363
303
|
setParserName(smaliClassDeclarationParser, 'smaliClassDeclarationParser');
|
|
364
|
-
const smaliSuperDeclarationParser =
|
|
365
|
-
createExactSequenceParser('.super '),
|
|
366
|
-
smaliTypeDescriptorParser,
|
|
367
|
-
smaliLineEndPraser,
|
|
368
|
-
|
|
369
|
-
superclass,
|
|
370
|
-
}));
|
|
304
|
+
const smaliSuperDeclarationParser = createObjectParser({
|
|
305
|
+
_super: createExactSequenceParser('.super '),
|
|
306
|
+
superclass: smaliTypeDescriptorParser,
|
|
307
|
+
_newline: smaliLineEndPraser,
|
|
308
|
+
});
|
|
371
309
|
setParserName(smaliSuperDeclarationParser, 'smaliSuperDeclarationParser');
|
|
372
310
|
const smaliInterfaceDeclarationParser = promiseCompose(createTupleParser([
|
|
373
311
|
createExactSequenceParser('.implements '),
|
|
@@ -375,25 +313,19 @@ const smaliInterfaceDeclarationParser = promiseCompose(createTupleParser([
|
|
|
375
313
|
smaliLineEndPraser,
|
|
376
314
|
]), ([_interface, interface_, _newline,]) => interface_);
|
|
377
315
|
setParserName(smaliInterfaceDeclarationParser, 'smaliInterfaceDeclarationParser');
|
|
378
|
-
const smaliSourceDeclarationParser =
|
|
379
|
-
createExactSequenceParser('.source '),
|
|
380
|
-
smaliQuotedStringParser,
|
|
381
|
-
smaliLineEndPraser,
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
createExactSequenceParser('
|
|
387
|
-
|
|
388
|
-
createExactSequenceParser('
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
smaliTypeDescriptorParser,
|
|
392
|
-
]), ([_enum, classType, _arrow, fieldName, _colon, fieldType,]) => ({
|
|
393
|
-
class: classType,
|
|
394
|
-
type: fieldType,
|
|
395
|
-
name: fieldName,
|
|
396
|
-
}));
|
|
316
|
+
const smaliSourceDeclarationParser = createObjectParser({
|
|
317
|
+
_source: createExactSequenceParser('.source '),
|
|
318
|
+
sourceFile: smaliQuotedStringParser,
|
|
319
|
+
_newline: smaliLineEndPraser,
|
|
320
|
+
});
|
|
321
|
+
const smaliEnumValueParser = createObjectParser({
|
|
322
|
+
_enum: createExactSequenceParser('.enum '),
|
|
323
|
+
class: smaliTypeDescriptorParser,
|
|
324
|
+
_arrow: createExactSequenceParser('->'),
|
|
325
|
+
name: smaliMemberNameParser,
|
|
326
|
+
_colon: createExactSequenceParser(':'),
|
|
327
|
+
type: smaliTypeDescriptorParser,
|
|
328
|
+
});
|
|
397
329
|
setParserName(smaliEnumValueParser, 'smaliEnumValueParser');
|
|
398
330
|
const smaliMethodPrototypeParser = promiseCompose(createTupleParser([
|
|
399
331
|
createExactSequenceParser('('),
|
|
@@ -411,16 +343,12 @@ const smaliMethodPrototypeParser = promiseCompose(createTupleParser([
|
|
|
411
343
|
}).join(''),
|
|
412
344
|
}));
|
|
413
345
|
setParserName(smaliMethodPrototypeParser, 'smaliMethodPrototypeParser');
|
|
414
|
-
const smaliParametersMethodParser =
|
|
415
|
-
smaliTypeDescriptorParser,
|
|
416
|
-
createExactSequenceParser('->'),
|
|
417
|
-
smaliMemberNameParser,
|
|
418
|
-
smaliMethodPrototypeParser,
|
|
419
|
-
|
|
420
|
-
class: classPath,
|
|
421
|
-
prototype,
|
|
422
|
-
name: methodName,
|
|
423
|
-
}));
|
|
346
|
+
const smaliParametersMethodParser = createObjectParser({
|
|
347
|
+
class: smaliTypeDescriptorParser,
|
|
348
|
+
_separator: createExactSequenceParser('->'),
|
|
349
|
+
name: smaliMemberNameParser,
|
|
350
|
+
prototype: smaliMethodPrototypeParser,
|
|
351
|
+
});
|
|
424
352
|
setParserName(smaliParametersMethodParser, 'smaliParametersMethodParser');
|
|
425
353
|
// Forward declaration to handle circular reference
|
|
426
354
|
let smaliSubannotationParser;
|
|
@@ -429,16 +357,46 @@ const smaliAnnotationElementParser = promiseCompose(createTupleParser([
|
|
|
429
357
|
smaliIdentifierParser,
|
|
430
358
|
createExactSequenceParser(' = '),
|
|
431
359
|
createDisjunctionParser([
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
360
|
+
createObjectParser({
|
|
361
|
+
kind: 'raw',
|
|
362
|
+
value: createParserAccessorParser(() => smaliSubannotationParser),
|
|
363
|
+
}),
|
|
364
|
+
createObjectParser({
|
|
365
|
+
kind: 'enum',
|
|
366
|
+
value: smaliEnumValueParser,
|
|
367
|
+
}),
|
|
368
|
+
createObjectParser({
|
|
369
|
+
kind: 'string',
|
|
370
|
+
value: smaliQuotedStringParser,
|
|
371
|
+
}),
|
|
372
|
+
createObjectParser({
|
|
373
|
+
kind: 'raw',
|
|
374
|
+
value: smaliParametersMethodParser,
|
|
375
|
+
}),
|
|
376
|
+
createObjectParser({
|
|
377
|
+
kind: 'type',
|
|
378
|
+
value: smaliTypeDescriptorParser,
|
|
379
|
+
}),
|
|
380
|
+
createObjectParser({
|
|
381
|
+
kind: 'raw',
|
|
382
|
+
value: smaliNumberParser,
|
|
383
|
+
}),
|
|
384
|
+
createObjectParser({
|
|
385
|
+
kind: 'raw',
|
|
386
|
+
value: true,
|
|
387
|
+
_true: createExactSequenceParser('true'),
|
|
388
|
+
}),
|
|
389
|
+
createObjectParser({
|
|
390
|
+
kind: 'raw',
|
|
391
|
+
value: false,
|
|
392
|
+
_false: createExactSequenceParser('false'),
|
|
393
|
+
}),
|
|
440
394
|
promiseCompose(createExactSequenceParser('null'), () => ({ kind: 'raw', value: null })),
|
|
441
|
-
|
|
395
|
+
createObjectParser({
|
|
396
|
+
kind: 'raw',
|
|
397
|
+
value: [],
|
|
398
|
+
_emptyBraces: createExactSequenceParser('{}'),
|
|
399
|
+
}),
|
|
442
400
|
promiseCompose(createTupleParser([
|
|
443
401
|
createExactSequenceParser('{\n'),
|
|
444
402
|
createSeparatedArrayParser(promiseCompose(createTupleParser([
|
|
@@ -487,37 +445,30 @@ const smaliAnnotationElementParser = promiseCompose(createTupleParser([
|
|
|
487
445
|
}));
|
|
488
446
|
setParserName(smaliAnnotationElementParser, 'smaliAnnotationElementParser');
|
|
489
447
|
// Now define the subannotation parser
|
|
490
|
-
smaliSubannotationParser =
|
|
491
|
-
createExactSequenceParser('.subannotation '),
|
|
492
|
-
smaliTypeDescriptorParser,
|
|
493
|
-
smaliLineEndPraser,
|
|
494
|
-
createArrayParser(smaliAnnotationElementParser),
|
|
495
|
-
smaliIndentationParser,
|
|
496
|
-
createExactSequenceParser('.end subannotation'),
|
|
497
|
-
|
|
498
|
-
type,
|
|
499
|
-
elements,
|
|
500
|
-
}));
|
|
448
|
+
smaliSubannotationParser = createObjectParser({
|
|
449
|
+
_subannotation: createExactSequenceParser('.subannotation '),
|
|
450
|
+
type: smaliTypeDescriptorParser,
|
|
451
|
+
_newline: smaliLineEndPraser,
|
|
452
|
+
elements: createArrayParser(smaliAnnotationElementParser),
|
|
453
|
+
_indentation: smaliIndentationParser,
|
|
454
|
+
_endSubannotation: createExactSequenceParser('.end subannotation'),
|
|
455
|
+
});
|
|
501
456
|
setParserName(smaliSubannotationParser, 'smaliSubannotationParser');
|
|
502
|
-
export const smaliAnnotationParser =
|
|
503
|
-
smaliIndentationParser,
|
|
504
|
-
createExactSequenceParser('.annotation '),
|
|
505
|
-
createUnionParser([
|
|
457
|
+
export const smaliAnnotationParser = createObjectParser({
|
|
458
|
+
_indentation0: smaliIndentationParser,
|
|
459
|
+
_annotation: createExactSequenceParser('.annotation '),
|
|
460
|
+
visibility: createUnionParser([
|
|
506
461
|
createExactSequenceParser('build'),
|
|
507
462
|
createExactSequenceParser('runtime'),
|
|
508
463
|
createExactSequenceParser('system'),
|
|
509
464
|
]),
|
|
510
|
-
smaliSingleWhitespaceParser,
|
|
511
|
-
smaliTypeDescriptorParser,
|
|
512
|
-
smaliLineEndPraser,
|
|
513
|
-
createArrayParser(smaliAnnotationElementParser),
|
|
514
|
-
smaliIndentationParser,
|
|
515
|
-
createExactSequenceParser('.end annotation\n'),
|
|
516
|
-
|
|
517
|
-
type,
|
|
518
|
-
elements,
|
|
519
|
-
visibility,
|
|
520
|
-
}));
|
|
465
|
+
_space: smaliSingleWhitespaceParser,
|
|
466
|
+
type: smaliTypeDescriptorParser,
|
|
467
|
+
_newline: smaliLineEndPraser,
|
|
468
|
+
elements: createArrayParser(smaliAnnotationElementParser),
|
|
469
|
+
_indentation1: smaliIndentationParser,
|
|
470
|
+
_endAnnotation: createExactSequenceParser('.end annotation\n'),
|
|
471
|
+
});
|
|
521
472
|
setParserName(smaliAnnotationParser, 'smaliAnnotationParser');
|
|
522
473
|
export const smaliFieldParser = promiseCompose(createTupleParser([
|
|
523
474
|
createExactSequenceParser('.field '),
|
|
@@ -640,19 +591,16 @@ function isSmaliRegister(value) {
|
|
|
640
591
|
&& typeof value.prefix === 'string'
|
|
641
592
|
&& typeof value.index === 'number');
|
|
642
593
|
}
|
|
643
|
-
const smaliParametersRegisterParser =
|
|
644
|
-
|
|
645
|
-
createExactSequenceParser('v'),
|
|
646
|
-
smaliNumberParser,
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
createExactSequenceParser('p'),
|
|
650
|
-
smaliNumberParser,
|
|
651
|
-
|
|
652
|
-
])
|
|
653
|
-
prefix,
|
|
654
|
-
index,
|
|
655
|
-
}));
|
|
594
|
+
const smaliParametersRegisterParser = createUnionParser([
|
|
595
|
+
createObjectParser({
|
|
596
|
+
prefix: createExactSequenceParser('v'),
|
|
597
|
+
index: smaliNumberParser,
|
|
598
|
+
}),
|
|
599
|
+
createObjectParser({
|
|
600
|
+
prefix: createExactSequenceParser('p'),
|
|
601
|
+
index: smaliNumberParser,
|
|
602
|
+
}),
|
|
603
|
+
]);
|
|
656
604
|
setParserName(smaliParametersRegisterParser, 'smaliParametersRegisterParser');
|
|
657
605
|
const smaliCodeLocalParser = promiseCompose(createTupleParser([
|
|
658
606
|
createExactSequenceParser(' .local '),
|
|
@@ -663,12 +611,18 @@ const smaliCodeLocalParser = promiseCompose(createTupleParser([
|
|
|
663
611
|
smaliQuotedStringParser,
|
|
664
612
|
createExactSequenceParser(':'),
|
|
665
613
|
smaliTypeDescriptorParser,
|
|
614
|
+
createOptionalParser(createTupleParser([
|
|
615
|
+
createExactSequenceParser(','),
|
|
616
|
+
smaliWhitespaceParser,
|
|
617
|
+
smaliQuotedStringParser,
|
|
618
|
+
])),
|
|
666
619
|
])),
|
|
667
620
|
smaliLineEndPraser,
|
|
668
621
|
]), ([_local, register, nameAndType,]) => ({
|
|
669
622
|
register,
|
|
670
623
|
name: nameAndType?.[2],
|
|
671
624
|
type: nameAndType?.[4],
|
|
625
|
+
signature: nameAndType?.[5]?.[2],
|
|
672
626
|
}));
|
|
673
627
|
setParserName(smaliCodeLocalParser, 'smaliCodeLocalParser');
|
|
674
628
|
const smaliCodeEndLocalParser = promiseCompose(createTupleParser([
|
|
@@ -732,39 +686,31 @@ const smaliCodeLabelLineParser = promiseCompose(createTupleParser([
|
|
|
732
686
|
smaliLineEndPraser,
|
|
733
687
|
]), ([_label, label, _newlabel,]) => label);
|
|
734
688
|
setParserName(smaliCodeLabelLineParser, 'smaliCodeLabelLineParser');
|
|
735
|
-
const smaliCatchDirectiveParser =
|
|
736
|
-
smaliIndentationParser,
|
|
737
|
-
createExactSequenceParser('.catch'),
|
|
738
|
-
createUnionParser([
|
|
689
|
+
const smaliCatchDirectiveParser = createObjectParser({
|
|
690
|
+
_indentation: smaliIndentationParser,
|
|
691
|
+
_catch: createExactSequenceParser('.catch'),
|
|
692
|
+
type: createUnionParser([
|
|
739
693
|
promiseCompose(createExactSequenceParser('all'), () => undefined),
|
|
740
694
|
promiseCompose(createTupleParser([
|
|
741
695
|
createExactSequenceParser(' '),
|
|
742
696
|
smaliTypeDescriptorParser,
|
|
743
697
|
]), ([_space, type,]) => type),
|
|
744
698
|
]),
|
|
745
|
-
createExactSequenceParser(' {'),
|
|
746
|
-
smaliCodeLabelParser,
|
|
747
|
-
createExactSequenceParser(' .. '),
|
|
748
|
-
smaliCodeLabelParser,
|
|
749
|
-
createExactSequenceParser('} '),
|
|
750
|
-
smaliCodeLabelParser,
|
|
751
|
-
smaliLineEndPraser,
|
|
752
|
-
|
|
753
|
-
type,
|
|
754
|
-
startLabel,
|
|
755
|
-
endLabel,
|
|
756
|
-
handlerLabel,
|
|
757
|
-
}));
|
|
699
|
+
_openBrace: createExactSequenceParser(' {'),
|
|
700
|
+
startLabel: smaliCodeLabelParser,
|
|
701
|
+
_dots: createExactSequenceParser(' .. '),
|
|
702
|
+
endLabel: smaliCodeLabelParser,
|
|
703
|
+
_closeBrace: createExactSequenceParser('} '),
|
|
704
|
+
handlerLabel: smaliCodeLabelParser,
|
|
705
|
+
_newline: smaliLineEndPraser,
|
|
706
|
+
});
|
|
758
707
|
setParserName(smaliCatchDirectiveParser, 'smaliCatchDirectiveParser');
|
|
759
|
-
const smaliLabeledCatchDirectiveParser =
|
|
760
|
-
createArrayParser(smaliCodeLineParser),
|
|
761
|
-
createOptionalParser(smaliCodeLocalParser),
|
|
762
|
-
createArrayParser(smaliCodeLabelLineParser),
|
|
763
|
-
smaliCatchDirectiveParser,
|
|
764
|
-
|
|
765
|
-
labels,
|
|
766
|
-
catchDirective,
|
|
767
|
-
}));
|
|
708
|
+
const smaliLabeledCatchDirectiveParser = createObjectParser({
|
|
709
|
+
_lines: createArrayParser(smaliCodeLineParser),
|
|
710
|
+
_local: createOptionalParser(smaliCodeLocalParser),
|
|
711
|
+
labels: createArrayParser(smaliCodeLabelLineParser),
|
|
712
|
+
catchDirective: smaliCatchDirectiveParser,
|
|
713
|
+
});
|
|
768
714
|
setParserName(smaliLabeledCatchDirectiveParser, 'smaliLabeledCatchDirectiveParser');
|
|
769
715
|
const smaliParametersRegisterRangeParser = promiseCompose(createTupleParser([
|
|
770
716
|
createExactSequenceParser('{'),
|
|
@@ -801,38 +747,15 @@ const smaliParametersRegistersParser = createUnionParser([
|
|
|
801
747
|
setParserName(smaliParametersRegistersParser, 'smaliParametersRegistersParser');
|
|
802
748
|
const smaliParametersStringParser = cloneParser(smaliQuotedStringParser);
|
|
803
749
|
setParserName(smaliParametersStringParser, 'smaliParametersStringParser');
|
|
804
|
-
const smaliParametersIntegerParser = promiseCompose(
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
async (parserContext) => {
|
|
808
|
-
const characters = [];
|
|
809
|
-
while (true) {
|
|
810
|
-
const character = await parserContext.peek(0);
|
|
811
|
-
parserContext.invariant(character !== undefined, 'Unexpected end of input');
|
|
812
|
-
invariant(character !== undefined, 'Unexpected end of input');
|
|
813
|
-
if ((character >= '0' && character <= '9')
|
|
814
|
-
|| (character >= 'a' && character <= 'f')
|
|
815
|
-
|| (character >= 'A' && character <= 'F')) {
|
|
816
|
-
characters.push(character);
|
|
817
|
-
parserContext.skip(1);
|
|
818
|
-
continue;
|
|
819
|
-
}
|
|
820
|
-
break;
|
|
821
|
-
}
|
|
822
|
-
return characters.join('');
|
|
823
|
-
},
|
|
824
|
-
createOptionalParser(createUnionParser([
|
|
825
|
-
createExactSequenceParser('L'),
|
|
826
|
-
createExactSequenceParser('t'),
|
|
827
|
-
createExactSequenceParser('s'),
|
|
828
|
-
])),
|
|
829
|
-
]), ([optionalMinus, _0x, value, optionalSuffix,]) => {
|
|
750
|
+
const smaliParametersIntegerParser = promiseCompose(createRegExpParser(/-?0x([0-9a-fA-F]+)([Lts])?/), match => {
|
|
751
|
+
const hexDigits = match[1];
|
|
752
|
+
const optionalSuffix = match[2];
|
|
830
753
|
if (optionalSuffix === 'L') {
|
|
831
|
-
const sign =
|
|
832
|
-
return sign * BigInt('0x' +
|
|
754
|
+
const sign = match[0].startsWith('-') ? -1n : 1n;
|
|
755
|
+
return sign * BigInt('0x' + hexDigits);
|
|
833
756
|
}
|
|
834
|
-
const sign =
|
|
835
|
-
return sign * Number.parseInt(
|
|
757
|
+
const sign = match[0].startsWith('-') ? -1 : 1;
|
|
758
|
+
return sign * Number.parseInt(hexDigits, 16);
|
|
836
759
|
});
|
|
837
760
|
setParserName(smaliParametersIntegerParser, 'smaliParametersIntegerParser');
|
|
838
761
|
const smaliParametersLabelParser = promiseCompose(createTupleParser([
|
|
@@ -842,17 +765,13 @@ const smaliParametersLabelParser = promiseCompose(createTupleParser([
|
|
|
842
765
|
setParserName(smaliParametersLabelParser, 'smaliParametersLabelParser');
|
|
843
766
|
const smaliParametersTypeParser = cloneParser(smaliTypeDescriptorParser);
|
|
844
767
|
setParserName(smaliParametersTypeParser, 'smaliParametersTypeParser');
|
|
845
|
-
const smaliParametersFieldParser =
|
|
846
|
-
smaliTypeDescriptorParser,
|
|
847
|
-
createExactSequenceParser('->'),
|
|
848
|
-
smaliMemberNameParser,
|
|
849
|
-
createExactSequenceParser(':'),
|
|
850
|
-
smaliTypeDescriptorParser,
|
|
851
|
-
|
|
852
|
-
class: classPath,
|
|
853
|
-
name: fieldName,
|
|
854
|
-
type,
|
|
855
|
-
}));
|
|
768
|
+
const smaliParametersFieldParser = createObjectParser({
|
|
769
|
+
class: smaliTypeDescriptorParser,
|
|
770
|
+
_separator: createExactSequenceParser('->'),
|
|
771
|
+
name: smaliMemberNameParser,
|
|
772
|
+
_colon: createExactSequenceParser(':'),
|
|
773
|
+
type: smaliTypeDescriptorParser,
|
|
774
|
+
});
|
|
856
775
|
setParserName(smaliParametersFieldParser, 'smaliParametersFieldParser');
|
|
857
776
|
const smaliCodeOperationParametersParser = createArrayParser(promiseCompose(createTupleParser([
|
|
858
777
|
createUnionParser([
|
|
@@ -884,18 +803,15 @@ const smaliCodeOperationNameParser = promiseCompose(createTupleParser([
|
|
|
884
803
|
]), ([slash, name]) => slash + name)),
|
|
885
804
|
]), ([name, optionalSlashName,]) => name + (optionalSlashName || ''));
|
|
886
805
|
setParserName(smaliCodeOperationNameParser, 'smaliCodeOperationNameParser');
|
|
887
|
-
const smaliOneLineCodeOperationParser =
|
|
888
|
-
smaliSingleIndentationParser,
|
|
889
|
-
smaliCodeOperationNameParser,
|
|
890
|
-
promiseCompose(createOptionalParser(createTupleParser([
|
|
806
|
+
const smaliOneLineCodeOperationParser = createObjectParser({
|
|
807
|
+
_indent: smaliSingleIndentationParser,
|
|
808
|
+
operation: smaliCodeOperationNameParser,
|
|
809
|
+
parameters: promiseCompose(createOptionalParser(createTupleParser([
|
|
891
810
|
smaliSingleWhitespaceParser,
|
|
892
811
|
smaliCodeOperationParametersParser,
|
|
893
812
|
])), undefinedOrParameters => undefinedOrParameters === undefined ? [] : undefinedOrParameters[1]),
|
|
894
|
-
smaliLineEndPraser,
|
|
895
|
-
|
|
896
|
-
operation,
|
|
897
|
-
parameters,
|
|
898
|
-
}));
|
|
813
|
+
_newline: smaliLineEndPraser,
|
|
814
|
+
});
|
|
899
815
|
setParserName(smaliOneLineCodeOperationParser, 'smaliOneLineCodeOperationParser');
|
|
900
816
|
const createMultilineSmaliCodeOperationLabelsBodyParser = operationName => promiseCompose(createTupleParser([
|
|
901
817
|
createArrayParser(promiseCompose(createTupleParser([
|
|
@@ -1223,21 +1139,13 @@ const smaliExecutableCodeParser = promiseCompose(createTupleParser([
|
|
|
1223
1139
|
delete operation.branchLabels;
|
|
1224
1140
|
}
|
|
1225
1141
|
}
|
|
1226
|
-
|
|
1227
|
-
let operationOffset = 0;
|
|
1228
|
-
for (const [operationIndex, operation] of instructions.entries()) {
|
|
1229
|
-
const operationSize = getOperationFormatSize(operation);
|
|
1230
|
-
branchOffsetByBranchOffsetIndex.set(operationIndex, operationOffset);
|
|
1231
|
-
operationOffset += operationSize;
|
|
1232
|
-
}
|
|
1142
|
+
// Convert branchOffsetIndex (relative) to targetInstructionIndex (absolute)
|
|
1233
1143
|
for (const [operationIndex, operation] of instructions.entries()) {
|
|
1234
1144
|
if ('branchOffsetIndex' in operation
|
|
1235
1145
|
&& typeof operation.branchOffsetIndex === 'number') {
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
invariant(branchOffset !== undefined, 'Expected branch offset for operation index %s, but got undefined', operationIndex);
|
|
1240
|
-
operation.branchOffset = operationOffset - branchOffset;
|
|
1146
|
+
// branchOffsetIndex is the relative instruction index from the label
|
|
1147
|
+
// targetInstructionIndex is the absolute instruction index
|
|
1148
|
+
operation.targetInstructionIndex = operationIndex + operation.branchOffsetIndex;
|
|
1241
1149
|
}
|
|
1242
1150
|
if ('branchOffsetIndices' in operation
|
|
1243
1151
|
&& typeof operation.branchOffsetIndices === 'object'
|
|
@@ -1248,12 +1156,11 @@ const smaliExecutableCodeParser = promiseCompose(createTupleParser([
|
|
|
1248
1156
|
invariant(sourceOperations.length === 1, 'Expected exactly one source operation to point to %s', JSON.stringify(operation));
|
|
1249
1157
|
const [sourceOperation] = sourceOperations;
|
|
1250
1158
|
const sourceOperationIndex = instructions.indexOf(sourceOperation);
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
return operationOffset - branchOffset;
|
|
1159
|
+
// For payload instructions, branchOffsetIndices contains instruction-relative indices
|
|
1160
|
+
// from the source switch instruction. Convert to absolute instruction indices.
|
|
1161
|
+
operation.targetInstructionIndices = operation.branchOffsetIndices.map((branchOffsetIndex) => {
|
|
1162
|
+
// branchOffsetIndex is relative to the source operation
|
|
1163
|
+
return sourceOperationIndex + branchOffsetIndex;
|
|
1257
1164
|
});
|
|
1258
1165
|
}
|
|
1259
1166
|
}
|
|
@@ -1292,6 +1199,7 @@ const smaliExecutableCodeParser = promiseCompose(createTupleParser([
|
|
|
1292
1199
|
}
|
|
1293
1200
|
}
|
|
1294
1201
|
// Build tries array from catch directives
|
|
1202
|
+
// Now using instruction indices directly instead of code unit offsets
|
|
1295
1203
|
const triesByRange = new Map();
|
|
1296
1204
|
for (const catchDirective of catchDirectives) {
|
|
1297
1205
|
// Find the start and end instruction indices
|
|
@@ -1301,44 +1209,53 @@ const smaliExecutableCodeParser = promiseCompose(createTupleParser([
|
|
|
1301
1209
|
invariant(startIndex !== undefined, 'Expected to find start label %s', catchDirective.startLabel);
|
|
1302
1210
|
invariant(endIndex !== undefined, 'Expected to find end label %s', catchDirective.endLabel);
|
|
1303
1211
|
invariant(handlerIndex !== undefined, 'Expected to find handler label %s', catchDirective.handlerLabel);
|
|
1304
|
-
|
|
1305
|
-
const
|
|
1306
|
-
const
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
invariant(handlerAddress !== undefined, 'Expected handler address for index %s', handlerIndex);
|
|
1310
|
-
const instructionCount = endAddress - startAddress;
|
|
1311
|
-
const rangeKey = `${startAddress}-${instructionCount}`;
|
|
1212
|
+
// Use instruction indices directly
|
|
1213
|
+
const startInstructionIndex = startIndex;
|
|
1214
|
+
const instructionCount = endIndex - startIndex;
|
|
1215
|
+
const handlerInstructionIndex = handlerIndex;
|
|
1216
|
+
const rangeKey = `${startInstructionIndex}-${instructionCount}`;
|
|
1312
1217
|
let tryEntry = triesByRange.get(rangeKey);
|
|
1313
1218
|
if (!tryEntry) {
|
|
1314
1219
|
tryEntry = {
|
|
1315
|
-
|
|
1220
|
+
startInstructionIndex,
|
|
1316
1221
|
instructionCount,
|
|
1317
1222
|
handlers: [],
|
|
1318
|
-
|
|
1223
|
+
catchAllInstructionIndex: undefined,
|
|
1319
1224
|
};
|
|
1320
1225
|
triesByRange.set(rangeKey, tryEntry);
|
|
1321
1226
|
}
|
|
1322
1227
|
if (catchDirective.type === undefined) {
|
|
1323
1228
|
// .catchall
|
|
1324
|
-
tryEntry.
|
|
1229
|
+
tryEntry.catchAllInstructionIndex = handlerInstructionIndex;
|
|
1325
1230
|
}
|
|
1326
1231
|
else {
|
|
1327
1232
|
// .catch Type
|
|
1328
1233
|
tryEntry.handlers.push({
|
|
1329
1234
|
type: catchDirective.type,
|
|
1330
|
-
|
|
1235
|
+
handlerInstructionIndex,
|
|
1331
1236
|
});
|
|
1332
1237
|
}
|
|
1333
1238
|
}
|
|
1334
1239
|
const tries = Array.from(triesByRange.values()).map(tryEntry => ({
|
|
1335
|
-
|
|
1240
|
+
startInstructionIndex: tryEntry.startInstructionIndex,
|
|
1336
1241
|
instructionCount: tryEntry.instructionCount,
|
|
1337
1242
|
handler: {
|
|
1338
1243
|
handlers: tryEntry.handlers,
|
|
1339
|
-
|
|
1244
|
+
catchAllInstructionIndex: tryEntry.catchAllInstructionIndex,
|
|
1340
1245
|
},
|
|
1341
1246
|
}));
|
|
1247
|
+
// Build debug info from debug directives
|
|
1248
|
+
// Debug info still uses code unit offsets (addressDiff), so we need to build the mapping
|
|
1249
|
+
// IMPORTANT: Must be done BEFORE deleting branchOffsetIndices, as getOperationSizeInCodeUnits uses it
|
|
1250
|
+
const codeUnitOffsetByInstructionIndex = new Map();
|
|
1251
|
+
let codeUnitOffset = 0;
|
|
1252
|
+
for (let i = 0; i < instructions.length; i++) {
|
|
1253
|
+
codeUnitOffsetByInstructionIndex.set(i, codeUnitOffset);
|
|
1254
|
+
codeUnitOffset += getOperationSizeInCodeUnits(instructions[i]);
|
|
1255
|
+
}
|
|
1256
|
+
codeUnitOffsetByInstructionIndex.set(instructions.length, codeUnitOffset);
|
|
1257
|
+
// Alias for backward compatibility with debug info code
|
|
1258
|
+
const branchOffsetByBranchOffsetIndex = codeUnitOffsetByInstructionIndex;
|
|
1342
1259
|
for (const operation of instructions) {
|
|
1343
1260
|
delete operation.labels;
|
|
1344
1261
|
delete operation.branchOffsetIndex;
|
|
@@ -1603,7 +1520,7 @@ export const smaliMethodParser = promiseCompose(createTupleParser([
|
|
|
1603
1520
|
const insSize = (accessFlags.static ? 0 : 1) + shortyGetInsSize(prototype.shorty);
|
|
1604
1521
|
code.insSize = insSize;
|
|
1605
1522
|
for (const operation of code.instructions) {
|
|
1606
|
-
const smaliRegisters =
|
|
1523
|
+
const smaliRegisters = rawDalvikBytecodeOperationCompanion.getRegisters(operation); // TODO
|
|
1607
1524
|
if (smaliRegisters.length === 0) {
|
|
1608
1525
|
continue;
|
|
1609
1526
|
}
|
|
@@ -1623,7 +1540,7 @@ export const smaliMethodParser = promiseCompose(createTupleParser([
|
|
|
1623
1540
|
if (!operation.operation.startsWith('invoke-')) {
|
|
1624
1541
|
continue;
|
|
1625
1542
|
}
|
|
1626
|
-
const registers =
|
|
1543
|
+
const registers = rawDalvikBytecodeOperationCompanion.getRegisters(operation);
|
|
1627
1544
|
outsSize = Math.max(outsSize, registers.length); // TODO?: two words for wide types?
|
|
1628
1545
|
}
|
|
1629
1546
|
code.outsSize = outsSize;
|