百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

安卓逆向jni的base笔记 安卓逆向教程 全套

suiw9 2024-11-11 15:53 25 浏览 0 评论

免责声明

本文章中所有内容仅供学习交流使用,严禁用于商业用途和非法用途。若有侵权,请联系我,立即删除!

获取当前程序的包名

adb shell dumpsys window | grep mCurrentFocus

frida 手动jnienv

frida -U -f com.james.easymd5 -l frida_hook_libart/hook_art.js --no-pause

frida 自动追踪 jnitracer

pip install jnitrace


利用objection找so名====>libeasymd5.so
    objection -g com.james.easymd5 explore
    memory list modules


      ps: libeasymd5.so    0x7386f08000  221184 (216.0 KiB)    /data/app/com.james.easymd5-3XeGcE9nwvgObFyalCNGsA==/lib/arm64/libeasymd5.s...


    emory list exports libeasymd5.so                                                                                                                     
      Save the output by adding `--json exports.json` to this command
      Type      Name                                          Address
      --------  --------------------------------------------  ----------
      function  Java_com_james_easymd5_MainActivity_mdFile    0xd2b96e39
      function  _Z7MD5InitP7MD5_CTX                           0xd2b96b63
      function  Java_com_james_easymd5_MainActivity_mdString  0xd2b96a59
      function  _Z9MD5UpdateP7MD5_CTXPhj                      0xd2b96ba5
      function  _ZN7_JNIEnv12NewStringUTFEPKc                 0xd2b96e19
      function  _Z8MD5FinalP7MD5_CTX                          0xd2b96c85
      function  _ZN7_JNIEnv17GetStringUTFCharsEP8_jstringPh   0xd2b96b3d


c++filt _Z9MD5UpdateP7MD5_CTXPhj
    MD5Update(MD5_CTX*, unsigned char*, unsigned int)


    命令:jnitrace -l libeasymd5.so com.james.easymd5   


    Tracing. Press any key to quit...
    Traced library "libeasymd5.so" loaded from path "/data/app/com.james.easymd5-3XeGcE9nwvgObFyalCNGsA==/lib/arm64".


             /* TID 7350 */
      370 ms [+] JNIEnv->NewStringUTF
      370 ms |- JNIEnv*          : 0x73a98cc1c0
      370 ms |- char*            : 0x7fd63a6cc1
      370 ms |:     Hello from C++
      370 ms |= jstring          : 0x75    { Hello from C++ }


      370 ms ----------------------------------------Backtrace----------------------------------------
      370 ms |->       0x7392b97098: _ZN7_JNIEnv12NewStringUTFEPKc+0x2c (libeasymd5.so:0x7392b88000)
      370 ms |->       0x7392b97098: _ZN7_JNIEnv12NewStringUTFEPKc+0x2c (libeasymd5.so:0x7392b88000)      

frida Hook so位置

frida -U -f com.james.easymd5 -l dump_dex.js --no-pause
    [Google Pixel XL::com.james.easymd5]-> android_dlopen_ext: /data/app/com.james.easymd5-7ZxsaFkVCnATrcrvoqQcSA==/oat/arm/base.odex
    android_dlopen_ext: /data/app/com.james.easymd5-7ZxsaFkVCnATrcrvoqQcSA==/lib/arm/libeasymd5.so
    android_dlopen_ext: /vendor/lib/hw/gralloc.msm8996.so
    dlopen: libadreno_utils.so
    dlopen: /vendor/lib/egl/libEGL_adreno.so
    android_dlopen_ext: /vendor/lib/hw/android.hardware.graphics.mapper@2.0-impl.so
    android_dlopen_ext: /vendor/lib/hw/gralloc.msm8996.so

read elf查看导出表

7z x app-debug.apk
  cd lib/armeabi-v7a
  readelf -s libeasymd5.so


    Symbol table '.dynsym' contains 30 entries:
       Num:    Value  Size Type    Bind   Vis      Ndx Name
         0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
         1: 00000000     0 FUNC    GLOBAL DEFAULT  UND __cxa_atexit@LIBC (2)
         2: 00000000     0 FUNC    GLOBAL DEFAULT  UND __cxa_f[...]@LIBC (2)
         3: 00000000     0 OBJECT  GLOBAL DEFAULT  UND __sF@LIBC (2)
         4: 00000000     0 FUNC    GLOBAL DEFAULT  UND __stack[...]@LIBC (2)
         5: 00000000     0 OBJECT  GLOBAL DEFAULT  UND __stack[...]@LIBC (2)
         6: 00000000     0 FUNC    GLOBAL DEFAULT  UND __strlen_chk@LIBC (2)
         7: 00000000     0 FUNC    GLOBAL DEFAULT  UND __vspri[...]@LIBC (2)
         8: 00000000     0 FUNC    GLOBAL DEFAULT  UND fclose@LIBC (2)
         9: 00000000     0 FUNC    GLOBAL DEFAULT  UND fopen@LIBC (2)
        10: 00000000     0 FUNC    GLOBAL DEFAULT  UND fprintf@LIBC (2)
        11: 00000000     0 FUNC    GLOBAL DEFAULT  UND fread@LIBC (2)
        12: 00000000     0 FUNC    GLOBAL DEFAULT  UND strlen@LIBC (2)
        13: 00000000     0 FUNC    GLOBAL DEFAULT  UND abort@LIBC (2)
        14: 00000000     0 FUNC    GLOBAL DEFAULT  UND fflush@LIBC (2)
        15: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_memclr
        16: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_memcpy
        17: 00000000     0 FUNC    GLOBAL DEFAULT  UND __gnu_Unwind_Fin[...]
        18: 00000000     0 FUNC    GLOBAL DEFAULT  UND dladdr@LIBC (3)
        19: 00000000     0 FUNC    GLOBAL DEFAULT  UND snprintf@LIBC (2)
        20: 00000e39   324 FUNC    GLOBAL DEFAULT   13 Java_com_james_e[...]
        21: 00000b63    66 FUNC    GLOBAL DEFAULT   13 _Z7MD5InitP7MD5_CTX
        22: 00005044     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
        23: 00005045     0 NOTYPE  GLOBAL DEFAULT  ABS _end
        24: 00000a59   228 FUNC    GLOBAL DEFAULT   13 Java_com_james_e[...]
        25: 00000ba5   224 FUNC    GLOBAL DEFAULT   13 _Z9MD5UpdateP7MD[...]
        26: 00000e19    32 FUNC    WEAK   DEFAULT   13 _ZN7_JNIEnv12New[...]
        27: 00005044     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
        28: 00000c85   284 FUNC    GLOBAL DEFAULT   13 _Z8MD5FinalP7MD5_CTX
        29: 00000b3d    38 FUNC    WEAK   DEFAULT   13 _ZN7_JNIEnv17Get[...]


  objdump -T libeasymd5.so


    libeasymd5.so:     file format elf32-little


    DYNAMIC SYMBOL TABLE:
    00000000      DF *UND*  00000000 (LIBC)       __cxa_atexit
    00000000      DF *UND*  00000000 (LIBC)       __cxa_finalize
    00000000      DO *UND*  00000000 (LIBC)       __sF
    00000000      DF *UND*  00000000 (LIBC)       __stack_chk_fail
    00000000      DO *UND*  00000000 (LIBC)       __stack_chk_guard
    00000000      DF *UND*  00000000 (LIBC)       __strlen_chk
    00000000      DF *UND*  00000000 (LIBC)       __vsprintf_chk
    00000000      DF *UND*  00000000 (LIBC)       fclose
    00000000      DF *UND*  00000000 (LIBC)       fopen
    00000000      DF *UND*  00000000 (LIBC)       fprintf
    00000000      DF *UND*  00000000 (LIBC)       fread
    00000000      DF *UND*  00000000 (LIBC)       strlen
    00000000      DF *UND*  00000000 (LIBC)       abort
    00000000      DF *UND*  00000000 (LIBC)       fflush
    00000000      DF *UND*  00000000              __aeabi_memclr
    00000000      DF *UND*  00000000              __aeabi_memcpy
    00000000      DF *UND*  00000000              __gnu_Unwind_Find_exidx
    00000000      DF *UND*  00000000 (LIBC)       dladdr
    00000000      DF *UND*  00000000 (LIBC)       snprintf
    00000e39 g    DF .text  00000144  Base        Java_com_james_easymd5_MainActivity_mdFile
    00000b63 g    DF .text  00000042  Base        _Z7MD5InitP7MD5_CTX
    00005044 g    D  *ABS*  00000000  Base        _edata
    00005045 g    D  *ABS*  00000000  Base        _end
    00000a59 g    DF .text  000000e4  Base        Java_com_james_easymd5_MainActivity_mdString
    00000ba5 g    DF .text  000000e0  Base        _Z9MD5UpdateP7MD5_CTXPhj
    00000e19  w   DF .text  00000020  Base        _ZN7_JNIEnv12NewStringUTFEPKc
    00005044 g    D  *ABS*  00000000  Base        __bss_start
    00000c85 g    DF .text  0000011c  Base        _Z8MD5FinalP7MD5_CTX
    00000b3d  w   DF .text  00000026  Base        _ZN7_JNIEnv17GetStringUTFCharsEP8_jstringPh

Frida hook jni

Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"), {
        onEnter: function(args) {
            var pathptr = args[0];
            this.target = false
            if (pathptr !== undefined && pathptr != null) {
                var path = ptr(pathptr).readCString();
                console.log("android_dlopen_ext:", path);
                if (path.indexOf("libeasymd5.so") >= 0) {
                    this.target = true;
                    console.log("[android_dlopen_ext:]", path);
                }
            }
        },
        onLeave: function(retval) {
            if (this.target) {
                var mdString_addr = Module.findExportByName("libeasymd5.so","Java_com_james_easymd5_MainActivity_mdString");
                console.log("mdString address is => ",mdString_addr)
                Interceptor.attach(mdString_addr, {
                    onEnter: function (args) {
                        console.log("arg2 jstring => ", args[2]);//mdString的方法第三个参数是我们要的值
                        console.log("arg2 jstring => ", Java.vm.tryGetEnv().getStringUtfChars(args[2], null).readCString());
                        console.log('CCCryptorCreate called from:\n' +
                            Thread.backtrace(this.context, Backtracer.ACCURATE)
                                .map(DebugSymbol.fromAddress).join('\n') + '\n');


                    }, onLeave: function (retval) {


                        console.log("retval is => ", retval);
                        console.log("retval is => ", Java.vm.tryGetEnv().getStringUtfChars(retval, null).readCString());
                    }
                })
            }
            // if (this.can_hook_libart && !is_hook_libart) {
            //     dump_dex();
            //     is_hook_libart = true;
            // }
        }
    });


  ps: Invoke JNI===>Java.vm.tryGetEnv()


  结果:
    [Google Pixel XL::com.james.easymd5]-> android_dlopen_ext: /data/app/com.james.easymd5-7ZxsaFkVCnATrcrvoqQcSA==/oat/arm/base.odex
  android_dlopen_ext: /data/app/com.james.easymd5-7ZxsaFkVCnATrcrvoqQcSA==/lib/arm/libeasymd5.so
  [android_dlopen_ext:] /data/app/com.james.easymd5-7ZxsaFkVCnATrcrvoqQcSA==/lib/arm/libeasymd5.so
  mdString address is =>  0xd1873a59
  arg2 jstring =>  0xffc6e2f0
  arg2 jstring =>  1234567890
  CCCryptorCreate called from:
  0xd1a6a143 base.odex!oatexec+0x143                                                                                                                                                                                                                                                                                                                                                                                                                 


  retval is =>  0x79
  retval is =>  e807f1fcf82d132f9bb018ca6738a19f
  android_dlopen_ext: /vendor/lib/hw/gralloc.msm8996.so
  dlopen: libadreno_utils.so
  dlopen: /vendor/lib/egl/libEGL_adreno.so
  android_dlopen_ext: /vendor/lib/hw/android.hardware.graphics.mapper@2.0-impl.so
  android_dlopen_ext: /vendor/lib/hw/gralloc.msm8996.so






Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"), {
        onEnter: function(args) {
            var pathptr = args[0];
            this.target = false
            if (pathptr !== undefined && pathptr != null) {
                var path = ptr(pathptr).readCString();
                console.log("android_dlopen_ext:", path);
                if (path.indexOf("libeasymd5.so") >= 0) {
                    this.target = true;
                    console.log("[android_dlopen_ext:]", path);
                }
            }
        },
        onLeave: function(retval) {
            if (this.target) {
                var mdString_addr = Module.findExportByName("libeasymd5.so","Java_com_james_easymd5_MainActivity_mdString");
                console.log("mdString address is => ",mdString_addr)




                var md5string = new NativeFunction(mdString_addr,"pointer",["pointer","pointer","pointer"]);
            
                Interceptor.replace(mdString_addr,new NativeCallback(function(env, jclass,jstring){
                    
                    console.log(Java.vm.tryGetEnv().getStringUtfChars(jstring, null).readCString())
                    var newJSTRING = Java.vm.tryGetEnv().newStringUtf('james123456');
                    var retval = md5string(env, jclass,newJSTRING);
                    console.log("retval is => ", Java.vm.tryGetEnv().getStringUtfChars(retval, null).readCString());                                   
                
                    return newJSTRING;
                },"pointer",["pointer","pointer","pointer"]))


            }
            // if (this.can_hook_libart && !is_hook_libart) {
            //     dump_dex();
            //     is_hook_libart = true;
            // }
        }
    });


 结果:
   [Google Pixel XL::com.james.easymd5]-> android_dlopen_ext: /data/app/com.james.easymd5-qBJw9ZijDSWX-eOLgtln-A==/oat/arm/base.odex
  android_dlopen_ext: /data/app/com.james.easymd5-qBJw9ZijDSWX-eOLgtln-A==/lib/arm/libeasymd5.so
  [android_dlopen_ext:] /data/app/com.james.easymd5-qBJw9ZijDSWX-eOLgtln-A==/lib/arm/libeasymd5.so
  mdString address is =>  0xd17d2a59
  1234567890
  retval is =>  cc6e7cb7cb71073647e833e2fb89482b

jni的动态注册(jni_onload)

1、// Dynamic register


  #define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))




  jstring zlj666(
          JNIEnv *env, jclass obj, jstring str) {
      MD5_CTX mdContext;
      int m = 0;
      char *inString = const_cast<char *>(env->GetStringUTFChars(str, NULL));


      unsigned int len = strlen(inString);


      MD5Init(&mdContext);
      MD5Update(&mdContext, reinterpret_cast<unsigned char *>(inString), len);
      MD5Final(&mdContext);


      int i;
      char dest[32] = { 0 };
      for (i = 0; i < 16; i++) {
          sprintf(dest + i * 2, "%02x", mdContext.digest[i]);
      }


      return env->NewStringUTF(dest);
  }


  // name (java function name) signature【签名】 jadx打开看mdString的smali的后缀
  static JNINativeMethod method_table[] = {
          {"mdString", "(Ljava/lang/String;)Ljava/lang/String;", (void *) zlj666},
  };


  static int registerMethods(JNIEnv *env, const char *className,
                             JNINativeMethod *gMethods, int numMethods) {
      jclass clazz = env->FindClass(className);
      if (clazz == nullptr) {
          return JNI_FALSE;
      }
      if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
          return JNI_FALSE;
      }
      return JNI_TRUE;
  }


  JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
      JNIEnv *env = nullptr;
      if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
          return JNI_ERR;
      }


      // 注册native方法
      if (!registerMethods(env,"com/james/easymd5/MainActivity" , method_table, NELEM(method_table))) {
          return JNI_ERR;
      }


      return JNI_VERSION_1_6;
  }




  2、frida hook jni动态注册
    2.1java层调用:
      setTimeout(() => {
          Java.perform(() => {
              var result = Java.use("com.james.easymd5.MainActivity").mdString("1234567890");
              console.log("result is => ",result)


          })
      }, 0);
      frida -UF -l invoke.js --runtime=V8   【程序要在运行中】
      结果:
        result is =>  e807f1fcf82d132f9bb018ca6738a19f
    2.2nativ层调用
    
     Java.perform(() => {


          var zlj666_address = Module.findExportByName('libeasymd5.so',"_Z6zlj666P7_JNIEnvP7_jclassP8_jstring")
          console.log("found address =>", zlj666_address)
          var zlj666 = new NativeFunction(zlj666_address, "pointer", ["pointer", "pointer", "pointer"]);
          var newJSTRING = Java.vm.tryGetEnv().newStringUtf("12345james")
          var result = zlj666(Java.vm.tryGetEnv(), Java.vm.tryGetEnv(), newJSTRING);
          console.log("result is => ", Java.vm.tryGetEnv().getStringUtfChars(result, null).readCString());


      })
      结果:
        found address => 0xd6b9cba5
      result is =>  048943059b19127c86e2069c6e804f3f
      [Google Pixel XL::easymd5]->  


    2.3脱离app环境运行so环境
      adb push libeasymd5.so /data/local/tmp
      cp -rf libeasymd5.so  /data/app
      chmod 777 libeasymd5.so


          Java.perform(() => {
              var module = Module.load("/data/app/libeasymd5.so")
              var zlj666_address = module.findExportByName("_Z6zlj666P7_JNIEnvP7_jclassP8_jstring")
              console.log("found address =>", zlj666_address)
              var zlj666 = new NativeFunction(zlj666_address, "pointer", ["pointer", "pointer", "pointer"]);
              var newJSTRING = Java.vm.tryGetEnv().newStringUtf("12345james")
              var result = zlj666(Java.vm.tryGetEnv(), Java.vm.tryGetEnv(), newJSTRING);
              console.log("result is => ", Java.vm.tryGetEnv().getStringUtfChars(result, null).readCString());


          })




      结果:
        found address => 0xd6b9cba5
        result is =>  048943059b19127c86e2069c6e804f3f
        [Google Pixel XL::easymd5]->


      判断32/64位进程:660就是32位
      marlin:/data/app # ps -ef | grep -i zyg
      root           659     1 1 16:25:38 ?     00:33:28 zygote64
      root           660     1 0 16:25:38 ?     00:00:02 zygote


      marlin:/data/app # ps -ef | grep -i 660                                                                                                                                                           
      root           660     1 0 16:25:38 ?     00:00:02 zygote
      u0_a134       5071   660 0 15:17:58 ?     00:00:06 com.james.easymd5


    2.4 调用非静态函数(java调用对象或者实例一个对象)
        Java.scheduleOnMainThread(() =>{
            var result = Java.use("com.roysue.easymd5.MainActivity").$new().mdString("12345james");
            console.log("result is => ",result)
        })
      结果:
        found address => 0xd6b9cba5
        result is =>  048943059b19127c86e2069c6e804f3f
        [Google Pixel XL::easymd5]->

unidbg调用jni

public class MainActivity {


      public static void main(String[] args) {
          long start = System.currentTimeMillis();
          com.james.easymd5.MainActivity mainActivity = new com.james.easymd5.MainActivity();
          System.out.println("load offset=" + (System.currentTimeMillis() - start) + "ms");
          mainActivity.crack();
      }


      private final AndroidEmulator emulator;
      private final VM vm;
      private final DvmClass dvmClass;


      private MainActivity() {
          emulator = AndroidEmulatorBuilder
                  .for32Bit()
                  .addBackendFactory(new DynarmicFactory(true))
                  .build();
          Memory memory = emulator.getMemory();
          LibraryResolver resolver = new AndroidResolver(23);
          memory.setLibraryResolver(resolver);


          vm = emulator.createDalvikVM();
          vm.setVerbose(true); // 日志开关
          DalvikModule dm = vm.loadLibrary(new File("unidbg-android/src/test/resources/example_binaries/armeabi-v7a/libeasymd5.so"), false);
          dm.callJNI_OnLoad(emulator);
          dvmClass = vm.resolveClass("com/james/easymd5/MainActivity");
      }


      private void crack() {




      //静态函数
          DvmObject result =  dvmClass.callStaticJniMethodObject(emulator,"mdString(Ljava/lang/String;)Ljava/lang/String;","12345james");
          System.out.println("result is => " + result.getValue());
      //非静态函数
          DvmObject<?> obj = ProxyDvmObject.createObject(vm, this);
          DvmObject result2  = obj.callJniMethodObject(emulator,"mdString(Ljava/lang/String;)Ljava/lang/String;","12345james");
          System.out.println("result2 is => " + result2.getValue());




      }
  }
  结果:
    JNIEnv->FindClass(com/james/easymd5/MainActivity) was called from RX@0x40001ed1[libeasymd5.so]0x1ed1
    JNIEnv->RegisterNatives(com/james/easymd5/MainActivity, RW@0x40005000[libeasymd5.so]0x5000, 1) was called from RX@0x40001f01[libeasymd5.so]0x1f01
    RegisterNative(com/james/easymd5/MainActivity, mdString(Ljava/lang/String;)Ljava/lang/String;, RX@0x40000ba5[libeasymd5.so]0xba5)
    load offset=734ms
    Find native function Java_com_james_easymd5_MainActivity_mdString => RX@0x40000ba5[libeasymd5.so]0xba5
    JNIEnv->GetStringUtfChars("12345james") was called from RX@0x40000cb7[libeasymd5.so]0xcb7
    JNIEnv->NewStringUTF("048943059b19127c86e2069c6e804f3f") was called from RX@0x40000f8d[libeasymd5.so]0xf8d
    result is => 048943059b19127c86e2069c6e804f3f
    Find native function Java_com_james_easymd5_MainActivity_mdString => RX@0x40000ba5[libeasymd5.so]0xba5
    JNIEnv->GetStringUtfChars("12345james") was called from RX@0x40000cb7[libeasymd5.so]0xcb7
    JNIEnv->NewStringUTF("048943059b19127c86e2069c6e804f3f") was called from RX@0x40000f8d[libeasymd5.so]0xf8d
    result2 is => 048943059b19127c86e2069c6e804f3f
    

相关推荐

设置文件的默认打开方式(如何设定文件的默认打开方式)

在操作系统中,设置文件的默认打开方式可以让特定类型的文件始终使用你选择的程序打开。以下是Windows和macOS系统中设置默认打开方式的详细步骤:Windows系统方法1:通过文件属性设置右键点...

电脑怎么设置默认浏览器(电脑怎么设置默认浏览器?)

在电脑上设置默认浏览器的步骤因操作系统不同而有所差异。以下是Windows和Mac系统的设置方法:Windows系统方法1:通过系统设置打开“设置”:...

Java接口默认方法:灵活与约束并存

Java接口默认方法:灵活与约束并存在Java编程的世界里,接口作为定义行为规范的重要工具,一直扮演着举足轻重的角色。然而,在Java8引入了默认方法之后,接口的设计和使用方式发生了微妙的变化。今天...

Java8新特性之默认方法:为接口注入灵魂

Java8新特性之默认方法:为接口注入灵魂Java8发布时,它带来的最大创新之一就是接口的默认方法。这就像给一个传统的木偶注入了生命,让它不仅能动还能说话了。今天我们就来聊聊这个让Java开发者欢呼雀...

CentOS系统在不重启的情况下为虚拟机添加新硬盘

一、概述用过虚拟机的都知道,如果在系统运行的时候去给虚拟机添加一块新设备,比如说硬盘,系统是读取不到这个新硬盘的,因为系统在启动的时候会去检测硬件设备。但是我们也可能会遇到这样的情况,比如正在运行比较...

[常用工具] 基于psutil和GPUtil获取系统状态信息

本文主要介绍在Python3中利用psutil库获取系统状态,利用GPUtil获取gpu状态。psutil(processandsystemutilities)(进程和系统实用程序)是一个跨平...

Docker容器内执行宿主机指令(docker执行宿主机shell)

一背景最近项目有个需求,需要程序配置服务器IP并且可以重启服务器。如果程序直接部署在服务器,相信大家都会操作。但是程序是用docker运行的,在docker中执行指令就很麻烦了。...

容器网络调试怎么办?一条命令就搞定!

nsenter命令是一个可以在指定进程的命令空间下运行指定程序的命令。它位于util-linux包中。用途...

linux自动化巡检脚本集(linux服务器巡检内容以及标准)

以下是一个自动化巡检脚本集的制作方案,包含常见系统检查项和可扩展框架,使用Python和Shell脚本实现:...

麒麟KOS|统信UOS系统添加新数据盘
麒麟KOS|统信UOS系统添加新数据盘

原文链接:麒麟KOS|统信UOS系统添加新数据盘...

2025-03-26 16:57 suiw9

Linux CentOS 7 根目录扩容(linux扩展根目录磁盘空间)

一、现状描述现有一台CentOS7的虚拟机,硬盘容量为30GB通过lsblk命令查看分区容量,当前根目录容量为27.5GB左右二、扩容需求...

从Linux底层分析Docker原理(linux docker-compose)

写在前面如果你觉得本人对你有帮助,请你记得评论,点赞,关注;如果你觉得文章还不错请记得收藏,点赞。如果你觉得文章非常的好可以私信我,我会在第一时间回复你。...

CentOS新增硬盘的使用步骤(centos扩展硬盘)

一、查看机器所挂硬盘个数及分区情况,新增硬盘为/dev/sdb...

Python之psutil库简介(python3 pil库)

psutil(pythonsystemandprocessutilities)是一个跨平台的第三方库,能够轻松实现获取系统运行的进程和系统利用率(包扩CPU、内存、磁盘、网络等)信息。它主...

运维,你还不会查看Linux系统cpu信息?

CPU也称为微处理器或简称为处理器。就像大脑如何控制人体一样,CPU控制着计算机的所有部分。因此CPU被认为是计算机的大脑。那我们怎么在Linux系统中查看如IntelCorei3、i5、AM...

取消回复欢迎 发表评论: