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

news2024/9/23 5:25:12

一: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.FragmentActivity
    public 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; // x0

  v4 = (*(__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; // x25
  unsigned __int8 v10; // w0
  unsigned int v11; // w27
  char v12; // w0
  __int64 v13; // x22
  __int64 v14; // x26
  char v15; // w0
  const char *v16; // x24
  __int64 v17; // x23
  __int64 v18; // x0
  __int64 v19; // x8
  unsigned int v20; // w0
  unsigned int v21; // w0
  int v22; // w25
  bool v23; // cc
  const char *v24; // x8
  __int64 v25; // x25
  __int64 v26; // x0
  __int64 v27; // x21
  __int64 v28; // x23
  __int64 v29; // x26
  __int64 v30; // x25
  unsigned int v31; // w27
  const char *v32; // x24
  __int64 v33; // x0
  unsigned int v34; // w0
  unsigned int v35; // w0
  __int64 v36; // x17
  __int64 v37; // x1
  __int64 v38; // x0
  __int64 i; // x8
  __int64 v40; // x9
  unsigned int v41; // w10
  char v42; // w14
  char v43; // w13
  _BYTE *v44; // x16
  _BYTE *v45; // x15
  char v46; // w11
  int v47; // w22
  _BYTE *v48; // x23
  int v49; // w24
  __int64 v50; // x8
  int v51; // w20
  FILE *v52; // x0
  FILE *v53; // x28
  int v58; // w8
  int v59; // w20
  FILE *v60; // x0
  FILE *v61; // x28
  __int64 v62; // x24
  FILE *v63; // x0
  FILE *v64; // x28
  FILE *v65; // x0
  FILE *v66; // x28
  __int64 v67; // x26
  __int64 v68; // x28
  __int64 v69; // x27
  __int64 v70; // x20
  int v71; // w22
  int v72; // w23
  int v73; // w9
  __int64 v74; // x3
  __int64 v75; // x25
  unsigned __int64 v76; // x24
  _BOOL4 v77; // w21
  FILE *v78; // x0
  FILE *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] BYREF
  char 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.coloradmin.cn/o/2156676.html

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

相关文章

Java语言程序设计基础篇_编程练习题**18.31 (替换单词)

目录 题目&#xff1a;**18.31 (替换单词) 习题思路 代码示例 运行结果 替换前 替换后 题目&#xff1a;**18.31 (替换单词) 编写一个程序&#xff0c;递归地用一个新单词替换某个目录下的所有文件中出现的某个单词。从命令行如下传递参数&#xff1a; java Exercise18…

C++标准库双向链表 list 中的insert函数实现。

CPrimer中文版&#xff08;第五版&#xff09;&#xff1a; //运行时错误&#xff1a;迭代器表示要拷贝的范围&#xff0c;不能指向与目的位置相同的容器 slist.insert(slist.begin(),slist.begin(),slist.end()); 如果我们传递给insert一对迭代器&#xff0c;它们不能…

【有啥问啥】深度剖析:大模型AI时代下的推理路径创新应用方法论

深度剖析&#xff1a;大模型AI时代下的推理路径创新应用方法论 随着大规模预训练模型&#xff08;Large Pretrained Models, LPMs&#xff09;和生成式人工智能的迅速发展&#xff0c;AI 在多领域的推理能力大幅提升&#xff0c;尤其是在自然语言处理、计算机视觉和自动决策领…

【C++11】异常处理

目录 一、异常的引入 二、C异常的关键字 三、异常的抛出与处理规则 四、异常缺陷的处理 五、自定义异常体系 六、异常规范 七、异常安全 八、异常的优缺点 1.优点 2.缺点 一、异常的引入 传统的C语言处理异常的方式有两种&#xff1a; 1.终止程序&#xff1a;使用as…

[WMCTF2020]Make PHP Great Again 2.01

又是php代码审计,开始吧. 这不用审吧&#xff0c;啊喂. 意思就是我们要利用require_once()函数和传入的file的value去读取flag的内容.&#xff0c;貌似呢require_once()已经被用过一次了&#xff0c;直接读取还不行&#xff0c;看一下下面的知识点. require_once() require…

Qt 注册表操作

一.操作环境 二.注册表查看 1. 搜索注册表打开 2. 注册表查看 例如我想操作 计算机\HKEY_CURRENT_USER\SOFTWARE\winzq\qwert下的内容 三.代码 1. H文件 #ifndef __REGISTER_H__ #define __REGISTER_H__#include <QString> #include <QSettings> #include <Q…

Web 安全(Web Security)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

信息安全工程师(11)网络信息安全科技信息获取

一、信息获取的重要性 在网络安全领域&#xff0c;及时、准确地获取科技信息对于防范和应对网络威胁至关重要。这些信息可以帮助安全团队了解最新的攻击手段、漏洞信息、防护技术等&#xff0c;从而制定有效的安全策略和应对措施。 二、信息获取的来源 网络信息安全科技信息的获…

s3c2440各部分应用

一、按位运算 按位与&&#xff1a;清零&#xff0c;清零位&0&#xff1b; 如&#xff1a;0xFFFF &&#xff08; ~&#xff08;1 << 7&#xff09;&#xff09;, 将第7位清零。 按位或 | &#xff1a;置1&#xff0c;置1位 | 1&#xff1b; 如&…

MySQL(七)——事务

文章目录 事务事务的概念事务的ACID特性事务的语法查看存储引擎查看自动提交参数和设置手动事务操作保存点 隔离级别与并发事务问题隔离级别并发事务问题 事务 事务的概念 事务&#xff08;Transaction&#xff09;是数据库管理系统中执行过程中的一个逻辑单位&#xff0c;由…

Rx Strategist:智能体实现处方验证的方方面面,如适应症、剂量、药物相互作用

Rx Strategist&#xff1a;智能体实现处方验证的方方面面&#xff0c;如适应症、剂量、药物相互作用 秒懂大纲提出背景&#xff1a;拆解解法分析全流程分析创意 秒懂大纲 ├── 处方验证系统【主题】 │ ├── 背景和问题【问题描述】 │ │ ├── 现代药物复杂性对严…

Java基础面试题——异常

目录 关系图 1. Throwable和Exception之间的关系 2.异常分为哪两大类 3.常见的 RuntimeException 4. 常见的 Error 5.什么是已检查异常和未检查异常&#xff1f;它们的区别是什么&#xff1f; 6.Java 中如何自定义异常&#xff1f; 7.throw 和 throws 的区别是什么&…

ML 系列:机器学习和深度学习的深层次总结(07)数据预处理—解决缺失值、异常值和错误数据

文章目录 一、说明二、数据预处理三、缺失值四、数据集中可能会出现多种类型的缺失值&#xff1a;五、处理缺失值的方法六、结论 一、说明 在AI数据挖掘中&#xff0c;对原始数据的预处理是必须的技术手段&#xff0c;本篇将对数据预处理的一系列注意事项进行展示。 二、数据…

JavaEE: 深入探索TCP网络编程的奇妙世界(五)

文章目录 TCP核心机制TCP核心机制六: 拥塞控制为什么要有拥塞控制?动态调整的拥塞控制拥塞控制中,窗口大小具体的变化过程 TCP核心机制七: 延时应答TCP核心机制八: 捎带应答 TCP核心机制 前一篇文章 JavaEE: 深入探索TCP网络编程的奇妙世界(四) 书接上文~ TCP核心机制六: 拥…

数据结构:二叉树OJ题(基础版)

前言 更完两期二叉树的知识之后&#xff0c;来做几道oj题巩固一下基础 一、翻转二叉树 链接&#xff1a;leetcode链接 还是分治思想&#xff0c;将问题分解成左子树和右子树交换&#xff0c;遇到空树停止 采用递归算法做题 TreeNode* invertTree(TreeNode* root) {if(root …

2D目标检测常用loss

在2D目标检测任务中&#xff0c;常用的损失函数&#xff08;Loss&#xff09;主要用于优化以下三个关键方面&#xff1a; 类别分类&#xff08;Classification&#xff09;&#xff1a;用于区分检测到的对象属于哪一类。边界框回归&#xff08;Bounding Box Regression&#x…

Spring Boot蜗牛兼职网:全栈开发

第4章 系统设计 4.1 系统体系结构 蜗牛兼职网的结构图4-1所示&#xff1a; 图4-1 系统结构 登录系统结构图&#xff0c;如图4-2所示&#xff1a; 图4-2 登录结构图 蜗牛兼职网结构图&#xff0c;如图4-3所示。 图4-3 蜗牛兼职网结构图 4.2开发流程设计 系统流程的分析是通…

在Web开发中使用和风天气接口

介绍 和风天气是一个提供全球天气预报和气象数据的服务平台&#xff0c;支持多种语言&#xff0c;提供实时天气、未来天气预报、空气质量指数、生活建议等多种气象数据&#xff0c;可以广泛用于网页开发、移动应用和物联网设备等场景。 开发文档&#xff1a;文档 | 和风天气开…

intellij idea 控制台运行java出现中文乱码的解决方法

原因&#xff1a; 字符编码不一致&#xff1a; 当你在intellij idea使用了UTF-8编码&#xff0c;而在控制台使用了其他编码&#xff08;比如gbk&#xff09;&#xff0c;就可能导致乱码。 文件读写编码问题&#xff1a; 如果读取文件时使用的编码与文件实际编码不一致&#xf…

Chainlit集成LlamaIndex实现知识库高级检索(自动合并检索)

检索原理 自动合并检索 自动合并检索原理&#xff0c;和我的上一篇文章的检索方案&#xff1a; 将文本分割成512大小&#xff08;一般对应段落大小&#xff09;和128&#xff08;一般对句子大小不是严格的句子长度&#xff09;大小两种分别存储到索引库&#xff0c;再用llama_…