frida学习及使用

news2024/12/27 11:17:25

文章目录

  • 安装frida
    • 安装python3.7
    • 设置环境变量
    • 安装pycharm和nodejs
  • 使用frida
    • 将frida-server push到手机设备中
    • 端口转发
    • 安装apk
    • 使用jadx查看java代码
    • 运行frida-server
  • frida源码阅读
  • frida hook方法
    • Frida Java层hoook
      • JavaHook.java
      • JavaHook.js
    • Frida native层hook 一
    • NativeHook.js

安装frida

Frida框架简介
Frida是一款基于Python + JavaScript的Hook与调试框架。
Firda是一款易用的跨平Hook工具,Java层到Native层的Hook无所不能,是一种动态 
的插桩工具,可以插入代码到原生 App 的内存空间中,动态的去监视和修改行为,
原生平台包括Win、Mac、Linux、Android、iOS全平台。

环境配置步骤:
1.安装Python环境 3.7

2.安装frida模块
	打开Py输入命令:
		pip install frida
		pip install frida-tools
		pip uninstall frida
		pip uninstall frida-tools
		pip install frida==15.1.27
		pip install frida-tools==10.6.2

google pixels 3a
frida=16.1.3
frida-tools=12.2.1

3.frida-server下载地址:
	查看版本信息:frida --version
	https://github.com/frida/frida/releases
	下载安装frida server 版本和类型对应,框架和设备对应

4.安装PyCharm 

5.启动frida-server

6.端口转发
	adb forward tcp:27042 tcp:27042

7.测试
	frida-ps -U	
	frida -U -f com.qianyu.fridaapp --no-pause

安装python3.7

在这里插入图片描述

设置环境变量

在这里插入图片描述

安装pycharm和nodejs

创建工程的时候,记得将鼠标所在的两个勾选框选上
在这里插入图片描述
在这里插入图片描述

使用frida

将frida-server push到手机设备中

在这里插入图片描述
在这里插入图片描述

端口转发

在这里插入图片描述

安装apk

使用jadx查看java代码

在这里插入图片描述

运行frida-server

我使用15.1.27版本的frida版本,在安卓手机上会报错。所以我果断升级了frida版本

sargo:/data/local/tmp # ./frida-server-15.1.27-android-arm64
{"type":"error",
"description":"Error: Unable to determine ClassLinker field offsets",
"stack":"Error: Unable to determine ClassLinker field offsets\n    
	at Ye (frida/node_modules/frida-java-bridge/lib/android.js:400:1)\n    
	at frida/node_modules/frida-java-bridge/lib/memoize.js:4:1\n    
	at ze (frida/node_modules/frida-java-bridge/lib/android.js:193:1)\n    
	at Oe (frida/node_modules/frida-java-bridge/lib/android.js:16:1)\n   
	 at _tryInitialize (frida/node_modules/frida-java-bridge/index.js:29:1)\n    
	 at new _ (frida/node_modules/frida-java-bridge/index.js:21:1)\n    
	 at Object.4../lib/android (frida/node_modules/frida-java-bridge/index.js:332:1)\n    
	 at o (frida/node_modules/browser-pack/_prelude.js:1:1)\n    
	 at frida/node_modules/browser-pack/_prelude.js:1:1\n    
	 at Object.22.frida-java-bridge (frida/runtime/java.js:1:1)",
"fileName":"frida/node_modules/frida-java-bridge/lib/android.js","lineNumber":400,"columnNumber":1}

frida源码阅读

在这里插入图片描述

frida hook方法

注意点:

  1. frida和frida-server版本号必须要一致
  2. hook的时候,必须要运行hook的程序,否则报错

Frida Java层hoook

JavaHook.java

# -*- coding: utf-8 -*-

import os
import sys
import frida
import codecs


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


process = frida.get_remote_device().attach('NDKDemo')
if not os.path.isfile('./JavaHook.js'):
    raise TypeError("./JavaHook.js does not exist")
with codecs.open('./JavaHook.js', 'r', 'UTF-8') as file:
    js_code = file.read()
script = process.create_script(js_code)
script.on("message", message)
script.load()
# script.exports.test()
# script.exports.test()
# script.exports.test()
# script.exports.test()
sys.stdin.read()


# frida使用非标准端口
# /data/local/tmp # ./fs_12.7.22_arm64 -l 127.0.0.1:31928  默认端口: 27046
# process = frida.get_device_manager().add_remote_device('127.0.0.1:31928').attach('FridaApp')
# if not os.path.isfile('./JavaHook.js'):
#     raise TypeError("./JavaHook.js does not exist")
# with codecs.open('./JavaHook.js', 'r', 'UTF-8') as file:
#     js_code = file.read()
# script = process.create_script(js_code)
# script.on("message", message)
# script.load()
# sys.stdin.read()

JavaHook.js

// HOOK普通方法、静态方法
function Test01(){
    let loginActivity = Java.use('com.yijincc.ndkdemo.LoginActivity');
    loginActivity.login.implementation = function () {
        console.log("=============login===============");
        console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
        console.log(arguments[0]);
        console.log(arguments[1]);
        this.login(arguments[0],arguments[1]);
    }
}

// HOOK构造方法、重载方法
function Test02(){
    let intent = Java.use('android.content.Intent');
    intent.$init.overload('android.content.Context', 'java.lang.Class').implementation = function () {
       console.log("=============intent===============");
       console.log(arguments[0]);
       console.log(arguments[1]);
       this.$init(arguments[0],arguments[1]);
    }
}

// HOOK内部类
function Test03(){
    let loginActivity$1 = Java.use('com.yijincc.ndkdemo.LoginActivity$1');
    loginActivity$1.onClick.implementation = function () {
        console.log("=============onClick===============");
        console.log(arguments[0]);
        this.onClick(arguments[0]);
    }
}

// 主动调用构造方法
function Test04(){
    let money = Java.use('com.yijincc.fridaapp.Money');
    let obj = money.$new(1000,'RMB');
    console.log(obj.getInfo());
}

// 操作对象里面的成员变量
function Test05(){
    let money = Java.use('com.yijincc.fridaapp.Money');
    let obj = money.$new(10000,'RMB');
    console.log(obj.name.value);
    console.log(obj.num.value);

    console.log('===============================');

    obj.name.value = 'RMB';
    obj.num.value = 10000000;
    console.log(obj.name.value);
    console.log(obj.num.value);
}

// 主动调用普通方法
function Test06(){
    let money = Java.use('com.yijincc.fridaapp.Money');
    let obj = money.$new(2000,'RMB');
    console.log(obj.getInfo());
}

// 获取当前类已有的实例实现主动调用普通方法
function Test07(){
    Java.choose('com.yijincc.ndkdemo.MainActivity',{
        onMatch: function(obj){ // 枚举时调用
                console.log(obj);
                console.log(obj.name.value);
                console.log(obj.age.value);
                console.log(obj.sex.value);
                console.log(obj.rand('B',99))
            }, onComplete: function(){ // 枚举完成后调用
                console.log("end");
            }
        });
}

// 主动调用静态方法
function Test08(){
    let mainActivity = Java.use('com.yijincc.ndkdemo.MainActivity');
    console.log(mainActivity.isRel(444,444));
}

// HOOK打印堆栈信息
// function Test09(){
//     let money = Java.use('com.yijincc.fridaapp.Money');
//     money.getInfo.implementation = function () {
//         console.log("=============getInfo===============");
//         console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
//         return this.getInfo();
//     }
// }

// HOOK指定类的所有方法
function Test10(){
    let money = Java.use('com.yijincc.ndkdemo.MainActivity');
    let methods = money.class.getDeclaredMethods();
    for(let j = 0; j < methods.length; j++){
        let methodName = methods[j].getName();
        console.log(methodName);
        for(let k = 0; k < money[methodName].overloads.length; k++){
            money[methodName].overloads[k].implementation = function(){
                console.log('==========='+methodName+'===========');
                for(let i = 0; i < arguments.length; i++){
                    console.log(arguments[i]);
                }
                console.log('===========end===========');
                return this[methodName].apply(this, arguments);
            }
        }
    }
}

// 枚举已加载的所有类与枚举类的所有方法
function Test11(){
    let classes = Java.enumerateLoadedClassesSync();
    for(let i = 0; i < classes.length; i++){
        if(classes[i].indexOf("com.") !== -1){
            console.log("clazz:"+classes[i]);
            let clazz = Java.use(classes[i]);
            let methods = clazz.class.getDeclaredMethods();
            for(let j = 0; j < methods.length; j++){
                console.log("method:"+methods[j]);
            }
        }
    }
}

// hook动态加载dex文件
function Test12(){
    // Java.enumerateLoadedClasses({
    //     onMatch: function (name, handle) {
    //         if (name.indexOf("com.example") >= 0) {
    //             console.log(name);
    //             let class6 = Java.use(name);
    //             class6.check.implementation = function () {
    //                 console.log("check:", this);
    //                 return true;
    //             };
    //         }
    //     }, onComplete: function () {}
    // });

    Java.enumerateClassLoaders({
        onMatch: function (loader) {
            try {
                if (loader.findClass("com.example.androiddemo.Dynamic.DynamicCheck")) {
                    console.log(loader);
                    Java.classFactory.loader = loader;      //切换classloader
                }
            } catch (error) {}
        }, onComplete: function () {}
    });
    let DynamicCheck = Java.use("com.example.androiddemo.Dynamic.DynamicCheck");
    console.log(DynamicCheck);
    DynamicCheck.check.implementation = function () {
        console.log("DynamicCheck.check");
        return true;
    }
}

// 动态加载dex文件
function Test13(){
    // jar -cvf dex.jar com/example/androiddemo/StringUtils.class
    // dx --dex --output=dex.dex dex.jar
    let dex= Java.openClassFile("/data/local/tmp/dex.dex");
    dex.load();
    let stringUtils = Java.use("com.example.androiddemo.StringUtils");
    console.log(stringUtils.tohexString("1234567890"));
}

rpc.exports = {
    test:function () {
        Java.choose('com.yijincc.ndkdemo.MainActivity',{
        onMatch: function(obj){ // 枚举时调用
                console.log(obj);
                console.log(obj.name.value);
                console.log(obj.age.value);
                console.log(obj.sex.value);
                console.log(obj.rand('B',99))
            }, onComplete: function(){ // 枚举完成后调用
                console.log("============end============");
            }
        });
    }
}

Java.perform(function () {
    Test01();
    // Test02(); // 重载方法
    // Test03(); // 内部类
    // Test04()  // 主动调用构造方法,创建一个对象
    // Test07();
    // Test08();
    // Test10(); // 打印所有的方法
    // Test11();
    //Test13();
});

Frida native层hook 一

通过IDA找到要hook的native函数(静态)
在这里插入图片描述base64魔改
在这里插入图片描述## NativeHook.py

# -*- coding: utf-8 -*-

import os
import sys
import frida
import codecs


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


process = frida.get_remote_device().attach('NDKDemo')
if not os.path.isfile('./NativeHook.js'):
    raise TypeError("./NativeHook.js does not exist")
with codecs.open('./NativeHook.js', 'r', 'UTF-8') as file:
    js_code = file.read()
script = process.create_script(js_code)
script.on("message", message)
script.load()
sys.stdin.read()


# frida使用非标准端口
# /data/local/tmp # ./fs_12.7.22_arm64 -l 127.0.0.1:31928  默认端口: 27046
# process = frida.get_device_manager().add_remote_device('127.0.0.1:31928').attach('Android_crackme')
# if not os.path.isfile('./NativeHook.js'):
#     raise TypeError("./NativeHook.js does not exist")
# with codecs.open('./NativeHook.js', 'r', 'UTF-8') as file:
#     js_code = file.read()
# script = process.create_script(js_code) # 创建脚本
# script.on("message", message)
# script.load()
# sys.stdin.read()

NativeHook.js

// HOOK导出函数
function Test01(){
    // 用于在指定的模块中查找导出函数的地址
    let funGetFlag = Module.findExportByName("libnative-lib.so", "Java_com_yijincc_ndkdemo_LoginActivity_login");
    send("native: " + funGetFlag); // 基地址
    Interceptor.attach(funGetFlag, {
        onEnter: function(args){
            send("============getFlag===============");
            send(args[0]);
            send(args[1]);
        },
        onLeave: function(retval){
            send("============result===============");
            send(retval);
            // 获取JNIEnv*
            let env = Java.vm.tryGetEnv();
            // 将jstring 转换 const char*
            let str=env.getStringUtfChars(retval,0);
            send(str.readCString());
        }
    });
}

// HOOK未导出函数
function Test02(){
    // 绝对地址=so模块起始地址(基地址)+偏移地址
    let baseAddr = Module.findBaseAddress("libnative-lib.so");
    send("baseAddr:"+baseAddr);
    // 指令集 分为ARM指令、thumb指令
    // ARM指令地址不变  thumb指令地址+1 sub_ 开头的函数 这种函数只能使用这种方式来进行
    Interceptor.attach(baseAddr.add(0x15F08), {
        onEnter: function(args){
            send("============encrypt===============");
            send(args[0]);
            send(args[1]);
            send(args[2]);
            console.log(hexdump(args[2], {
                offset: 0,
                length: 16,
                header: true,
                ansi: false
            }));
            // 获取JNIEnv*
            let env = Java.vm.tryGetEnv();
            // 将jstring 转换 const char*
            let str=env.getStringUtfChars(args[2],0);
            send(str.readCString());
        },
        onLeave: function(retval){
            send("============result===============");
            send(retval);
            // 获取JNIEnv*
            let env = Java.vm.tryGetEnv();
            // 将jstring 转换 const char*
            let str=env.getStringUtfChars(retval,0);
            send(str.readCString());
        }
    });
}

// HOOK枚举导入函数信息
function Test03(){
    send("Test03")
    let imports = Module.enumerateImportsSync("libnative-lib.so");
    send(imports)
    for(let i=0;i<imports.length;i++){
        // if(imports[i].name.indexOf('raise') !== -1){
            send(imports[i]);
        // }
    }
}

// HOOK枚举导出函数信息
function Test04(){
    send("Test04-start")
    send(device)
    let exports = Module.enumerateExportsSync("libnative-lib.so");
    send(exports)
    for(let i=0;i<exports.length;i++){
        if(exports[i].name.indexOf('Java_') !== -1){
            send("name:"+exports[i].name+"  address:"+exports[i].address);
        }
    }
    send("Test04-end")
}

// 遍历模块列表信息
function Test05(){
    Process.enumerateModules({
        onMatch: function(exp){
            send(exp)
            if(exp.name.indexOf('libnative-lib.so') !== -1){
                send('enumerateModules find');
                send(exp);
                return 'stop';
            }
        },
        onComplete: function(){
            send('enumerateModules stop');
        }
    });
}

// 读写内存数据
function Test06(){
    let mem_addr=Memory.alloc(20);
    //Memory.writeInt(mem_addr,0x1234567890abcdef);
    Memory.writeLong(mem_addr,0x1234567890abcdef);
    // console.log(hexdump(mem_addr));
    console.log(hexdump(mem_addr, {
        offset: 0,
        length: 20,
        header: true,
        ansi: true
    }));
}

// 使用frida api读写文件
function Test07(){
    let file = new File("/data/data/com.yijincc.ndkdemo/yijincc.txt", "w");
    file.write("hello world!!!\\n");
    file.flush();
    file.close();
}

// 基于主动调用libc.so里面的函数实现文件的读写操作
function Test08(){
    let addr_fopen = Module.findExportByName("libc.so", "fopen");
    send("1")
    let addr_fputs = Module.findExportByName("libc.so", "fputs");
    send("2")
    let addr_fclose = Module.findExportByName("libc.so", "fclose");
    send("3")

    let fopen = new NativeFunction(addr_fopen, "pointer", ["pointer", "pointer"]);
    send("4")
    let fputs = new NativeFunction(addr_fputs, "int", ["pointer", "pointer"]);
    send("5")
    let fclose = new NativeFunction(addr_fclose, "int", ["pointer"]);
    send("6")

    let filename = Memory.allocUtf8String("/data/data/com.yijincc.ndkdemo/yijincc.txt");
    send("7")
    let open_mode = Memory.allocUtf8String("w");
    send("8")
    let file = fopen(filename, open_mode);
    send("9")

    let buffer = Memory.allocUtf8String("hello world!!!\\n");
    send("10")
    let result = fputs(buffer, file);
    send("11")
    send("fputs:" + result);
    fclose(file);
}

Java.perform(function () {
    // Test01();
    // Test02();
    // Test03();
    // Test04();
    // Test05();
    // Test06();
    // Test07();
    Test08();
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/832846.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Leetcode】(自食用)找到消失的数字

step by step. 题目&#xff1a; 给你一个含 n 个整数的数组 nums &#xff0c;其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字&#xff0c;并以数组的形式返回结果。 示例 1&#xff1a; 输入&#xff1a;nums [4,3,2,7,8,2,3,1] 输…

模板方法模式——定义算法的框架

1、简介 1.1、概述 模板方法模式是结构最简单的行为型设计模式&#xff0c;在其结构中只存在父类与子类之间的继承关系。通过使用模板方法模式&#xff0c;可以将一些复杂流程的实现步骤封装在一系列基本方法中。在抽象父类中提供一个称之为模板方法的方法来定义这些基本方法…

js沙箱逃逸

目录 一、什么是沙箱(sandbox) 二、沙箱技术的实现 & node.js 2.1简单沙箱程序示例 2.2this.tostring S1&#xff1a; S2&#xff1a; 三、arguments.callee.caller 一、什么是沙箱(sandbox) 在计算机安全性方面&#xff0c;沙箱&#xff08;沙盒、sanbox&#xff…

【【萌新的STM32学习-4】】

萌新的STM32学习-4 STM32系统框架 1.1 Cortex M 内核& 芯片 F1有四个驱动单元 四个被动单元 AHB 高级高性能总线 APB 高级外围总线 部分系统结构 最上面的ICode 总线直接连接到了内部Flash 不需要通过总线矩阵 . D Code 总线&#xff08;D - Bus&#xff09; 这是Cort…

Kubernetes高可用集群二进制部署(五)kubelet、kube-proxy、Calico、CoreDNS

Kubernetes概述 使用kubeadm快速部署一个k8s集群 Kubernetes高可用集群二进制部署&#xff08;一&#xff09;主机准备和负载均衡器安装 Kubernetes高可用集群二进制部署&#xff08;二&#xff09;ETCD集群部署 Kubernetes高可用集群二进制部署&#xff08;三&#xff09;部署…

Delphi Enterprise Crack

Delphi Enterprise Crack Delphi帮助您使用Object Pascal为Windows、Mac、Mobile、IoT和Linux构建和更新数据丰富、超连接、可视化的应用程序。Delphi Enterprise适合开发团队构建客户端/服务器或多层应用程序、REST服务等。 Delphi功能 单一代码库-用更少的编码工作为所有主要…

MySQL 详细学习教程【万字长文, 建议收藏】

目录 1. Mysql入门1.1 Mysql5.7 安装配置1.2 命令行连接到Mysql1.3 图形化软件1.3.1 Navicat1.3.2 SQLyog 1.4 数据库三层结构 2. Java操作数据库、表2.1 创建数据库2.2 查询数据库2.3 备份恢复数据库2.4 创建表2.5 修改表 3 CRUD3.1 insert插入3.2 update修改3.3 delete修改3.…

一篇文章搞定《LeakCanary源码详解(全)》

一篇文章搞定《LeakCanary源码解析》 前言LeakCanary和LeakCanary2区别LeakCanary的快速使用第一步&#xff1a;添加依赖第二步&#xff1a;初始化LeakCanary第三步&#xff1a;运行应用程序并监测内存泄漏 LeakCanary基础铺垫四大引用WeakReference和ReferenceQueueRefercence…

【Spring】(二)从零开始的 Spring 项目搭建与使用

文章目录 前言一、Spring 项目的创建1.1 创建 Maven 项目1.2 添加 Spring 框架支持1.3 添加启动类 二、储存 Bean 对象2.1 创建 Bean2.1 将 Bean 注册到 Spring 容器 三、获取并使用 Bean 对象3.1 获取Spring 上下文3.2 ApplicationContext 和 BeanFactory 的区别3.3 获取指定的…

2023-02-03——2023-08-03,半年以来与客服交流的记录【CSND 文章撰写 网站使用求解】客服咨询交流记录(长期更新ing)

这世界上久处不厌,都是因为用心。 🎯作者主页: 追光者♂🔥 🌸个人简介: 💖[1] 计算机专业硕士研究生💖 🌿[2] 2023年城市之星领跑者TOP1(哈尔滨)🌿 🌟[3] 2022年度博客之星人工智能领域TOP4🌟 🏅[4] 阿里云社区特邀专家博主🏅 🏆

Cesium 实战教程 - 调整 3dtiles 倾斜摄影大小

Cesium 实战教程 - 调整 3dtiles 倾斜摄影大小 核心代码完整代码在线示例 之前由于误解遇到一个特殊的需求&#xff1a;想要把三维球上叠加倾斜摄影进行自由放大缩小&#xff0c;跟随地图的缩放进行缩放。 后来经过搜索、尝试&#xff0c;终于实现了需求。 但是&#xff0c;后…

什么是强化学习?

&#x1f4dd;什么是强化学习&#xff1f; 1. &#x1f4dd;监督&#xff0c;非监督&#xff0c;强化2. &#x1f4dd;非 i.i.d3. &#x1f4dd;强化学习基本形式4. &#x1f4dd;马尔可夫过程 &#x1f31f; 强化学习&#xff08;Reinforcement Learning&#xff0c;RL&#x…

windows安装kafka配置SASL-PLAIN安全认证

目录 1.Windows安装zookeeper&#xff1a; 1.1下载zookeeper 1.2 解压之后如图二 1.3创建日志文件 1.4复制 “zoo_sample.cfg” 文件 1.5更改 “zoo.cfg” 配置 1.6新建zk_server_jaas.conf 1.7修改zkEnv.cmd 1.8导入相关jar 1.9以上配置就配好啦&#xff0c;接下来启…

小红书博主排名丨狂揽近百万粉丝,女性议题成“爆款制造机”?

从上野千鹤子和北大女生的对谈&#xff0c;到电影《消失的她》&#xff0c;再到引爆“粉色狂潮”的电影《芭比》&#xff0c;近年来&#xff0c;女性话题、两性情感话题成为社会热门议题。“踩过恋爱所有坑&#xff0c;想给姑娘撑把伞”&#xff0c;近期&#xff0c;小红书博主…

2023年华数杯数学建模B题思路代码分析 - 不透明制品最优配色方案设计

# 1 赛题 B 题 不透明制品最优配色方案设计 日常生活中五彩缤纷的不透明有色制品是由着色剂染色而成。因此&#xff0c;不透明 制品的配色对其外观美观度和市场竞争力起着重要作用。然而&#xff0c;传统的人工配色 存在一定的局限性&#xff0c;如主观性强、效率低下等。因此…

docker容器学习笔记1

docker容器是干什么用的 docker就是一个轻量级的虚拟机&#xff0c;是一个容器&#xff0c;隔离性好&#xff0c;能够确保环境的统一&#xff0c;有效利用系统资源&#xff0c;轻松迁移和拓展。简单的可以理解为容器就是一个小型功能齐全的虚拟机。 实际上是如何使用的呢&…

RocketMQ发送消息超时异常

说明&#xff1a;在使用RocketMQ发送消息时&#xff0c;出现下面这个异常&#xff08;org.springframework.messging.MessgingException&#xff1a;sendDefaultImpl call timeout……&#xff09;&#xff1b; 解决&#xff1a;修改RocketMQ中broke.conf配置&#xff0c;添加下…

2023华数杯数学建模竞赛C题思路解析

如下为&#xff1a;2023华数杯数学建模竞赛C题 母亲身心健康对婴儿成长的影响 的思路解析 C题 母亲身心健康对婴儿成长的影响 母亲是婴儿生命中最重要的人之一&#xff0c;她不仅为婴儿提供营养物质和身体保护&#xff0c;还为婴儿提供情感支持和安全感。母亲心理健康状态的不…

HCIP作业3

题目 配置IP地址 R1 [r1]int g0/0/1 [r1-GigabitEthernet0/0/1]ip add 192.168.1.1 24 [r1-Serial4/0/0]ip add 12.1.1.1 24 R2 [r2]int s4/0/0 [r2-Serial4/0/0]ip add 12.1.1.2 24 [r2-Serial4/0/0]int s4/0/1 [r2-Serial4/0/1]ip add 32.1.1.1 24 [r2-Serial4/0/1]in…

数据管理基础知识

数据管理原则 数据管理与其他形式的资产管理的共同特征&#xff0c;涉及了解组织拥有哪些数据以及可以使用这些数据完成哪些工作&#xff0c;然后确定如何最好的使用数据资产来实现组织目标与其他流程一样&#xff0c;他必须平衡战略和运营需求&#xff0c;通过遵循一套原则&a…