@zsa233/frida-analykit-agent 2.0.0
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/LICENSE +21 -0
- package/README.md +5 -0
- package/package.json +41 -0
- package/src/api/android.ts +80 -0
- package/src/bridges.ts +18 -0
- package/src/cmodule/scan_adrp.c +81 -0
- package/src/cmodule/scan_adrp.ts +118 -0
- package/src/config.ts +56 -0
- package/src/consts.ts +31 -0
- package/src/elf/insn.ts +61 -0
- package/src/elf/module.ts +751 -0
- package/src/elf/struct.ts +271 -0
- package/src/elf/tools.ts +33 -0
- package/src/elf/verifier.ts +74 -0
- package/src/elf/xref.ts +360 -0
- package/src/func.ts +32 -0
- package/src/helper.ts +685 -0
- package/src/index.ts +10 -0
- package/src/jni/env.ts +1439 -0
- package/src/jni/struct.ts +217 -0
- package/src/lib/libc.ts +161 -0
- package/src/lib/libssl.ts +95 -0
- package/src/message.ts +26 -0
- package/src/net/ssl.ts +360 -0
- package/src/net/struct.ts +51 -0
- package/src/net/tools.ts +0 -0
- package/src/process.ts +137 -0
- package/src/rpc.ts +268 -0
- package/src/runtime-globals.d.ts +11 -0
- package/src/utils/array_pointer.ts +102 -0
- package/src/utils/queue.ts +102 -0
- package/src/utils/scan.ts +103 -0
- package/src/utils/std.ts +165 -0
- package/src/utils/text_endec.ts +35 -0
- package/src/utils/utils.ts +111 -0
package/src/utils/std.ts
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { Java } from '../bridges.js'
|
|
2
|
+
import { help, NativePointerObject } from '../helper.js'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export class StdVector extends NativePointerObject {
|
|
6
|
+
private readonly _start: NativePointer
|
|
7
|
+
private readonly _finish: NativePointer
|
|
8
|
+
private readonly _end_of_storage: NativePointer
|
|
9
|
+
|
|
10
|
+
constructor(handle: NativePointer = NULL){
|
|
11
|
+
let shouldDelete = handle.isNull()
|
|
12
|
+
if(handle.isNull()) {
|
|
13
|
+
handle = Memory.alloc(3 * Process.pointerSize)
|
|
14
|
+
}
|
|
15
|
+
super(handle)
|
|
16
|
+
|
|
17
|
+
this._start = this.$handle
|
|
18
|
+
this._finish = this.$handle.add(Process.pointerSize)
|
|
19
|
+
this._end_of_storage = this.$handle.add(Process.pointerSize * 2)
|
|
20
|
+
|
|
21
|
+
if (shouldDelete) {
|
|
22
|
+
const weakRef = ptr(handle.toString())
|
|
23
|
+
Script.bindWeak(this.$handle, () =>{
|
|
24
|
+
Java.api.$delete(weakRef)
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static cast(handle: NativePointer): StdVector {
|
|
30
|
+
return new StdVector(handle)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
get start(): NativePointer {
|
|
34
|
+
return this._start.readPointer()
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
set start(val: NativePointer){
|
|
38
|
+
this._start.writePointer(val)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
get finish(): NativePointer {
|
|
42
|
+
return this._finish.readPointer()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
set finish(val: NativePointer) {
|
|
46
|
+
this._finish.writePointer(val)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
get end_of_storage(): NativePointer {
|
|
50
|
+
return this._end_of_storage.readPointer()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
set end_of_storage(val: NativePointer) {
|
|
54
|
+
this._end_of_storage.writePointer(val)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
get length(): number {
|
|
58
|
+
return this.finish.sub(this.start).toUInt32() / Process.pointerSize
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
get capacity(): number {
|
|
62
|
+
return this.end_of_storage.sub(this.start).toUInt32() / Process.pointerSize
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
[Symbol.iterator](){
|
|
66
|
+
let nextPtr = this.start
|
|
67
|
+
const that = this
|
|
68
|
+
return {
|
|
69
|
+
next(){
|
|
70
|
+
let done = false
|
|
71
|
+
let value = nextPtr
|
|
72
|
+
if(value >= that.finish) {
|
|
73
|
+
done = true
|
|
74
|
+
value = NULL
|
|
75
|
+
}else{
|
|
76
|
+
nextPtr = nextPtr.add(Process.pointerSize)
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
value: value,
|
|
80
|
+
done: done,
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
toArray(): NativePointer[] {
|
|
87
|
+
const list = []
|
|
88
|
+
for(let v of this) {
|
|
89
|
+
list.push(v)
|
|
90
|
+
}
|
|
91
|
+
return list
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
const STD_STRING_MEM_BYTE_SIZE = Process.pointerSize === 4 ? 12 : 24
|
|
97
|
+
const STD_STRING_CAP_LONG_MODE_CAP_MASK = help.androidGetApiLevel() <= 16
|
|
98
|
+
? (Process.pointerSize === 4 ? '0x80000000': '0x8000000000000000')
|
|
99
|
+
: '0x1'
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
export class StdString extends NativePointerObject {
|
|
103
|
+
private readonly _cap: NativePointer
|
|
104
|
+
private readonly _size: NativePointer
|
|
105
|
+
private readonly _data: NativePointer
|
|
106
|
+
|
|
107
|
+
constructor(handle: NativePointer = NULL) {
|
|
108
|
+
if (handle.isNull()) {
|
|
109
|
+
handle = Memory.alloc(STD_STRING_MEM_BYTE_SIZE)
|
|
110
|
+
}
|
|
111
|
+
super(handle)
|
|
112
|
+
|
|
113
|
+
this._cap = this.$handle
|
|
114
|
+
this._size = this.$handle.add(Process.pointerSize)
|
|
115
|
+
this._data = this.$handle.add(Process.pointerSize * 2)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
static cast(handle: NativePointer): StdString {
|
|
119
|
+
return new StdString(handle)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
get size(): number {
|
|
123
|
+
return this.longMode ? this._size.readU64().toNumber() : this.$handle.add(STD_STRING_MEM_BYTE_SIZE - 1).and(0x7F).toUInt32()
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
get data(): ArrayBuffer | null {
|
|
127
|
+
return this._data.readByteArray(this.size)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
get length(): number {
|
|
131
|
+
return this.size
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
get capacity(): number {
|
|
135
|
+
return this.longMode ? this._cap.readU64().toNumber() : this.size
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
get longMode(): boolean {
|
|
139
|
+
return !this._cap.readU64().and(STD_STRING_CAP_LONG_MODE_CAP_MASK).equals(0)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
get stringPtr(): NativePointer {
|
|
143
|
+
if(this.longMode) {
|
|
144
|
+
return this._data.readPointer()
|
|
145
|
+
}else{
|
|
146
|
+
return this.$handle.readPointer()
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
toString(): string {
|
|
151
|
+
return this.stringPtr.readUtf8String(this.size) || ''
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
toCString(): string {
|
|
155
|
+
return this.stringPtr.readCString(this.size) || ''
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
toUtf8String(): string {
|
|
159
|
+
return this.stringPtr.readUtf8String(this.size) || ''
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
toUtf16String(): string {
|
|
163
|
+
return this.stringPtr.readUtf16String(this.size) || ''
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { setGlobalProperties } from "../config.js"
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export class TextEncoder {
|
|
5
|
+
readonly encoding = 'utf-8'
|
|
6
|
+
|
|
7
|
+
encode(input: string): Uint8Array {
|
|
8
|
+
const strPtr = Memory.allocUtf8String(input)
|
|
9
|
+
const eosZeros = Memory.scanSync(strPtr, input.length * 4, "00")
|
|
10
|
+
const blen = eosZeros[0].address.sub(strPtr)
|
|
11
|
+
return new Uint8Array(strPtr.readByteArray(Number(blen))!)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
export class TextDecoder {
|
|
18
|
+
readonly encoding = 'utf-8'
|
|
19
|
+
|
|
20
|
+
decode(input: ArrayBuffer): string {
|
|
21
|
+
if (typeof(input['unwrap']) === 'function') {
|
|
22
|
+
return input.unwrap().readUtf8String() || ''
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const tmp = Memory.alloc(input.byteLength)
|
|
26
|
+
tmp.writeByteArray(input)
|
|
27
|
+
return tmp.readUtf8String() || ''
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
setGlobalProperties({
|
|
33
|
+
TextDecoder,
|
|
34
|
+
TextEncoder,
|
|
35
|
+
})
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
|
|
2
|
+
import { ArrayPointer } from "./array_pointer.js"
|
|
3
|
+
|
|
4
|
+
export function mustType<T>(val: T | null | undefined): T {
|
|
5
|
+
if (!val) {
|
|
6
|
+
throw new Error(`val不能为null`)
|
|
7
|
+
}
|
|
8
|
+
return val
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function unwrapArgs(args: InvocationArguments, n: number): (any|NativePointer)[] {
|
|
12
|
+
const list = []
|
|
13
|
+
for(let i = 0; i < n; i++) {
|
|
14
|
+
list.push(args[i])
|
|
15
|
+
}
|
|
16
|
+
return list
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
type NumberReaderMethod =
|
|
21
|
+
'readU8' |
|
|
22
|
+
'readU16' |
|
|
23
|
+
'readU32' |
|
|
24
|
+
'readU64' |
|
|
25
|
+
'readS8' |
|
|
26
|
+
'readS16' |
|
|
27
|
+
'readS32' |
|
|
28
|
+
'readS64'
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
type BianaryBaseReader<T> = (base: NativePointer | ArrayPointer) => T
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
function binaryNumberReader(offset: number, method: NumberReaderMethod): BianaryBaseReader<number> {
|
|
36
|
+
return function (base: NativePointer | ArrayPointer): number {
|
|
37
|
+
return Number(base.add(offset)[method]())
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function binaryPointerReader(offset: number): BianaryBaseReader<NativePointer> {
|
|
42
|
+
return function (base: NativePointer | ArrayPointer): NativePointer {
|
|
43
|
+
return base.add(offset).readPointer()
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function binaryPointerOffset(offset: number): BianaryBaseReader<NativePointer> {
|
|
48
|
+
return function (base: NativePointer | ArrayPointer): NativePointer {
|
|
49
|
+
return ptr(base.add(offset).toString())
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
function readByteArray(offset: number, length: number) { return (base: NativePointer | ArrayPointer) => mustType(base.add(offset).readByteArray(length)) }
|
|
55
|
+
function binaryReadU8(offset: number) { return binaryNumberReader(offset, 'readU8') }
|
|
56
|
+
function binaryReadU16(offset: number) { return binaryNumberReader(offset, 'readU16') }
|
|
57
|
+
function binaryReadU32(offset: number) { return binaryNumberReader(offset, 'readU32') }
|
|
58
|
+
function binaryReadS32(offset: number) { return binaryNumberReader(offset, 'readS32') }
|
|
59
|
+
function binaryReadU64(offset: number) { return binaryNumberReader(offset, 'readU64') }
|
|
60
|
+
function binaryReadS64(offset: number) { return binaryNumberReader(offset, 'readS64') }
|
|
61
|
+
function binaryReadPointer(offset: number) { return binaryPointerReader(offset) }
|
|
62
|
+
function binaryPointer(offset: number) { return binaryPointerOffset(offset) }
|
|
63
|
+
function binaryReadPointerStruct(offset: number, structOfs: { B64: { [key: string]: BianaryBaseReader<any> }, B32?: { [key: string]: BianaryBaseReader<any> } }) {
|
|
64
|
+
return function (base: NativePointer | ArrayPointer): { [key: string]: any } {
|
|
65
|
+
const structOf = Process.pointerSize === 4 ? structOfs['B32'] : structOfs['B64']
|
|
66
|
+
const structBase = binaryPointerReader(offset)(base)
|
|
67
|
+
const obj: { [key: string]: any } = {}
|
|
68
|
+
for (let [k, offseter] of Object.entries(structOf!)) {
|
|
69
|
+
Object.defineProperty(obj, k, {
|
|
70
|
+
value: offseter(structBase),
|
|
71
|
+
writable: false,
|
|
72
|
+
enumerable: true,
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
return obj
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export {
|
|
80
|
+
readByteArray,
|
|
81
|
+
binaryReadU8,
|
|
82
|
+
binaryReadU16,
|
|
83
|
+
binaryReadU32,
|
|
84
|
+
binaryReadS32,
|
|
85
|
+
binaryReadU64,
|
|
86
|
+
binaryReadS64,
|
|
87
|
+
binaryReadPointer,
|
|
88
|
+
binaryPointer,
|
|
89
|
+
binaryReadPointerStruct,
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
export function wrapArgTypes(typ: NativeFunctionArgumentType, length: number): NativeFunctionArgumentType[] {
|
|
95
|
+
return Array.from({ length: length }, () => typ)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
export function arrayBuffer2Hex(
|
|
100
|
+
buffer: ArrayBuffer,
|
|
101
|
+
options: { uppercase?: boolean } = {}
|
|
102
|
+
): string {
|
|
103
|
+
const { uppercase = false } = options
|
|
104
|
+
const bytes = new Uint8Array(buffer)
|
|
105
|
+
return Array.from(bytes)
|
|
106
|
+
.map(b => {
|
|
107
|
+
const hex = b.toString(16).padStart(2, '0')
|
|
108
|
+
return uppercase ? hex.toUpperCase() : hex
|
|
109
|
+
})
|
|
110
|
+
.join(' ')
|
|
111
|
+
}
|