安卓逆向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系统添加新数据盘...
-
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...
你 发表评论:
欢迎- 一周热门
-
-
Linux:Ubuntu22.04上安装python3.11,简单易上手
-
宝马阿布达比分公司推出独特M4升级套件,整套升级约在20万
-
MATLAB中图片保存的五种方法(一)(matlab中保存图片命令)
-
别再傻傻搞不清楚Workstation Player和Workstation Pro的区别了
-
Linux上使用tinyproxy快速搭建HTTP/HTTPS代理器
-
如何提取、修改、强刷A卡bios a卡刷bios工具
-
Element Plus 的 Dialog 组件实现点击遮罩层不关闭对话框
-
日本组合“岚”将于2020年12月31日停止团体活动
-
SpringCloud OpenFeign 使用 okhttp 发送 HTTP 请求与 HTTP/2 探索
-
tinymce 号称富文本编辑器世界第一,大家同意么?
-
- 最近发表
- 标签列表
-
- dialog.js (57)
- importnew (44)
- windows93网页版 (44)
- yii2框架的优缺点 (45)
- tinyeditor (45)
- qt5.5 (60)
- windowsserver2016镜像下载 (52)
- okhttputils (51)
- android-gif-drawable (53)
- 时间轴插件 (56)
- docker systemd (65)
- slider.js (47)
- android webview缓存 (46)
- pagination.js (59)
- loadjs (62)
- openssl1.0.2 (48)
- velocity模板引擎 (48)
- pcre library (47)
- zabbix微信报警脚本 (63)
- jnetpcap (49)
- pdfrenderer (43)
- fastutil (48)
- uinavigationcontroller (53)
- bitbucket.org (44)
- python websocket-client (47)