IDA+Frida分析CTF样本和Frid源码和objection模块
文章目录
- 一些资料
- IDA调试命令
- IDA调试安卓的10个技巧
- objection基本使用+ Wallbreaker1
- frida源码阅读之frida-java
- 第一个实例EasyJNI
- 第二个实例
- objection
- 资料
- art_trace2.py
- art_trace2.js
IDA+Frida分析CTF样本和Frid源码和objection模块
一些资料
IDA调试命令
adb devices
adb push d:\as /data/local/tmp/asadb shell
suchmod 777 /data/local/tmp/as/data/local/tmp/as
/data/local/tmp/as -p31928再开一个cmd窗口
adb forward tcp:23946 tcp:23946
adb forward tcp:31928 tcp:31928adb shell am start -D -n com.yaotong.crackme/.MainActivity
adb shell am start -D -n com.wolf.ndktest/.MainActivity
adb shell am start -D -n com.faloo.BookReader4Android/com.faloo.app.activity.LogoPageActivity
adb shell am start -D -n com.example.helloworld/com.example.helloworld.MainActivity
adb shell am start -D -n com.pingan.peanut/com.pingan.peanut.activity.GuideActivity
adb shell am start -D -n com.lalamove.huolala.driver/.main.mvp.ui.SplashActivity打开DDMS或者执行adb forward tcp:8700 jdwp:7319jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8616如果出现错误
查看serverSocket所监听的端口
netstat -naostatic main(void)
{
auto fp, dexAddress, end, size;
dexAddress = 0xD9B18000;
size = 0xBF000;
end = dexAddress + size;
fp = fopen("C:\\Users\\Administrator\\Desktop\\upx.so", "wb");
for ( ; dexAddress < end; dexAddress++ )
fputc(Byte(dexAddress), fp);
}动态调式本身就是很复杂的,和APP本身,安卓系统,IDA软件,电脑环境,要下断的函数等都有联系,
任何一个因素都可能影响动态调试的成败。大部分错误都在JDB启动那一步,网上没有好的解决或原因
分析,下面就做一些小结:
1.不满足动态调试条件,安卓系统配置文件build.prop的ro.debugable或APP的Androidmainfest.xml中的android:debugable,必须两个有1个为true。
2.使用jdb前的步骤出现错误:如android_server文件权限不够,没有am start启动目标程序等。
3.一般来说,使用jdb连接前后都是可以下断的,但确实会出现,有的必须jdb连接前下断,有的必须jdb连接后下断,否则可能出现错误。
4.虽然说jdb连接前后都可以下断,但在jdb连接前,一定要先用IDA附加,这个次序是一定的。
5.jdb属于电脑的JDK,如果JDK出错,JDB也可能出错。有关so层逆向分析的问题
问题解决:
1.加密方法在一个叫libmt2.so的so文件中,然后用ida动态调试附加之后,
发现搜不到这个libmt2.so的so文件,这种类型问题怎么解决?第一步:要先判断so文件是否已经加载到内存中 如果在IDA里面搜索不到第二步:cat /proc/$pid/maps 执行该命令获取模块列表信息获取指定应用程序的进程pidps 获取当前存在进程信息补充:|grep 特征字符串ida工具里面搜索不到? 如何下段调试?解决方法:
b3cfe000-b3d0c000 r-xp 00000000 b3:17 521239 /data/app/bin.mt.plus-2/lib/arm/libmt2.so
b3d0c000-b3d0d000 r--p 0000d000 b3:17 521239 /data/app/bin.mt.plus-2/lib/arm/libmt2.so
b3d0d000-b3d0e000 rw-p 0000e000 b3:17 521239 /data/app/bin.mt.plus-2/lib/arm/libmt2.sob3cfe000 模块起始地址+偏移地址(ida静态分析时在反汇编窗口中的左边的地址栏)dd if=/dev/zero of=/data/local/tmp/info.txt bs=1 count=1if 代表输入文件。如果不指定if,默认就会从stdin中读取输入,/dev/zero 是一个字符设备,会不断返回0值字节(\0)。
of 代表输出文件。如果不指定of,默认就会将stdout作为默认输出。
bs 代表字节为单位的块大小。
count 代表被复制的块数。 获取指定进程模块信息
cat /proc/6594/maps >info.txtdex是看0x20处找大小,odex是看0x32处就有
dd if=/proc/7081/mem of=/data/local/tmp/dump.so skip=3421749248 bs=1 count=16384tcpdump+Wireshark:
adb shell tcpdump -p -vv -s 0 -w /sdcard/capture.pcap 开始抓包
ctrl+c 结束抓包
adb pull /sdcard/capture.pcap 导出文件tcpdump下载地址
https://www.androidtcpdump.com/android-tcpdump/downloads孤挺花(Armariris)基于LLVM的支持多平台多语言的混淆器开源工程:https://github.com/GoSSIP-SJTU/ArmaririsControl Flow Flattening(-fla,控制流程平坦化)
Bogus Control Flow(-bcf,虚假控制流程)
Instructions Substitution & SplitBasicBlock (-sub,指令替换)
字符串加密Pass
函数名称加密Pass分析技巧:
分析被ollvm混淆的算法的时候,关心的参数的加密过程,以及结果的生成过程。Android源码在线阅读:http://androidxref.com/http://aospxref.com/系统源码下载地址
链接:https://pan.baidu.com/s/1IW-UR2UaDQaEQKB8DRa_bg 提取码:n5sb seLinux安全机制:adb shell getenforce adb shell setenforce 0当系统引导程序启动Linux内核,内核会加载各种数据结构,和驱动程序,
加载完毕之后,Android系统开始启动并加载第一个用户级别的进程,
即init进程。
1.启动电源以及系统启动当电源按下时引导芯片代码从预定义的地方(固化在ROM)开始执行加载引导程序BootLoader到ARM,然后执行
2.引导程序bootloader引导程序BootLoader是在Android操作系统运行前的一个小程序,它的主要作用是把系统OS拉起来并运行
3.Linux内核启动当内核启动时,设置换成、被好好存储器、计划列表、加载驱动当内核完成系统设置时,它首先在系统文件中寻找init.rc文件,并启动init进程
4.init进程启动创建和挂载启动需要的文件目录初始化和启动属性服务解析init.rc配置文件并启动zygote进程
5.zygote进程启动创建AndroidRuntime并调用其start函数,启动zygote进程创建java虚拟机并为java虚拟机注册JNI函数通过JNI调用ZygoteInit的main方法进入zygote的java框架层通过registerServerSocket方法创建服务器端socket,并通过runSelectLoop方法等待AMS的请求来创建新的应用程序进程启动SystemServer进程,该进程主要用来创建系统服务
6.systemserver进程启动启动binder线程池,这样就可以与其他进程进行通信创建SystemServiceManager,其用于对系统的服务进行创建、启动和生命周期管理启动各种系统方法(引导服务、核心服务、其他服务)
7.launcher启动Android 8.1.0 libart.so 32 JNI_onLoad
.text:0024F88C
.text:0024F88C loc_24F88C ; CODE XREF: .text:0024FD9Cj
.text:0024F88C ; .text:0024FE10j
.text:0024F88C MOV R0, R6
.text:0024F88E MOVS R1, #0
.text:0024F890 BLX R5
.text:0024F892 MOV R7, R0
.text:0024F894 LDR R0, [R6,#4]
.text:0024F896 LDR.W R0, [R0,#0x2D4]
.text:0024F89A CBZ R0, loc_24F8A6
.text:0024F89C CMP R0, #0x15
.text:0024F89E BGT loc_24F8A6
.text:0024F8A0 MOVS R0, #0xBAndroid 8.1.0 libart.so 64 JNI_onLoad
.text:0000000000300F68 loc_300F68 ; CODE XREF: art::JavaVMExt::LoadNativeLibrary(_JNIEnv *,std::__1::basic_string<char,std::__1::char_traits<char>,std::__1::allocator<char>> const&,_jobject *,_jstring *,std::__1::basic_string<char,std::__1::char_traits<char>,std::__1::allocator<char>>*)+FAC↓j
.text:0000000000300F68 ; art::JavaVMExt::LoadNativeLibrary(_JNIEnv *,std::__1::basic_string<char,std::__1::char_traits<char>,std::__1::allocator<char>> const&,_jobject *,_jstring *,std::__1::basic_string<char,std::__1::char_traits<char>,std::__1::allocator<char>>*)+1030↓j
.text:0000000000300F68 MOV X0, X22
.text:0000000000300F6C MOV X1, XZR
.text:0000000000300F70 BLR X27
.text:0000000000300F74 LDR X8, [X22,#8]
.text:0000000000300F78 MOV W24, W0
.text:0000000000300F7C LDR W8, [X8,#0x4A8]
.text:0000000000300F80 CBZ W8, loc_300F94
.text:0000000000300F84 CMP W8, #0x15
.text:0000000000300F88 B.GT loc_300F94
.text:0000000000300F8C MOV W0, #0xBAndroid 8.1.0 linker 32 function
.text:00013562 LDR R1, =(aLinker - 0x13572)
.text:00013564 ADR R2, aCallingCTorSPF ; "[ Calling c-tor %s @ %p for '%s' ]"
.text:00013566 MOVS R0, #4
.text:00013568 MOV R3, R4
.text:0001356A STRD.W R6, R5, [SP]
.text:0001356E ADD R1, PC ; "linker"
.text:00013570 BL __dl_async_safe_format_log
.text:00013574
.text:00013574 loc_13574 ; CODE XREF: __dl__ZL13call_functionPKcPFviPPcS2_ES0_+18↑j
.text:00013574 LDR R0, =(__dl_g_envp_ptr - 0x1357A)
.text:00013576 ADD R0, PC ; __dl_g_envp_ptr
.text:00013578 LDR R0, [R0] ; __dl_g_envp
.text:0001357A LDR R2, [R0]
.text:0001357C LDR R0, =(__dl_g_argv_ptr - 0x13582)
.text:0001357E ADD R0, PC ; __dl_g_argv_ptr
.text:00013580 LDR R0, [R0] ; __dl_g_argv
.text:00013582 LDR R1, [R0]
.text:00013584 LDR R0, =(__dl_g_argc_ptr - 0x1358A)
.text:00013586 ADD R0, PC ; __dl_g_argc_ptr
.text:00013588 LDR R0, [R0] ; __dl_g_argc
.text:0001358A LDR R0, [R0]
.text:0001358C BLX R6
.text:0001358E LDR R0, =(__dl_g_ld_debug_verbosity - 0x13594)
.text:00013590 ADD R0, PC ; __dl_g_ld_debug_verbosity
.text:00013592 LDR R0, [R0]Android 8.1.0 linker 64 function
.text:0000000000020838 ADRP X2, #aCallingCTorSPF@PAGE ; "[ Calling c-tor %s @ %p for '%s' ]"
.text:000000000002083C MOV W0, #4
.text:0000000000020840 MOV X1, X23
.text:0000000000020844 ADD X2, X2, #aCallingCTorSPF@PAGEOFF ; "[ Calling c-tor %s @ %p for '%s' ]"
.text:0000000000020848 MOV X3, X26
.text:000000000002084C MOV X4, X28
.text:0000000000020850 MOV X5, X19
.text:0000000000020854 BL __dl_async_safe_format_log
.text:0000000000020858
.text:0000000000020858 loc_20858 ; CODE XREF: __dl__ZL10call_arrayIPFviPPcS1_EEvPKcPT_mbS5_+D0↑j
.text:0000000000020858 ADRP X8, #__dl_g_argc_ptr@PAGE
.text:000000000002085C LDR X8, [X8,#__dl_g_argc_ptr@PAGEOFF]
.text:0000000000020860 LDR W0, [X8]
.text:0000000000020864 ADRP X8, #__dl_g_argv_ptr@PAGE
.text:0000000000020868 LDR X8, [X8,#__dl_g_argv_ptr@PAGEOFF]
.text:000000000002086C LDR X1, [X8]
.text:0000000000020870 ADRP X8, #__dl_g_envp_ptr@PAGE
.text:0000000000020874 LDR X8, [X8,#__dl_g_envp_ptr@PAGEOFF]
.text:0000000000020878 LDR X2, [X8]
.text:000000000002087C BLR X28
.text:0000000000020880 LDR W8, [X25,#__dl_g_ld_debug_verbosity@PAGEOFF]
.text:0000000000020884 CMP W8, #2.text:0000000000020AE0 ADRP X1, #__dl_$d.20_0@PAGE ; "linker"
.text:0000000000020AE4 ADRP X2, #aCallingCTorSPF@PAGE ; "[ Calling c-tor %s @ %p for '%s' ]"
.text:0000000000020AE8 ADRP X3, #aDtInit@PAGE ; "DT_INIT"
.text:0000000000020AEC ADD X1, X1, #__dl_$d.20_0@PAGEOFF ; "linker"
.text:0000000000020AF0 ADD X2, X2, #aCallingCTorSPF@PAGEOFF ; "[ Calling c-tor %s @ %p for '%s' ]"
.text:0000000000020AF4 ADD X3, X3, #aDtInit@PAGEOFF ; "DT_INIT"
.text:0000000000020AF8 MOV W0, #4
.text:0000000000020AFC MOV X4, X20
.text:0000000000020B00 MOV X5, X21
.text:0000000000020B04 BL __dl_async_safe_format_log
.text:0000000000020B08
.text:0000000000020B08 loc_20B08 ; CODE XREF: __dl__ZN6soinfo17call_constructorsEv+1C0↑j
.text:0000000000020B08 ADRP X8, #__dl_g_argc_ptr@PAGE
.text:0000000000020B0C ADRP X9, #__dl_g_argv_ptr@PAGE
.text:0000000000020B10 ADRP X10, #__dl_g_envp_ptr@PAGE
.text:0000000000020B14 LDR X8, [X8,#__dl_g_argc_ptr@PAGEOFF]
.text:0000000000020B18 LDR X9, [X9,#__dl_g_argv_ptr@PAGEOFF]
.text:0000000000020B1C LDR X10, [X10,#__dl_g_envp_ptr@PAGEOFF]
.text:0000000000020B20 LDR W0, [X8]
.text:0000000000020B24 LDR X1, [X9]
.text:0000000000020B28 LDR X2, [X10]
.text:0000000000020B2C BLR X20
.text:0000000000020B30 LDR W8, [X23,#__dl_g_ld_debug_verbosity@PAGEOFF]
.text:0000000000020B34 CMP W8, #2
IDA调试安卓的10个技巧
objection基本使用+ Wallbreaker1
frida源码阅读之frida-java
第一个实例EasyJNI
发现只有32位的so
运行64位的frida
常见的ps命令及输出格式
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 168448 9776 ? Ss Aug28 0:03 /usr/lib/systemd/systemd --system --deserialize 19
root 2 0.0 0.0 0 0 ? S Aug28 0:00 [kthreadd]
...
第二个实例
jadx先看java代码,看调用的时机
复制这个代码
找到偏移地址
因为我的手机是64位的,将64位的so库放入到IDA工具中
选中我们要调试的函数
如何看64位的指令
arm64位指令集
将Graph View切换成TextView
目标要得到的结果
IDA导入头文件
- 步骤一:点击IDA Pro 菜单项“File->Load file->Parse c header file ” 选择jni.h头文件
- 步骤二:点击IDA Pro 主界面上的“Structures”选项卡 然后按下Insert键打开“Create structure/union”对话框,点击界面上的"Add standard structure"按钮,在打开的结构体选择对话框中选择JNINativeInterface并点击OK返回,同理JNIInvokeInterface结构体也导入进来
- 步骤四:在0x29C等调用env的地方右键,出现jni函数
输出一个结果
使用下面的脚本
// HOOK未导出函数
function Test02() {// 绝对地址=so模块起始地址(基地址)+偏移地址let baseAddr = Module.findBaseAddress("libcyberpeace.so");send("baseAddr:" + baseAddr);// 指令集 分为ARM指令、thumb指令// ARM指令地址不变 thumb指令地址+1 sub_ 开头的函数 这种函数只能使用这种方式来进行Interceptor.attach(baseAddr.add(0x840), {onEnter: function (args) {send("============CheckString===============");send(args[0]); // 第一个参数send(args[1]); // 第二个参数send(args[2]); // 第三个参数// 获取JNIEnv*let env = Java.vm.tryGetEnv();// 将jstring 转换 const char*let str = env.getStringUtfChars(args[2], 0);send(str.readCString());console.log(hexdump(str, {offset: 0,length: 32,header: true,ansi: false}));},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());}});
}Java.perform(function () {Test02();
})
能得到正确的结果
返回结果是0x0,并不是我们想要的结果,所以要使用IDA调试一下
关闭frida-server
使用64位的android_server64
选择一个进程
搜索模块
双击进入, 并找到我们要找到的函数
跳转到你想要看指定寄存器的位置
老师又返回看了看静态分析的函数
拿数据
分析后的结果
objection
资料
Windows/Ubuntu安装frida和objection 原创
kali Linux 逆向环境pyenv、Frida、objection、jadx、的安装
先运行frida-sever
端口转发
跳转到指定的界面
生成Hook样例代码
监控类
art_trace2.py
# -*- coding: utf-8 -*-import os
import sys
import frida
import codecsdef message(message, data):if message["type"] == 'send':print("[*] {0}".format(message['payload']))else:print(message)# process = frida.get_remote_device().attach('Transformers')
# if not os.path.isfile('./art_trace2.js'):
# raise TypeError("./art_trace2.js does not exist")
# with codecs.open('./art_trace2.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()
rdev = frida.get_remote_device()
pid = rdev.spawn(["com.zhuotong.crackme"])
process = rdev.attach(pid)
if not os.path.isfile('art_trace2.js'):raise TypeError("./art_trace2.js does not exist")
with codecs.open('art_trace2.js', 'r', 'UTF-8') as file:js_code = file.read()
script = process.create_script(js_code)
script.on('message', message)
script.load()
rdev.resume(pid)
sys.stdin.read()
art_trace2.js
Java.perform(function () {let symbols = Module.enumerateSymbolsSync("libart.so");let addrRegisterNatives = null;for (let i = 0; i < symbols.length; i++) {let symbol = symbols[i];//_ZN3art3JNI15RegisterNativesEP7_JNIEnvP7_jclassPK15JNINativeMethodiif (symbol.name.indexOf("art") >= 0 &&symbol.name.indexOf("JNI") >= 0 && symbol.name.indexOf("RegisterNatives") >= 0 && symbol.name.indexOf("CheckJNI") < 0) {addrRegisterNatives = symbol.address;console.log("RegisterNatives is at ", symbol.address, symbol.name);}}if (addrRegisterNatives != null) {Interceptor.attach(addrRegisterNatives, {onEnter: function (args) {console.log("[RegisterNatives] method_count:", args[3]);let java_class = args[1];let class_name = Java.vm.tryGetEnv().getClassName(java_class);let methods_ptr = ptr(args[2]);let method_count = parseInt(args[3]);for (let i = 0; i < method_count; i++) {let name_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3));let sig_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize));let fnPtr_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize * 2));let name = Memory.readCString(name_ptr);let sig = Memory.readCString(sig_ptr);let find_module = Process.findModuleByAddress(fnPtr_ptr);console.log("[RegisterNatives] java_class:", class_name, "name:", name, "sig:", sig, "fnPtr:", fnPtr_ptr, "module_name:", find_module.name, "module_base:", find_module.base, "offset:", ptr(fnPtr_ptr).sub(find_module.base));// console.log("[RegisterNatives] java_class:", class_name, "name:", name, "sig:", sig, "fnPtr:", fnPtr_ptr);}}});}
});
相关文章:

IDA+Frida分析CTF样本和Frid源码和objection模块
文章目录 一些资料IDA调试命令IDA调试安卓的10个技巧objection基本使用 Wallbreaker1frida源码阅读之frida-java 第一个实例EasyJNI第二个实例objection资料 art_trace2.pyart_trace2.js IDAFrida分析CTF样本和Frid源码和objection模块 一些资料 IDA调试命令 adb devices adb…...

ConCurrentHashMap常见面试题
1. JDK1.7和JDK1.8中ConCurrentHashMap的实现有什么不同? JDK1.7中的实现可以认为是大数组套小数组,大数组是Segment数组,小数组是HashEntry数组,锁是锁在大数组的元素上(Segment),力度比较大&…...
mysql数据备份并重置
mysql数据备份并重置 1.备份mysql数据 mysqldump -uroot --single-transaction -R -E --databases lc2 cpm a10_goods self_warehouse > /mnt/vdc1/var/lib/mysql/datadir/lc2_cpm_a10_goods_self_warehouse.sql -p Y6B2wb 2.初始化mysql mysqld --initialize; 3.修改配…...

I- yh的线段(2023河南萌新联赛第(四)场:河南大学)
链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网 yh喜欢好线段,好线段即两条线段相交且不与其他线段重合的线段。 两条线段[l1,r1]和[l2,r2]相交(如果存在至少一个x,使得l1≤x≤r1和l2≤x≤r2,则认为两个线段…...

python与深度学习(十四):CNN和IKUN模型二
目录 1. 说明2. IKUN模型的CNN模型测试2.1 导入相关库2.2 加载模型2.3 设置保存图片的路径2.4 加载图片2.5 图片预处理2.6 对图片进行预测2.7 显示图片 3. 完整代码和显示结果4. 多张图片进行测试的完整代码以及结果 1. 说明 本篇文章是对上篇文章猫狗大战训练的模型进行测试。…...

chrome扩展在popup、background、content之间通信解决传输文件问题
文章目录 背景介绍案例介绍代码示例popup页面,上传文件页面popup页面,js上传代码,file文件转base64background监听消息,base64转file文件,axios上传 附-转base64后直接下载 背景介绍 示例扩展API版本MV2。 以弹…...
Oracle获取创建对象的DDL脚本
Oracle获取创建对象的DDL脚本 Oracle获取创建对象的DDL脚本查看 dbms_metadata.get_ddl()函数的定义 Oracle获取创建对象的DDL脚本 例如,对tzq schema下的表 test2,查看DDL脚本的SQL如下: SELECT SELECT dbms_metadata.get_ddl(upper(table…...
《算法竞赛·快冲300题》每日一题:“01树”
《算法竞赛快冲300题》将于2024年出版,是《算法竞赛》的辅助练习册。 所有题目放在自建的OJ New Online Judge。 用C/C、Java、Python三种语言给出代码,以中低档题为主,适合入门、进阶。 文章目录 题目描述题解C代码Java代码Python代码 “ 0…...

Mac提示文件:已损坏,无法打开。你应该把它移到废纸篓
文章目录 一、电脑信息二、打开任何来源设置三、更改应用程序拓展属性 一、电脑信息 我的是新版的Venture 13的系统。UI改的比较多。与之前的配置还是有很大的区别的。 打开下载的软件,显示已经损坏,打不开。抛开软件本身的问题外,一般是Ma…...
探索嵌入式系统:从入门到实践
随着科技的飞速发展,嵌入式系统已经成为了我们生活中不可或缺的一部分。从智能手机、智能家居到工业自动化设备,嵌入式系统的应用已经渗透到了各个领域。那么,如何学习嵌入式系统呢?本文将从入门到实践,为你详细解答。…...

网络安全知识点整理(作业2)
目录 一、js函数声明->function 第一种 第二种 第三种 二、this关键字 this使用场合 1.全局环境 2.构造函数 3.对象的方法 避免多层this 三、js的同步与异步 定时器 setTimeout和setInterval 同步与异步的例子 四、宏任务与微任务 分辨宏任务与微任务 一、js…...

idea数据库快速上手-库操作与表结构和数据操作
引言 对数据库的操作无非就是执行SQL语句,要想熟练操作数据库,就要熟练运用SQL语句。 一,数据库操作 展示当前服务器内的数据库 -- 展示服务器内的数据库 show databases; show schemas; 执行结果: 创建数据库: --…...

当“国潮”遇见“双语” 以传承之心种下一颗文化的种子
看,活灵活现的纸片人在“跳舞”。光影的辉映下,两个形神兼备的“齐天大圣”究竟孰真孰假?舞台上,京西皮影非遗传承人王熙和5岁的Mona小朋友正在用双语为大家带来一段“真假美猴王”的好戏。生动的皮影造型和精彩的故事演绎看得台下…...
计划管理与项目管理:有何区别?
简而言之,是的。尽管它们经常互换使用并对全局产生影响,但它们是完全不同的。 在本文中,我们将了解计划和项目管理之间的差异,提供每个示例,并向您展示如何使计划和项目管理工作更有效地实现您的业务目标。 计划管理与…...

个人信息保护合规审计如何做?
8月3日,为指导、规范个人信息保护合规审计活动,根据《中华人民共和国个人信息保护法》等法律法规,国家互联网信息办公室就《个人信息保护合规审计管理办法(征求意见稿)》(简称《办法》)及配套的…...

HTTP杂谈之Referer和Origin请求头再探
一 关于Referer和Origin的汇总 1) 知识是凌乱的,各位看官看个热闹即可2) 内容不断更新1、理解有盲区,需要及时纠正2、内容交叉有重复,需要适当删减3、扩展视野3) 以下内容都与Referer和Origin请求头有关联 nginx防盗链 HTTP杂谈之Referrer-Policy响应头 iframe标签referre…...

数学建模-爬虫入门
Python快速入门 简单易懂Python入门 爬虫流程 获取网页内容:HTTP请求解析网页内容:Requst库、HTML结果、Beautiful Soup库储存和分析数据 什么是HTTP请求和响应 如何用Python Requests发送请求 下载pip macos系统下载:pip3 install req…...
HSRM各表
文章目录 表规则接口种类服务与网关路由菜单一、采购申请1、采购申请—查询2、采购申请-操作记录二、采购申请跟踪报表1、采购申请跟踪报表—列表查询三、寻源1、寻源大厅—列表查询2、寻源大厅—询价单明细3、寻源大厅—物料明细4、寻源大厅—供应商列表5、寻源模板—列表查询…...

Ansible自动化运维工具 —— Playbook 剧本
playbooks 本身由以下各部分组成 (1)Tasks:任务,即通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行 (2)Variables:变量 (3)Templates:模…...

第二章:多态
系列文章目录 文章目录 系列文章目录前言多态的概念概念 多态的定义及实现多态的构成条件虚函数虚函数的重写C11 override 和 final重载、覆盖(重写)、隐藏(重定义)的对比 抽象类概念接口继承和实现继承 多态的原理虚函数表多态的原理动态绑定与静态绑定 单继承和多继承关系的虚…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...

Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...