FRIDA-API使用篇

frida中有五种对象,分别是Java、Interceptor、NativePointer、NativeFunction、NativeCallback对象

这些都是在编写frida脚本的时候会用到的对象以及对应的函数。

frida知识更多的学习,可以查看这些文章

Java对象

无论是想对so层亦或java层进行拦截,都必须编写Java.perform,java对象是很重要的

附加调用Java.perform

Java.perform(fn)主要用于当前线程附加到Java VM并且调用fn方法。该API是非常重要的

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
unction frida_Java() {
//运行当前js脚本时会对当前线程附加到Java VM虚拟机,并且执行function方法
Java.perform(function () {
//判断是否Java VM正常运行
if(Java.available)
{
//如不意外会直接输出 hello
console.log("hello");
}else{
console.log("error");
}
});
}
setImmediate(frida_Java,0);

输出如下。
[Google Pixel::com.roysue.roysueapplication]-> hello

判断加载Java.available

该函数一般用来判断当前进程是否加载了**JavaVM,DalvikART虚拟机**

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function frida_Java() {
Java.perform(function () {
//作为判断用
if(Java.available)
{
//注入的逻辑代码
console.log("hello java vm");
}else{
//未能正常加载JAVA VM
console.log("error");
}
});
}
setImmediate(frida_Java,0);

输出如下。
hello java vm

版本号Java.androidVersion

显示android系统版本号

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function frida_Java() {
Java.perform(function () {
//作为判断用
if(Java.available)
{
//注入的逻辑代码
console.log("",Java.androidVersion);
}else{
//未能正常加载JAVA VM
console.log("error");
}
});
}
setImmediate(frida_Java,0);

获取类Java.use

Java.use(className),动态获取className的类定义,通过对其调用$new()来调用构造函数,可以从中实例化对象。当想要回收类时可以调用$Dispose()方法显式释放,当然也可以等待JavaScript的垃圾回收机制,当实例化一个对象之后,可以通过其实例对象调用类中的静态或非静态的方法

示例:

1
2
3
4
5
6
7
8
9
10
11
Java.perform(function () {
//获取android.app.Activity类
var Activity = Java.use('android.app.Activity');
//获取java.lang.Exception类
var Exception = Java.use('java.lang.Exception');
//拦截Activity类的onResume方法
Activity.onResume.implementation = function () {
//调用onResume方法的时候,会在此处被拦截并且调用以下代码抛出异常!
throw Exception.$new('Oh noes!');
};
});

枚举类Java.enumerateLoadedClasses

该API枚举当前加载的所有类信息,它有一个回调函数分别是onMatch、onComplete函数

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
function frida_Java() {
Java.perform(function () {
if(Java.available)
{
//console.log("",Java.androidVersion);
//枚举当前加载的所有类
Java.enumerateLoadedClasses({
//每一次回调此函数时其参数className就是类的信息
onMatch: function (className)
{
//输出类字符串
console.log("",className);
},
//枚举完毕所有类之后的回调函数
onComplete: function ()
{
//输出类字符串
console.log("输出完毕");
}
});
}else{
console.log("error");
}
});
}
setImmediate(frida_Java,0);

扫描实例类Java.choose

在堆上查找实例化的对象,实例化对象的意思就是用这个类创建的一个对象(如同人这个类中的叫小明的这个人)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Java.perform(function () {
//查找android.view.View类在堆上的实例化对象
Java.choose("android.view.View", {
//枚举时调用
onMatch:function(instance){
//打印实例
console.log(instance);
},
//枚举完成后调用
onComplete:function() {
console.log("end")
}});
});

输出如下:
android.view.View{2292774 V.ED..... ......ID 0,1794-1080,1920 #1020030 android:id/navigationBarBackground}
android.view.View{d43549d V.ED..... ......ID 0,0-1080,63 #102002f android:id/statusBarBackground}
end

类型转换器Java.cast

使用 Java.cast(object,Class) 可以转换一个对象的类型。通常在拦截so层时会使用此函数将jstring、jarray等等转换之后查看其值。

示例:

1
2
3
4
5
6
7
8
9
10
11
Java.performNow(function () {
var Student = Java.use('com.example.myapplication.Student');
var student = Student.$new('田所浩二',24);
console.log(student.class);
//将Student类对象强制转化成Object类对象
student = Java.cast(student,Java.use("java.lang.Object"));
console.log(student.class);
//将上面强制转换成的Object类对象转换成Student类对象
student = Java.cast(student,Student);
console.log(student.class);
});

定义任意数组类型Java.array

frida提供了在js代码中定义java数组的api,该数组可以用于传递给java API。定义格式为Java.array('type',[value1,value2,....]);

示例:

1
2
3
4
5
6
7
8
9
10
11
Java.perform(function () {
//定义一个int数组、值是1003, 1005, 1007
var intarr = Java.array('int', [ 1003, 1005, 1007 ]);
//定义一个byte数组、值是0x48, 0x65, 0x69
var bytearr = Java.array('byte', [ 0x48, 0x65, 0x69 ]);
for(var i=0;i<bytearr.length;i++)
{
//输出每个byte元素
console.log(bytearr[i])
}
});

Java.vm对象

Java.vm对象十分常用,比如想要拿到JNI层的JNIEnv对象,可以使用**getEnv()**。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function frida_Java() {     
Java.perform(function () {
//拦截getStr函数
Interceptor.attach(Module.findExportByName("libhello.so" , "Java_com_roysue_roysueapplication_hellojni_getStr"), {
onEnter: function(args) {
console.log("getStr");
},
onLeave:function(retval){
//它的返回值的是retval 在jni层getStr的返回值的jstring
//我们在这里做的事情就是替换掉结果
//先获取一个Env对象
var env = Java.vm.getEnv();
//通过newStringUtf方法构建一个jstirng字符串
var jstring = env.newStringUtf('roysue');
//replace替换掉结果
retval.replace(jstring);
console.log("getSum方法返回值为:roysue")
}
});
}
setImmediate(frida_Java,0);

Interceptor对象

函数原型是**Interceptor.attach(target, callbacks)**:

target参数:是需要拦截的位置的函数地址,也就是填某个**so层函数的地址即可对其拦截,target是一个NativePointer参数**,用来指定你想要拦截的函数的地址,NativePointer是一个指针(下面有对NativePointer的说明);对于Thumb函数需要对函数地址+1

callbacks参数:它的回调函数,有两个onEnter: function (args) 和 onLeave: function (retval)函数

Interceptor.attach

两个回调函数

  • onEnter:函数(args):回调函数,给定一个参数args,可用于读取或写入参数作为 NativePointer 对象的数组。

  • onLeave:函数(retval):回调函数给定一个参数 retval,该参数是包含原始返回值的 NativePointer 派生对象。可以调用 retval.replace(1337) 以整数 1337 替换返回值,或者调用 retval.replace(ptr("0x1234"))以替换为指针。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
//使用Module对象getExportByNameAPI直接获取libc.so中的导出函数read的地址,对read函数进行附加拦截
Interceptor.attach(Module.getExportByName('libc.so', 'read'), {
//每次read函数调用的时候会执行onEnter回调函数
onEnter: function (args) {
this.fileDescriptor = args[0].toInt32();
},
//read函数执行完成之后会执行onLeave回调函数
onLeave: function (retval) {
if (retval.toInt32() > 0) {
/* do something with this.fileDescriptor */
}
}
});

Interceptor.attach函数的一些属性

  • returnAddress 返回地址,类型是NativePointer
    threadId 操作系统线程ID
    context 上下文:具有键pcsp的对象,它们是分别为ia32/x64/arm指定EIP/RIP/PCESP/RSP/SP的NativePointer对象。其他处理器特定的键也可用,例如eax、rax、r0、x0等。也可以通过分配给这些键来更新寄存器值。
    errno 当前errno
    lastError 当前操作系统错误值
    depth 相对于其他调用的调用深度

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Interceptor.attach(Module.findExportByName("libhello.so" , "Java_com_roysue_roysueapplication_hellojni_getSum"), {
onEnter: function(args) {
//输出
console.log('Context information:');
//输出上下文因其是一个Objection对象,需要它进行接送、转换才能正常看到值
console.log('Context : ' + JSON.stringify(this.context));
//输出返回地址
console.log('Return : ' + this.returnAddress);
//输出线程id
console.log('ThreadId : ' + this.threadId);
console.log('Depth : ' + this.depth);
console.log('Errornr : ' + this.err);
},
onLeave:function(retval){
}
});

Interceptor.detachAll

简单来说这个的函数的作用就是让之前所有的Interceptor.attach附加拦截的回调函数失效

Interceptor.replace

相当于替换掉原本的函数,用替换时的实现替换目标处的函数。如果想要完全或部分替换现有函数的实现,则通常使用此函数。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function frida_Interceptor() {
Java.perform(function () {
//这个c_getSum方法有两个int参数、返回结果为两个参数相加
//这里用NativeFunction函数自己定义了一个c_getSum函数
var add_method = new NativeFunction(Module.findExportByName('libhello.so', 'c_getSum'),
'int',['int','int']);
//输出结果 那结果肯定就是 3
console.log("result:",add_method(1,2));
//这里对原函数的功能进行替换实现
Interceptor.replace(add_method, new NativeCallback(function (a, b) {
//h不论是什么参数都返回123
return 123;
}, 'int', ['int', 'int']));
//再次调用 则返回123
console.log("result:",add_method(1,2));
});
}

NativePointer对象

同等与C语言中的指针

new NativePointer(s)

声明定义NativePointer类型

1
2
const ptr1 = new NativePointer("100");
console.log("ptr1:",ptr1);

运算符以及指针读写API

这里有个表,可以用这个指针对这些API进行调用

img

img

示例:

1
2
3
4
// 用readByteArray函数来读取libc.so文件在内存中的数据
var pointer = Process.findModuleByName("libc.so").base;
//读取从pointer地址开始的16个字节 (从libc文件读取0x10个字节的长度)
console.log(pointer.readByteArray(0x10));

上面这些API的调用的部分示例可以查看这篇文章中的NativePointer对象这个部分

NativeFunction对象

作用:调用address处的函数(用NativePointer指定)

函数定义格式:new NativeFunction(address, returnType, argTypes[, options])

  • returnType和argTypes[,]中能够填写的数据类型:void、pointer、int、uint、long、ulong、char、uchar、float、double、int8、uint8、int16、uint16、int32、uint32、int64、uint64这些类型。假设有三个参数都是int,则new NativeFunction(address, returnType, [‘int’, ‘int’, ‘int’])
  • 定义的时候必须要将参数类型个数参数类型以及返回值完全匹配。
  • 并且第一个参数一定要是函数地址指针

示例:

1
2
3
4
5
6
7
8
// LargeObject HandyClass::friendlyFunctionName();
//创建friendlyFunctionPtr地址的函数
var friendlyFunctionName = new NativeFunction(friendlyFunctionPtr,
'void', ['pointer', 'pointer']);
//申请内存空间
var returnValue = Memory.alloc(sizeOfLargeObject);
//调用friendlyFunctionName函数
friendlyFunctionName(returnValue, thisPtr);

NativeCallback对象

作用:创建一个回调函数

函数定义格式:new NativeCallback(func,rereturn Type,argTypes[,ABI])

  • func参数:由JavaScript函数实现的函数
  • rereturn Type指定返回类型,argTypes数组指定参数类型

当将产生的回调与Interceptor.replace()一起使用时,将调用func,并将其绑定到具有一些有用属性的对象,就像Interceptor.Attach()中的那样

示例:

1
2
3
4
5
6
7
8
9
10
11
Java.perform(function () {
//替换对象的函数指针
var add_method = new NativeFunction(Module.findExportByName('libhello.so', 'c_getSum'),
'int',['int','int']);
console.log("result:",add_method(1,2));
//在这里new一个新的函数,但是参数的个数和返回值必须对应
Interceptor.replace(add_method, new NativeCallback(function (a, b) {
return 123;
}, 'int', ['int', 'int']));
console.log("result:",add_method(1,2));
});

使用java.perform()中写入js脚本

使用Module对象获得一些so文件的地址信息

利用so文件的地址信息使用NativeFunction 得到so文件之中的对象,再使用Interceptor对象的API,对相应的函数进行一定的操作

运行这个函数,设置这个函数的输入的参数,设置这个函数的返回的参数

FRIDA-API使用篇:rpc、Process、Module、Memory

这里对frida官方的一些非常常用的API进行介绍

FRIDA输出打印

在官方API有两种打印的方式,分别是consolesend

console输出

FRIDAconsole中有三个级别分别是log、warn、error。一般在使用中我们只会使用log来输出想看的值。

1
2
3
4
5
6
7
8
9
function hello_printf() {
Java.perform(function () {
console.log("");
console.log("hello-log");
console.warn("hello-warn");
console.error("hello-error");
});
}
setImmediate(hello_printf,0);

console之hexdump

hexdump的含义:打印内存中的地址,target参数可以是ArrayBuffer或者NativePointer,而options参数则是自定义输出格式可以填这几个参数offset、lengt、header、ansi

示例:

1
2
3
4
5
6
7
var libc = Module.findBaseAddress('libc.so');
console.log(hexdump(libc, {
offset: 0,
length: 64,
header: true,
ansi: true
}));

执行效果:

1
2
3
4
5
           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 .ELF............
00000010 03 00 28 00 01 00 00 00 00 00 00 00 34 00 00 00 ..(.........4...
00000020 34 a8 04 00 00 00 00 05 34 00 20 00 08 00 28 00 4.......4. ...(.
00000030 1e 00 1d 00 06 00 00 00 34 00 00 00 34 00 00 00 ........4...4...

send

原理:send是在python层定义的on_message回调函数,jscode内所有的信息都被监控script.on(‘message’, on_message),当输出信息的时候on_message函数会拿到其数据再通过format转换、

输出效果:能够直接将数据以**json格式**输出,当然数据是二进制的时候也依然是可以使用send

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import frida
import sys

def on_message(message, data):
if message['type'] == 'send':
print("[*] {0}".format(message['payload']))
else:
print(message)

jscode = """
Java.perform(function ()
{
var jni_env = Java.vm.getEnv();
console.log(jni_env);
send(jni_env);
});
"""

process = frida.get_usb_device().attach('com.roysue.roysueapplication')
script = process.create_script(jscode)
script.on('message', on_message)
script.load()
sys.stdin.read()

效果:

1
2
3
roysue@ubuntu:~/Desktop/Chap09$ python Chap03.py 
[object Object]
[*] {'handle': '0xdf4f8000', 'vm': {}}

FRIDA变量类型

在脚本之中如何声明变量类型。以及fridaInt64(v)提供了一些相关的API的使用

声明变量类型

索引 API 含义
1 new Int64(v) 定义一个有符号Int64类型的变量值为v,参数v可以是字符串或者以0x开头的的十六进制值
2 new UInt64(v) 定义一个无符号Int64类型的变量值为v,参数v可以是字符串或者以0x开头的的十六进制值
3 new NativePointer(s) 定义一个指针,指针地址为s
4 ptr(“0”) 同上

示例:

1
2
3
4
5
6
7
Java.perform(function () {
console.log("");
console.log("new Int64(1):"+new Int64(1));
console.log("new UInt64(1):"+new UInt64(1));
console.log("new NativePointer(0xEC644071):"+new NativePointer(0xEC644071));
console.log("new ptr('0xEC644071'):"+new ptr(0xEC644071));
});

Int64(v)使用的API

索引 API 含义
1 add(rhs)、sub(rhs)、and(rhs)、or(rhs)、xor(rhs) 加、减、逻辑运算
2 shr(N)、shl(n) 向右/向左移位n位生成新的Int64
3 Compare(Rhs) 返回整数比较结果
4 toNumber() 转换为数字
5 toString([radix=10]) 转换为可选基数的字符串(默认为10)

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function hello_type() {
Java.perform(function () {
console.log("");
//8888 + 1 = 8889
console.log("8888 + 1:"+new Int64("8888").add(1));
//8888 - 1 = 8887
console.log("8888 - 1:"+new Int64("8888").sub(1));
//8888 << 1 = 4444
console.log("8888 << 1:"+new Int64("8888").shr(1));
//8888 == 22 = 1 1是false
console.log("8888 == 22:"+new Int64("8888").compare(22));
//转string
console.log("8888 toString:"+new Int64("8888").toString());
});
}

Process对象

介绍以及使用一些Process对象中比较常用的api

Process.id

Process.id:返回附加目标进程的PID

Process.isDebuggerAttached()

检测当前是否对目标程序已经附加

Process.enumerateModules()

枚举当前加载的模块,返回模块对象的数组。会枚举当前所有已加载的so模块,并且返回了数组Module对象。

枚举得到的每个module对象,再使用每个module对象进行操作

1
2
3
4
5
6
7
8
9
function frida_Process() {
Java.perform(function () {
var process_Obj_Module_Arr = Process.enumerateModules();
for(var i = 0; i < process_Obj_Module_Arr.length; i++) {
console.log("",process_Obj_Module_Arr[i].name);//这里使用了module的name属性
}
});
}
setImmediate(frida_Process,0);

Process.enumerateThreads()

枚举当前所有的线程,返回包含以下属性的对象数组:

索引 属性 含义
1 id 线程id
2 state 当前运行状态有running, stopped, waiting, uninterruptible or halted
3 context 带有键pc和sp的对象,它们是分别为ia32/x64/arm指定EIP/RIP/PC和ESP/RSP/SP的NativePointer对象。也可以使用其他处理器特定的密钥,例如eax、rax、r0、x0等。

Process.getCurrentThreadId()

获取此线程的操作系统特定 ID 作为数字

Module对象

获得程序中函数 类等的一些信息的时候(基地址,偏移地址等)就会用到这个对象

Module对象的属性

索引 属性 含义
1 name 模块名称
2 base 模块地址,其变量类型为NativePointer
3 size 大小
4 path 完整文件系统路径

Module对象的API

索引 API 含义
1 Module.load() 加载指定so文件,返回一个Module对象
2 enumerateImports() 枚举所有Import库函数,返回Module数组对象
3 enumerateExports() 枚举所有Export库函数,返回Module数组对象
4 enumerateSymbols() 枚举所有Symbol库函数,返回Module数组对象
5 Module.findExportByName(exportName)、Module.getExportByName(exportName) 寻找指定so中export库中的函数地址
6 Module.findBaseAddress(name)、Module.getBaseAddress(name) 返回so的基地址

enumerateImports()

该API会枚举模块中所有中的所有Import函数

1
2
const hooks = Module.load('libhello.so');
var Imports = hooks.enumerateImports();//再遍历这个得到的枚举数组

enumerateExports()

该API会枚举模块中所有中的所有Export函数

1
2
const hooks = Module.load('libhello.so');
var Exports = hooks.enumerateExports();

enumerateSymbols()

该API会枚举模块中所有中的所有symbols 符号,使用symbols 符号可以定位native方法。返回的是一个数组对象

1
2
const hooks = Module.load('libc.so');
var Symbol = hooks.enumerateSymbols();

Module.findExportByName(exportName), Module.getExportByName(exportName)

返回so文件中Export函数库中函数名称为**exportName函数绝对地址**

这个方法只适用于Export函数

1
2
3
4
5
6
Module.getExportByName('libhello.so', 'c_getStr')

console.log("Java_com_roysue_roysueapplication_hellojni_getStraddress:",Module.findExportByName('libhello.so', 'Java_com_roysue_roysueapplication_hellojni_getStr'));

console.log("Java_com_roysue_roysueapplication_hellojni_getStraddress:",Module.getExportByName('libhello.so', 'Java_com_roysue_roysueapplication_hellojni_getStr'));

Module.findBaseAddress(name)、Module.getBaseAddress(name)

返回name模块的基地址

示例:

1
2
3
var name = "libhello.so";
console.log("so address:",Module.findBaseAddress(name));
console.log("so address:",Module.getBaseAddress(name));

Memory对象

Memory的一些API的作用:通常是对内存处理,譬如Memory.copy()复制内存

Memory.scan搜索内存数据

功能:搜索内存中以address地址开始,搜索长度为size,需要搜是条件是pattern,callbacks搜索之后的回调函数

格式:Memory.scan(module.base, module.size, pattern,callbacks)

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Java.perform(function () {
//先获取so的module对象
var module = Process.findModuleByName("libhello.so");
//??是通配符
var pattern = "03 49 ?? 50 20 44";
//基址
console.log("base:"+module.base)
//从so的基址开始搜索,搜索大小为so文件的大小,搜指定条件03 49 ?? 50 20 44的数据
var res = Memory.scan(module.base, module.size, pattern, {
onMatch: function(address, size){
//搜索成功
console.log('搜索到 ' +pattern +" 地址是:"+ address.toString());
},
onError: function(reason){
//搜索失败
console.log('搜索失败');
},
onComplete: function()
{
//搜索完毕
console.log("搜索完毕")
}
});
});

内存分配Memory.alloc

作用:在目标进程中的堆上申请size大小的内存,并且会按照Process.pageSize对齐,返回一个NativePointer,并且申请的内存如果在JavaScript里面没有对这个内存的使用的时候会自动释放的。

1
2
3
4
5
6
7
const r = Memory.alloc(10);
console.log(hexdump(r, {
offset: 0,
length: 10,
header: true,
ansi: false
}));

内存复制Memory.copy

示例:

1
2
3
4
//申请一个内存空间大小为10个字节
const r = Memory.alloc(10);
//复制以module.base地址开始的10个字节 那肯定会是7F 45 4C 46...因为一个ELF文件的Magic属性如此。
Memory.copy(r,module.base,10);

写入内存Memory.writeByteArray’

将字节数组写入一个指定内存

示例:

1
2
3
4
5
6
//定义需要写入的字节数组 这个字节数组是字符串"roysue"的十六进制
var arr = [ 0x72, 0x6F, 0x79, 0x73, 0x75, 0x65];
//申请一个新的内存空间 返回指针 大小是arr.length
const r = Memory.alloc(arr.length);
//将arr数组写入R地址中
Memory.writeByteArray(r,arr);

读取内存Memory.readByteArray

这个函数的第一个参数传入的是 NativePointer 类型的地址指针

1
2
//读取r指针,长度是arr.length 也就是会打印上面一样的值
var buffer = Memory.readByteArray(r, arr.length);

参考文章:FRIDA-API使用篇:rpc、Process、Module、Memory使用方法及示例 - 安全客

frida的so函数hook

so文件之中的函数有导出函数和非导出函数,导出函数打开IDA后能够在导出表中找到的函数就是导出函数,未导出函数则在导出表中寻找不到。一般来说静态编写的native函数都能在导出表中寻找到,而动态加载的则无法在导出表中发现

在IDA的Exports页面之中查看导出函数窗口

示例:

image-20220315233226275

导出函数hook:导出函数窗口可以看到导出函数的函数名,偏移量 。导出函数的hook可以通过函数名或者偏移量

非导出函数hook:只能通过地址hook。定位到函数的位置,直接看它的偏移量即可

通过函数地址获取指定 so 文件的函数

函数地址 = so基地址 + 函数偏移(如果Thumb 指令, hook 的偏移地址需要进行 +1 操作)

IDA 判断 Thumb 指令集和 Arm指令集

  • IDA - Options - General - number of opcode bytes - 设置为 4
  • 此时查看 IDA VIew 中 opcode 的长度, 如果出现 2 个字节4 个字节的, 说明为 thumb 指令集
  • 如果都是 4 个字节的, 说明是 arm 指令集;
  • 在 Thumb 指令集下, inline hook 的偏移地址需要进行 +1 操作;
1
2
3
4
5
var str_name_so = "libjnitest.so";    //需要hook的so名
var n_addr_func_offset = 0x00000680; //需要hook的函数的偏移
var n_addr_so = Module.findBaseAddress(str_name_so); //加载到内存后 函数地址 = so地址 + 函数偏移
var n_addr_func = parseInt(n_addr_so, 16) + n_addr_func_offset;
var ptr_func = new NativePointer(n_addr_func);

通过函数名获取指定 so 文件的函数

1
var ptr_func = Module.findExportByName("libjnitest.so","test_add") //对函数名hook

通过 symbols 符号定位 native 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    var NewStringUTF_addr = null;
var symbols = Process.findModuleByName("libart.so").enumerateSymbols(); //使用enumerateSymbols()函数得到所有的symbols 然后对symbols中所有的对象进行遍历,然后判断语句获得目标函数的地址
for (var i in symbols) {
var symbol = symbols[i];
if (symbol.name.indexOf("art") >= 0 &&
symbol.name.indexOf("JNI") >= 0 &&
symbol.name.indexOf("CheckJNI") < 0
){
if (symbol.name.indexOf("NewStringUTF") >= 0) {
console.log("find target symbols", symbol.name, "address is ", symbol.address);
NewStringUTF_addr = symbol.address;
}
}
}

console.log("NewStringUTF_addr is ", NewStringUTF_addr);
//得到函数地址之后 使用这个函数地址attach
Interceptor.attach(NewStringUTF_addr, {
onEnter: function (args) {
},
onLeave: function (returnResult) {
}
})

通过 Intercept 拦截器打印 native 方法参数和返回值, 并修改返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var add_c_addr = Module.findExportByName("libnative-lib.so", "add_c");
console.log("add_c_addr is :",add_c_addr);
// 添加拦截器
Interceptor.attach(add_c_addr,{
// 打印入参
onEnter: function (args) {
console.log("add_c called");
console.log("arg1:",args[0].toInt32());
console.log("arg2", args[1].toInt32());
},
// 打印返回值
onLeave: function (returnValue) {
console.log("add_c result is :", returnValue.toInt32());
// 修改返回值
returnValue.replace(100);
}
})

获取指定 so 文件的基地址

1
2
var baseAddr = Module.findBaseAddress("libnative-lib.so");
console.log("baseAddr", baseAddr);

Hook修改native层函数返回值为int类型的情况

使用replace()函数直接修改即可

frida脚本示例:

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
import frida
import sys

jscode = """
Java.perform(function(){
var str_name_so = "libjnitest.so"; //需要hook的so名
var n_addr_func_offset = 0x00000680; //需要hook的函数的偏移
var n_addr_so = Module.findBaseAddress(str_name_so); //加载到内存后 函数地址 = so地址 + 函数偏移
var n_addr_func = parseInt(n_addr_so, 16) + n_addr_func_offset;
var ptr_func = new NativePointer(n_addr_func);
//var ptr_func = Module.findExportByName("libjnitest.so","test_add") //对函数名hook

Interceptor.attach(ptr_func,{
//onEnter: 进入该函数前要执行的代码,其中args是传入的参数,一般so层函数第一个参数都是JniEnv,第二个参数是jclass,从第三个参数开始是我们java层传入的参数
onEnter: function(args) {
send("Hook start");
send("args[2]=" + args[2]); //第一个传入的参数
send("args[3]=" + args[3]); //第二个参数
},
onLeave: function(retval){ //onLeave: 该函数执行结束要执行的代码,其中retval参数即是返回值
send("return:"+retval); //返回值
retval.replace(100); //替换返回值为100
}
});
});
"""
def printMessage(message,data):
if message['type'] == 'send':
print('[*] {0}'.format(message['payload']))
else:
print(message)

process = frida.get_remote_device().attach('com.example.testso') #进程名
script = process.create_script(jscode)
script.on('message',printMessage)
script.load()
sys.stdin.read()

Hook修改native层函数返回值为string类型

返回值为字符串其实是返回了一个char \*(字符串指针),所以简单的替换是无法取效果的

关键代码:

1
2
3
var env = Java.vm.getEnv(); //获取env对象,也就是native函数的第一个参数
var jstrings = env.newStringUtf("tamper"); //因为返回的是字符串指针,使用我们需要构造一个newStringUtf对象,用来代替这个指针
retval.replace(jstrings); //替换返回值

示例

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
import frida
import sys

jscode = """
Java.perform(function(){
Interceptor.attach(Module.findExportByName("libfridaso.so","Java_com_example_fridasostring_fridaSoString_FridaSo"),{
onEnter: function(args) {
send("Hook start");
send("args[2]=" + args[2]);
},
onLeave: function(retval){
send("return:"+retval);
var env = Java.vm.getEnv(); //获取env对象,也就是native函数的第一个参数
var jstrings = env.newStringUtf("tamper"); //因为返回的是字符串指针,使用我们需要构造一个newStringUtf对象,用来代替这个指针
retval.replace(jstrings); //替换返回值
}
});
});
"""
def printMessage(message,data):
if message['type'] == 'send':
print('[*] {0}'.format(message['payload']))
else:
print(message)

process = frida.get_remote_device().attach('com.example.fridasostring')
script = process.create_script(jscode)
script.on('message',printMessage)
script.load()
sys.stdin.read()

Frida命令

基础命令

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
# 启动frida-server(模拟器)
./data/local/tmp/frida-server-12.8.0-android-x86

# 启动frida-server(Pixel真机)
./data/local/tmp/frida-server-12.8.0-android-arm64

# 在我的电脑之中模拟器运行frida-server(因为将这个文件导入的时候进行了重命名为frida-server)
./data/local/tmp/frida-server

# 转发端口
adb forward tcp:27042 tcp:27042
adb forward tcp:27043 tcp:27043

# 列举出来所有连接到电脑上的设备
frida-ls-devices

# 连接到指定设备
frida-ps -D tcp

# 列举出来设备上的所有进程
frida-ps -U

# 列举出来设备上的所有应用程序
frida-ps -Ua

# 列举出来设备上的所有已安装应用程序和对应的名字
frida-ps -Uai

# 跟踪某个函数
frida-trace -U -f Name -i "函数名"
# frida-trace -U -f com.autonavi.minimap -i "getRequestParams"

# 跟踪某个方法
frida-trace -U -f Name -m "方法名"
# frida-trace -U -f com.autonavi.minimap -m "MapLoader"

d3mug

ctf之中的游戏逆向(unity3D逆向分析)

unity逆向的文章(里面有各种各样的有关unity的题目,可以学习一下):https://forum.butian.net/share/1294

unity游戏IL2CPP类型

这道题是 :IL2CPP类型相对来说,题目难度有一个质的提升。对unity的理解程度需要更深。IL2CPP的Unity3D游戏的逆向,只需要根据global-metadata.dat和libil2cpp.so来进行就可以了。

il2cpp的内部实现文档https://blogs.unity3d.com/2015/05/06/an-introduction-to-ilcpp-internals/

il2cpp(主要分析metadata的一篇文章)

游戏的主页面

image-20220305085623123

游戏的运行界面:需要在白线的上面不停的点击这些蓝色的模块,如果能在白线的位置上点击到,那么GOOD就会增加一

image-20220305085823662

IL2CPPDumper

使用IL2CPPDumper这个工具将apk解包之后的global-metadata.datlibil2cpp.so这两个文件,dump出该DLL里的所有类以及类里的方法和成员,

使用IL2CPPDumper这个工具dump的方法以及dump出来的文件说明

dump(input文件)

image-20220305092747884

dump(output文件)

image-20220305092816043

dump.cs:

这个文件会把C#dll代码的类、方法、字段列出来。这里面有非常多的数据

image-20220305093238515

il2cpp.h

生成的cpp的头文件,从头文件里我们也可以看到相关的数据结构

image-20220305093516208

script.json

json格式显示类的方法信息

image-20220305093703245

stringliteral.json

以json的格式显示所有的字符串信息

image-20220305094319654

DummyDll/Assembly-CSharp.dll

进入DummyDll目录,可以看到很多dll,其中就有Assembly-CSharp.dll,使用dnspy打开这个文件

image-20220305095103745

文件列表:可以看到这里是游戏页面的初始化,组件(线),音乐等等

image-20220305095653171

从上面IL2CppDumper我们可以发现,逆向得到的函数体都是空的,看不了内部逻辑。内部的逻辑结构就需要使用IDA查看libil2cpp.so这个文件,在这个文件中使用上面得到的cs文件的偏移量找到目标的函数

关键函数定位

将Il2CppDumper 处理之后得到的Assembly-CSharp.dll文件放入到dnspy之中,这个文件里面存放了这个游戏里面函数的偏移地址

image-20220314175022511

根据需要查看相应的类,再查看相应的类中的函数的偏移地址

这里我们需要查看 GameManager和 ScoreScene类中的函数

image-20220314175327440

image-20220314175404995

游戏逻辑分析

使用上面得到的Assembly-CSharp.dll文件定位到函数的关键地址

NoteObject类中的OnClicked()函数

image-20220314180743397

再跟进这个判断时间的函数之中 它的rva是RVA = “0x62B64C” ,查看Assembly-CSharp.dll这个文件我们可以知道它就是NoteHit()函数

GameManager类的NoteHit()函数

image-20220314180815068

GameManager类中的update()函数

从上面那张图中可以得到在NoteHit()函数的结尾的地方调用了update()函数

image-20220314182013914

上面这个update()函数调用了libd3mug.so的update()函数,这个函数的最后调用了server.run

image-20220315210534201

逻辑分析:点击了NodeObject是表示音游之中的方块的类,NoteObject类中的OnClicked()函数表示点击方块,之后会触发GameManager类的NoteHit()函数分析点击的时间,从而确定是否点击成功与否,该函数之后会调用GameManager类中的update()函数

然后查看分数的模块ScoreScene类

ScoreScene类的get()函数

image-20220314183330050

上面这个get()函数里面调用了libd3mug.so中的get()函数

libd3mug.so中的get()函数

image-20220315210430564

通过这个函数交叉查询一下,找到引用该函数的函数sub_62EE40() 它便是ScoreScene类的Start()函数

ScoreScene类的Start()函数

image-20220314183807139

逻辑分析:游戏结束之后会转到的类是ScoreScene类,其中最后显示分数的函数中,调用了get()函数,这样获得了一个字符串

AssertStudio获得谱面

这是一个音游的游戏,由于需要我们踩点正确,所以就要我们找到这个游戏中的谱面(音乐的谱子),使用AssertStudio Unity解包提取资源/AssetStudio的简单使用_咲奈的平行时空-CSDN博客_unity解包](https://blog.csdn.net/qq_21567385/article/details/107015800))加载这个unity游戏的assets目录,在它的Asset List下面我们能够看到很多资源文件,其中的hitpoints的文件就是它的谱面

image-20220314193510893

在这个游戏页面的首页之中我们就能够看到这个游戏的音乐是 Chromevox

这里有三个音乐的hitpoints 我们选择其中是Chromevox的

image-20220314194026586

将这个文件导出出来,这个文件之中前面表示的是轨道数,后面表示的是时间

image-20220314194629112

按照之前的方法找到GameManager类的NoteMissed()函数

image-20220314195819635

image-20220314195836835

从图中我们可以知道update()中的参数就是msecs,所以我们需要将得到的hitpoints中的msecs作为 参数传入其中,这个过程就需要frida来hook函数

frida

查看frida-server是否成功开启,-U表示USB,允许Frida检查USB设备,这时将看到一个进程列表。

image-20220314205710639

通过该命令可以得到frida脚本中所需要的文件信息(pid 和 应用名和包名)

脚本

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
import frida, sys

jscode = """
console.log('12345')
let hitpoints = [0, 0, 0, 146, 292, 292, 439, 512, 585, 585, 658, 731, 804, 878, 1024, 1170, 1170, 1317, 1463, 1463, 1609, 1682, 1756, 1756, 1902, 2048, 2195, 2341, 2341, 2487, 2634, 2634, 2780, 2853, 2926, 2926, 3073, 3146, 3219, 3219, 3365, 3439, 3512, 3512, 3658, 3804, 3878, 3951, 4024, 4097, 4097, 4243, 4390, 4682, 4682, 4682, 4829, 4975, 4975, 5121, 5195, 5268, 5341, 5414, 5487, 5560, 5560, 5853, 5853, 5999, 6146, 6146, 6292, 6365, 6439, 6439, 6585, 6731, 6731, 6731, 7024, 7024, 7170, 7317, 7317, 7463, 7536, 7609, 7609, 7682, 7756, 7829, 7902, 7902, 7975, 8048, 8121, 8195, 8341, 8487, 8634, 8780, 9073, 9073, 9073, 9219, 9365, 9365, 9512, 9658, 9658, 9804, 9878, 9951, 9951, 10097, 10243, 10243, 10243, 10390, 10463, 10536, 10536, 10682, 10829, 10829, 10975, 11121, 11121, 11268, 11414, 11414, 11560, 11707, 11707, 11853, 11999, 11999, 11999, 12146, 12292, 12292, 12439, 12439, 12585, 12585, 12585, 12731, 12878, 12951, 13024, 13097, 13170, 13170, 13317, 13463, 13463, 13463, 13609, 13756, 13756, 13756, 13902, 14048, 14048, 14195, 14341, 14487, 14634, 14634, 14926, 14926, 14926, 15219, 15219, 15219, 15365, 15365, 15512, 15512, 15658, 15804, 15804, 15951, 16024, 16097, 16097, 16170, 16243, 16317, 16390, 16390, 16536, 16682, 16682, 16829, 16902, 16975, 16975, 17121, 17268, 17268, 17268, 17414, 17560, 17634, 17707, 17780, 17853, 17926, 17999, 18073, 18146, 18146, 18292, 18439, 18439, 18731, 18731, 18731, 18878, 19024, 19024, 19024, 19170, 19243, 19317, 19463, 19609, 19609, 19609, 19756, 19829, 19902, 20048, 20195, 20195, 20341, 20487, 20487, 20634, 20780, 20780, 20926, 21073, 21073, 21219, 21365, 21365, 21365, 21512, 21585, 21658, 21658, 21804, 21951, 21951, 21951, 22097, 22243, 22317, 22390, 22463, 22536, 22536, 22609, 22682, 22756, 22829, 22829, 22975, 23121, 23121, 23268, 23414, 23560, 23707, 23780, 23853, 23926, 23999, 23999, 24073, 24146, 24219, 24292, 24365, 24439, 24512, 24585, 24585, 24731, 24731, 24878, 24878, 24878, 25024, 25170, 25170, 25317, 25390, 25463, 25463, 25609, 25756, 25756, 25756, 25902, 25902, 26048, 26048, 26195, 26195, 26341, 26341, 26414, 26487, 26487, 26560, 26634, 26634, 26780, 26780, 26926, 27219, 27512, 27585, 27658, 27731, 27804, 27804, 28097, 28097, 28390, 28682, 28682, 28975, 29268, 29268, 29560, 29560, 29853, 29853, 30146, 30439, 30439, 30731, 31024, 31024, 31317, 31609, 31609, 31902, 32195, 32195, 32487, 32780, 32780, 32780, 33365, 33365, 33365, 33951, 33951, 34243, 34536, 34536, 34829, 35121, 35121, 35414, 35707, 35707, 35707, 35999, 36292, 36585, 36878, 36878, 37024, 37024, 37170, 37170, 37463, 37463, 37463, 37609, 37756, 37756, 37902, 38048, 38048, 38195, 38341, 38341, 38487, 38634, 38634, 38780, 38926, 39073, 39219, 39365, 39512, 39658, 39804, 39804, 39951, 40097, 40097, 40243, 40390, 40390, 40536, 40682, 40829, 40975, 40975, 41121, 41268, 41414, 41560, 41707, 41853, 41999, 42146, 42146, 42292, 42292, 42439, 42585, 42731, 42731, 42878, 42878, 43024, 43170, 43317, 43317, 43463, 43463, 43609, 43609, 43682, 43756, 43756, 43829, 43902, 43902, 44048, 44048, 44195, 44195, 44341, 44341, 44487, 44560, 44634, 44707, 44780, 44853, 44926, 44999, 45073, 45146, 45219, 45292, 45365, 45439, 45512, 45585, 45658, 45658, 45804, 45951, 45951, 46097, 46243, 46243, 46536, 46536, 46536, 46829, 46829, 46902, 46975, 47121, 47121, 47268, 47414, 47414, 47560, 47634, 47707, 47707, 47853, 47926, 47999, 47999, 48146, 48292, 48292, 48439, 48585, 48585, 48731, 48878, 48878, 49024, 49170, 49170, 49243, 49317, 49463, 49463, 49609, 49756, 49756, 49902, 49975, 50048, 50048, 50121, 50195, 50268, 50341, 50341, 50487, 50487, 50707, 50707, 50926, 50926, 51073, 51219, 51365, 51512, 51512, 51585, 51658, 51804, 51804, 51951, 52097, 52097, 52170, 52243, 52317, 52390, 52390, 52536, 52609, 52682, 52682, 52829, 52975, 52975, 53121, 53268, 53268, 53414, 53560, 53560, 53707, 53853, 53853, 53926, 53999, 54073, 54146, 54146, 54219, 54292, 54365, 54439, 54439, 54512, 54585, 54658, 54731, 54731, 54878, 54878, 55024, 55024, 55024, 55317, 55317, 55317, 55609, 55609, 55609, 55902, 55902, 55902, 56195, 56268, 56341, 56487, 56487, 56634, 56780, 56780, 56926, 56999, 57073, 57073, 57219, 57292, 57365, 57365, 57512, 57658, 57658, 57804, 57951, 57951, 58097, 58243, 58243, 58390, 58536, 58536, 58609, 58682, 58829, 58829, 58975, 59121, 59121, 59268, 59341, 59414, 59414, 59560, 59634, 59707, 59707, 59853, 59926, 59999, 59999, 60073, 60292, 60292, 60439, 60585, 60585, 60731, 60878, 60878, 60951, 61024, 61024, 61170, 61170, 61317, 61317, 61463, 61463, 61463, 61536, 61609, 61609, 61756, 61756, 61902, 61902, 62048, 62048, 62048, 62121, 62195, 62195, 62341, 62341, 62414, 62487, 62560, 62634, 62634, 62780, 62780, 62926, 62926, 63073, 63073, 63219, 63219, 63292, 63365, 63439, 63512, 63512, 63585, 63658, 63731, 63804, 63804, 63878, 63951, 64024, 64097, 64097, 64170, 64243, 64317, 64390, 64390, 64536, 64536, 64609, 64682, 64829, 64975, 65121, 65268, 65414, 65560, 65560, 65707, 65853, 65999, 66146, 66146, 66439, 66585, 66878, 67170, 67317, 67317, 67609, 67902, 68048, 68195, 68341, 68487, 68487, 68780, 68926, 69073, 69219, 69365, 69512, 69658, 69658, 69804, 69951, 70243, 70390, 70536, 70682, 70829, 70829, 71121, 71268, 71560, 71853, 71999, 71999, 72292, 72585, 72731, 72878, 73024, 73170, 73317, 73463, 73609, 73609, 73756, 73975, 74195, 74341, 74341, 74634, 74707, 74780, 74926, 74926, 75073, 75073, 75219, 75219, 75219, 75365, 75512, 75512, 75658, 75658, 75804, 75804, 75804, 75951, 76097, 76097, 76390, 76390, 76390, 76536, 76682, 76682, 76829, 76829, 76975, 76975, 76975, 77268, 77268, 77414, 77560, 77560, 77561, 77707, 77853, 77853, 77999, 77999, 78146, 78146, 78146, 78292, 78439, 78439, 78731, 78732, 78732, 78878, 79024, 79024, 79170, 79171, 79317, 79317, 79463, 79609, 79609, 79756, 79902, 79902, 80048, 80195, 80341, 80341, 80487, 80487, 80634, 80780, 80780, 80926, 80926, 81073, 81073, 81073, 81219, 81365, 81512, 81512, 81658, 81658, 81658, 81951, 81951, 81951, 82097, 82243, 82243, 82390, 82536, 82682, 82682, 82829, 82829, 82829, 82975, 83121, 83121, 83268, 83414, 83414, 83560, 83707, 83853, 83853, 83999, 83999, 83999, 84292, 84292, 84365, 84439, 84512, 84585, 84585, 84731, 84804, 84878, 84878, 84951, 85024, 85097, 85170, 85170, 85317, 85390, 85463, 85463, 85536, 85609, 85682, 85756, 85756, 85829, 85902, 85975, 86048, 86048, 86121, 86195, 86268, 86341, 86341, 86487, 86634, 86634, 86707, 86780, 86853, 86926, 86926, 87073, 87146, 87219, 87219, 87292, 87365, 87439, 87512, 87512, 87658, 87804, 87804, 87878, 87951, 88024, 88097, 88097, 88170, 88243, 88317, 88390, 88390, 88536, 88609, 88682, 88682, 88829, 88975, 88975, 89121, 89121, 89268, 89268, 89414, 89414, 89560, 89560, 89707, 89707, 89853, 89853, 89999, 89999, 90146, 90146, 90292, 90292, 90439, 90439, 90585, 90585, 90731, 90731, 90878, 90878, 91024, 91024, 91170, 91170, 91317, 91317, 91390, 91463, 91536, 91609, 91682, 91756, 91829, 91902, 91975, 92048, 92121, 92195, 92268, 92341, 92634, 92780, 92926, 93219, 93365, 93365, 93365, 93365, 93658, 93658, 93804, 93878, 93951, 93951, 94097, 94243, 94317, 94390, 94463, 94536, 94536, 94682, 94829, 94829, 94975, 95121, 95121, 95268, 95414, 95487, 95560, 95634, 95707, 95707, 95853, 95853, 95999, 95999, 96146, 96292, 96292, 96292, 96439, 96585, 96585, 96658, 96731, 96804, 96878, 96878, 97024, 97170, 97170, 97317, 97390, 97463, 97463, 97609, 97756, 97756, 97829, 97902, 98048, 98048, 98048, 98195, 98341, 98341, 98487, 98560, 98634, 98634, 98780, 98926, 98926, 99073, 99219, 99219, 99365, 99512, 99512, 99658, 99804, 99804, 99951, 100097, 100170, 100243, 100317, 100390, 100390, 100536, 100682, 100682, 100829, 100975, 100975, 100975, 101121, 101268, 101268, 101341, 101414, 101487, 101560, 101560, 101707, 101853, 101853, 101926, 101999, 102073, 102146, 102146, 102292, 102439, 102439, 102439, 102585, 102658, 102731, 102731, 102878, 103024, 103024, 103024, 103170, 103243, 103317, 103317, 103317, 103463, 103609, 103682, 103756, 103829, 103902, 103902, 104048, 104195, 104195, 104341, 104487, 104487, 104487, 104634, 104780, 104853, 104926, 104999, 105073, 105073, 105219, 105365, 105365, 105512, 105658, 105658, 105658, 105804, 105951, 105951, 106097, 106170, 106243, 106243, 106317, 106390, 106536, 106536, 106682, 106756, 106829, 106829, 106829, 106975, 107121, 107121, 107268, 107268, 107414, 107414, 107414, 107560, 107707, 107707, 107707, 107853, 107999, 107999, 107999, 108146, 108292, 108292, 108439, 108585, 108585, 108731, 108878, 108878, 108878, 109024, 109170, 109170, 109317, 109463, 109463, 109536, 109609, 109682, 109756, 109756, 109902, 110048, 110048, 110048, 110195, 110195, 110341, 110341, 110341, 110487, 110487, 110634, 110634, 110634, 110780, 110780, 110926, 110926, 110926, 111073, 111073, 111219, 111219, 111219, 111365, 111512, 111658, 111731, 111804, 111878, 111951, 112024, 112097, 112097, 112097, 112390, 112390, 112536, 112682, 112682, 112682, 112829, 112975, 112975, 113121, 113268, 113268, 113414, 113560, 113560, 113707, 113853, 113853, 113999, 114146, 114219, 114292, 114365, 114439, 114439, 114585, 114731, 114731, 114878, 115024, 115024, 115024, 115170, 115317, 115317, 115463, 115536, 115609, 115609, 115756, 115902, 115902, 115975, 116048, 116121, 116195, 116195, 116268, 116341, 116414, 116487, 116487, 116560, 116634, 116707, 116780, 116780, 116926, 117073, 117073, 117219, 117365, 117365, 117512, 117658, 117658, 117804, 117878, 117951, 117951, 118097, 118243, 118243, 118390, 118536, 118536, 118682, 118829, 118902, 118975, 119048, 119121, 119121, 119268, 119414, 119414, 119560, 119707, 119707, 119853, 119999, 119999, 120146, 120292, 120292, 120439, 120439, 120731, 121024, 121170, 121463, 121536, 121609, 121682, 121756, 121756, 121756, 121902, 122048, 122048, 122048, 122195, 122341, 122341, 122341, 122487, 122560, 122634, 122634, 122634, 122780, 122926, 122926, 122926, 123073, 123219, 123219, 123219, 123365, 123512, 123512, 123512, 123585, 123658, 123731, 123804, 123804, 123804, 123951, 124097, 124097, 124097, 124243, 124390, 124390, 124390, 124536, 124682, 124682, 124682, 124829, 124975, 124975, 124975, 125121, 125268, 125268, 125268, 125414, 125487, 125560, 125560, 125560, 125707, 125853, 125853, 125853, 125999, 126146, 126146, 126146, 126292, 126439, 126439, 126439, 126585, 126585, 126731, 126731, 126878, 126878, 127024, 127024, 127024, 127170, 127170, 127317, 127317, 127463, 127463, 127609, 127609, 127609, 127756, 127756, 127902, 127902, 128048, 128048, 128195, 128195, 128268, 128341, 128341, 128414, 128487, 128487, 128560, 128634, 128707, 128780, 128780, 128853, 128926, 128999, 129073, 129146, 129219, 129292, 129365, 129365, 129439, 129512, 129585, 129658, 129731, 129804, 129878, 129951, 129951, 130024, 130097, 130170, 130243, 130243, 130317, 130390, 130463, 130536, 130536, 130682, 130756, 130829, 130829, 130829, 130975, 130975, 131121, 131195, 131268, 131341, 131560, 131707, 131707, 131780, 131853, 131926, 132146, 132292, 132365, 132439, 132512, 132731, 132878, 132878, 132951, 133024, 133097, 133463, 133463, 133756, 134048, 134048, 134048, 134341, 134634, 134634, 134926, 134926, 135219, 135219, 135219, 135512, 135512, 135658, 135658, 135804, 135804, 135951, 135951, 136097, 136097, 136243, 136243, 136390, 136390, 136536, 136536, 136609, 136682, 136682, 136829, 136829, 136902, 136975, 136975, 137121, 137121, 137268, 137268, 137414, 137414, 137560, 137560, 137707, 137707, 137780, 137853, 137926, 137999, 137999, 138073, 138146, 138146, 138219, 138292, 138365, 138439, 138439, 138512, 138585, 138658, 138731, 138731, 138804, 138878, 138951, 139024, 139024, 139097, 139170, 139243, 139317, 139317, 139463, 139463, 139609, 139609, 139756, 139756, 139902, 139902, 140195, 140195, 140195, 140195]
let UpdateFunc = new NativeFunction(Module.findExportByName("libd3mug.so","update"),"void",['int'])
for(let i=0;i<hitpoints.length;i++){
UpdateFunc(hitpoints[i]);
}
let GetFunc = new NativeFunction(Module.findExportByName("libd3mug.so","get"),"pointer",[]);
var result = GetFunc();
console.log(ptr(result));
"""

def on_message(message, data):
if message['type'] == 'send':
print("[*] {0}".format(message['payload']))
else:
print(message)
pass

# 查找USB设备并附加到目标进程
#session = frida.get_remote_device(timeout=1000).attach(4103) # 通过命令查到的pid
# 使用进程名称attach
# session = frida.get_remote_device(timeout=1000).attach("LostBits")
# 在我的电脑上能够attach的方法
device = frida.get_remote_device()
pid = device.spawn(['com.DefaultCompany.com.unity.template.mobile2D'])
print(pid)
session = device.attach(pid)
# 在目标进程里创建脚本
script = session.create_script(jscode)
# 注册消息回调
script.on('message', on_message)
print('[*] Start attach')
# 加载创建好的javascript脚本
script.load()
# 读取系统输入
sys.stdin.read()

D3CTF{Gb78e-7b04-4364-82d2-7f44}

如果用解密的方法从libd3mug.so函数分析加密的结果得到flag的脚本

官方的解释:libd3mug.so中的算法是一个类似于feistel的东西,通过一个静态的种子初始化

mt19937随机数生成器,然后先生成随机数判定是否要进入下一步解密,在解密中重新生成随机数作为key,然后选取

一个偏移在数据中取出32字节,加密其中的16字节并将左右位置互换,将每个note的击打时间都录入update函数,即

可解出正确答案。

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
#include <stdio.h>
#include <random>
#include <Windows.h>

using namespace std;

const DWORD hitp[] = { 0,0,0,146,292,292,439,512,585,585,658,731,804,878,1024,1170,1170,1317,1463,1463,1609,1682,1756,1756,1902,2048,2195,2341,2341,2487,2634,2634,2780,2853,2926,2926,3073,3146,3219,3219,3365,3439,3512,3512,3658,3804,3878,3951,4024,4097,4097,4243,4390,4682,4682,4682,4829,4975,4975,5121,5195,5268,5341,5414,5487,5560,5560,5853,5853,5999,6146,6146,6292,6365,6439,6439,6585,6731,6731,6731,7024,7024,7170,7317,7317,7463,7536,7609,7609,7682,7756,7829,7902,7902,7975,8048,8121,8195,8341,8487,8634,8780,9073,9073,9073,9219,9365,9365,9512,9658,9658,9804,9878,9951,9951,10097,10243,10243,10243,10390,10463,10536,10536,10682,10829,10829,10975,11121,11121,11268,11414,11414,11560,11707,11707,11853,11999,11999,11999,12146,12292,12292,12439,12439,12585,12585,12585,12731,12878,12951,13024,13097,13170,13170,13317,13463,13463,13463,13609,13756,13756,13756,13902,14048,14048,14195,14341,14487,14634,14634,14926,14926,14926,15219,15219,15219,15365,15365,15512,15512,15658,15804,15804,15951,16024,16097,16097,16170,16243,16317,16390,16390,16536,16682,16682,16829,16902,16975,16975,17121,17268,17268,17268,17414,17560,17634,17707,17780,17853,17926,17999,18073,18146,18146,18292,18439,18439,18731,18731,18731,18878,19024,19024,19024,19170,19243,19317,19463,19609,19609,19609,19756,19829,19902,20048,20195,20195,20341,20487,20487,20634,20780,20780,20926,21073,21073,21219,21365,21365,21365,21512,21585,21658,21658,21804,21951,21951,21951,22097,22243,22317,22390,22463,22536,22536,22609,22682,22756,22829,22829,22975,23121,23121,23268,23414,23560,23707,23780,23853,23926,23999,23999,24073,24146,24219,24292,24365,24439,24512,24585,24585,24731,24731,24878,24878,24878,25024,25170,25170,25317,25390,25463,25463,25609,25756,25756,25756,25902,25902,26048,26048,26195,26195,26341,26341,26414,26487,26487,26560,26634,26634,26780,26780,26926,27219,27512,27585,27658,27731,27804,27804,28097,28097,28390,28682,28682,28975,29268,29268,29560,29560,29853,29853,30146,30439,30439,30731,31024,31024,31317,31609,31609,31902,32195,32195,32487,32780,32780,32780,33365,33365,33365,33951,33951,34243,34536,34536,34829,35121,35121,35414,35707,35707,35707,35999,36292,36585,36878,36878,37024,37024,37170,37170,37463,37463,37463,37609,37756,37756,37902,38048,38048,38195,38341,38341,38487,38634,38634,38780,38926,39073,39219,39365,39512,39658,39804,39804,39951,40097,40097,40243,40390,40390,40536,40682,40829,40975,40975,41121,41268,41414,41560,41707,41853,41999,42146,42146,42292,42292,42439,42585,42731,42731,42878,42878,43024,43170,43317,43317,43463,43463,43609,43609,43682,43756,43756,43829,43902,43902,44048,44048,44195,44195,44341,44341,44487,44560,44634,44707,44780,44853,44926,44999,45073,45146,45219,45292,45365,45439,45512,45585,45658,45658,45804,45951,45951,46097,46243,46243,46536,46536,46536,46829,46829,46902,46975,47121,47121,47268,47414,47414,47560,47634,47707,47707,47853,47926,47999,47999,48146,48292,48292,48439,48585,48585,48731,48878,48878,49024,49170,49170,49243,49317,49463,49463,49609,49756,49756,49902,49975,50048,50048,50121,50195,50268,50341,50341,50487,50487,50707,50707,50926,50926,51073,51219,51365,51512,51512,51585,51658,51804,51804,51951,52097,52097,52170,52243,52317,52390,52390,52536,52609,52682,52682,52829,52975,52975,53121,53268,53268,53414,53560,53560,53707,53853,53853,53926,53999,54073,54146,54146,54219,54292,54365,54439,54439,54512,54585,54658,54731,54731,54878,54878,55024,55024,55024,55317,55317,55317,55609,55609,55609,55902,55902,55902,56195,56268,56341,56487,56487,56634,56780,56780,56926,56999,57073,57073,57219,57292,57365,57365,57512,57658,57658,57804,57951,57951,58097,58243,58243,58390,58536,58536,58609,58682,58829,58829,58975,59121,59121,59268,59341,59414,59414,59560,59634,59707,59707,59853,59926,59999,59999,60073,60292,60292,60439,60585,60585,60731,60878,60878,60951,61024,61024,61170,61170,61317,61317,61463,61463,61463,61536,61609,61609,61756,61756,61902,61902,62048,62048,62048,62121,62195,62195,62341,62341,62414,62487,62560,62634,62634,62780,62780,62926,62926,63073,63073,63219,63219,63292,63365,63439,63512,63512,63585,63658,63731,63804,63804,63878,63951,64024,64097,64097,64170,64243,64317,64390,64390,64536,64536,64609,64682,64829,64975,65121,65268,65414,65560,65560,65707,65853,65999,66146,66146,66439,66585,66878,67170,67317,67317,67609,67902,68048,68195,68341,68487,68487,68780,68926,69073,69219,69365,69512,69658,69658,69804,69951,70243,70390,70536,70682,70829,70829,71121,71268,71560,71853,71999,71999,72292,72585,72731,72878,73024,73170,73317,73463,73609,73609,73756,73975,74195,74341,74341,74634,74707,74780,74926,74926,75073,75073,75219,75219,75219,75365,75512,75512,75658,75658,75804,75804,75804,75951,76097,76097,76390,76390,76390,76536,76682,76682,76829,76829,76975,76975,76975,77268,77268,77414,77560,77560,77561,77707,77853,77853,77999,77999,78146,78146,78146,78292,78439,78439,78731,78732,78732,78878,79024,79024,79170,79171,79317,79317,79463,79609,79609,79756,79902,79902,80048,80195,80341,80341,80487,80487,80634,80780,80780,80926,80926,81073,81073,81073,81219,81365,81512,81512,81658,81658,81658,81951,81951,81951,82097,82243,82243,82390,82536,82682,82682,82829,82829,82829,82975,83121,83121,83268,83414,83414,83560,83707,83853,83853,83999,83999,83999,84292,84292,84365,84439,84512,84585,84585,84731,84804,84878,84878,84951,85024,85097,85170,85170,85317,85390,85463,85463,85536,85609,85682,85756,85756,85829,85902,85975,86048,86048,86121,86195,86268,86341,86341,86487,86634,86634,86707,86780,86853,86926,86926,87073,87146,87219,87219,87292,87365,87439,87512,87512,87658,87804,87804,87878,87951,88024,88097,88097,88170,88243,88317,88390,88390,88536,88609,88682,88682,88829,88975,88975,89121,89121,89268,89268,89414,89414,89560,89560,89707,89707,89853,89853,89999,89999,90146,90146,90292,90292,90439,90439,90585,90585,90731,90731,90878,90878,91024,91024,91170,91170,91317,91317,91390,91463,91536,91609,91682,91756,91829,91902,91975,92048,92121,92195,92268,92341,92634,92780,92926,93219,93365,93365,93365,93365,93658,93658,93804,93878,93951,93951,94097,94243,94317,94390,94463,94536,94536,94682,94829,94829,94975,95121,95121,95268,95414,95487,95560,95634,95707,95707,95853,95853,95999,95999,96146,96292,96292,96292,96439,96585,96585,96658,96731,96804,96878,96878,97024,97170,97170,97317,97390,97463,97463,97609,97756,97756,97829,97902,98048,98048,98048,98195,98341,98341,98487,98560,98634,98634,98780,98926,98926,99073,99219,99219,99365,99512,99512,99658,99804,99804,99951,100097,100170,100243,100317,100390,100390,100536,100682,100682,100829,100975,100975,100975,101121,101268,101268,101341,101414,101487,101560,101560,101707,101853,101853,101926,101999,102073,102146,102146,102292,102439,102439,102439,102585,102658,102731,102731,102878,103024,103024,103024,103170,103243,103317,103317,103317,103463,103609,103682,103756,103829,103902,103902,104048,104195,104195,104341,104487,104487,104487,104634,104780,104853,104926,104999,105073,105073,105219,105365,105365,105512,105658,105658,105658,105804,105951,105951,106097,106170,106243,106243,106317,106390,106536,106536,106682,106756,106829,106829,106829,106975,107121,107121,107268,107268,107414,107414,107414,107560,107707,107707,107707,107853,107999,107999,107999,108146,108292,108292,108439,108585,108585,108731,108878,108878,108878,109024,109170,109170,109317,109463,109463,109536,109609,109682,109756,109756,109902,110048,110048,110048,110195,110195,110341,110341,110341,110487,110487,110634,110634,110634,110780,110780,110926,110926,110926,111073,111073,111219,111219,111219,111365,111512,111658,111731,111804,111878,111951,112024,112097,112097,112097,112390,112390,112536,112682,112682,112682,112829,112975,112975,113121,113268,113268,113414,113560,113560,113707,113853,113853,113999,114146,114219,114292,114365,114439,114439,114585,114731,114731,114878,115024,115024,115024,115170,115317,115317,115463,115536,115609,115609,115756,115902,115902,115975,116048,116121,116195,116195,116268,116341,116414,116487,116487,116560,116634,116707,116780,116780,116926,117073,117073,117219,117365,117365,117512,117658,117658,117804,117878,117951,117951,118097,118243,118243,118390,118536,118536,118682,118829,118902,118975,119048,119121,119121,119268,119414,119414,119560,119707,119707,119853,119999,119999,120146,120292,120292,120439,120439,120731,121024,121170,121463,121536,121609,121682,121756,121756,121756,121902,122048,122048,122048,122195,122341,122341,122341,122487,122560,122634,122634,122634,122780,122926,122926,122926,123073,123219,123219,123219,123365,123512,123512,123512,123585,123658,123731,123804,123804,123804,123951,124097,124097,124097,124243,124390,124390,124390,124536,124682,124682,124682,124829,124975,124975,124975,125121,125268,125268,125268,125414,125487,125560,125560,125560,125707,125853,125853,125853,125999,126146,126146,126146,126292,126439,126439,126439,126585,126585,126731,126731,126878,126878,127024,127024,127024,127170,127170,127317,127317,127463,127463,127609,127609,127609,127756,127756,127902,127902,128048,128048,128195,128195,128268,128341,128341,128414,128487,128487,128560,128634,128707,128780,128780,128853,128926,128999,129073,129146,129219,129292,129365,129365,129439,129512,129585,129658,129731,129804,129878,129951,129951,130024,130097,130170,130243,130243,130317,130390,130463,130536,130536,130682,130756,130829,130829,130829,130975,130975,131121,131195,131268,131341,131560,131707,131707,131780,131853,131926,132146,132292,132365,132439,132512,132731,132878,132878,132951,133024,133097,133463,133463,133756,134048,134048,134048,134341,134634,134634,134926,134926,135219,135219,135219,135512,135512,135658,135658,135804,135804,135951,135951,136097,136097,136243,136243,136390,136390,136536,136536,136609,136682,136682,136829,136829,136902,136975,136975,137121,137121,137268,137268,137414,137414,137560,137560,137707,137707,137780,137853,137926,137999,137999,138073,138146,138146,138219,138292,138365,138439,138439,138512,138585,138658,138731,138731,138804,138878,138951,139024,139024,139097,139170,139243,139317,139317,139463,139463,139609,139609,139756,139756,139902,139902,140195,140195,140195,140195 };

DWORD __ROR4__(DWORD a1, char a2)
{
return (a1 >> a2) | (a1 << (32 - a2));
}

int rounds(uint8_t* bytes, unsigned int a2, int a3)
{
DWORD* v3; // r4
DWORD v4; // r12
DWORD v5[2]; // r5
DWORD v6; // r3
DWORD result; // r0

v3 = (DWORD*)((char*)bytes + a3);
v4 = *(DWORD*)((char*)bytes + a3);
*(DWORD64*)&v5[0] = *(DWORD64*)((char*)bytes + a3 + 4);
v6 = *(DWORD*)((char*)bytes + a3 + 12);
*(DWORD*)((char*)bytes + a3) = *(&v5[0] + 1);
result = v4 ^ __ROR4__(*(&v5[0] + 1) ^ a2, 19);
v3[3] = v5[0] ^ __ROR4__(v6, 18) ^ __ROR4__(*(&v5[0] + 1) ^ a2, 19);
v3[1] = v6;
v3[2] = result;
return result;
}

int main(int argc, char const* argv[])
{
unsigned char enc_bytes[] =
{
0x3C, 0xAC, 0x92, 0x6F, 0x44, 0xA1, 0xC1, 0x17, 0xFD, 0x62,
0x60, 0xDD, 0x63, 0xF8, 0xE3, 0x2A, 0x5E, 0x75, 0x78, 0xBE,
0x59, 0x46, 0x33, 0xF6, 0x2E, 0x64, 0x61, 0x8A, 0x27, 0x93,
0x21, 0x7D, 0x00
};
mt19937 rng(-196167794);
for (int i = 0; i < 1608; ++i)
{
if (rng() % 7 >= 3)
{
rounds(enc_bytes, rng(), hitp[i] & 0xF);
}
}
printf("%s\n", enc_bytes);
getchar();
return 0;
}
D3CTF{Gb78e-7b04-4364-82d2-7f44}

最后得到flag:D3CTF{Gb78e-7b04-4364-82d2-7f44}