0e35e41121
Changes include:
* Added a couple no-such-method decoders.
* Apply deobfuscation rules more than once per line
* Fixed pattern matched for minified names.
* Added support for expanding the call signature from call selectors
* Fix backward search to find the function declaration
* Refactor trace deobfuscation logic:
* add dependency on stack\_trace to parse frames
* add library to expose trace deobfsucation and keep that separate from
printing the results
* Fix off-by-one error when extracting the name of a function whose index is 0.
* Avoid crash if we can't get a function name.
Change-Id: I016a293efadbdd8ddf66a007b182d5485eb2311f
Reviewed-on: https://dart-review.googlesource.com/c/82711
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Auto-Submit: Sigmund Cherem <sigmund@google.com>
60 lines
2.6 KiB
Dart
60 lines
2.6 KiB
Dart
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
/// Utility functions to make it easier to work with source-map files.
|
|
import 'package:source_span/source_span.dart';
|
|
import 'package:source_maps/source_maps.dart';
|
|
import 'package:source_maps/src/utils.dart';
|
|
import 'util.dart' show FileProvider;
|
|
|
|
/// Search backwards in [sources] for a function declaration that includes the
|
|
/// [start] offset.
|
|
TargetEntry findEnclosingFunction(FileProvider provider, Uri uri, int start) {
|
|
String sources = provider.sourcesFor(uri);
|
|
if (sources == null) return null;
|
|
SourceFile file = provider.fileFor(uri);
|
|
SingleMapping mapping = provider.mappingFor(uri).sourceMap;
|
|
int index = start;
|
|
while (true) {
|
|
index = sources.lastIndexOf('function', index);
|
|
if (index < 0) return null;
|
|
var line = file.getLine(index);
|
|
var lineEntry = findLine(mapping, line);
|
|
var column = file.getColumn(index);
|
|
TargetEntry result = findColumn(line, column, lineEntry);
|
|
// If the name entry doesn't start exactly at the column corresponding to
|
|
// `index`, we must be in the middle of a string or code that uses the word
|
|
// "function", but that doesn't have a corresponding mapping. In those
|
|
// cases, we keep searching backwards until we find the actual definition of
|
|
// a function.
|
|
if (result?.column == column) return result;
|
|
index--;
|
|
}
|
|
}
|
|
|
|
/// Returns [TargetLineEntry] which includes the location in the target [line]
|
|
/// number. In particular, the resulting entry is the last entry whose line
|
|
/// number is lower or equal to [line].
|
|
///
|
|
/// Copied from [SingleMapping._findLine].
|
|
TargetLineEntry findLine(SingleMapping sourceMap, int line) {
|
|
int index = binarySearch(sourceMap.lines, (e) => e.line > line);
|
|
return (index <= 0) ? null : sourceMap.lines[index - 1];
|
|
}
|
|
|
|
/// Returns [TargetEntry] which includes the location denoted by
|
|
/// [line], [column]. If [lineEntry] corresponds to [line], then this will be
|
|
/// the last entry whose column is lower or equal than [column]. If
|
|
/// [lineEntry] corresponds to a line prior to [line], then the result will be
|
|
/// the very last entry on that line.
|
|
///
|
|
/// Copied from [SingleMapping._findColumn].
|
|
TargetEntry findColumn(int line, int column, TargetLineEntry lineEntry) {
|
|
if (lineEntry == null || lineEntry.entries.length == 0) return null;
|
|
if (lineEntry.line != line) return lineEntry.entries.last;
|
|
var entries = lineEntry.entries;
|
|
int index = binarySearch(entries, (e) => e.column > column);
|
|
return (index <= 0) ? null : entries[index - 1];
|
|
}
|