frida3(看书1)

function main(){
Java.perform(function(){
hookTest1();
})
}
setTimeout(main)

1
这个代码片段定义了一个名为`main`的函数,然后使用`setTimeout`函数将`main`函数作为回调函数延迟执行。当定时器到期时,`main`函数将被调用。在`main`函数内部,使用`Java.perform`执行了一个匿名函数,并在该匿名函数中调用了`hookTest1`函数。

setTimeout(
function(){
Java.perform(function(){
hookTest1()
})
}
)

1
这个代码片段直接使用`setTimeout`函数,并将一个匿名函数作为回调函数传递给`setTimeout`。当定时器到期时,该匿名函数将被调用。在匿名函数内部,使用`Java.perform`执行了另一个匿名函数,并在该匿名函数中调用了`hookTest1`函数

两个代码片段的主要区别在于函数的定义和执行时机。第一个代码片段在main函数中定义了另一个匿名函数,然后将main函数传递给setTimeout,从而延迟执行了整个main函数。而第二个代码片段直接将匿名函数传递给setTimeout,省略了中间的main函数定义。因此,第一个代码片段具有一个命名的入口函数main,而第二个代码片段直接使用匿名函数作为入口函数。

另外需要注意的是,第一个代码片段中的setTimeout(main)应该在函数名main后面加上括号来立即执行main函数,即setTimeout(main())

tips:回调函数

回调函数是指在某个操作完成或事件发生时,通过将一个函数作为参数传递给其他函数,以便在适当的时机调用该函数。

在JavaScript中,回调函数常用于异步编程,以处理异步操作的结果或事件的发生。当异步操作完成时,回调函数会被调用,并传递相应的参数。

以下是一个简单的示例,演示了回调函数的使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 定义一个执行异步操作的函数,接受一个回调函数作为参数
function fetchData(callback) {
// 模拟异步操作
setTimeout(function() {
const data = '这是获取的数据';
// 异步操作完成后调用回调函数,并将结果作为参数传递
callback(data);
}, 2000);
}

// 定义一个回调函数,用于处理异步操作的结果
function handleData(data) {
console.log('处理数据:', data);
}

// 调用fetchData函数,并传递handleData函数作为回调函数
fetchData(handleData);

在上述示例中,fetchData函数执行一个模拟的异步操作,并在操作完成后调用传递的回调函数。handleData函数作为回调函数传递给fetchData函数,它用于处理异步操作返回的数据。

通过使用回调函数,我们可以在异步操作完成后执行特定的代码逻辑,以便处理结果或触发其他操作。这种方式可以避免阻塞代码执行,并充分利用异步操作的特性。

java主动调用(hook)

  1. tips:
    
    1.栈(Stack):
       栈内存用于存储方法调用和局部变量。每个线程在执行方法时,都会在栈上创建一个栈帧(Stack Frame),栈帧包含了方法的参数、局部变量以及方法调用和返回的信息。栈是一种后进先出(LIFO)的数据结构,方法的调用和返回遵循栈的顺序。当方法执行结束时,对应的栈帧会被销毁。
    
    2. 堆(Heap):
       堆内存用于存储对象实例。在堆中分配的内存可以动态地分配和释放,允许对象的创建、销毁和动态修改。堆内存由垃圾回收器负责管理,当对象不再被引用时,垃圾回收器会自动回收该对象所占用的内存空间。
    
    3. 方法区(Method Area):
       方法区用于存储类的结构信息、常量、静态变量和编译后的代码等。它是所有线程共享的内存区域,存储了应用程序中所有类的元数据信息。方法区也称为永久代(Permanent Generation),在早期版本的Java中,永久代用于存储类的元数据。从Java 8开始,永久代被元数据区(Metaspace)取代,但是概念上仍然可以将方法区看作是存储类的结构信息的区域。
    
    4. 本地方法栈(Native Method Stack):
       本地方法栈与栈类似,但是它用于存储本地方法(Native Method)的调用和执行信息。本地方法是使用其他语言(如C、C++)编写的方法,通过Java Native Interface(JNI)与Java代码进行交互。本地方法栈的功能与栈类似,但是用于本地方法的调用。
    
    5. PC寄存器(Program Counter Register):
       PC寄存器用于存储当前线程执行的字节码指令的地址。每个线程都有自己的PC寄存器,用于保存线程执行的当前位置。PC寄存器在线程切换时起到重要的作用,确保线程能够正确恢复执行。
       除了上述常见的内存区域,还有一些其他的内存区域,如直接内存(Direct Memory)用于存储通过NIO(New I/O)库进行的直接内存操作。
    

两种方法:类函数,实例函数

类函数(静态):主动调用直接Java.use()

实例函数(动态):java.choose(),能够在java堆里面寻找指定函数

image-20231126210514176

RPC调用

image-20231126213308494

在确认我们的函数都没有写错且功能达到预期后,接下来我们开 始RPC远程调用。将CallSecretFunc()函数和getTotalValue()函数导 出,使得外部可以进行调用,在JavaScript代码末尾加上RPC相关代 码

image-20231126213447215

image-20231126213506803