乱码三千 – 分享实用IT技术

乱码三千 – 码出一个新世界


  • 首页

  • 归档

  • 搜索

Xposed 如何Hook静态变量or构造方法or复杂参数的方法or替换函数执行内容or内部类中的函数or匿名类的函数

发表于 2020-10-14

Xposed框架Hook相关api的使用

首先创建测试类继承IXposedHookLoadPackage, 以下所有的hook方法都在handleLoadPackage方法内部进行调用

1
2
3
4
5
public class HookTest implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
XposedBridge.log("HOOK初体验:" + lpparam.processName + ":" + lpparam.packageName);
}

准备需要被hook的代码用于测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
public class HookDemo {
private String Tag = "HookDemo";
private static int staticInt = 100;
public int publicInt = 200;
private int privateInt = 300;

public HookDemo(){
this("NOHook");
Log.d(Tag, "HookDemo() was called|||");
}

private HookDemo(String str){
Log.d(Tag, "HookDemo(String str) was called|||" + str);
}

public void hookDemoTest(){
Log.d(Tag, "staticInt = " + staticInt);
Log.d(Tag, "PublicInt = " + publicInt);
Log.d(Tag, "privateInt = " + privateInt);
publicFunc("NOHook");
Log.d(Tag, "PublicInt = " + publicInt);
Log.d(Tag, "privateInt = " + privateInt);
privateFunc("NOHook");
staticPrivateFunc("NOHook");

String[][] str = new String[1][2];
Map map = new HashMap<String, String>();
map.put("key", "value");
ArrayList arrayList = new ArrayList();
arrayList.add("listValue");
complexParameterFunc("NOHook", str, map, arrayList);

repleaceFunc();
anonymousInner(new Animal() {
@Override
public void eatFunc(String value) {
Log.d(Tag, "eatFunc(String value) was called|||" + value);
Log.d(Tag, "anonymoutInt = " + anonymoutInt);
}
}, "NOHook");

InnerClass innerClass = new InnerClass();
innerClass.InnerFunc("NOHook");
}

public void publicFunc(String value){
Log.d(Tag, "publicFunc(String value) was called|||" + value);
}

private void privateFunc(String value){
Log.d(Tag, "privateFunc(String value) was called|||" + value);
}

static private void staticPrivateFunc(String value){
Log.d("HookDemo", "staticPrivateFunc(Strin value) was called|||" + value);
}

private void complexParameterFunc(String value, String[][] str, Map<String,String> map, ArrayList arrayList)
{
Log.d("HookDemo", "complexParameter(Strin value) was called|||" + value);
}

private void repleaceFunc(){
Log.d(Tag, "repleaceFunc will be replace|||");
}

public void anonymousInner(Animal dog, String value){
Log.d(Tag, "anonymousInner was called|||" + value);
dog.eatFunc("NOHook");
}

private void hideFunc(String value){
Log.d(Tag, "hideFunc was called|||" + value);
}
private void argFunc(Objcet... value){
Log.d(Tag, "argFunc was called|||" + value);
}

class InnerClass{
public int innerPublicInt = 10;
private int innerPrivateInt = 20;
public InnerClass(){
Log.d(Tag, "InnerClass constructed func was called");
}
public void InnerFunc(String value){
Log.d(Tag, "InnerFunc(String value) was called|||" + value);
Log.d(Tag, "innerPublicInt = " + innerPublicInt);
Log.d(Tag, "innerPrivateInt = " + innerPrivateInt);
}
}
}
  1. 修改类中的私有静态变量
1
2
Class<?> clazz = XposedHelpers.findClass("com.example.xposedhooktarget.HookDemo", lpparam.classLoader);
XposedHelpers.setStaticIntField(clazz, "staticInt", 99);
  1. Hook无参构造函数
1
2
3
4
5
6
7
8
9
10
Class<?> clazz = XposedHelpers.findClass("com.example.xposedhooktarget.HookDemo", loadPackageParam.classLoader);
XposedHelpers.findAndHookConstructor(clazz, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("Haha, HookDemo constructed was hooked");
//大坑,此时对象还没有建立,即不能获取对象,也不能修改非静态变量的值
//XposedHelpers.setIntField(param.thisObject, "publicInt", 199);
//XposedHelpers.setIntField(param.thisObject, "privateInt", 299);
}
});
  1. Hook有参构造函数,并修改参数
1
2
3
4
5
6
XposedHelpers.findAndHookConstructor(clazz, String.class,  new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.args[0] = "Haha, HookDemo(str) are hooked";
}
});
  1. Hook公有方法publicFunc,并修改参数以及修改下publicInt和privateInt的值,再顺便调用一下隐藏函数hideFunc
1
2
3
4
5
6
7
8
9
10
11
12
13
XposedHelpers.findAndHookMethod(clazz, "publicFunc", String.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.args[0] = "Haha, publicFunc are hooked";
//修改成员变量的值
XposedHelpers.setIntField(param.thisObject, "publicInt", 199);
XposedHelpers.setIntField(param.thisObject, "privateInt", 299);
//调用函数
XposedHelpers.callMethod(param.thisObject, "hideFunc", "Haha, hideFunc was hooked");


}
});
  1. Hook私有方法privateFunc,并修改参数
1
2
3
4
5
6
XposedHelpers.findAndHookMethod(clazz, "privateFunc", String.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.args[0] = "Haha, privateFunc are hooked";
}
});
  1. Hook私有静态方法staticPrivateFunc, 并修改参数
1
2
3
4
5
6
XposedHelpers.findAndHookMethod(clazz, "staticPrivateFunc", String.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.args[0] = "Haha, staticPrivateFunc are hooked";
}
});
  1. Hook复杂参数函数complexParameterFunc
1
2
3
4
5
6
7
8
9
Class fclass1 = XposedHelpers.findClass("java.util.Map", loadPackageParam.classLoader);
Class fclass2 = XposedHelpers.findClass("java.util.ArrayList", loadPackageParam.classLoader);
XposedHelpers.findAndHookMethod(clazz, "complexParameterFunc", String.class,
"[[Ljava.lang.String;", fclass1, fclass2, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.args[0] = "Haha, complexParameterFunc are hooked";
}
});
  1. Hook私有方法repleaceFunc, 并替换打印内容
1
2
3
4
5
6
7
XposedHelpers.findAndHookMethod(clazz, "repleaceFunc", new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
Log.d("HookDemo", "Haha, repleaceFunc are replaced");
return null;
}
});
  1. Hook方法, anonymousInner, 参数是抽象类,先加载所需要的类即可
1
2
3
4
5
6
7
8
Class animalClazz  = loadPackageParam.classLoader.loadClass("com.example.xposedhooktarget.Animal");
XposedHelpers.findAndHookMethod(clazz, "anonymousInner", animalClazz, String.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("HookDemo This is test");
param.args[1] = "Haha, anonymousInner are hooked";
}
});
  1. Hook匿名类的eatFunc方法,修改参数,顺便修改类中的anonymoutInt变量
1
2
3
4
5
6
7
8
XposedHelpers.findAndHookMethod("com.example.xposedhooktarget.HookDemo$1", clazz.getClassLoader(),
"eatFunc", String.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.args[0] = "Haha, eatFunc are hooked";
XposedHelpers.setIntField(param.thisObject, "anonymoutInt", 499);
}
});
  1. Hook内部类InnerClass的InnerFunc方法,修改参数,顺便修改类中的innerPublicInt和innerPrivateInt变量
1
2
3
4
5
6
7
8
9
final Class<?> clazz1 = XposedHelpers.findClass("com.example.xposedhooktarget.HookDemo$InnerClass", loadPackageParam.classLoader);
XposedHelpers.findAndHookMethod(clazz1, "InnerFunc", String.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.args[0] = "Haha, InnerFunc was hooked";
XposedHelpers.setIntField(param.thisObject, "innerPublicInt", 9);
XposedHelpers.setIntField(param.thisObject, "innerPrivateInt", 19);
}
});
  1. 对于一些延迟动态加载的代码,hook方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
XposedHelpers.findAndHookMethod("dalvik.system.DexFile", lpparam.classLoader, "loadClass",
String.class, "java.lang.ClassLoader", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
String className = (String) param.args[0];
Object result = param.getResult();
if (result != null && result instanceof Class) {
if ("com.alipay.mobile.nebulauc.impl.UCWebViewClient".equals(className)) {
// hookLoadWebViewClient(((Class) result).getClassLoader());
}
}
}

});
  1. Hook有可变参数的方法
1
2
3
4
5
6
XposedHelpers.findAndHookMethod(clazz, "argFunc", Object[].class,new XC_MethodHook() {
@Override
protected Object afterHookedMethod(MethodHookParam methodHookParam) throws Throwable {

}
});

总结

  1. 无论hook公有私有方法还是静态方法 ,抑或可变参方法,甚至是带返回值的方法,统一使用findAndHookMethod这个Api

  2. xposed无法hook接口和抽象类方法

  3. Hook逻辑类可实现的接口有 :

    • 安卓系统启动的时候(使用 IXposedHookZygoteInit 接口)、

    • 一个新的app被加载的时候(使用 IXposedHookLoadPackage 接口)、

    • 一个资源被初始化的时候( 使用 IXposedHookInitPackageResources 接口 )

  4. 实现IXposedHookLoadPackage 并使用 XposedBridge.log 打印的日志,当启动第三方应用后,Android Studio控制台无法查看到日志信息,需要在xposed应用内进行查看

  5. 参数为基本数据类型时需要传对应包装类的type属性,比如int传Integer.TYPE, 否则提示找不到方法,如果参数为引用数据类型,那直接传xxx.class即可

    • beforeHookedMethod 会在调用原方法前执行,如果使用setResult则跳过原方法,并返回setResult参数中的值。

    • afterHookedMethod 会在调用原方法后执行,setResult可改变返回值

    • replaceHookedMethod 会完全替换原方法,即原方法不执行,且返回值可以直接return,setResult不生效。

注:每次修改完毕后需要重启才生效

附

Hook 修改方法返回值
1
2
3
4
5
XposedHelpers.findAndHookMethod(clazz, method, new Object[]{new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
param.setResult(result); // 设置返回值
}
}});
Hook 获取方法返回值
1
2
3
4
5
XposedHelpers.findAndHookMethod(clazz, method, new Object[]{new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
Object result = param.getResult(); //获取返回值
}
}});
Hook 获取方法传入的参数值
1
2
3
4
5
6
7
8
9
XposedHelpers.findAndHookMethod(claName, cl, "i", String.class, String.class, Object[].class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
// 数组param.args存储的参数列表里的值
XposedBridge.log(TAG + param.args[0]);
XposedBridge.log(TAG + param.args[1]);
XposedBridge.log(TAG + param.args[2]);
}
});
Hook 给方法传值
1
2
3
Class cla = XposedHelpers.findClass(className, loadPackageParam.classLoader);
Object com = XposedHelpers.callStaticMethod(cla, "getInstance");
XposedHelpers.callMethod(com, "setDebug", true); // 传入指定值
Hook 获取Intent的值
1
2
3
4
5
6
7
8
9
10
11
12
13
private void hookGetIntent(XC_LoadPackage.LoadPackageParam loadPackageParam) {
try {
XposedHelpers.findAndHookMethod("android.app.Activity", loadPackageParam.classLoader, "getIntent", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
Intent sou = (Intent) param.getResult();
KLog.d("hookGetIntent:" + sou.toURI().toString());
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
Hook 广播发送的Intent信息
1
2
3
4
5
6
7
8
9
10
11
12
13
private void hookSendBroadcast(XC_LoadPackage.LoadPackageParam loadPackageParam) {
try {
XposedHelpers.findAndHookMethod("android.content.ContextWrapper", loadPackageParam.classLoader, "sendBroadcast", Intent.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
Intent sou = (Intent) param.args[0];
KLog.d("sendBroadcast:" + sou.toURI().toString());
}
});
} catch (Exception e) {
e.printStackTrace();
}
}

Xposed一般Hook的是默认的dex文件,但是现在很多的APP都有多个Dex文件,所以使用Xposed时,经常遇到类名路径正确却出现ClassNotFoundError找不到类的错误。要解决这个问题,需要获取对应Dex文件的上下文环境。

Android在加载dex文件后会创建一个Application类,然后会调用attach方法,attach方法的参数就是上下文context,而且attach方法是final方法,不会因为被覆盖而hook不到,拿到这个context就可以获取对应的classload,然后就可以顺利hook到multidex的类了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
XposedHelpers.findAndHookMethod(Application.class, "attach", Context.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
ClassLoader cl = ((Context) param.args[0]).getClassLoader(); // 获取ClassLoader
Class<?> hookClass = null;
try {
hookClass = cl.loadClass(claName); // 获取Class
// 使用cl 和 hookClass 完成hook
XposedHelpers.setStaticIntField(hookClass, fieldName, val);
XposedHelpers.findAndHookMethod(claName, cl, "i", String.class, String.class, Object[].class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log(TAG + param.args[0]);
XposedBridge.log(TAG + param.args[1]);
XposedBridge.log(TAG + param.args[2]);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
});

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

Linux系统查看时区以及时区修改

发表于 2020-10-12

wp-config.php里加入下面代码:

这里以Ubuntu系统为例

查看时区:

1
date -R

修改时区为东八区

1
timedatectl set-timezone Asia/Shanghai
老版本系统以上修改时区指令可能不生效, 需要采用以下办法

1.运行tzselect

1
root@ubuntu:/# tzselect

在这里我们选择亚洲 Asia,确认之后选择中国(China),最后选择北京(Beijing)

**

2.复制文件到/etc目录下

1
root@ubuntu:/# cp /usr/share/zoneinfo/Asia/Shanghai  /etc/localtime

3.再次查看时间date -R,已经修改为北京时间

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

docker设置启动docker后 开启或关闭自启容器

发表于 2020-10-12

前言

我们需要在docker启动的时候自动运行容器, 具体操作分为以下两种情况

容器未创建

如果容器还没有创建, 可以采用增加容器运行参数的方式实现

命令如下:

1
docker run xxx –-restart=always

容器已创建

当然如果你的容器已经启动,可以通过update命令进行修改.
命令如下:

1
docker update –-restart=always <CONTAINER ID>

取消自启动

如果你想取消掉
命令如下:

1
docker update --restart=no <CONTAINER ID>

容器批量操作

  1. 给已启动所有容器设置自启动

    1
    docker update --restart=no $(docker ps -q)
  2. 给所有容器设置自启动 包括停止的容器

    1
    docker update --restart=no $(docker ps -aq)
  3. 查看容器是否配置成功

    1
    docker inspect 容器名

    image-20210916151358153

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

使用docker在服务器部署vscode实现云端web开发

发表于 2020-10-12

采用codercom/code-server

拉取codercom/code-server镜像

1
docker pull codercom/code-server

运行code-server 容器

1
docker run -it --name=code_server  -p 8443:8080 -p 4001:4000 -v /root/songjian:/home/coder/songjian -h code_server -e PASSWORD=123  codercom/code-server

浏览器中输入ip:8843 开始云端开发之旅

编辑代码时出现权限问题

解决方案:
在宿主机中开放读写权限

1
chmod a+rwx -R /root/songjian/

或者在容器运行的时候指定用户组为root (推荐)

1
docker run -it -u root --name=code_server  -p 8443:8080 -p 4001:4000 -v /root/songjian:/home/coder/songjian -h code_server -e PASSWORD=123  codercom/code-server

问题解决

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

MySQL8.0登录提示caching_sha2_password问题解决方法

发表于 2020-09-30

背景

用docker构建mysql容器后连接遇到以下问题

问题

1
2
3
4
5
6
Authentication plugin 'caching_sha2_password' cannot be loaded: dlopen(/usr/local/mysql/lib/plugin/caching_sha2_password.so, 2): image not found
1
mysqli_real_connect(): The server requested authentication method unknown to the client [caching_sha2_password]
1
mysqli_real_connect(): (HY000/2054): The server requested authentication method unknown to the client
1

MySQL官方说明

解决方法1(docker)

适用场景

  1. 第一次构建容器/安装
  2. 已安装完成后新增用户

配置

配置 mysql.cnf 配置默认身份验证插件

1
2
3
[mysqld]
default_authentication_plugin = mysql_native_password
12

验证是否生效

使用CLI进入MySQL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ mysql -u root -p
1
mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> SELECT Host, User, plugin from user;
+-----------+------------------+-----------------------+
| Host | User | plugin |
+-----------+------------------+-----------------------+
| % | root | mysql_native_password |
| localhost | mysql.infoschema | caching_sha2_password |
| localhost | mysql.session | caching_sha2_password |
| localhost | mysql.sys | caching_sha2_password |
| localhost | root | mysql_native_password |
+-----------+------------------+-----------------------+
5 rows in set (0.00 sec)
12345678910111213141516

root用户的身份验证器插件已经变为:mysql_native_password

解决方法2

适用场景

  1. MySQL 已成功安装完成后

查看身份验证类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql> use mysql;
Database changed

mysql> SELECT Host, User, plugin from user;
+-----------+------------------+-----------------------+
| Host | User | plugin |
+-----------+------------------+-----------------------+
| % | root | caching_sha2_password |
| localhost | mysql.infoschema | caching_sha2_password |
| localhost | mysql.session | caching_sha2_password |
| localhost | mysql.sys | caching_sha2_password |
| localhost | root | caching_sha2_password |
+-----------+------------------+-----------------------+
5 rows in set (0.00 sec)
1234567891011121314

root 用户的验证器插件为 caching_sha2_password

修改身份验证类型(修改密码)

1
2
3
4
5
6
mysql> ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
Query OK, 0 rows affected (0.00 sec)

mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';
Query OK, 0 rows affected (0.01 sec)
12345

使生效

1
2
mysql> FLUSH PRIVILEGES;
1

验证是否生效

1
2
3
4
5
6
7
8
9
10
11
mysql> SELECT Host, User, plugin from user;
+-----------+------------------+-----------------------+
| Host | User | plugin |
+-----------+------------------+-----------------------+
| % | root | mysql_native_password |
| localhost | mysql.infoschema | caching_sha2_password |
| localhost | mysql.session | caching_sha2_password |
| localhost | mysql.sys | caching_sha2_password |
| localhost | root | mysql_native_password |
+-----------+------------------+-----------------------+
5 rows in set (0.00 sec)

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

关于WordPress 安装主题或插件时提示需要登陆FTP解决方法

发表于 2020-09-30

wp-config.php里加入下面代码:

在wp-config.php里加入下面代码:

1
2
3
define( 'FS_METHOD',  'direct');
define( 'FS_CHMOD_DIR', 0777);
define( 'FS_CHMOD_FILE', 0777);

加入完毕后不再提示FTP登录, 但是有可能安装插件时提示 安装失败,无法创建目录

解决方案:

1
2
3
4
chmod -R 777 wp-content/ 
chmod -R 777 theme/
chmod -R 777 plugin/
chmod -R 777 language/

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

怎样修改Wordpress地址和站点地址怎样改回IP地址

发表于 2020-09-30

wordpress搭建后地址栏页面显示IP地址的问题

如果可以登录wordpress后台管理面板

1.先点击wordpress右边的小房子图标

2.点击仪表盘图片进入仪表盘菜单

3.点击设置,进入设置界面,找到WordPress地址(URL)和站点地址(URL)所对应的ip地址,如下图

4.将ip地址更改为你网站的域名,之后保存,如下图

5.清空浏览器的缓存,之后用域名访问网站,就不会在地址栏出现ip地址了。

如果无法登陆wordpress

那么需要修改数据库 如图


乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

Linux文件误删后如何恢复

发表于 2020-09-30

以下方法适用于文件或目录被删,如果被覆盖则无法恢复

方法一 使用系统自带的还原工具debugfs

  1. 第一步 查看文件或目录锁挂载的磁盘名
1
df  /root/你被删的目录
  1. 输入debugfs指令进入命令区
1
root@xxx:# /debugfs
  1. 进入挂载磁盘 查找被删目录和文件
1
2
open dev/vda1 #这个是我服务磁盘名 你的也许不一样
ls -d /root/你被删的目录 #查找被删文件

带尖括号开头的文件表示已经被删除的 无尖括号表示当前已经存在的文件

接下来 咱们需要借助尖括号中的地址进行文件还原

  1. 根据node地址查找文件信息, 在debugfs命令区中输入
1
logdump -i <19662057>

  1. 文件还原

    1
    dd  if=/dev/vda1 of=/root/被删除文件  bs=3456 count=1 skip=524974

* bs对应offset 表示文件大小
* count 表示需要还原几份
* skip对应block值 表示跳过blocks个块后再开始复制

至此 恢复完毕

### 方法二 使用第三方的还原工具extundelete

  1. 第一步 安装
1
apt-get install extundelete -y
  1. 第二步 获取被删文件或目录的node
1
ls -lia 目标目录
  1. 根据node查看文件信息
1
extundelete /dev/sda5 --inode 24904454
1
2
3
4
5
6
#以下为控制台输出信息
File name | Inode number | Deleted status
. 2
.. 2
deletetest 12 Deleted
tmppasswd 14 Deleted
  1. 恢复全部数据
1
extundelete /dev/sda5 --restore-all
  1. 恢复单个数据
1
extundelete /dev/sdb5 --restore-file xxx
  1. 恢复指定目录
1
extundelete /dev/sdb5 --restore-directory  xxx

至此 ,恢复完毕

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

mysql使用命令导入和导出sql文件

发表于 2020-09-30

window下

1.导出整个数据库,首先打开要导出的目录

1
2
3
4
5
mysqldump -u 用户名 -p 数据库名 > 导出的文件名

mysqldump -u dbuser -p dbname > dbname.sql 下一行需要输入密码

mysqldump -uroot -proot [dbname]> english.sql 在本行直接输入密码

2.导出一个表

1
2
3
mysqldump -u 用户名 -p 数据库名 表名> 导出的文件名

mysqldump -u dbuser -p dbname users> dbname_users.sql

3.导出一个数据库结构

1
2
3
mysqldump -u dbuser -p -d --add-drop-table dbname >d:/dbname_db.sql

-d 没有数据 --add-drop-table 在每个create语句之前增加一个drop table

4.导入数据库

常用source 命令

进入mysql数据库控制台,如

1
2
3
mysql -u root -p

mysql>use 数据库名;

如果数据库不存在 则则新建:

1
mysql>create database 数据库名;

然后使用source命令,后面参数为脚本文件(如这里用到的.sql)

1
mysql>source d:/dbname.sql

linux下

一、导出数据库用mysqldump命令(注意mysql的安装路径,即此命令的路径):

1、导出数据和表结构:

1
2
3
mysqldump -u用户名 -p密码 数据库名 > 数据库名.sql

\#/usr/local/mysql/bin/ mysqldump -uroot -p abc > abc.sql

敲回车后会提示输入密码

2、只导出表结构

1
2
3
4
5
mysqldump -u用户名 -p密码 -d 数据库名 > 数据库名.sql

\#/usr/local/mysql/bin/ mysqldump -uroot -p -d abc > abc.sql

注:/usr/local/mysql/bin/ ---> mysql的data目录

二、导入数据库

1、首先建空数据库

1
mysql>create database abc;

2、导入数据库

方法一:

(1)选择数据库

1
mysql>use abc;

(2)设置数据库编码

1
mysql>set names utf8;

(3)导入数据(注意sql文件的路径)

1
mysql>source /home/abc/abc.sql;

方法二:

1
2
3
mysql -u用户名 -p密码 数据库名 < 数据库名.sql

\#mysql -uabc_f -p abc < abc.sql

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

使用nginx部署django项目需要注意的问题

发表于 2020-09-23

首先配置nginx.conf文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
worker_processes  1;
events {
worker_connections 1024;
}
http{
server{
listen 80;
server_name py.newban.cn; #
root /usr/share/nginx/html/blog;
index index.html;
}
server{
listen 80;
server_name blog.newban.cn; #
root /usr/share/nginx/html/blog2;
index index.html;
}


#反向代理部分
upstream my.blog{ #部署django 名称不能使用下滑线分割比如my_blog 否则报错
server 118.10.25.17:8000 weight=1;
#负载均衡 随机访问 权重1:1 各占50%
server 118.10.25.17:8001 weight=1;
}
server{
listen 80;
server_name py.insoan.com; #
location / {
proxy_pass http://my.blog;
index index.html;
}
}
}

问题1 DisallowedHost at /

使用 nginx 部署django时,会出现下面的错误

  1. 首先使用的域名不符合 RFC 1034/1035.规范时,会出现下面的错误(如包含下划线)
1
DisallowedHost at /Invalid HTTP_HOST header: 'learning_log.cent.com'. The domain name provided is not valid according to RFC 1034/1035.
  1. 解决方式:

修改域名,去除下划线,即将 learning_log.cent.com 修改成 llog.cent.com

  1. 再重新访问出现另外一个错误
1
invalid http_host header
  1. 解决方式

将 setting.py 的 ALLOWED_HOSTS = [] 修改成 ALLOWED_HOSTS = [‘*’]

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

1…373839…52

乱码三千

android程序员一枚,擅长java,kotlin,python,金融投资,欢迎交流~

512 日志
147 标签
RSS
© 2026 乱码三千
本站总访问量次
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.4
0%