当前位置:网站首页>Tiktok data acquisition Frida advanced: shelling, automation, high frequency problems

Tiktok data acquisition Frida advanced: shelling, automation, high frequency problems

2021-01-23 20:17:49 Data Toolbox

Tiktok data acquisition Frida Advanced : Shelling 、 automation 、 High frequency problems

Short video 、 Live data real time acquisition interface , Please view the document : TiToData


disclaimer : This document is for learning and reference only , Do not use for illegal purposes ! Otherwise, I will bear all the consequences .

1 Frida For shelling

After the security engineer gets the task of application evaluation , The first thing is to catch him , The second thing should be to get it apk, Open it and see what's inside , If unfortunately it has a shell , It's possible to open a scene like this , See the picture below , I can't see anything , At this time, we must first shell it .
image.png
There are many kinds of shells , Depending on the type , The technology used is also different , Here's a little bit of a simple classification :

  • A generation of monolithic shells : use Dex Overall encryption , Dynamic loading and running mechanism ;
  • Second generation functions extract shells : Finer particle size , Extract the methods separately , Encrypted storage , Decryption execution ;
  • The three generation VMP、Dex2C shell : The independent virtual machine interprets and executes 、 Semantic equivalence and grammatical transfer , The highest intensity .

Let's start with the hardest part Dex2C There is no way to restore it at present , We can only track and analyze ;VMP What the virtual machine interprets and implements protection is the mapping table , Just be careful 、 Deep skill , You can restore the mapping table ; At present, the extraction of second generation shell function can be fundamentally restored ,dump All runtime method bodies are listed , Fill in dump Coming down dex Middle going , This is also fart The core principle of ; Finally, we recommend several in memory search and dump Out dex Of Frida Tools , In some scenarios, you can meet your needs .

The address is :https://github.com/r0ysue/frida_dump

# frida -U --no-pause -f com.xxxxxx.xxxxxx  -l dump_dex.js
     ____
    / _  |   Frida 12.8.9 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://www.frida.re/docs/home/
Spawned `com.xxxxx.xxxxx`. Resuming main thread!                
[Google Pixel::com.xxxxx.xxxxx]-> [dlopen:] libart.so
_ZN3art11ClassLinker11DefineClassEPNS_6ThreadEPKcmNS_6HandleINS_6mirror11ClassLoaderEEERKNS_7DexFileERKNS9_8ClassDefE 0x7adcac4f74
[DefineClass:] 0x7adcac4f74
[find dex]: /data/data/com.xxxxx.xxxxx/files/7abfc00000_8341c4.dex
[dump dex]: /data/data/com.xxxxx.xxxxx/files/7abfc00000_8341c4.dex
[find dex]: /data/data/com.xxxxx.xxxxx/files/7ac4096000_6e6c8.dex
[dump dex]: /data/data/com.xxxxx.xxxxx/files/7ac4096000_6e6c8.dex 
[find dex]: /data/data/com.xxxxx.xxxxx/files/7ac37c4028_8781c4.dex
[dump dex]: /data/data/com.xxxxx.xxxxx/files/7ac37c4028_8781c4.dex

Its core logic principle is the following sentence magic.indexOf("dex") == 0, As long as the file header contains magic numbers dex, Just put it dump Come down .

if (dex_maps[base] == undefined) {
    dex_maps[base] = size;
    var magic = ptr(base).readCString();
    if (magic.indexOf("dex") == 0) {
        var process_name = get_self_process_name();
        if (process_name != "-1") {
            var dex_path = "/data/data/" + process_name + "/files/" + base.toString(16) + "_" + size.toString(16) + ".dex";
            console.log("[find dex]:", dex_path);
            var fd = new File(dex_path, "wb");
            if (fd && fd != null) {
                var dex_buffer = ptr(base).readByteArray(size);
                fd.write(dex_buffer);
                fd.flush();
                fd.close();
                console.log("[dump dex]:", dex_path);
            }
        }
    }
}

1.2 DexClassLoader:objection

Android can only use the BaseDexClassLoader Two kinds of ClassLoader, One is PathClassLoader, Used to load the installed apk; One is to DexClassLoader, Load not installed jar Package or apk.
It can be used objcetion Go straight to the pile and brutally search all of them dalvik.system.DexClassLoader example , See the figure below for the effect :

# android heap search instances dalvik.system.DexClassLoader


Even hot patches have been found , It works well on some generation shells .

Address :https://github.com/hluwa/FRIDA-DEXDump

  • For complete dex, Use violent search dex035 You can find it .
  • And for the disheveled dex, Find... By matching some features , Then automatically fix the file header .

The effect is very good :

root@roysuekali:~/Desktop/FRIDA-DEXDump# python main.py 
[DEXDump]: found target [7628] com.xxxxx.xxxxx
[DEXDump]: DexSize=0x8341c4, SavePath=./com.xxxxx.xxxxx/0x7abfc00000.dex
[DEXDump]: DexSize=0x8341c4, SavePath=./com.xxxxx.xxxxx/0x7ac0600000.dex
root@roysuekali:~/Desktop/FRIDA-DEXDump# du -h com.xxxxx.xxxxx/*
8.3M    com.xxxxx.xxxxx/0x7abfc00000.dex
8.3M    com.xxxxx.xxxxx/0x7ac0600000.dex
root@roysuekali:~/Desktop/FRIDA-DEXDump# file com.xxxxx.xxxxx/*
com.xxxxx.xxxxx/0x7abfc00000.dex: Dalvik dex file version 035
com.xxxxx.xxxxx/0x7ac0600000.dex: Dalvik dex file version 035

open dump Coming down dex, Very complete , It can be used jadx Direct analytical . use 010 Open to see the full header ——dexn035, In fact, modern code is also simple and crude , Search directly :64 65 78 0a 30 33 35 00

Memory.scanSync(range.base, range.size, "64 65 78 0a 30 33 35 00").forEach(function (match) {
var range = Process.findRangeByAddress(match.address);
if (range != null && range.size < match.address.toInt32() + 0x24 - range.base.toInt32()) {
    return;
}
var dex_size = match.address.add("0x20").readInt();
if (range != null) {
    if (range.file && range.file.path
        && (range.file.path.startsWith("/data/app/")
            || range.file.path.startsWith("/data/dalvik-cache/")
            || range.file.path.startsWith("/system/"))) {
        return;
    }
    if (match.address.toInt32() + dex_size > range.base.toInt32() + range.size) {
        return;
    }
}

There are still some features that we want to match :

// @TODO improve fuzz
if (
    range.size >= 0x60
    && range.base.readCString(4) != "dexn"
    && range.base.add(0x20).readInt() <= range.size //file_size
    // && range.base.add(0x24).readInt() == 112 //header_size
    && range.base.add(0x34).readInt() < range.size
    && range.base.add(0x3C).readInt() == 112 //string_id_off
) {
    result.push({
        "addr": range.base,
        "size": range.base.add(0x20).readInt()
    });
}

Since you use it directly Frida Of API You can brutally search memory , So don't forget what we've described above objection You can also use violence to search memory .

# memory search "64 65 78 0a 30 33 35 00"


Found out offset yes :0x79efc00000, Size is c4 41 83 00, That is to say 0x8341c4, Converting to decimal is 8602052, Last dump The following contents are related to FRIDA-DEXDump It's as like as two peas , Drag onto jdax You can parse it directly .

2 Frida For Automation

stay Frida Before appearance , There is no tool , It can be called directly on the computer at the language level app The method in . image Xposed Is pure Java, There is no version running on the computer at all ; Various Native The same goes for the framework , It's all by C/C++/asm Realization , It has nothing to do with computers at all .
and Frida It's mainly a tool to operate on a computer , It itself determines its “ High concurrency ”、“ More connected ”、“ automation ” Other characteristics :

  • “ High concurrency ”: Operating multiple phones at the same time , Call multiple... On multiple phones at the same time app Algorithm in ;
  • “ More connected ”: Computers and mobile phones are interconnected , What can't be handled on a mobile phone can be handled on a computer 、 vice versa ;
  • “ automation ”: Mobile phones and computers work together , Across the desktop 、 Mobile platform collaboration automation tool .

2.1 Connect multiple devices

Frida For automated scenarios , It must be impossible to knock at the terminal frida-tools The command line tools in , Some say you can script these commands in order , Why don't you just write python The script ? In vain, uncle bearded (Frida The author of oleavr Head portrait ) Write it for us Python bindings, We just need to call it directly to enjoy .
Python bindings After installation frida-tools It has been installed on our computer by default , You can use it directly .
It's very easy to connect multiple devices , If it is USB It's directly connected , Just make sure that adb It's connected , If it's network debugging , Also use adb connect Connected to the , And it's all on frida server, type adb devices perhaps frida-ls-devices The command time of multiple devices id Will appear , Finally, you can use frida.get_device(id) Of API To choose the device , As shown in the figure below .

2.2 Interconnection

Interconnection refers to app The content captured in is transferred to the computer , Send it back to app To continue processing . A seemingly simple function , At present, only Frida Can achieve .
For example, we have such a app, The most important part is to judge whether the user is admin, If it is , The error is returned directly , No landing . If not , Upload the user and password to the server for verification and login , The core code logic is as follows :

public class MainActivity extends AppCompatActivity {
    EditText username_et;
    EditText password_et;
    TextView message_tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        password_et = (EditText) this.findViewById(R.id.editText2);
        username_et = (EditText) this.findViewById(R.id.editText);
        message_tv = ((TextView) findViewById(R.id.textView));
        this.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (username_et.getText().toString().compareTo("admin") == 0) {
                    message_tv.setText("You cannot login as admin");
                    return;
                }
                // We hook That's where our goal is 
                message_tv.setText("Sending to the server :" + Base64.encodeToString((username_et.getText().toString() + ":" + password_et.getText().toString()).getBytes(), Base64.DEFAULT));
            }
        });
    }
}

The running effect is shown in the figure below :
image.png
Our goal is to be on the computer “ obtain ” What's in the input box , And modify its input , also “ transmission ” For Android machines , Make it through validation . in other words , Our goal is to input admin Your account name and password , You can also bypass local validation , Carry out the operation of server verification login .
So in the end our hook The logic of the code is , Intercept input , To the computer , Suspend execution , After getting the data from the computer , Carry on , use js Let's write it. That's it :

Java.perform(function () {
    var tv_class = Java.use("android.widget.TextView");
    tv_class.setText.overload("java.lang.CharSequence").implementation = function (x) {
        var string_to_send = x.toString();
        var string_to_recv;
        send(string_to_send); //  Send the data to kali The host python Code 
        recv(function (received_json_object) {
            string_to_recv = received_json_object.my_data
            console.log("string_to_recv: " + string_to_recv);
        }).wait(); // After receiving the data , Go on 
        return this.setText(string_to_recv);
    }
});

The process on the computer is , Will receive JSON Data analysis , Extract the password part and keep it unchanged , Then replace the user name with admin, In this way, we can achieve the goal of admin and password The result sent to the server . Our code is as follows :

import time
import frida
def my_message_handler(message, payload):
    print message
    print payload
    if message["type"] == "send":
        print message["payload"]
        data = message["payload"].split(":")[1].strip()
        print 'message:', message
        data = data.decode("base64") #  decode 
        user, pw = data.split(":") #  Extract the user name and password 
        data = ("admin" + ":" + pw).encode("base64") #  Make new combinations and code 
        print "encoded data:", data
        script.post({"my_data": data})  #  take JSON Object sent back 
        print "Modified data sent"
device = frida.get_usb_device()
pid = device.spawn(["com.roysue.demo04"])
device.resume(pid)
time.sleep(1)
session = device.attach(pid)
with open("s4.js") as f:
    script = session.create_script(f.read())
script.on("message", my_message_handler)  #  Register message handler 
script.load()
raw_input()

Also, a lot of data that can't be processed on mobile phones , It can also be encoded and sent to the computer for processing , For example, deal with GBK Encoded Chinese character set data , Another example is right dump Down memory or so Second analysis and reduction, etc , These in js It's almost impossible to deal with ( Or very difficult ), But it's easy to get to the computer , use python Just import a few libraries .
In some ( The Internet ) In the scene of fuzzy test of interface , Some dictionaries and malformed data will also be constructed on the computer ,app At most, the client receives and sends the data as the executor , At this time, we also need to use Frida The function of dynamic modification of interconnection .

2.3 The remote invocation (RPC)

Define an export function in the script , And use rpc.exports The dictionary of :

function callSecretFun() { // Define export function 
    Java.perform(function () {
        //to-do  Do what you want to do  
        // For example, find the hidden function and call 
        Java.choose("com.roysue.demo02.MainActivity", {
            onMatch: function (instance) {
                console.log("Found instance: " + instance);
                console.log("Result of secret func: " + instance.secret());
            },
            onComplete: function () { }
        });
    });
}
rpc.exports = {
    callsecretfunction: callSecretFun // hold callSecretFun The function is exported as callsecretfunction Symbol , The export name cannot have capital letters or underscores 
};

On the computer, you can directly py Call this method in the code :

import time
import frida
def my_message_handler(message, payload):
    print message
    print payload
device = frida.get_usb_device()
pid = device.spawn(["com.roysue.demo02"])
device.resume(pid)
time.sleep(1)
session = device.attach(pid)
with open("s3.js") as f:
    script = session.create_script(f.read())
script.on("message", my_message_handler)
script.load()
command = ""
while 1 == 1:
    command = raw_input("Enter command:n1: Exitn2: Call secret functionnchoice:")
    if command == "1":
        break
    elif command == "2": # Call it here 
        script.exports.callsecretfunction()

The end result is a click 2,function callSecretFun() Will be executed once , And the results will be displayed on the computer py Script , For further processing , Very convenient .
One of my friends even used this interface python Of flask The frame is exposed , Let everyone in the network call this method , Sign your contract , It can be said that it's a very large demand scenario .

3 Frida More tricks

Finally, collect and sort out what you are learning Frida Several high-frequency problems may be encountered in the process of production , To please readers .

3.1 Version management is required

Frida It's been four or five years since it came out , Probably 17~18 It started to get hot back then , A lot of scripts and tool code were written at that time , and Frida And the upgrade is very fast , new Frida It's not very compatible with old scripts , See the latest Frida Run the old script , The log format is out of order , And the old version (12.4.8) Is no problem , See the picture 2-18. If you're going to run some code that's two or three years old , It's necessary to install the version about two or three years ago , So that we can run , And don't make mistakes .

Version management uses pyenv that will do , Skillfully use pyenv It can basically meet the requirement of installing dozens of devices at the same time Frida Version requirements .

3.2 Basic idea of anti debugging

Some of the most basic ideas , First frida-server Change the file name of , Be similar to frida-server-12.8.9-android-arm64 Such a filename , I usually change it to fs1289amd64, Of course, readers can change it to whatever they want .
Some debuggers also check ports , such as frida-server The default port is 27042, This port is usually not used by anyone , If 27042 The port is open and listening , Anti debugging will work , You can change the port to a non-standard port , Methods the next section is about .
Finally, there is another way to pass Frida Memory characteristics are very important to maps in elf File scan matching characteristics of the anti debugging method , Support frida-gadget and frida-server, Project address at here .
The core code is as follows :

void *check_loop(void *) {
    int fd;
    char path[256];
    char perm[5];
    unsigned long offset;
    unsigned int base;
    long end;
    char buffer[BUFFER_LEN];
    int loop = 0;
    unsigned int length = 11;
    //"frida:rpc" Memory layout features of 
    unsigned char frida_rpc[] =
            {
                    0xfe, 0xba, 0xfb, 0x4a, 0x9a, 0xca, 0x7f, 0xfb,
                    0xdb, 0xea, 0xfe, 0xdc
            };
    for (unsigned char &m : frida_rpc) {
        unsigned char c = m;
        c = ~c;
        c ^= 0xb1;
        c = (c >> 0x6) | (c << 0x2);
        c ^= 0x4a;
        c = (c >> 0x6) | (c << 0x2);
        m = c;
    }
    // Start detection frida Reverse debug loop 
    LOGI("start check frida loop");
    while (loop < 10) {
        fd = wrap_openat(AT_FDCWD, "/proc/self/maps", O_RDONLY, 0);
        if (fd > 0) {
            while ((read_line(fd, buffer, BUFFER_LEN)) > 0) {
                //  matching frida-server and frida-gadget Memory characteristics of 
                if (sscanf(buffer, "%x-%lx %4s %lx %*s %*s %s", &base, &end, perm, &offset, path) !=
                    5) {
                    continue;
                }
                if (perm[0] != 'r') continue;
                if (perm[3] != 'p') continue; 
                if (0 != offset) continue;
                if (strlen(path) == 0) continue;
                if ('[' == path[0]) continue;
                if (end - base <= 1000000) continue;
                if (wrap_endsWith(path, ".oat")) continue;
                if (elf_check_header(base) != 1) continue;
                if (find_mem_string(base, end, frida_rpc, length) == 1) {
                    // Find its memory characteristics 
                    LOGI("frida found in memory!");
#ifndef DEBUG
                    // The process of killing yourself 
                    wrap_kill(wrap_getpid(),SIGKILL);
#endif
                    // sign out 
                    break;
                }
            }
        } else {
            LOGI("open maps error");
        }
        wrap_close(fd);
        // Take a three second break , Enter the next inspection cycle , In other words, this anti debugging will work together 30 second ,30 Seconds later 
        loop++;
        sleep(3);
    }
    return nullptr;
}
void anti_frida_loop() {
    pthread_t t;
    // Create a thread , Perform anti debugging work 
    if (pthread_create(&t, nullptr, check_loop, (void *) nullptr) != 0) {
        exit(-1);
    };
    pthread_detach(t);
}

Think about this kind of anti debugging , We have to find out where the anti debugging is so Where is it ,nop I want to create check_loop Where the thread is , perhaps nop fall kill Where you're going , Fine . It can also be direct kill Abort debugging process , The author has encountered this situation ,frida After the command is injected ,app Can't adjust , Use at this time ps -e Command to see one more anti debug process , direct kill After dropping that process ,app So I got up , This app Is the use of a large factory reinforcement service , This process is part of the shell .

3.3 Non standard port connections

For example, will frida-server Start at 6666 port :

# ./fs1287amd64 -l 0.0.0.0:6666

Use frida-tools Tools and objection The method of connection is as follows :

# frida-ps -H 192.168.1.102:6666
# objection -N -h 192.168.1.102 -p 6666 -g com.android.settings explore

The effect is shown in the figure :
image.png
chart Connecting to non-standard ports
stay python bindings If you're connected in , It's going to be a little bit more complicated , because python bindings Recognize only adb, So we have to go through adb The command will send the phone's 6666 Port mapped to the computer's 27042 port :

$ adb forward tcp:27042 tcp:6666

such python bindings It can also be used normally .

3.4 Print byte[]``[B

ByteString.of Is used to put byte[] The array is converted to hex String function , Android comes with ByteString,app It doesn't matter if it's not in there , You can get it from the system , Here's a small case :

var ByteString = Java.use("com.android.okhttp.okio.ByteString");
var j = Java.use("xxxxxxx.business.comm.j");
j.x.implementation = function() {
    var result = this.x();
    console.log("j.x:", ByteString.of(result).hex());
    return result;
};
j.a.overload('[B').implementation = function(bArr) {
    this.a(bArr);
    console.log("j.a:", ByteString.of(bArr).hex());
};

3.5 hook Manage subprocesses

People often ask , Like that com.xxx.xxx:pushcom.xxx.xxx:servicecom.xxx.xxx:notificationcom.xxx.xxx:search How about this process hook, Or how to do it at the beginning of its creation hook, Because such a process is generally made up of the main process fork() Coming out .
It's going to use Frida Abreast of the times Child gating Mechanism , Please refer to my past articles , The official full code is in here . You can control and control a process at the beginning of its creation hook, It's been used by a lot of people , The effect is very good , Achieve the goal .

3.6 hook Confuse method names

There is a strong confusion in the names of some methods , How to deal with it ? It's very simple , You can see it ZenTracer Source code ,hook All subclasses of class ,hook Class , also hook All overloads of methods .

3.7 Chinese parameter problem

hook In some ways , I found that the parameter passed in is actually in Chinese , How to print it out ? If it is utf8 not so bad ,Frida Of CLI It's also direct support utf8 Of , If it is GBK Of the character set , At present, we have not found js The way to print in the computer , Sure send() Print on the computer .

3.8 hook Active registration

Use Frida Come on hook JNI Some functions of , Print out the execution path of the active call . Here is hook Google play Market Example :

frida -U --no-pause -f com.android.vending -l hook_RegisterNatives.js
     ____
    / _  |   Frida 12.6.13 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at http://www.frida.re/docs/home/
Spawning `com.android.vending`...                                      
GetFieldID is at  0xf1108e4d _ZN3art3JNI10GetFieldIDEP7_JNIEnvP7_jclassPKcS6_
AllocObject is at  0xf10f1809 _ZN3art3JNI11AllocObjectEP7_JNIEnvP7_jclass
GetMethodID is at  0xf10f3175 _ZN3art3JNI11GetMethodIDEP7_JNIEnvP7_jclassPKcS6_
NewStringUTF is at  0xf111fc71 _ZN3art3JNI12NewStringUTFEP7_JNIEnvPKc
GetObjectClass is at  0xf10f2841 _ZN3art3JNI14GetObjectClassEP7_JNIEnvP8_jobject
RegisterNatives is at  0xf11301fd _ZN3art3JNI15RegisterNativesEP7_JNIEnvP7_jclassPK15JNINativeMethodi
CallObjectMethod is at  0xf10f3745 _ZN3art3JNI16CallObjectMethodEP7_JNIEnvP8_jobjectP10_jmethodIDz
GetStaticFieldID is at  0xf111949d _ZN3art3JNI16GetStaticFieldIDEP7_JNIEnvP7_jclassPKcS6_
GetStaticMethodID is at  0xf110e6d1 _ZN3art3JNI17GetStaticMethodIDEP7_JNIEnvP7_jclassPKcS6_
GetStringUTFChars is at  0xf11203e1 _ZN3art3JNI17GetStringUTFCharsEP7_JNIEnvP8_jstringPh
ReleaseStringUTFChars is at  0xf11207fd _ZN3art3JNI21ReleaseStringUTFCharsEP7_JNIEnvP8_jstringPKc
FindClass is at  0xf10ec7a1 _ZN3art3JNI9FindClassEP7_JNIEnvPKc
Spawned `com.android.vending`. Resuming main thread!                   
[Google Pixel XL::com.android.vending]-> [RegisterNatives] method_count: 0x6
[RegisterNatives] java_class: org.chromium.base.CommandLine name: nativeInit sig: ([Ljava/lang/String;)V fnPtr: 0xd454f349 module_name: libcronet.76.0.3809.21.so module_base: 0xd441f000 offset: 0x130349
[RegisterNatives] java_class: org.chromium.base.CommandLine name: nativeHasSwitch sig: (Ljava/lang/String;)Z fnPtr: 0xd454f369 module_name: libcronet.76.0.3809.21.so module_base: 0xd441f000 offset: 0x130369
[RegisterNatives] java_class: org.chromium.base.CommandLine name: nativeGetSwitchValue sig: (Ljava/lang/String;)Ljava/lang/String; fnPtr: 0xd454f3bd module_name: libcronet.76.0.3809.21.so module_base: 0xd441f000 offset: 0x1303bd
[RegisterNatives] java_class: org.chromium.base.CommandLine name: nativeAppendSwitch sig: (Ljava/lang/String;)V fnPtr: 0xd454f461 module_name: libcronet.76.0.3809.21.so module_base: 0xd441f000 offset: 0x130461
[RegisterNatives] java_class: org.chromium.base.CommandLine name: nativeAppendSwitchWithValue sig: (Ljava/lang/String;Ljava/lang/String;)V fnPtr: 0xd454f499 module_name: libcronet.76.0.3809.21.so module_base: 0xd441f000 offset: 0x130499
[RegisterNatives] java_class: org.chromium.base.CommandLine name: nativeAppendSwitchesAndArguments sig: ([Ljava/lang/String;)V fnPtr: 0xd454f4f1 module_name: libcronet.76.0.3809.21.so module_base: 0xd441f000 offset: 0x1304f1
[RegisterNatives] method_count: 0x3
[RegisterNatives] java_class: org.chromium.base.EarlyTraceEvent name: nativeRecordEarlyEvent sig: (Ljava/lang/String;JJIJ)V fnPtr: 0xd454f94d module_name: libcronet.76.0.3809.21.so module_base: 0xd441f000 offset: 0x13094d
[RegisterNatives] java_class: org.chromium.base.EarlyTraceEvent name: nativeRecordEarlyStartAsyncEvent sig: (Ljava/lang/String;JJ)V fnPtr: 0xd454fa3d module_name: libcronet.76.0.3809.21.so module_base: 0xd441f000 offset: 0x130a3d
[RegisterNatives] java_class: org.chromium.base.EarlyTraceEvent name: nativeRecordEarlyFinishAsyncEvent sig: (Ljava/lang/String;JJ)V fnPtr: 0xd454fae5 module_name: libcronet.76.0.3809.21.so module_base: 0xd441f000 offset: 0x130ae5
[RegisterNatives] method_count: 0x4
[RegisterNatives] java_class: org.chromium.base.FieldTrialList name: nativeFindFullName sig: (Ljava/lang/String;)Ljava/lang/String; fnPtr: 0xd454fb8d module_name: libcronet.76.0.3809.21.so module_base: 0xd441f000 offset: 0x130b8d
[RegisterNatives] java_class: org.chromium.base.FieldTrialList name: nativeTrialExists sig: (Ljava/lang/String;)Z fnPtr: 0xd454fbff module_name: libcronet.76.0.3809.21.so module_base: 0xd441f000 offset: 0x130bff
[RegisterNatives] java_class: org.chromium.base.FieldTrialList name: nativeGetVariationParameter sig: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; fnPtr: 0xd454fc2f module_name: libcronet.76.0.3809.21.so module_base: 0xd441f000 offset: 0x130c2f
[RegisterNatives] java_class: org.chromium.base.FieldTrialList name: nativeLogActiveTrials sig: ()V fnPtr: 0xd454fd1d module_name: libcronet.76.0.3809.21.so module_base: 0xd441f000 offset: 0x130d1d
[RegisterNatives] method_count: 0x2

Source code address :https://github.com/lasting-yang/frida_hook_libart

3.9 track JNI API

Address :https://github.com/chame1eon/jnitrace
image.png

3.10 Delay hook

A lot of the time in the shell hook When , Make good use of two frida The delay provided hook Mechanism :

  • frida --no-pause It's process execution , Sometimes hook Less than , If you put --no-pause Remove , Get into CLI Then delay for a few seconds %resume Resume execution , will hook To ;
  • js Medium setTimeout(func, delay[, ...parameters]) function , It's going to delay delay Millisecond to call func, Sometimes without delay hook Less than , Add a delay of a few hundred to a few thousand milliseconds hook To .

版权声明
本文为[Data Toolbox ]所创,转载请带上原文链接,感谢
https://chowdera.com/2021/01/20210123201637211j.html

随机推荐