作业报告┭┮﹏┭┮(Android反调试)

一:Android反调试

主要是用来防止IDA进行附加的,主要的方法思路就是,判断自身是否有父进程,判断是否端口被监听,然后通过调用so文件中的线程进行监视,这个线程开启一般JNI_OnLoad中进行开启的。但是这个是在这个之前断开的。思路→过反调试的话呢,就要把相关的函数进行NOP掉,直接将这几个字节改为00就可以了。

反编译截图:

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

我们可以fax1这个软件是不可以调试的,要想调试这个软件,我们有俩个方法。

其一:我们给他增加上:android:debuggable="true"在application的节点中,然后进行编译,签名,安装。

其二:我们有magisk面具,刷入MagiskHideProsp Config模块
在这里插入图片描述

调试软件的时候执行以下命令,就可以调试软件了

adb shell
su
magisk resetprop ro.debuggable 1
stop
start

然后打开IDA进行附加:

  1. 常规的运行服务器,转发端口

adb forward tcp:23946 tcp:23946
  1. 然后使用调试模式进行运行:
adb shell am start -D -n com.ctf.mobile/com.ctf.mobile.MainActivity
  1. 查看我们软件的进程,并进行转发
adb shell ps | findstr ctf
adb forward tcp:8700 jdwp:
  1. 运行之后,使用IDA进行附加,附加的时候正常操作,但是进去之后我们需要选择一下:

在调试器的调试器选项中设置:
在这里插入图片描述

  1. 然后点击运行,之后就会不动,这个时候我们用jdb绑定端口(ddms需要打开的情况下使用8700端口),使用命令:

jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700然后程序就会断下,因为在加载so文件。
  1. 我们一次运行就查看是否是我们的so被载入,我们的so文件名是:libmobile.so

  2. 当被载入的时候,我们就选择在JNI_OnLoad中进行下断点。然后破除反调试

(不会/(ㄒoㄒ)/~~)

参考文章

https://www.cnblogs.com/bmjoker/p/11962585.html

二:java分析

在这里插入图片描述

package com.ctf.mobile;import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.ctf.mobile.databinding.ActivityMainBinding;public class MainActivity extends AppCompatActivity {private ActivityMainBinding binding;private Button button;private EditText flagText;public native boolean check(String str);static {System.loadLibrary("mobile");}/* access modifiers changed from: protected */@Override // androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, androidx.fragment.app.FragmentActivitypublic void onCreate(Bundle bundle) {super.onCreate(bundle);ActivityMainBinding inflate = ActivityMainBinding.inflate(getLayoutInflater());this.binding = inflate;setContentView(inflate.getRoot());final op opVar = new op();this.button = (Button) findViewById(R.id.button);this.flagText = (EditText) findViewById(R.id.editText);this.button.setOnClickListener(new View.OnClickListener() {/* class com.ctf.mobile.MainActivity.AnonymousClass1 */public void onClick(View view) {if (MainActivity.this.flagText.getText().toString().trim().length() < 50) {MainActivity mainActivity = MainActivity.this;if (mainActivity.check(mainActivity.flagText.getText().toString().trim())) {Toast.makeText(MainActivity.this, op.flagRight, 0).show();return;}}Toast.makeText(MainActivity.this, op.flagWrong, 0).show();}});}
}

载入时候的,发现按钮被点击之后,调用了Check这个方法,这是个本地函数,我们在IDA中进行寻找:

在这里插入图片描述

看一下IDA给我们的伪代码:

__int64 __fastcall Java_com_ctf_mobile_MainActivity_check(__int64 a1, __int64 a2, __int64 a3)
{__int64 v4; // x0v4 = (*(__int64 (__fastcall **)(__int64, __int64, _QWORD))(*(_QWORD *)a1 + 1352LL))(a1, a3, 0LL);return sub_EF0(a1, v4) & 1;
}

sub_EF0

bool __fastcall sub_EF0(__int64 a1, const char *a2)
{__int64 v3; // x25__int64 v4; // x0__int64 v5; // x24__int64 v6; // x0__int64 v7; // x8__int64 v8; // x26__int64 v9; // x25unsigned __int8 v10; // w0unsigned int v11; // w27char v12; // w0__int64 v13; // x22__int64 v14; // x26char v15; // w0const char *v16; // x24__int64 v17; // x23__int64 v18; // x0__int64 v19; // x8unsigned int v20; // w0unsigned int v21; // w0int v22; // w25bool v23; // ccconst char *v24; // x8__int64 v25; // x25__int64 v26; // x0__int64 v27; // x21__int64 v28; // x23__int64 v29; // x26__int64 v30; // x25unsigned int v31; // w27const char *v32; // x24__int64 v33; // x0unsigned int v34; // w0unsigned int v35; // w0__int64 v36; // x17__int64 v37; // x1__int64 v38; // x0__int64 i; // x8__int64 v40; // x9unsigned int v41; // w10char v42; // w14char v43; // w13_BYTE *v44; // x16_BYTE *v45; // x15char v46; // w11int v47; // w22_BYTE *v48; // x23int v49; // w24__int64 v50; // x8int v51; // w20FILE *v52; // x0FILE *v53; // x28int v58; // w8int v59; // w20FILE *v60; // x0FILE *v61; // x28__int64 v62; // x24FILE *v63; // x0FILE *v64; // x28FILE *v65; // x0FILE *v66; // x28__int64 v67; // x26__int64 v68; // x28__int64 v69; // x27__int64 v70; // x20int v71; // w22int v72; // w23int v73; // w9__int64 v74; // x3__int64 v75; // x25unsigned __int64 v76; // x24_BOOL4 v77; // w21FILE *v78; // x0FILE *v79; // x23_BYTE v81[256]; // [xsp-630h] [xbp-8A0h] BYREF__int64 v82; // [xsp-530h] [xbp-7A0h] BYREF_BYTE v83[48]; // [xsp-430h] [xbp-6A0h] BYREF_BYTE v84[256]; // [xsp-400h] [xbp-670h] BYREF_BYTE v85[12]; // [xsp-300h] [xbp-570h] BYREF__int128 v86; // [xsp-2F4h] [xbp-564h]__int128 v87; // [xsp-2E4h] [xbp-554h]__int128 v88; // [xsp-2D4h] [xbp-544h]__int128 v89; // [xsp-2C4h] [xbp-534h]__int128 v90; // [xsp-2B4h] [xbp-524h]__int128 v91; // [xsp-2A4h] [xbp-514h]__int128 v92; // [xsp-294h] [xbp-504h]__int128 v93; // [xsp-284h] [xbp-4F4h]__int128 v94; // [xsp-274h] [xbp-4E4h]__int128 v95; // [xsp-264h] [xbp-4D4h]__int128 v96; // [xsp-254h] [xbp-4C4h]__int128 v97; // [xsp-244h] [xbp-4B4h]__int128 v98; // [xsp-234h] [xbp-4A4h]__int128 v99; // [xsp-224h] [xbp-494h]__int128 v100; // [xsp-214h] [xbp-484h]int v101; // [xsp-204h] [xbp-474h]_BYTE v102[520]; // [xsp-200h] [xbp-470h] BYREF__int64 v103; // [xsp+8h] [xbp-268h]__int64 v104; // [xsp+10h] [xbp-260h]unsigned __int64 StatusReg; // [xsp+18h] [xbp-258h]_BYTE *v106; // [xsp+20h] [xbp-250h]_BYTE *v107; // [xsp+28h] [xbp-248h]__int64 *v108; // [xsp+30h] [xbp-240h]const char *v109; // [xsp+38h] [xbp-238h]_BYTE *v110; // [xsp+40h] [xbp-230h]__int64 v111; // [xsp+48h] [xbp-228h]_BYTE *v112; // [xsp+50h] [xbp-220h]const char *v113; // [xsp+58h] [xbp-218h]char v114[10]; // [xsp+60h] [xbp-210h] BYREF_BYTE v115[6]; // [xsp+6Ah] [xbp-206h] BYREFchar v116[256]; // [xsp+160h] [xbp-110h] BYREF__int64 v117; // [xsp+260h] [xbp-10h]v109 = a2;StatusReg = _ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2));v117 = *(StatusReg + 40);if ( y >= 10 && (((x - 1) * x) & 1) != 0 )goto LABEL_5;while ( 1 ){v106 = v85;v112 = v84;v110 = v84;v107 = v83;v113 = v83;v108 = &v82;v3 = (*(*a1 + 48LL))(a1, &xmmword_4350);v4 = (*(*a1 + 264LL))(a1, v3, &byte_4364, &byte_436C);v5 = sub_1B58(a1, v3, v4);v6 = (*(*a1 + 264LL))(a1, v3, &byte_4370, &byte_4374);v7 = *a1;v111 = v6;v8 = (*(v7 + 264))(a1, v3, &byte_437C, &byte_4374);v9 = (*(*a1 + 264LL))(a1, v3, &byte_4380, &byte_4374);v101 = 0;memset(v102, 0, 256);v100 = 0u;v99 = 0u;v98 = 0u;v97 = 0u;v96 = 0u;v95 = 0u;v94 = 0u;v93 = 0u;v92 = 0u;v91 = 0u;v90 = 0u;v89 = 0u;v88 = 0u;v87 = 0u;v86 = 0u;v10 = sub_1BF4(a1, v5, v8, 20LL, 28LL);v11 = v10;v85[0] = v10;v85[1] = sub_1BF4(a1, v5, v8, v10, 72LL);v85[2] = sub_1BF4(a1, v5, v8, v11, 1LL);v85[3] = sub_1BF4(a1, v5, v8, v11, 2LL);v85[4] = sub_1BF4(a1, v5, v8, v11, 3LL);v85[5] = sub_1BF4(a1, v5, v8, v11, 4LL);v85[6] = sub_1BF4(a1, v5, v8, v11, 5LL);v85[7] = sub_1BF4(a1, v5, v8, v11, 6LL);v85[8] = sub_1BF4(a1, v5, v8, v11, 7LL);v12 = sub_1BF4(a1, v5, v8, v11, 8LL);v13 = v112;v85[9] = v12;v85[10] = sub_1BF4(a1, v5, v8, v11, 9LL);v14 = v5;v15 = sub_1BF4(a1, v5, v9, v11, v11);v16 = v109;v85[11] = v15;v17 = v111;memset(v84, 0, sizeof(v84));v18 = strlen(v109);__memcpy_chk(v13, v16, v18 + 1, 256LL);v19 = v110;*(v110 - 3) = unk_980;*(v19 - 32) = unk_990;*(v19 - 19) = unk_99D;*(v19 - 48) = sub_1BF4(a1, v14, v17, 6LL, 115LL);v20 = sub_1BF4(a1, v14, v17, 42LL, 189LL);v21 = sub_1BF4(a1, v14, v9, 226LL, v20);v22 = sub_1BF4(a1, v14, v17, v21, 331LL);v23 = y < 10;v24 = v113;*(v113 - 16) = 0u;*(v24 - 15) = 0u;*(v24 - 14) = 0u;*(v24 - 13) = 0u;*(v24 - 12) = 0u;*(v24 - 11) = 0u;*(v24 - 10) = 0u;*(v24 - 9) = 0u;*(v24 - 8) = 0u;*(v24 - 7) = 0u;*(v24 - 6) = 0u;*(v24 - 5) = 0u;*(v24 - 4) = 0u;*(v24 - 3) = 0u;*(v24 - 2) = 0u;*(v24 - 1) = 0u;if ( v23 || (((x - 1) * x) & 1) == 0 )break;
LABEL_5:v25 = (*(*a1 + 48LL))(a1, &xmmword_4350);v26 = (*(*a1 + 264LL))(a1, v25, &byte_4364, &byte_436C);v27 = sub_1B58(a1, v25, v26);v28 = (*(*a1 + 264LL))(a1, v25, &byte_4370, &byte_4374);v29 = (*(*a1 + 264LL))(a1, v25, &byte_437C, &byte_4374);v30 = (*(*a1 + 264LL))(a1, v25, &byte_4380, &byte_4374);v31 = sub_1BF4(a1, v27, v29, 20LL, 28LL);sub_1BF4(a1, v27, v29, v31, 72LL);sub_1BF4(a1, v27, v29, v31, 1LL);sub_1BF4(a1, v27, v29, v31, 2LL);sub_1BF4(a1, v27, v29, v31, 3LL);sub_1BF4(a1, v27, v29, v31, 4LL);sub_1BF4(a1, v27, v29, v31, 5LL);sub_1BF4(a1, v27, v29, v31, 6LL);sub_1BF4(a1, v27, v29, v31, 7LL);sub_1BF4(a1, v27, v29, v31, 8LL);sub_1BF4(a1, v27, v29, v31, 9LL);sub_1BF4(a1, v27, v30, v31, v31);memset(v81, 0, sizeof(v81));v32 = v109;v33 = strlen(v109);__memcpy_chk(v81, v32, v33 + 1, 256LL);sub_1BF4(a1, v27, v28, 6LL, 115LL);v34 = sub_1BF4(a1, v27, v28, 42LL, 189LL);v35 = sub_1BF4(a1, v27, v30, 226LL, v34);sub_1BF4(a1, v27, v28, v35, 331LL);}v103 = v14;v104 = a1;if ( v22 < 1 ){v36 = v108;v37 = 0LL;goto LABEL_14;}v36 = v108;v37 = v22;if ( v22 == 1 ){v38 = v106;for ( i = 0LL; i != v22; *(v36 + i++) = v46 ){
LABEL_13:v46 = *(v38 + i % 0x2A);v102[i] = i;}goto LABEL_14;}v38 = v106;v40 = 0LL;i = v22 & 0xFFFFFFFE;v41 = 1;do{v42 = *(v38 + v40 % 0x2A);v43 = *(v38 + v40 + ((-42 * (v41 / 0x2A)) | 1));v44 = &v102[v40];v44[1] = v40 | 1;v45 = (v36 + v40);*v44 = v40;v40 += 2LL;v41 += 2;*v45 = v42;v45[1] = v43;}while ( i != v40 );if ( i != v22 )goto LABEL_13;
LABEL_14:v113 = v115;if ( v37 ){v47 = 0;v48 = 0LL;v110 = v37;do{v49 = v48[v36];while ( 1 ){v51 = v102[v48];getpid();sub_1C90(v116, 256LL);v52 = fopen(v116, &byte_43A0);if ( v52 ){v53 = v52;while ( fgets(v114, 256, v53) ){if ( strstr(v114, &qword_43A8) ){if ( atoi(v113) )__asm { SVC             0x80 }break;}}fclose(v53);}v58 = (v47 + v51 + v49) % v22;v23 = y < 10;v102[v48] = v102[v58];v102[v58] = v51;if ( v23 || (((x - 1) * x) & 1) == 0 )break;v59 = v102[v48];getpid();sub_1C90(v116, 256LL);v60 = fopen(v116, &byte_43A0);if ( v60 ){v61 = v60;while ( fgets(v114, 256, v61) ){if ( strstr(v114, &qword_43A8) ){if ( atoi(v113) )__asm { SVC             0x80 }break;}}fclose(v61);}v50 = (v47 + v59 + v49) % v22;v102[v48] = v102[v50];v102[v50] = v59;}v36 = v108;++v48;v47 = (v47 + v51 + v49) % v22;}while ( v48 != v110 );}v62 = v104;while ( 1 ){getpid();sub_1C90(v116, 256LL);v63 = fopen(v116, &byte_43A0);if ( v63 ){v64 = v63;while ( fgets(v114, 256, v64) ){if ( strstr(v114, &qword_43A8) ){if ( atoi(v113) )__asm { SVC             0x80 }break;}}fclose(v64);}if ( y < 10 || (((x - 1) * x) & 1) == 0 )break;getpid();sub_1C90(v116, 256LL);v65 = fopen(v116, &byte_43A0);if ( v65 ){v66 = v65;while ( fgets(v114, 256, v66) ){if ( strstr(v114, &qword_43A8) ){if ( atoi(v113) )__asm { SVC             0x80 }break;}}fclose(v66);}}v68 = v111;v67 = v112;v69 = v103;v70 = 0LL;v71 = 0;v72 = 0;do{v72 = (v72 + 1) % v22;v73 = v102[v72];v74 = *(v67 + v70);v71 = (v71 + v73) % v22;v102[v72] = v102[v71];v102[v71] = v73;*(v67 + v70++) = sub_1BF4(v62, v69, v68, v74, v102[(v102[v72] + v73) % v22]);}while ( v70 != 42 );v75 = v107;v76 = 0LL;v77 = 1;do{getpid();sub_1C90(v116, 256LL);v78 = fopen(v116, &byte_43A0);if ( v78 ){v79 = v78;while ( fgets(v114, 256, v79) ){if ( strstr(v114, &qword_43A8) ){if ( atoi(v113) )__asm { SVC             0x80 }break;}}fclose(v79);}if ( *(v67 + v76) != *(v75 + v76) )break;_CF = v76++ >= 0x29;v77 = !_CF;}while ( v76 != 42 );return !v77;
}

最重要的一部分

在这里插入图片描述

我们发现最后返回的是根据V67和V76,V75进行判断的,在java层我们也分析道我们要的就是返回值,看最后的循环语句,可以清楚的发现,其实就是就是一个类似于strcmp的一个函数,每一个字符进行比较,如果有一处不一样,就跳出循环,否则都一样的话呢,返回v77,这个是1,需要获取到值,这个就是注册码,或者试试将这个返回修改一下也是可以的。

然后尝试分析流程图(不会/(ㄒoㄒ)/~~
在这里插入图片描述

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

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

相关文章

Easy Excel从入门到精通!!!

目录 1.文件导入 1.1基本方式读取excel文件内容 1.2注解模型映射器读取excel 1.3多行表头读取 1.4文件上传读取 2.文件导出 2.1基本方式导出 2.2模型映射导出 2.3设置行高、列宽等内容 2.4合并单元格 2.5导出设置超链接、批注、公式 2.6模板填充对象导出 2.7模板填…

数据集-目标检测系列-火车检测数据集 train >> DataBall

数据集-目标检测系列-火车检测数据集 train >> DataBall 数据集-目标检测系列-火车检测数据集 数据量&#xff1a;1W 想要进一步了解&#xff0c;请联系 DataBall。 DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种数据集&#xff0c;不断增加…

K8s Calico替换为Cilium,以及安装Cilium过程

一、删除Calico kubectl delete daemonset calico-node -n kube-systemkubectl delete deployment calico-kube-controllers -n kube-system kubectl delete ds kube-flannel-ds -n kube-system kubectl delete cm calico-config -n kube-system kubectl delete secret calico…

Docker安装mysql并配置主从,超详细

简介&#xff1a; 本文使用docker安装mysql&#xff0c;并创建master节点&#xff0c;slave节点用于实现主从。废话不多说&#xff0c;直接开始。 1.docker下载镜像&#xff0c;这里我以5.7版本为例。 docker pull mysql:5.7 2.在宿主机上新建如下目录&#xff0c;进行文件挂…

STM32F407单片机编程入门(十四) 内部RTC实时时钟详解及实战含源码

文章目录 一.概要二.RTC基本介绍三.STM32单片机RTC内部结构图四.CubeMX配置一个RTC时间例程五.CubeMX工程源代码下载六.小结 一.概要 RTC&#xff08;Real-Time Clock&#xff09;是一种用于追踪和记录实际时间的时钟系统。在STM32中&#xff0c;RTC通常用于提供实时时钟和日期…

cnn机器学习时python版本不兼容报错

在使用python执行CNN算法时&#xff0c;发生如下报错&#xff1a; A module that was compiled using NumPy 1.x cannot be run in NumPy 2.1.1 as it may crash. To support both 1.x and 2.x versions of NumPy, modules must be compiled with NumPy 2.0. Some module may …

MySQL 中的全文索引:强大的文本搜索利器

《MySQL 中的全文索引&#xff1a;强大的文本搜索利器》 在 MySQL 数据库中&#xff0c;全文索引是一种非常有用的功能&#xff0c;它可以帮助我们快速地在大量文本数据中进行搜索。那么&#xff0c;什么是 MySQL 中的全文索引呢&#xff1f;它又是如何工作的呢&#xff1f;让…

wordpress迁移到别的服务器

wordpress论坛网站搭建 于2023/11/16写的该文章 一-配置环境 配置LNMP&#xff08;linuxnginxmysqlphpphpmyadmin&#xff09;环境或者LAMP&#xff08;apache&#xff09; 可以选择集成了这些软件的套件 下载链接&#xff1a;https://www.xp.cn/download.html 手动下载这…

传输层 IV(TCP协议——流量控制、拥塞控制)【★★★★】

&#xff08;★★&#xff09;代表非常重要的知识点&#xff0c;&#xff08;★&#xff09;代表重要的知识点。 一、TCP 流量控制&#xff08;★★&#xff09; 1. 利用滑动窗口实现流量控制 一般说来&#xff0c;我们总是希望数据传输得更快一些。但如果发送方把数据发送得…

Linux 一些快捷键使用操作技巧

ctrl c : 强制停止 如图仅输入tail命令时程序会卡住&#xff0c;这时就需要强制停止 ctrl d : 退出或者登出 history : 查看历史输入命令 &#xff01;命令 &#xff1a;自动执行上一次匹配前缀的命令 &#xff08;注意不要用这个命令执行太过久远的&#xff0c;容易执行错误…

设置VsCode搜索时排除文件,文件列表中隐藏文件

按照《VsCode gdb gdbserver远程调试C程序》中介绍的方法&#xff0c;配置好VsCode后&#xff0c;打开一个C/C工程&#xff0c;发现左侧的面板会显示编译时生成的中间文件&#xff08;比如.d和.o文件&#xff09;。我们可以通过设置隐藏掉一些我们不需要打开的文件以简洁面板…

C++基础(8.继承_多态)

目录 继承&#xff1a; 继承的概念&#xff1a; 继承的定义&#xff1a; 基类和派生类对象赋值转换 &#xff1a; 继承中的作用域&#xff1a; 派生类的默认成员函数&#xff1a; 例题&#xff1a; ​编辑​编辑​编辑 继承与友元&#xff1a; 继承与静态成员&#xff1…

【C++】C++入门概念(二)

引用 概念 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟内存空间&#xff0c;它和它引用的变量共用同一块内存空间。 比如&#xff1a;李逵&#xff0c;在家称为"铁牛"&#xff0c;江湖上人称"黑旋…

汇川AM600 与 codesys opc server 通讯并建立 OPCserver 的方法

AM600 与 codesys opc server 通讯并建立 OPCserver 的方法 AM600 OPC Server 架构 1、程序后台“应用中”添加 symbols config 2、 选择作为 OPCsever 跟 PLC 通讯数据 点击 ACCERSS rights 下的箭头选择权限 安装目录下:打开“OPCConfig”

re题(38)BUUCTF-[FlareOn6]Overlong

BUUCTF在线评测 (buuoj.cn) 运行一下.exe文件 查壳是32位的文件&#xff0c;放到ida反汇编 对unk_402008前28位进行一个操作&#xff0c;我们看到运行.exe文件的窗口正好是28个字符&#xff0c;而unk_402008中不止28个数据&#xff0c;所以猜测MessageBoxA&#xff08;&#x…

MySQL --表的约束

文章目录 1.空属性2.默认值3.列描述4.zerofill5.主键6.自增长7.唯一键8.外键9.综合案例-阅读 1.空属性 两个值&#xff1a;null&#xff08;默认的&#xff09;和not null(不为空) 数据库默认字段基本都是字段为空&#xff0c;但是实际开发时&#xff0c;尽可能保证字段不为空…

AI客服对决:智能客服PK赛揭示企业级AI应用未来

如今的AI对抗场景&#xff0c;简直成了颇具娱乐性的“观赏项目”。围观群众们不仅看得津津有味&#xff0c;时不时还会发出阵阵笑声。 最近&#xff0c;一场别开生面的AI客服挑战赛引发了热议&#xff1a;一位使用“花开富贵”阿姨人设的Agent甩出一条链接&#xff0c;结果对面…

如何在命令执行超时时自动终止该命令

问题 问题 《Command line command to auto-kill a command after a certain amount of time》 中的回答提出了一种从 bash 命令行中为长时间运行的命令设置超时的方法&#xff1a; ( /path/to/slow command with options ) & sleep 5 ; kill $!但是有可能某个“耗时长”…

python绘制弦图-科研作图

一、背景 弦图以其直观、精美的展示方式受到越来越多人的关注&#xff0c;它不仅能够有效展示两个变量之间的联系&#xff0c;还能同时展现多个变量间的复杂互动&#xff0c;本文将通过Python语言中的pycirclize库&#xff0c;带你深入了解如何绘制弦图。 弦图是一种圆…

CQRS模型解析

简介 CQRS中文意思为命令于查询职责分离&#xff0c;我们可以将其了解成读写分离的思想。分为两个部分 业务侧和数据侧&#xff0c;业务侧主要执行的就是数据的写操作&#xff0c;而数据侧主要执行的就是数据的读操作。当然两侧的数据库可以是不同的。目前最为常用的CQRS思想方…