Android之Xposed框架完全使用指南

文章目录

    • Xposed环境搭建
      • Xposed简介
      • Xposed原理
      • Xposed的安装
    • Xposed插件开发
      • Xposed插件编写流程
      • Xposed开发之Hook构造函数
        • 相关API
        • 无参构造函数的hook
        • 有参构造函数的hook
        • 实际效果
      • Xposed开发之修改属性
        • 相关API
        • 修改静态字段和成员字段
        • 实际效果
      • Xposed开发之hook一般函数
        • 相关API
        • hook一般函数
        • 实际效果
      • Xposed开发之主动调用函数
        • 相关API
        • 调用静态函数
        • 调用成员函数
        • 实际效果
      • Xposed开发之加壳APP处理
        • 实际效果
      • Xposed指纹检测

Xposed环境搭建

Xposed简介

Xposed是一款可以在不修改APK的情况下影响程序运行的框架,基于它可以制作出许多功能强大的模块,且在功能不冲突的情况下同时运作。在这个框架下,我们可以编写并加载自己编写的插件APP,实现对目标apk的注入拦截等。

Xposed原理

控制zygote进程,通过替换/system/bin/app_precess程序控制zygote进程,使得它在系统启动的时候会加载Xposed framework的一个jar文件即XposedBridge.jar,从而完成对zygote进程及其创建的Dalvik/ART虚拟机的劫持,并且能够允许开发者独立的替代任何class。

Xposed的安装

4.4以下的Android版本安装较为简单,只需要两步:

  1. 对需要安装xposed的手机进行root
  2. 下载并安装xposedinstall,之后授予root权限,进入app点击安装即可

从Android 5.0开始,谷歌使用ART替换Dalvik,所以Xposed安装有点麻烦,分为两个部分:xposed*.zip和XposedInstaller.apk。zip文件是框架主体,需要进入Recovery后刷入,apk文件是xposed模块管理应用的,主要用于下载,激活,是否启用模块等功能管理。步骤如下:

  1. 完成对手机的root,并刷入recovery(比如twrp)
  2. 下载对应的zip补丁包,进入recovery刷入
  3. 重启手机,安装XposedInstaller并授予root权限即可

实际操作如下:

http://dl-xda.xposed.info/framework/

在这里插入图片描述

首先去官网下载对应的补丁包,sdk23对应Android 6.0版本,其他对应版本请自行查询,我这里用的是6.0的系统

在这里插入图片描述

然后选择对应的系统架构

在这里插入图片描述

版本选择最新版,接着按照上面的步骤安装xposed模块即可。

Xposed插件开发

Xposed插件编写流程

  1. 拷贝XposedBridgeApi.jar到新建工程的libs目录并导入模块

在这里插入图片描述

将jar包导入到模块,并设置Configuration为compileOnly

在这里插入图片描述

  1. 在AndroidMainfest.xml中增加Xposed相关内容
//是否配置为xposed插件 设置为true
<meta-data android:name="xposedmodule" android:value="true"/>
//模块名称
<meta-data android:name="xposeddescription" android:value="模块描述(例如:第一个xposed插件)"/>
//最低版本号
<meta-data android:name="xposedminversion"android:value="54"/>
  1. 新建hook类,编写hook代码
package com.example.xposeddemo01;import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.callbacks.XC_LoadPackage;public class Xposed01 implements IXposedHookLoadPackage {@Overridepublic void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {}
}

实现IXposedHookLoadPackage接口,然后在handleLoadPackage函数内编写Hook代码

  1. 新建assets文件夹,然后在assets目录下新建xposed_init,在里面写上hook类的完整路径(包名+类名),可以有多个,每一个类写一行

在这里插入图片描述

Xposed开发之Hook构造函数

相关API

需要用到的API如下:

XposedHelpers.findAndHookConstructor

无参构造函数的hook

首先编写一个目标hook类,类代码包含多个构造函数

package com.example.hookdemo01;public class Student {String name;String id;int age;public Student(){name="default";id="default";}public Student(String name) {this.name = name;}public Student(String name, String id) {this.name = name;this.id = id;}public Student(String name, String id, int age) {this.name = name;this.id = id;this.age = age;}
}

然后打印出类的信息

package com.example.hookdemo01;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.util.Log;public class MainActivity extends AppCompatActivity {public void PrintStudent(Student stu){Log.i("Xposed",stu.name+"--"+stu.id+"--"+stu.age);}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Student studenta=new Student();Student studentb=new Student("GuiShou");Student studentc=new Student("GuiShou2","2021");Student studentd=new Student("GuiShou3","2021",20);PrintStudent(studenta);PrintStudent(studentb);PrintStudent(studentc);PrintStudent(studentd);}
}

接着编写hook代码,代码实现写在handleLoadPackage里

 //判断包名是否是要hook的包if (loadPackageParam.packageName.equals("com.example.hookdemo01")){//获取当前的classloaderClassLoader classLoader=loadPackageParam.classLoader;//获取当前的ClassClass studentClass=classLoader.loadClass("com.example.hookdemo01.Student");//hook无参构造函数 参数列表为空 第二个参数类型不需要传入XposedHelpers.findAndHookConstructor(studentClass, new XC_MethodHook() {@Overrideprotected void beforeHookedMethod(MethodHookParam param) throws Throwable {super.beforeHookedMethod(param);XposedBridge.log("com.example.hookdemo01.Student() is called! beforeHookedMethod");}@Overrideprotected void afterHookedMethod(MethodHookParam param) throws Throwable {super.afterHookedMethod(param);XposedBridge.log("com.example.hookdemo01.Student() is called! afterHookedMethod");}});

有参构造函数的hook

然后编写有参函数的hook代码

 //hook一个参数的构造函数 传入参数类型XposedHelpers.findAndHookConstructor(studentClass,String.class ,new XC_MethodHook() {@Overrideprotected void beforeHookedMethod(MethodHookParam param) throws Throwable {super.beforeHookedMethod(param);//获取参数数组Object[] argsarray=param.args;String name=(String)argsarray[0];//打印参数名XposedBridge.log("com.example.hookdemo01.Student(String) is called! beforeHookedMethod--"+name);}@Overrideprotected void afterHookedMethod(MethodHookParam param) throws Throwable {super.afterHookedMethod(param);XposedBridge.log("com.example.hookdemo01.Student(String) is called! afterHookedMethod");}});//hook两个参数的构造函数 传入参数类型XposedHelpers.findAndHookConstructor(studentClass,String.class ,String.class,new XC_MethodHook() {@Overrideprotected void beforeHookedMethod(MethodHookParam param) throws Throwable {super.beforeHookedMethod(param);//获取参数数组Object[] argsarray=param.args;String name=(String)argsarray[0];String id=(String)argsarray[1];//打印参数名XposedBridge.log("com.example.hookdemo01.Student(String,String) is called! beforeHookedMethod--"+name+"--"+id);}@Overrideprotected void afterHookedMethod(MethodHookParam param) throws Throwable {super.afterHookedMethod(param);XposedBridge.log("com.example.hookdemo01.Student(String,String) is called! afterHookedMethod");}});//hook三个参数的构造函数 传入参数类型XposedHelpers.findAndHookConstructor(studentClass,String.class ,String.class,int.class,new XC_MethodHook() {@Overrideprotected void beforeHookedMethod(MethodHookParam param) throws Throwable {super.beforeHookedMethod(param);//获取参数数组Object[] argsarray=param.args;String name=(String)argsarray[0];String id=(String)argsarray[1];int age=(int)argsarray[2];//打印参数名XposedBridge.log("com.example.hookdemo01.Student(String,String,int) is called! beforeHookedMethod--"+name+"--"+id+"--"+age);}@Overrideprotected void afterHookedMethod(MethodHookParam param) throws Throwable {super.afterHookedMethod(param);XposedBridge.log("com.example.hookdemo01.Student(String,String,int) is called! afterHookedMethod");}});

这里只需要调用findAndHookConstructor函数,完成回调函数编写即可

实际效果

启用xposed模块,重启目标app

在这里插入图片描述

可以看到这里打印出了所有相关的信息,如果需要还可以对参数进行修改

Xposed开发之修改属性

相关API

需要用到的API如下:

XposedHelpers.getStaticObjectField
XposedHelpers.setStaticObjectField
XposedHelpers.getObjectField
XposedHelpers.setObjectField

Xposed不只是可以实现对app自己实现的类构造函数的hook,对于类的属性字段也提供了一系列修改的API,首先修改目标类代码

package com.example.hookdemo01;
import android.util.Log;public class Student {String name;String id;int age;private String nickname;public static String teachername;public Student(String name, String id, int age, String teacher,String nickname) {this.name = name;this.id = id;this.age = age;this.nickname = nickname;teachername=teacher;Log.i("Xposed","构造函数--teachername:"+teachername);Log.i("Xposed","构造函数--nickname:"+nickname);}
}

接着编写hook代码

修改静态字段和成员字段

package com.example.xposeddemo01;
import java.lang.reflect.Field;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;public class Xposed01 implements IXposedHookLoadPackage {@Overridepublic void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {//判断包名是否是要hook的包if (loadPackageParam.packageName.equals("com.example.hookdemo01")){//获取当前的classloaderClassLoader classLoader=loadPackageParam.classLoader;//获取当前的ClassClass studentClass=classLoader.loadClass("com.example.hookdemo01.Student");//hook三个参数的构造函数 传入参数类型XposedHelpers.findAndHookConstructor(studentClass,String.class ,String.class,int.class,String.class,String.class,new XC_MethodHook() {@Overrideprotected void afterHookedMethod(MethodHookParam param) throws Throwable {super.afterHookedMethod(param);XposedBridge.log("com.example.hookdemo01.Student(String,String,int) is called! afterHookedMethod");//------------------------修改static属性-------------------------------------//设置teacher字段XposedHelpers.setStaticObjectField(studentClass,"teachername","teacher888");//获取teacher字段 打印输出String teacher = (String)XposedHelpers.getStaticObjectField(studentClass,"teachername");XposedBridge.log("修改后的teachername字段:"+teacher);//-------------------修改对象属性-----------------------------------------XposedHelpers.setObjectField(param.thisObject,"nickname","pandan888");//获取nickname字段 打印输出String nickname=(String)XposedHelpers.getObjectField(param.thisObject,"nickname");XposedBridge.log("修改后的nickname字段:"+nickname);}});}}
}

对于修改静态字段和成员字段,需要使用不同的API,xposed类内部已经取消了字段的访问检查,所以不需要自己取消检查,比反射修改字段的方案更加简洁

实际效果

在这里插入图片描述

Xposed开发之hook一般函数

相关API

XposedHelpers.findAndHookMethod

hook一般函数

首先修改一下目标app的代码

   public static String publicstaticfun(String arg1,int arg2){//String result= privatestaticfun("test2",200);return arg1+"---"+arg2;}

增加一个静态的成员函数,接着编写hook代码

public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {if (loadPackageParam.packageName.equals("com.example.hookdemo01")){//获取当前的classloaderClassLoader classLoader=loadPackageParam.classLoader;//获取当前的ClassClass studentClass=classLoader.loadClass("com.example.hookdemo01.Student");//hookXposedHelpers.findAndHookMethod(studentClass, "publicstaticfun", String.class, int.class, new XC_MethodHook() {@Overrideprotected void beforeHookedMethod(MethodHookParam param) throws Throwable {super.beforeHookedMethod(param);//打印参数Object[] objectarray=param.args;String arg0=(String)objectarray[0];int arg1=(int)objectarray[1];XposedBridge.log("beforeHookedMethod---arg0:"+objectarray[0]+"arg1:"+objectarray[1]);//修改参数objectarray[0]="GuiShou";objectarray[1]=888;XposedBridge.log("beforeHookedMethod---arg0:"+objectarray[0]+"arg1:"+objectarray[1]);}@Overrideprotected void afterHookedMethod(MethodHookParam param) throws Throwable {super.afterHookedMethod(param);//打印返回值String result=(String)param.getResult();XposedBridge.log("afterHookedMethod---result:"+result);//修改返回值param.setResult("this it result");String result2=(String)param.getResult();XposedBridge.log("afterHookedMethod---result:"+result2);}});}}

实际效果

在这里插入图片描述

可以看到,这里已经打印出了修改前后的参数和返回值。实际上,类中的其他函数,例如私有成员函数,匿名内部类函数等等,都是用同样的方法进行hook,只要填入jadx反编译的类名和函数名即可。

Xposed开发之主动调用函数

 public static String publicstaticfun(String arg1,int arg2){Log.i("xposed","publicstaticfun is call");return arg1+"---"+arg2;}private String privatefun(String arg1,int arg2){Log.i("xposed","privatefun is call");return arg1+"---"+arg2;}

首先修改代码,增加一个静态函数和一个成员函数,调用时触发log信息

相关API

XposedHelpers.callStaticMethod()
XposedHelpers.callMethod()

调用静态函数

	//获取当前的classloaderClassLoader classLoader=loadPackageParam.classLoader;//获取当前的ClassClass studentClass=classLoader.loadClass("com.example.hookdemo01.Student");//调用静态函数XposedHelpers.callStaticMethod(studentClass,"publicstaticfun","guishou",100);

调用成员函数

            //获取当前的classloaderClassLoader classLoader=loadPackageParam.classLoader;//获取当前的ClassClass studentClass=classLoader.loadClass("com.example.hookdemo01.Student");//调用构造函数 获取对象Object obj = XposedHelpers.newInstance(studentClass,"GuiShou3","2021",20,"teacher666","pandan666");//调用成员函数XposedHelpers.callMethod(obj,"privatefun","guishou",100);

实际效果

在这里插入图片描述

可以看到,静态函数和成员函数均被调用了。对于类中的静态函数,直接调用即可;对于成员函数,需要先得到类的实例,然后才能完成调用。

Xposed开发之加壳APP处理

对于加壳app的hook处理,实际上就是解决ClassLoader的问题。

对于加壳的APP,如果我们直接去hook当前的apk的话,那么壳代码中的ClassLoder必定是没有我们所需要hook的目标类。

由于壳代码的ClassLoader中并没有我们需要的类,所以在编写hook代码之前还需要一个步骤,就是在壳代码的修正ClassLoader之后,利用反射的方式拿到修正后的ClassLoader,然后传入修正后的ClassLoader,再对目标类进行hook

实际代码如下:

 public static Field getClassField(ClassLoader classloader, String class_name,String filedName) {try {Class obj_class = classloader.loadClass(class_name);//Class.forName(class_name);Field field = obj_class.getDeclaredField(filedName);field.setAccessible(true);return field;} catch (SecurityException e) {e.printStackTrace();} catch (NoSuchFieldException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}return null;}public static Object getClassFieldObject(ClassLoader classloader, String class_name, Object obj,String filedName) {try {Class obj_class = classloader.loadClass(class_name);//Class.forName(class_name);Field field = obj_class.getDeclaredField(filedName);field.setAccessible(true);Object result = null;result = field.get(obj);return result;} catch (SecurityException e) {e.printStackTrace();} catch (NoSuchFieldException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return null;}public static Object invokeStaticMethod(String class_name,String method_name, Class[] pareTyple, Object[] pareVaules) {try {Class obj_class = Class.forName(class_name);Method method = obj_class.getMethod(method_name, pareTyple);return method.invoke(null, pareVaules);} catch (SecurityException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}return null;}public static Object getFieldOjbect(String class_name, Object obj,String filedName) {try {Class obj_class = Class.forName(class_name);Field field = obj_class.getDeclaredField(filedName);field.setAccessible(true);return field.get(obj);} catch (SecurityException e) {e.printStackTrace();} catch (NoSuchFieldException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NullPointerException e) {e.printStackTrace();}return null;}public static ClassLoader getClassloader() {ClassLoader resultClassloader = null;Object currentActivityThread = invokeStaticMethod("android.app.ActivityThread", "currentActivityThread",new Class[]{}, new Object[]{});Object mBoundApplication = getFieldOjbect("android.app.ActivityThread", currentActivityThread,"mBoundApplication");Application mInitialApplication = (Application) getFieldOjbect("android.app.ActivityThread",currentActivityThread, "mInitialApplication");Object loadedApkInfo = getFieldOjbect("android.app.ActivityThread$AppBindData",mBoundApplication, "info");Application mApplication = (Application) getFieldOjbect("android.app.LoadedApk", loadedApkInfo, "mApplication");resultClassloader = mApplication.getClassLoader();return resultClassloader;}

调用代码中的getClassloader函数,即可获取到修正后的classloader,接着编写hook代码

    @Overridepublic void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {if (loadPackageParam.packageName.equals("com.kanxue.xposedhook01")) {//对壳入口类的onCreate函数进行hook 拿到classloaderXposedHelpers.findAndHookMethod("com.stub.StubApp", loadPackageParam.classLoader, "onCreate", new XC_MethodHook() {@Overrideprotected void afterHookedMethod(MethodHookParam param) throws Throwable {super.afterHookedMethod(param);XposedBridge.log("com.stub.StubApp->onCreate afterHookedMethod");ClassLoader finalClassLoader=getClassloader();XposedBridge.log("finalClassLoader->" + finalClassLoader);GetClassLoaderClasslist(finalClassLoader);//再对目标类进行hook 传入拿到的classloaderXposedHelpers.findAndHookMethod("com.kanxue.xposedhook01.Student", finalClassLoader, "privatefunc", String.class, int.class, new XC_MethodHook() {@Overrideprotected void beforeHookedMethod(MethodHookParam param) throws Throwable {super.beforeHookedMethod(param);Object[] objectarray = param.args;String arg0 = (String) objectarray[0];int arg1 = (int) objectarray[1];XposedBridge.log("beforeHookedMethod11 privatefunc->arg0:" + arg0 + "---arg1:" + arg1);}@Overrideprotected void afterHookedMethod(MethodHookParam param) throws Throwable {super.afterHookedMethod(param);String result = (String) param.getResult();XposedBridge.log("afterHookedMethod11 privatefunc->result:" + result);}});Class personClass = XposedHelpers.findClass("com.kanxue.xposedhook01.Student$person", finalClassLoader);XposedHelpers.findAndHookMethod(personClass, "getpersonname", String.class, new XC_MethodHook() {@Overrideprotected void beforeHookedMethod(MethodHookParam param) throws Throwable {super.beforeHookedMethod(param);XposedBridge.log("beforeHookedMethod getpersonname->" + param.args[0]);}@Overrideprotected void afterHookedMethod(MethodHookParam param) throws Throwable {super.afterHookedMethod(param);XposedBridge.log("afterHookedMethod getpersonname->" + param.getResult());}});}});}}

首先需要hook入口类中的onCreate函数,在onCreate函数执行完成之后,获取到修正后的ClassLoader,接着再对目标类进行hook,此时hook的代码和hook一般函数一样,区别在于需要传入修正后的ClassLoder

实际效果

在这里插入图片描述

实际效果如图:可以看到这里已经成功对目标函数进行hook,打印出了hook之前和之后的函数相关信息。

Xposed指纹检测

可以根据下面的特征对xposed框架进行检测

  1. xposed插件的管理:XposedInstaller
  2. xposed对函数hook的根本原理:java函数变为native函数
  3. xposed框架拥有大量的api
  4. xposed框架特定的文件:运行库文件和链接库

github上检测Xposed的demo:XposedChecker

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

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

相关文章

深入理解Android(三):Xposed详解

编者按&#xff1a;随着移动设备硬件能力的提升&#xff0c;Android系统开放的特质开始显现&#xff0c;各种开发的奇技淫巧、黑科技不断涌现&#xff0c;InfoQ特联合《深入理解Android》系列图书作者邓凡平&#xff0c;开设深入理解Android专栏&#xff0c;探索Android从框架到…

Xposed入门教程

2019年8月27日16时51分47秒以前一直没机会接触Android Hook方式的逆向今天有空试了下&#xff0c;以前也很少写这种东西&#xff0c;今天第一次&#xff0c;认真写下&#xff0c;记录一下?准备 准备搞太极的&#xff0c;但是Xposed都不会&#xff0c;不好搞&#xff0c;所以就…

RabbitMQ---订阅模型-Topic

订阅模型-Topic • Topic类型的Exchange与Direct相比&#xff0c;都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定Routing key 的时候使用通配符&#xff01; • Routingkey 一般都是有一个或多个单词组成&#xff0c;多个单词之间以…

PostgreSQL命令行工具psql常用命令

1. 概述 通常情况下操作数据库使用图形化客户端工具&#xff0c;在实际工作中&#xff0c;生产环境是不允许直接连接数据库主机&#xff0c;只能在跳板机上登录到Linux服务器才能连接数据库服务器&#xff0c;此时就需要使用到命令行工具。psql是PostgreSQL中的一个命令行交互…

pyreverse+Graphviz 快速理清整个项目中的代码结构

作用 &#xff1a; 分析代码中的调用关系&#xff0c;帮助快速理清代码。 安装方法&#xff1a;以windows为例 • 从官网下载 https://www.graphviz.org/download/ 安装• 记得将其添加到系统路径• 运行下面命令来检查安装是否完成&#xff1a; dot -V• 安装Pyreverse&…

配置web服务

Web服务器又称为WWW服务器&#xff0c;它是放置一般网站的服务器。一台Web服务器上可以建立多个网站&#xff0c;各网站的拥有者只需要把做好的网页和相关文件放置在Web服务器的网站中&#xff0c;其它用户就可以用浏览器访问网站中的网页了。 LAMP是Linux, Apache, MySQL, PH…

Web Service(Web服务)

什么是webservice&#xff1f; 一句话概括&#xff1a;WebService是一种跨编程语言和跨操作系统平台的远程调用技术。 所谓跨编程语言和跨操作平台&#xff0c;就是说服务端程序采用Java编写&#xff0c;客户端程序则可以采用其他编程语言编写&#xff0c;反之亦然&#xff01…

什么是Web 服务?

Web 服务是一种可以用来解决跨网络应用集成问题的开发模式&#xff0c;这种模式为实现“软件作为服务”提供了技术保障。而“软件作为服务”实质上是一种提供软件服务的机制&#xff0c;这种机制可以在网络上暴露可编程接口&#xff0c;并通过这些接口来共享站点开放出来的功能…

什么是web服务

2001年秋天互联网公司&#xff08;dot-com)泡沫的破灭标志着互联网的一个转折点。许多人由此断定互联网是被大家过分炒作了&#xff0c;事实上网络泡沫和相继而来的股市大衰退是所有技术革命的共同特征。股市大衰退通常标志着蒸蒸日上的技术已经开始占领中央舞台&#xff0c;假…

Web服务基础

1 Web服务器 WEB服务器用来接收客户的请求&#xff0c;然后向客户返回一些结果。 用户可以通过web浏览器请求一个资源。Web服务器在接收到请求之后&#xff0c;负责查找资源&#xff0c;然后向用户返回一个结果。 2 Web客户端 Web客户端允许用户请求服务器上的某个资源&#xf…

WEB服务的部署

文章目录 一、WEB服务相关概念1. WEB服务器2. 协议端口号3. WEB服务器发布软件 二、WEB服务器的部署1.配置服务器的静态IP&#xff1a;10.1.1.12.安装IIS-WEB插件3.停用默认站点4. 新建站点senting5. 一台服务器同时发布多个WEB站点6. 对于动态网站的搭建 一、WEB服务相关概念 …

Web 服务的概述

Web 服务的概述 由于能够提供图形、声音等多媒体数据&#xff0c;再加上可以交互的动态 Web 语言的广泛普及&#xff0c;WWW&#xff08;World Wide Web&#xff0c;万维网&#xff09;深受Internet用户欢迎。一个最重要的证明就是&#xff0c;当前的绝大部分Internet流量都…

【网络安全】Web服务器

文章目录 1、Web服务器概述1.1、Web服务器1.2、端口1.3、网站与网页 2、Web服务器发布2.1、发布软件2.2、发布形式2.3、网站类型 3、部署Web服务器3.1、配置服务器IP地址3.2、安装IIS服务3.3、新建和发布网站3.3.1、同端口&#xff0c;不同IP3.3.2、同IP&#xff0c;不同端口3.…

Web服务(02)——Web服务器中间件

文章目录 Web服务&#xff08;02&#xff09;——Web服务器中间件前言一、JAVA中间件1、Tomcat2.Weblogic3.Jboss4.Webshaere 二、Python中间件1、wsgi2、uwsgi3.uWSGI 三、Php中间件1、php-fpm2、CGI3、FastCGI4、Php-FastCGI 四、其他中间件1、事务处理中间件——Hadoop2、消…

Web服务是什么

1、Web服务 服务&#xff1a;提供的某个功能&#xff1b;网络服务&#xff08;Net Service&#xff09;&#xff1a;使用不同的网络协议&#xff08;http、ftp、stmp/pop3&#xff09;提供的服务&#xff1b;Web服务&#xff1a;指使用 http 或 https 协议接受用户的服务请求并…

【优化算法】Python实现面向对象的遗传算法

遗传算法 遗传算法(Genetic Algorithm)属于智能优化算法的一种&#xff0c;本质上是模拟自然界中种群的演化来寻求问题的最优解。与之相似的还有模拟退火、粒子群、蚁群等算法。 在具体介绍遗传算法之前&#xff0c;我们先来了解一些知识&#x1f9c0; DNA&#xff1a; 携带有…

pyinstaller打包openvino 2021.4.2

打包准备 1. 测试环境准备 conda create -n opinstall python3.7 -y conda activate opinstall pip install openvino2021.4.2 pip install pyinstaller PyCharm新建openvino_install&#xff0c;选择虚拟环境opinstall&#xff0c;编写测试代码 app.py import numpy as n…

8.27周报

文章目录 前言论文阅读摘要介绍模型算法 总结 前言 本周学习了GAN论文《Generative Adversarial Nets》&#xff0c;了解GAN主要由两部分组成&#xff1a;生成器和判别器&#xff0c;知道生成器G和判别器D的作用及原理&#xff0c;相比于其他的生成模型&#xff0c;了解GAN的优…

API管理测试 - 最佳实践和关键要素

什么是API管理测试&#xff1f; API管理测试是在软件开发和集成功能中对应用程序接口&#xff08;API&#xff09;进行测试和验证的过程。它涵盖了测试API的功能、性能、安全性以及与其他系统的交互。API管理测试对于确保API的正确运行和稳定性非常重要。 ​ 为什么API管理测…

谷歌浏览器 设置多账户_使用多个Google帐户时如何设置默认帐户?

谷歌浏览器 设置多账户 If you’re using multiple Google accounts simultaneously there’s a good chance that one of them is the one you want to default. When it isn’t the default it’s rather frustrating; read on as we show a reader how to ensure the accoun…