当前位置: 首页 > news >正文

通过扩展指令增强基于覆盖引导的模糊测试

本文由Bruno Oliveira于2024年4月25日发表于IncludeSec的官方网站上。作为IncludeSec的安全研究人员,在他们日常的安全审计和渗透测试工作中,有时需要为客户开发一些模糊测试工具。在安全评估方法中使用模糊测试技术,可以有效地在复杂的现代化软件产品中发现和识别安全漏洞,并为应用程序快速提供高度结构化的输入数据。

当我们的客户要求在手动和传统自动化测试之外进行更全面的工作,以提供额外的分析来发现更复杂的漏洞时,通常会应用此技术。在这篇文章中,我们将跟大家介绍于模糊测试相关的内容,并详细阐述如何通过扩展指令增强基于覆盖引导的模糊测试。

介绍

基于覆盖引导的模糊测试是很多高级模糊测试工具所使用的一种十分有用的功能,例如AFL、libFuzzer和Fuzzilli等。这种功能允许模糊测试工具确认一个输入是否能够在源程序路径中发现新的边或执行分支。在控制流图(CFG)中,一个边连接两个分支。比如说,如果一个辑条件涉及if-else语句,则会有两条边,一条用于if,另一条用于else语句。它是模糊测试过程中的重要组成部分,有助于确定模糊测试工具是否有效地覆盖了目标程序的可执行代码。

引导模糊测试通常会使用基于覆盖引导的模糊测试(CGF)技术,这种技术会使用非常基本的指令来收集所需数据,以识别在模糊测试用力的执行过程中是否命中了新的边或代码块。

这种指令指的是在程序编译过程中添加的代码,这些代码的功能非常丰富,包括软件调试在内。

本文我们将以JerryScript(包含了一个已知且公开的漏洞)为例,介绍如何使用相关技术来扩展Fuzzili的检测以提升漏洞识别效率,并为模糊测试工具提供更有价值的数据以进行进一步的测试。

模糊测试

模糊测试指的是向目标应用程序提供一系列随机输入以尝试触发应用程序非预期行为的过程。根据最新的模糊测试方法,很多模糊测试工具会考虑目标应用程序的多个方面以生成更合适测试场景的输入数据。其中一个考虑因素就是种子,即生成输入数据的源。某些现代软件的结构比较复杂,我们无法通过简单的输入来获取期望的结果。换言之,也就是无法通过简单的输入对目标应用程序产生足够的影响,这样也就难以发现潜在的安全漏洞。

下图中显示的是带有变异策略和代码覆盖功能的模糊测试程序的通用基本结构:

1、选择种子;

2、变异过程需要获取种子作为初始的执行输入;

3、程序执行;

4、触发漏洞,或者...;

5、输入命中了目标程序中的一个新的边,模糊测试工具继续对种子执行变异操作,或者...;

6、输入没有命中新的边,模糊测试工具选择一个新的种子执行变异;

代码覆盖率可以让模糊测试工具在目标应用程序执行过程中发现新的边或代码块,有助于识别输入是否能够抵达目标应用程序的各个部分。

下图所示为Fuzzilli在对样本进行处理和变异时所使用的算法:

Clang

Clang是一款针对C、C++、Objective-C和Objective-C++编程语言的编译器,该编译器属于LLVM项目的一个部分,可以提供比GCC这种传统编译器更强大的功能。

Clang编译器中很重要的一个工具就是数据清洗器(Sanitizer),Sanitizer可以被视作一种安全库或工具,可以通过检查目标代码来自动检测安全漏洞。启用了Sanitizer之后,编译器会自动检查编译后的代码是否存在安全问题。

常见的Sanitizer包括:

1、AddressSanitizer (ASAN);

2、UndefinedBehaviorSanitizer (UBSAN);

3、MemorySanitizer (MSAN);

4、ThreadSanitizer (TSAN);

5、LeakSanitizer (LSAN);

下面给出的Shell代码段显示了如何使用ASAN选项在代码编译过程中跟踪程序计数器:

$ clang -o targetprogram -g -fsanitize=address -fsanitize-coverage=trace-pc-guard targetprogram.c

根据Clang文档的描述,LLVM内置了一个简单的代码覆盖指令,可以向用户定义的函数插入函数调用,并提供了回调的默认实现,从而实现了简单的覆盖率报告和可视化。

比如说,Fuzzilli(Google的JavaScript引擎模糊测试工具)就使用了简单的指令来响应Fuzzilli的进程,具体如下代码段所示:

extern "C" void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {uint32_t index = *guard;__shmem->edges[index / 8] |= 1 << (index % 8);*guard = 0;}

当找到一个新的边时,__sanitizer_cov_trace_pc_guard()函数会持续执行,因此无需任何条件来处理新的边被发现时要做什么。接下来,函数会将共享位图中的__shmem->edges设置为1,Fuzzilli会在执行后对位图进行分析。

其他工具,比如说LLVM-COV,能够静态地捕获代码覆盖率信息,在执行之后提供人类可读的文档。但是,需要高效读取磁盘中文档的模糊测试工具,可能会影响性能。

获取更多的信息

我们可以修改Fuzzilli的指令,并观察__sanitizer_cov_trace_pc_guard()能够给代码覆盖率带来什么其他的东西。下列代码段演示了我们对Fuzzilli指令的部分修改:

extern "C" void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {uint32_t index = *guard;void *PC = __builtin_return_address(0);char PcDescr[1024];__sanitizer_symbolize_pc(PC, "%p %F %L", PcDescr, sizeof(PcDescr));printf("guard: %p %x PC %s\n", guard, *guard, PcDescr);__shmem->edges[index / 8] |= 1 << (index % 8);*guard = 0;}

我们已经知道的是,__sanitizer_cov_trace_pc_guard()函数在每次程序命中新的边时便会执行。此时,我们可以利用__builtin_return_address()函数来收集每一个命中的新的边所返回的地址。现在,PC指针已经获取到了返回的地址信息。我们可以利用__sanitizer_symbolize_pc()函数来将地址与符号相关联,从而提供有关执行过程中所使用的源代码文件的更多信息。

大多数模糊测试工具只会使用边的信息来引导模糊测试。然而,正如我们接下来会给大家演示的那样,我们可以使用Sanitizer接口来为安全评估提供更多有价值的信息。

动手实操

在我们的演示过程中,我们将利用一个旧版本的JerryScript JavaScript引擎来创建一个环境,环境信息如下:

1、操作系统(OS):Ubuntu 22.04;

2、目标程序:JerryScript;

3、漏洞:CVE-2023-36109;

环境搭建

我们可以使用下列命令构建JerryScript,首先克隆项目代码库:

$ git clone https://github.com/jerryscript-project/jerryscript.git

切换到JerryScript目录,并校验8ba0d1b6ee5a065a42f3b306771ad8e3c0d819bc commit:

$ git checkout 8ba0d1b6ee5a065a42f3b306771ad8e3c0d819bc

然后应用Fuzziilli库提供的修补程序:

$ cd jerry-main$ wget https://github.com/googleprojectzero/fuzzilli/raw/main/Targets/Jerryscript/Patches/jerryscript.patch$ patch < jerryscript.patchpatching file CMakeLists.txtpatching file main-fuzzilli.cpatching file main-fuzzilli.hpatching file main-options.cpatching file main-options.hpatching file main-unix.c

Fuzziilli修补程序提供的指令文件为jerry-main/main-fuzzilli.c,其中也包含了简单的代码覆盖功能,但这还远远不够。因此 ,我们还需要像之前一样在编译代码之前更新__sanitizer_cov_trace_pc_guard()函数。除此之外,还需要将下列Header添加到jerry-main/main-fuzzilli.c文件中:

void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {uint32_t index = *guard;if(!index) return;index--;void *PC = __builtin_return_address(0);char PcDescr[1024];__sanitizer_symbolize_pc(PC, "%p %F %L", PcDescr, sizeof(PcDescr));printf("guard: %p %x PC %s\n", (void *)guard, *guard, PcDescr);__shmem->edges[index / 8] |= 1 << (index % 8);*guard = 0;}

我们现在更改编译配置并禁用strip,这些符号仅用于识别我们演示中可能存在的易受攻击功能。修改根目录中的CMakeLists.txt文件:

# Strip binaryif(ENABLE_STRIP AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug")jerry_add_link_flags(-g)endif()

确保jerry-main/CMakeLists.txt包含了main-fuzzilli.c文件之后,我们就可以准备编译代码并使用Fuzzilli指令完成构建了:

$ python jerryscript/tools/build.py --compile-flag=-fsanitize-coverage=trace-pc-guard --profile=es2015-subset --lto=off --compile-flag=-D_POSIX_C_SOURCE=200809 --compile-flag=-Wno-strict-prototypes --stack-limit=15

如果你安装了Clang,但CMAKE_C_COMPILER_ID却显示 GNU或其他内容的话,你可能构建过程出错了:

$ python tools/build.py --compile-flag=-fsanitize-coverage=trace-pc-guard --profile=es2015-subset --lto=off --compile-flag=-D_POSIX_C_SOURCE=200809 --compile-flag=-Wno-strict-prototypes --stack-limit=15-- CMAKE_BUILD_TYPE               MinSizeRel-- CMAKE_C_COMPILER_ID            GNU-- CMAKE_SYSTEM_NAME              Linux-- CMAKE_SYSTEM_PROCESSOR         x86_64

你可以直接修改CMakeLists.txt文件中的28-42行,通过将USING_GCC 1修改为USING_CLANG 1来强制使用Clang:

# Determining compilerif(CMAKE_C_COMPILER_ID MATCHES "GNU")set(USING_CLANG 1)endif()if(CMAKE_C_COMPILER_ID MATCHES "Clang")set(USING_CLANG 1)endif()

构建出的代码路径为“build/bin/jerry”。

测试执行

首先,我们先禁用掉ASLR:

$ echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

测试完成后,我们可以通过将值设置为2来重新启用ASLR:

$ echo 2 | sudo tee /proc/sys/kernel/randomize_va_space

现在,我们可以先尝试跟踪源码文件的地址,禁用ASLR将有助于我们在分析过程中不受干扰,且不会影响我们的结果。

现在,我们使用针对CVE-2023-36109的PoC文件来执行JerryScript,并尝试触发漏洞。根据漏洞描述,该漏洞位于jerry-core/ecma/base/ecma-helpers-string.c文件的ecma_stringbuilder_append_raw函数中,具体如下所示:

$ ./build/bin/jerry ./poc.js[...]guard: 0x55e17d12ac88 7bb PC 0x55e17d07ac6b in ecma_string_get_ascii_size ecma-helpers-string.cguard: 0x55e17d12ac84 7ba PC 0x55e17d07acfe in ecma_string_get_ascii_size ecma-helpers-string.cguard: 0x55e17d12ac94 7be PC 0x55e17d07ad46 in ecma_string_get_size (/jerryscript/build/bin/jerry+0x44d46) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)guard: 0x55e17d12e87c 16b8 PC 0x55e17d09dfe1 in ecma_regexp_replace_helper (/jerryscript/build/bin/jerry+0x67fe1) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)guard: 0x55e17d12ae04 81a PC 0x55e17d07bb64 in ecma_stringbuilder_append_raw (/jerryscript/build/bin/jerry+0x45b64) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)guard: 0x55e17d12e890 16bd PC 0x55e17d09e053 in ecma_regexp_replace_helper (/jerryscript/build/bin/jerry+0x68053) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)guard: 0x55e17d12e8b8 16c7 PC 0x55e17d09e0f1 in ecma_regexp_replace_helper (/jerryscript/build/bin/jerry+0x680f1) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)guard: 0x55e17d133508 29db PC 0x55e17d0cc292 in ecma_builtin_replace_substitute (/jerryscript/build/bin/jerry+0x96292) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)guard: 0x55e17d133528 29e3 PC 0x55e17d0cc5bd in ecma_builtin_replace_substitute (/jerryscript/build/bin/jerry+0x965bd) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)guard: 0x55e17d12f078 18b7 PC 0x55e17d040a78 in jmem_heap_realloc_block (/jerryscript/build/bin/jerry+0xaa78) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)guard: 0x55e17d12f088 18bb PC 0x55e17d040ab4 in jmem_heap_realloc_block (/jerryscript/build/bin/jerry+0xaab4) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)guard: 0x55e17d12f08c 18bc PC 0x55e17d040c26 in jmem_heap_realloc_block (/jerryscript/build/bin/jerry+0xac26) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)guard: 0x55e17d12f094 18be PC 0x55e17d040ca3 in jmem_heap_realloc_block (/jerryscript/build/bin/jerry+0xaca3) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)UndefinedBehaviorSanitizer:DEADLYSIGNAL==27636==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x55e27da7950c (pc 0x7fe341fa092b bp 0x000000000000 sp 0x7ffc77634f18 T27636)==27636==The signal is caused by a READ memory access.#0 0x7fe341fa092b  string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:513#1 0x55e17d0cc3bb in ecma_builtin_replace_substitute (/jerryscript/build/bin/jerry+0x963bb) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)#2 0x55e17d09e103 in ecma_regexp_replace_helper (/jerryscript/build/bin/jerry+0x68103) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)#3 0x55e17d084a23 in ecma_builtin_dispatch_call (/jerryscript/build/bin/jerry+0x4ea23) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)#4 0x55e17d090ddc in ecma_op_function_call_native ecma-function-object.c#5 0x55e17d0909c1 in ecma_op_function_call (/jerryscript/build/bin/jerry+0x5a9c1) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)#6 0x55e17d0d4743 in ecma_builtin_string_prototype_object_replace_helper ecma-builtin-string-prototype.c#7 0x55e17d084a23 in ecma_builtin_dispatch_call (/jerryscript/build/bin/jerry+0x4ea23) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)#8 0x55e17d090ddc in ecma_op_function_call_native ecma-function-object.c#9 0x55e17d0909c1 in ecma_op_function_call (/jerryscript/build/bin/jerry+0x5a9c1) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)#10 0x55e17d0b929f in vm_execute (/jerryscript/build/bin/jerry+0x8329f) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)#11 0x55e17d0b8d4a in vm_run (/jerryscript/build/bin/jerry+0x82d4a) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)#12 0x55e17d0b8dd0 in vm_run_global (/jerryscript/build/bin/jerry+0x82dd0) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)#13 0x55e17d06d4a5 in jerry_run (/jerryscript/build/bin/jerry+0x374a5) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)#14 0x55e17d069e32 in main (/jerryscript/build/bin/jerry+0x33e32) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)#15 0x7fe341e29d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16#16 0x7fe341e29e3f in __libc_start_main csu/../csu/libc-start.c:392:3#17 0x55e17d0412d4 in _start (/jerryscript/build/bin/jerry+0xb2d4) (BuildId: 9588e1efabff4190fd492d05d3710c7810323407)UndefinedBehaviorSanitizer can not provide additional info.SUMMARY: UndefinedBehaviorSanitizer: SEGV string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:513==27636==ABORTING

通过使用这种技术,我们可以识别出ecma_stringbuilder_append_raw()中漏洞存在根本原因的栈地址。

如果我们仅仅依赖于Sanitizer来检测堆栈记录的话,我们将无法在输出中看到存在漏洞的函数名称:

$ ./build/bin/jerry ./poc.js[COV] no shared memory bitmap available, skipping[COV] edge counters initialized. Shared memory: (null) with 14587 edgesUndefinedBehaviorSanitizer:DEADLYSIGNAL==54331==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x5622ae01350c (pc 0x7fc1925a092b bp 0x000000000000 sp 0x7ffed516b838 T54331)==54331==The signal is caused by a READ memory access.#0 0x7fc1925a092b  string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:513#1 0x5621ad66636b in ecma_builtin_replace_substitute (/jerryscript/build/bin/jerry+0x9636b) (BuildId: 15a3c1cd9721e9f1b4e15fade2028ddca6dc542a)#2 0x5621ad6380b3 in ecma_regexp_replace_helper (/jerryscript/build/bin/jerry+0x680b3) (BuildId: 15a3c1cd9721e9f1b4e15fade2028ddca6dc542a)#3 0x5621ad61e9d3 in ecma_builtin_dispatch_call (/jerryscript/build/bin/jerry+0x4e9d3) (BuildId: 15a3c1cd9721e9f1b4e15fade2028ddca6dc542a)#4 0x5621ad62ad8c in ecma_op_function_call_native ecma-function-object.c#5 0x5621ad62a971 in ecma_op_function_call (/jerryscript/build/bin/jerry+0x5a971) (BuildId: 15a3c1cd9721e9f1b4e15fade2028ddca6dc542a)#6 0x5621ad66e6f3 in ecma_builtin_string_prototype_object_replace_helper ecma-builtin-string-prototype.c#7 0x5621ad61e9d3 in ecma_builtin_dispatch_call (/jerryscript/build/bin/jerry+0x4e9d3) (BuildId: 15a3c1cd9721e9f1b4e15fade2028ddca6dc542a)#8 0x5621ad62ad8c in ecma_op_function_call_native ecma-function-object.c#9 0x5621ad62a971 in ecma_op_function_call (/jerryscript/build/bin/jerry+0x5a971) (BuildId: 15a3c1cd9721e9f1b4e15fade2028ddca6dc542a)#10 0x5621ad65324f in vm_execute (/jerryscript/build/bin/jerry+0x8324f) (BuildId: 15a3c1cd9721e9f1b4e15fade2028ddca6dc542a)#11 0x5621ad652cfa in vm_run (/jerryscript/build/bin/jerry+0x82cfa) (BuildId: 15a3c1cd9721e9f1b4e15fade2028ddca6dc542a)#12 0x5621ad652d80 in vm_run_global (/jerryscript/build/bin/jerry+0x82d80) (BuildId: 15a3c1cd9721e9f1b4e15fade2028ddca6dc542a)#13 0x5621ad607455 in jerry_run (/jerryscript/build/bin/jerry+0x37455) (BuildId: 15a3c1cd9721e9f1b4e15fade2028ddca6dc542a)#14 0x5621ad603e32 in main (/jerryscript/build/bin/jerry+0x33e32) (BuildId: 15a3c1cd9721e9f1b4e15fade2028ddca6dc542a)#15 0x7fc192429d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16#16 0x7fc192429e3f in __libc_start_main csu/../csu/libc-start.c:392:3#17 0x5621ad5db2d4 in _start (/jerryscript/build/bin/jerry+0xb2d4) (BuildId: 15a3c1cd9721e9f1b4e15fade2028ddca6dc542a)UndefinedBehaviorSanitizer can not provide additional info.SUMMARY: UndefinedBehaviorSanitizer: SEGV string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:513==54331==ABORTING

总结

在这篇文章中,我们演示了如何通过扩展Fuzzilli的指令来对目标应用程序的栈进行实施跟踪,以更好地了解返回地址信息以及相关的源代码文件信息,从而给模糊测试工具提供更多的路径,最终产生更多有价值的测试结果。

参考资料

Not All Coverage Measurements Are Equal: Fuzzing by Coverage Accounting for Input Prioritization - NDSS Symposium

Clang C Language Family Frontend for LLVM

SanitizerCoverage — Clang 19.0.0git documentation

GitHub - googleprojectzero/fuzzilli: A JavaScript Engine Fuzzer

fuzzilli/Targets/Jerryscript/Patches/jerryscript.patch at main · googleprojectzero/fuzzilli · GitHub

GitHub - Limesss/CVE-2023-36109: a poc for cve-2023-36109

参考链接

Coverage Guided Fuzzing - Extending Instrumentation to Hunt Down Bugs Faster! - Include Security Research Blog

相关文章:

通过扩展指令增强基于覆盖引导的模糊测试

本文由Bruno Oliveira于2024年4月25日发表于IncludeSec的官方网站上。作为IncludeSec的安全研究人员&#xff0c;在他们日常的安全审计和渗透测试工作中&#xff0c;有时需要为客户开发一些模糊测试工具。在安全评估方法中使用模糊测试技术&#xff0c;可以有效地在复杂的现代化…...

第一节:Redis的数据类型和基本操作

最近整理了关于Redis的一些文档&#xff0c;分享给大家&#xff0c;后续会持续更新...... Redis的数据类型 字符串String String&#xff1a;字符串&#xff0c;可以存储String、Integer、Float型的数据&#xff0c;甚至是二进制数据&#xff0c;一个字符串最大容量是512M 列表…...

组件的传参等

一:组件的生命周期函数 组件的生命周期函数: created只是创建了组件内的实例对象 attached,给组件实例绑定了属性,绑定到页面节点树之后 ready准备好渲染之后,还未渲染之前 moved组件实例被移动到另一个位置后执行 detached在整个组件被被移除执行 error执行的时候,组件内…...

构建php环境、安装、依赖、nginx配置、ab压力测试命令、添加php-fpm为系统服务

目录 php简介 官网php安装包 选择下载稳定版本 &#xff08;建议使用此版本&#xff0c;文章以此版本为例&#xff09; 安装php解析环境 准备工作 安装依赖 zlib-devel 和 libxml2-devel包。 安装扩展工具库 安装 libmcrypt 安装 mhash 安装mcrypt 安装php 选项含…...

服装服饰商城小程序的作用是什么

要说服装商家&#xff0c;那数量是非常多&#xff0c;厂家/经销门店/小摊/无货源等&#xff0c;线上线下同行竞争激烈&#xff0c;虽然用户群体广涵盖每个人&#xff0c;但每个商家肯定都希望更多客户被自己转化&#xff0c;渠道运营方案营销环境等不可少。 以年轻人为主的消费…...

HNU-计算机体系结构-实验2-Tomasulo算法

计算机体系结构 实验2 计科210X 甘晴void 202108010XXX 1 实验目的 熟悉Tomasulo模拟器同时加深对Tomasulo算法的理解&#xff0c;从而理解指令级并行的一种方式-动态指令调度。 掌握Tomasulo算法在指令流出、执行、写结果各阶段对浮点操作指令以及load和store指令进行什么…...

深入分析 Android Activity (一)

文章目录 深入分析 Android Activity (一)1. Activity 的窗口管理2. Activity 的生命周期管理onCreateonStartonResumeonPauseonStoponDestroyonRestart 3. Activity 与 Fragment 的交互添加 FragmentFragment 的生命周期 4. Activity 的任务和返回栈5. 配置变化处理 总结 深入…...

Python 调整PDF文件的页面大小

在处理PDF文件时&#xff0c;我们可能会遇到这样的情况&#xff1a;原始PDF文档不符合我们的阅读习惯&#xff0c;或者需要适配不同显示设备等。这时&#xff0c;我们就需要及时调整PDF文档中的页面尺寸&#xff0c;以满足不同应用场景的需求。 利用Python语言的高效性和灵活性…...

支付功能、支付平台、支持渠道如何测试?

有学员提问&#xff1a;作为一个支付平台&#xff0c;接入了快钱、易宝或直连银行等多家的渠道&#xff0c;内在的产品流程是自己的。业内有什么比较好的测试办法&#xff0c;来测试各渠道及其支持的银行通道呢&#xff1f; 作为产品&#xff0c;我自己办了十几张银行卡方便测…...

永久代(Permanent Generation)和元空间(Metaspace)

永久代&#xff08;Permanent Generation&#xff09;和元空间&#xff08;Metaspace&#xff09;是Java虚拟机&#xff08;JVM&#xff09;内存管理中的两个概念&#xff0c;主要区别在于它们的实现方式和内存分配策略。 永久代&#xff08;Permanent Generation&#xff09;…...

前端面试题23-34

23. 说说你对 Promise 的理解 Promise 是 ECMAScript6 引入的一种异步编程解决方案&#xff0c;用于处理异步操作。它表示一个尚未完成但最终会结束的操作&#xff0c;具有三种状态&#xff1a;pending&#xff08;进行中&#xff09;、fulfilled&#xff08;已完成&#xff0…...

Hadoop3:HDFS中DataNode与NameNode的工作流程

一、DataNode中的数据情况 数据位置 /opt/module/hadoop-3.1.3/data/dfs/data/current/BP-823420375-192.168.31.102-1714395693863/current/finalized/subdir0/subdir0块信息 每个块信息&#xff0c;由两个文件保存&#xff0c;xxx.meta保存的是数据长度、校验和、时间戳&am…...

MySQL(一) 库和表的基础操作

1. 数据库基础 1.1 什么是数据库 存储数据用文件就可以了&#xff0c;为什么还要弄个数据库? 文件保存数据有以下几个缺点&#xff1a; 文件的安全性问题文件不利于数据查询和管理文件不利于存储海量数据文件在程序中控制不方便 数据库存储介质&#xff1a;磁盘内存 为了解…...

python -【二】判断语句

判断语句 一、 布尔类型 True&#xff1a;真(1)False&#xff1a;假(0) 比较运算符 运算符实例1 1 True!1 ! 1 Flase<1 < 1 Flse>1 > 1 Flse<1 < 1 True>1 > 1 True b1 True b2 False print(f"b1值是{b1},类型是{type(b1)}") print(…...

高通Android 12/13 设置和获取ADB状态

/*** 设置ADB状态** param isEnable*/public void setADB(boolean isEnable) {Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.ADB_ENABLED, isEnable ? 1 : 0);}/*** 获取ADB状态** return*/public boolean getADB() {return Settings.Global.getIn…...

存储器和CPU的连接与TCP的流量控制

存储器与CPU的连接 存储容量的拓展 &#xff08;1)位拓展&#xff1a;增加存储字长 &#xff08;2&#xff09;字拓展 增加存储器字的数量 例题&#xff1a;设CPU有16根地址线&#xff0c;8根数据线&#xff0c;并用MREQ作为访问存储控制信号(低电平有效)&#xff0c;WR作为…...

红蓝对抗提权篇之一文看懂提权

一、计算机中的权限 1.1 不同的权限系统 权限在不同的应用中有着不同的分类&#xff0c;与安全相关的大致上我们分为&#xff1a; 匿名访问权限 来宾权限 用户权限 管理员权限 系统权限 不同的权限对应的权力各不相同&#xff0c;我们对自己电脑一般是用户权限和管理员权限。…...

【Tlias智能学习辅助系统】01 准备工作

Tlias智能学习辅助系统 01 创建员工、部门表创建springboot工程&#xff0c;引入对应的起步依赖(web、mybatis、mysql驱动、lombok)准备 Mapper、Service、Controller 等基础结构MapperServiceControllerpojo封装类application.properties 接口开发规范 创建员工、部门表 -- 创…...

yq—2024/5/29—零钱兑换

代码实现&#xff1a; #define min(a, b) ((a) > (b) ? (b) : (a))int coinChange(int *coins, int coinsSize, int amount) {int dp[amount 1];// 初始化for (int i 0; i < amount 1; i) {dp[i] INT32_MAX;}dp[0] 0;// 01背包 -----先遍历物品&#xff0c;再遍历背…...

【 Quartz框架中各个表及其字段含义】

Quartz框架中各个表及其字段含义 Quartz是一个强大的任务调度框架,它通过在数据库中维护多张表来存储和管理任务信息。了解这些表的结构和字段含义,有助于我们更好地理解Quartz的工作原理,并在实际应用中进行有针对性的优化和管理。 想了解Quartz框架其他信息可以参考下面的博…...

SAP_SD模块 物料科目分配/成本简介

SAP系统各模块与财务都有个方面的集成。文本主要说明销售模块中的科目分配和成本的一个对应关系。 1、首先是在物料主数据上销售视图中的物料科目分配组&#xff0c;S1主营、S2材料等字段&#xff0c;物料销售的时候会将这个物料产生的记录到对应的科目中。 首先是物料主数据中…...

el-select 组件获取整个对象

法一&#xff1a;要获取整个对象的话&#xff0c;如果有列表就可以遍历列表&#xff0c;找到指定对象 let obj this.chainTaskList.find((item) > item.chainTaskNo e); if (obj) {this.form.storeNo obj.storeNo;this.form.storeName obj.couponVO.storeName; }或 fo…...

基础—SQL—DQL(数据查询语言)基础查询

一、引言 1、介绍&#xff1a; 分类全称描述DQL英文全称&#xff1a;Data Query Language(数据查询语言)主要是学习对数据库表中的记录进行查询的语句 2、讲解 日常的开发中或者对于一个正常的业务系统中&#xff0c;对于查询的操作次数是远远多于数据的增删改的频次。例如…...

【QT八股文】系列之篇章2 | QT的信号与槽机制及通讯流程

【QT八股文】系列之篇章2 | QT的信号与槽机制及通讯流程 前言2. 信号与槽信号与槽机制介绍/本质/原理&#xff0c;什么是Qt信号与槽机制&#xff1f;如何在Qt中使用&#xff1f;信号与槽机制原理&#xff0c;解析流程Qt信号槽的调用流程信号与槽机制的优缺点信号与槽机制需要注…...

excel表格里怎样不删除0,又不显示0呢?

在单元格里不显示0&#xff0c;大体上有这么几种方法&#xff1a; 1.设置单元格自定义格式 选中数据区域&#xff0c;鼠标右键&#xff0c;点一下设置单元格格式&#xff0c;选中数字&#xff0c;自定义&#xff0c;在右侧的类型栏&#xff0c;设置格式&#xff1a; [0]&quo…...

精准操控时间的艺术:JavaScript节流函数的深度探索与实践【含代码示例】

精准操控时间的艺术&#xff1a;JavaScript节流函数的深度探索与实践【含代码示例】 节流基础&#xff1a;概念与作用实现策略&#xff1a;案例展示案例一&#xff1a;基础定时器实现案例二&#xff1a;立即执行版本案例三&#xff1a;使用requestAnimationFrame实现动画节流 功…...

自学SPSS,有哪些教学视频或书籍推荐?

书籍推荐 经过长达八年的不断迭代与优化&#xff0c;SPSSAU的用户群体已经远超简单的数据分析层面&#xff0c;而是逐步深入到了学术研究的精髓之中。如今&#xff0c;无论是在SCI、EI等国际权威学术期刊&#xff0c;还是北大核心期刊、CSSCI等国内顶尖学术期刊上&#xff0c;…...

开源数据库同步工具DBSyncer

前言&#xff1a; 这么实用的工具&#xff0c;竟然今天才发现&#xff0c;相见恨晚呀&#xff01;&#xff01;&#xff01;&#xff01; DBSyncer&#xff08;英[dbsɪŋkɜː]&#xff0c;美[dbsɪŋkɜː 简称dbs&#xff09;是一款开源的数据同步中间件&#xff0c;提供M…...

【SpringMVC】_SpringMVC项目返回HTML与JSON

目录 1. SpringMVC项目返回HTML页面 2. SpringMVC项目返回JSON 2.1 程序演示 2.2 关于响应的Content-Type 2.2.1 接口为对象 2.2.2 接口为String 2.2.3 接口为Map 本专栏已介绍&#xff1a; 返回静态页面&#xff1a; 【Spring MVC】_SpringMVC项目返回静态页面_mvc 返…...

STL库--stack

目录 stack的定义 stack容器内元素的访问 stack常用函数实例解析 stack的常见用途 stack的定义 其定义的写法和其他STL容器相同&#xff0c;typename可以任意基本类型或容器&#xff1a; stack<typename> name; stack容器内元素的访问 由于栈本身就是一种后进先出…...