问题

几乎99%的软件都有登录功能,而登录这一个动作真的将我们的用户名和密码上传到了服务器吗,会不会有个人隐私呢。根据我们这个问题,我们用FaceU这个软件,逆向来看看他的登录功能到底都传了什么数据。

准备工作

首先下载faceu的APK,具体下载地址大家可以去各大应用市场,我下载的版本是v2.2.6。

需要的工具

  • apktool (拆包APK用)
  • dex2jar (反编译dex文件用)

需要的工具下载地址:github.com/hanhan12312…

拆包

首先,我们利用apktool拆包apk,执行命令

apktool d faceu.apk
复制代码

这样在当前文件夹就得到了一个faceu的文件夹。

定位代码

我们打开Faceu软件,点击下面的已有账号在此登录,然后弹出来登录界面,如图所示

我们利用字符串搜索法,这个页面的注册的EditText的hint字为"Faceu号/手机号",我们搜索res文件夹内所有文件的内容,搜索此关键字找到两处,位置都在res/values/strings.xml文件内

strings.xml

<string name="str_account_hint">Faceu号 / 手机号</string>
<string name="str_search_user">Faceu号/手机号</string>复制代码

根据name我们也能知道,account_hint是账号的输入框,而另一个是用于搜索的。 我们知道一个布局文件肯定有用到过这个值。所以我们在工程内搜索"str_account_hint",可是结果却发现只有两处引用到,如图

看来faceu的程序员们是没有在布局中引用,那就有可能在java代码内引用到,那就去看看"str_account_hint"在代码对应的值是多少。
紧接着我们顺着str_account_hint这个名字在res/values/public.xml文件内搜索"str_account_hint",public.xml是在编译期间生成的文字对应编译后资源的id。
public.xml

<public type="string" name="str_account_hint" id="0x7f070047" />
复制代码

由此我们可以看出在java代码内对应的是0x7f070047。因此我们再次在代码里面搜索0x7f070047试试。 找到了引用到这个常量的地方。

在文件com/lemon/faceu/login/b内

    const v2, 0x7f070047 invoke-virtual {v1, v2}, Landroid/content/res/Resources;->getString(I)Ljava/lang/String; move-result-object v1 invoke-virtual {v0, v1}, Lcom/lemon/faceu/uimodule/view/AccountEditText->setHintText(Ljava/lang/String;)V复制代码

熟悉smali语法的话,我们能够读懂,这个翻译成Java代码其实就是

    String v1 = context.getString(0x7f070047);editText.setHintText(v1);
复制代码

目的是找到到这个字符串。

到此为止我们分析一下当前的类是个什么类,是个Activity?Fragment?还是自定义View。

我们找到当前页面网上翻几行,看看还有没有用到什么别的资源id,找到了如下代码

 const v0, 0x7f0e026e invoke-virtual {p1, v0}, Landroid/view/View;->findViewById(I)Landroid/view/View; move-result-object v0 check-cast v0, Lcom/lemon/faceu/uimodule/view/PasswordEditText; iput-object v0, p0, Lcom/lemon/faceu/login/b;->bpP:Lcom/lemon/faceu/uimodule/view/PasswordEditText;复制代码

很明显,这个凭借PasswordEditText名称我们也能发现他就是密码输入的EditText
翻译成java代码

    PasswordEditText v0 = (PasswordEditText)this.findViewById(0x7f0e026e);this.bpP = v0;
复制代码

根据这一句话我们在public.xml里面找到对应的xml

<public type="id" name="cet_login_password" id="0x7f0e026e" />
复制代码

然后我们再看看有没有布局文件引用到了cet_login_password,于是找到了4处

我们进入fragment_login.xml发现他只有登录页面的上半部分。却没有下面的取消和确认按钮。可以猜测他并不是Activity,Fragment,因为没有标志性的onCreate方法,父类最终也没有找到Activity,Fragment等。很可能是一个负责处理业务的类。

但是我们知道了当前的成员变量bpP就是对应的密码的EditText了,那么看看都哪里调用这个bpP了。
通过对当前类分析,我最终找到了Lu方法里面对应到了登录按钮的。

逆向登录代码,查看传递参数

经过一番努力总算找到了登录界面,登录代码,现在我们进行分析,并且加入一段我们自己的代码,进行二次打包。
下面是分析详解

Lcom/lemon/faceu/login/b;

  .method Lu()V
    .locals 4    .prologue
    .line 216 invoke-virtual {p0}, Lcom/lemon/faceu/login/b;->Ls()Z#检测用户名是否合法 move-result v0#如果不合法就返回 if-eqz v0, :cond_0 invoke-virtual {p0}, Lcom/lemon/faceu/login/b;->Lt()Z#检测密码是否合法 move-result v0#如果不合法就返回 if-nez v0, :cond_1    .line 241 :cond_0 :goto_0 return-void

    .line 220 :cond_1 invoke-virtual {p0}, Lcom/lemon/faceu/login/b;->Uv()V    .line 222 const-string v0, "LoginFragment" const-string v1, "startLogin" invoke-static {v0, v1}, Lcom/lemon/faceu/sdk/utils/c;->i(Ljava/lang/String;Ljava/lang/String;)V#调用Faceu自己的统计打点方法    .line 223 iget-object v0, p0, Lcom/lemon/faceu/login/b;->bpO:Lcom/lemon/faceu/uimodule/view/AccountEditText; invoke-virtual {v0}, Lcom/lemon/faceu/uimodule/view/AccountEditText;->getAccount()Ljava/lang/String; move-result-object v0#调用AccountEditText的getAccount方法,并将用户户名存入v0  iput-object v0, p0, Lcom/lemon/faceu/login/b;->aAS:Ljava/lang/String;#将aAs赋值为用户名    .line 224 iget-object v0, p0, Lcom/lemon/faceu/login/b;->bpP:Lcom/lemon/faceu/uimodule/view/PasswordEditText; invoke-virtual {v0}, Lcom/lemon/faceu/uimodule/view/PasswordEditText;->getEditText()Landroid/widget/EditText; move-result-object v0 invoke-virtual {v0}, Landroid/widget/EditText;->getText()Landroid/text/Editable; move-result-object v0 invoke-virtual {v0}, Ljava/lang/Object;->toString()Ljava/lang/String; move-result-object v0#将密码从bpP取出来,并取出String类型的密码复制给v0    .line 227 invoke-static {}, Lcom/lemon/faceu/common/e/a;->xJ()Lcom/lemon/faceu/common/e/a; move-result-object v1 iget-object v2, p0, Lcom/lemon/faceu/login/b;->aAS:Ljava/lang/String; invoke-virtual {v1, v2}, Lcom/lemon/faceu/common/e/a;->setAccount(Ljava/lang/String;)V#将现在的用户名存入sharedprefence,以便于记住用户名下次直接显示    .line 229 new-instance v1, Ljava/util/HashMap;#new一个HashMap存储进v1 invoke-direct {v1}, Ljava/util/HashMap;-><init>()V#初始化v1    .line 230 const-string v2, "account" iget-object v3, p0, Lcom/lemon/faceu/login/b;->aAS:Ljava/lang/String; invoke-interface {v1, v2, v3}, Ljava/util/Map;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;#将用户名存入HashMap    .line 231 const-string v2, "pwd" invoke-static {v0}, Lcom/lemon/faceu/common/i/g;->bS(Ljava/lang/String;)Ljava/lang/String; move-result-object v0 invoke-interface {v1, v2, v0}, Ljava/util/Map;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;#将密码调用bS方法加密并且存入map    .line 232 const-string v0, "councode" const-string v2, "86" invoke-interface {v1, v0, v2}, Ljava/util/Map;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;#国家编号86,存入map    .line 233 const-string v0, "manufacture" sget-object v2, Landroid/os/Build;->MANUFACTURER:Ljava/lang/String; invoke-interface {v1, v0, v2}, Ljava/util/Map;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;#将厂商信息存入map    .line 234 const-string v0, "model" sget-object v2, Landroid/os/Build;->MODEL:Ljava/lang/String; invoke-interface {v1, v0, v2}, Ljava/util/Map;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;#将model信息存入map    .line 235 const-string v0, "version" sget v2, Lcom/lemon/faceu/common/d/b;->aAL:I invoke-static {v2}, Ljava/lang/String;->valueOf(I)Ljava/lang/String; move-result-object v2 invoke-interface {v1, v0, v2}, Ljava/util/Map;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;#将软件版本信息存入map    .line 236 const-string v0, "deviceinfo" invoke-static {}, Lcom/lemon/faceu/common/b/a;->xt()Lorg/json/JSONObject; move-result-object v2#将调用com.lemon.faceu.common.b.a->xt()方法,取回JsonObject并且赋值给v2 invoke-interface {v1, v0, v2}, Ljava/util/Map;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;#将JSONObject存入map    .line 238 new-instance v0, Lcom/lemon/faceu/common/t/a; sget-object v2, Lcom/lemon/faceu/common/d/a;->azO:Ljava/lang/String; invoke-static {}, Landroid/os/Looper;->getMainLooper()Landroid/os/Looper; move-result-object v3 invoke-direct {v0, v2, v1, v3}, Lcom/lemon/faceu/common/t/a;-><init>(Ljava/lang/String;Ljava/util/Map;Landroid/os/Looper;)V    .line 239 iget-object v1, p0, Lcom/lemon/faceu/login/b;->aKe:Lcom/lemon/faceu/common/t/a$a; invoke-virtual {v0, v1}, Lcom/lemon/faceu/common/t/a;->a(Lcom/lemon/faceu/common/t/a$a;)V    .line 240 const-string v1, "login" invoke-static {v0, v1}, Lcom/lemon/faceu/sdk/i/b;->a(Ljava/lang/Runnable;Ljava/lang/String;)V goto :goto_0
.end method  #此方法主要校验用户名是否合法,错误的话输出错误信息,返回值为boolean
.method Ls()Z
    .locals 5    .prologue const/4 v1, 0x0 #使v0寄存器为0
    .line 177 iget-object v0, p0, Lcom/lemon/faceu/login/b;->bpO:Lcom/lemon/faceu/uimodule/view/AccountEditText;#将成员变量bpO赋值给v0,此时v0就是用户名 invoke-virtual {v0}, Lcom/lemon/faceu/uimodule/view/AccountEditText;->getAccount()Ljava/lang/String; move-result-object v2#调用AccountEditText的getAccount方法,并将返回值存入v2    .line 178 invoke-virtual {v2}, Ljava/lang/String;->length()I#取出用户名长度 move-result v0#v0 = 用户名长度 if-lez v0, :cond_0 invoke-virtual {v2, v1}, Ljava/lang/String;->charAt(I)C move-result v0 invoke-static {v0}, Ljava/lang/Character;->isDigit(C)Z move-result v0 if-eqz v0, :cond_0    .line 180 invoke-static {v2}, Lcom/lemon/faceu/common/u/t;->dz(Ljava/lang/String;)Z move-result v0 if-nez v0, :cond_4    .line 181 iget-object v0, p0, Lcom/lemon/faceu/login/b;->bpO:Lcom/lemon/faceu/uimodule/view/AccountEditText; const v2, 0x7f0700ae invoke-virtual {p0, v2}, Lcom/lemon/faceu/login/b;->getString(I)Ljava/lang/String; move-result-object v2 invoke-virtual {v0, v2}, Lcom/lemon/faceu/uimodule/view/AccountEditText;->setTips(Ljava/lang/String;)V    .line 202 :goto_0 return v1    .line 185 :cond_0 invoke-virtual {v2}, Ljava/lang/String;->length()I move-result v0 const/16 v3, 0x14 if-le v0, v3, :cond_1    .line 186 iget-object v0, p0, Lcom/lemon/faceu/login/b;->bpO:Lcom/lemon/faceu/uimodule/view/AccountEditText; const v2, 0x7f070087 invoke-virtual {p0, v2}, Lcom/lemon/faceu/login/b;->getString(I)Ljava/lang/String; move-result-object v2 invoke-virtual {v0, v2}, Lcom/lemon/faceu/uimodule/view/AccountEditText;->setTips(Ljava/lang/String;)V goto :goto_0    .line 188 :cond_1 invoke-virtual {v2}, Ljava/lang/String;->length()I move-result v0 if-lez v0, :cond_2 invoke-virtual {v2, v1}, Ljava/lang/String;->charAt(I)C move-result v0 invoke-static {v0}, Lcom/lemon/faceu/sdk/utils/h;->u(C)Z move-result v0 if-nez v0, :cond_2    .line 189 iget-object v0, p0, Lcom/lemon/faceu/login/b;->bpO:Lcom/lemon/faceu/uimodule/view/AccountEditText; const v2, 0x7f070086 invoke-virtual {p0, v2}, Lcom/lemon/faceu/login/b;->getString(I)Ljava/lang/String; move-result-object v2 invoke-virtual {v0, v2}, Lcom/lemon/faceu/uimodule/view/AccountEditText;->setTips(Ljava/lang/String;)V goto :goto_0 :cond_2 move v0, v1    .line 192 :goto_1 invoke-virtual {v2}, Ljava/lang/String;->length()I move-result v3 if-ge v0, v3, :cond_4    .line 193 invoke-virtual {v2, v0}, Ljava/lang/String;->charAt(I)C move-result v3    .line 194 const/16 v4, 0x5f if-eq v3, v4, :cond_3 invoke-static {v3}, Ljava/lang/Character;->isDigit(C)Z move-result v4 if-nez v4, :cond_3 invoke-static {v3}, Lcom/lemon/faceu/sdk/utils/h;->u(C)Z move-result v3 if-nez v3, :cond_3    .line 195 iget-object v0, p0, Lcom/lemon/faceu/login/b;->bpO:Lcom/lemon/faceu/uimodule/view/AccountEditText; const v2, 0x7f070085 invoke-virtual {p0, v2}, Lcom/lemon/faceu/login/b;->getString(I)Ljava/lang/String; move-result-object v2 invoke-virtual {v0, v2}, Lcom/lemon/faceu/uimodule/view/AccountEditText;->setTips(Ljava/lang/String;)V goto :goto_0    .line 192 :cond_3 add-int/lit8 v0, v0, 0x1 goto :goto_1    .line 202 :cond_4 const/4 v1, 0x1 goto :goto_0
.end method
#此方法主要校验密码是否合法,错误的话输出错误信息,做一些动画之类,正确返回true
.method Lt()Z
    .locals 2    .prologue
    .line 206 iget-object v0, p0, Lcom/lemon/faceu/login/b;->bpP:Lcom/lemon/faceu/uimodule/view/PasswordEditText; invoke-virtual {v0}, Lcom/lemon/faceu/uimodule/view/PasswordEditText;->getEditText()Landroid/widget/EditText; move-result-object v0 invoke-virtual {v0}, Landroid/widget/EditText;->getText()Landroid/text/Editable; move-result-object v0 invoke-virtual {v0}, Ljava/lang/Object;->toString()Ljava/lang/String; move-result-object v0 invoke-virtual {v0}, Ljava/lang/String;->length()I move-result v0    .line 207 const/4 v1, 0x6 if-lt v0, v1, :cond_0 const/16 v1, 0x10 if-le v0, v1, :cond_1    .line 208 :cond_0 iget-object v0, p0, Lcom/lemon/faceu/login/b;->bpP:Lcom/lemon/faceu/uimodule/view/PasswordEditText; const v1, 0x7f0700b5 invoke-virtual {p0, v1}, Lcom/lemon/faceu/login/b;->getString(I)Ljava/lang/String; move-result-object v1 invoke-virtual {v0, v1}, Lcom/lemon/faceu/uimodule/view/PasswordEditText;->setTips(Ljava/lang/String;)V    .line 209 const/4 v0, 0x0    .line 211 :goto_0 return v0 :cond_1 const/4 v0, 0x1 goto :goto_0
.end method复制代码

我们主要看Lu方法里面的以下几行,他调用了com.lemon.faceu.common.b.a->xt()方法,这个主要是用于窃取我们的手机型号,系统,厂商等信息,我们进入方法看看

    const-string v0, "deviceinfo" invoke-static {}, Lcom/lemon/faceu/common/b/a;->xt()Lorg/json/JSONObject; move-result-object v2#将调用com.lemon.faceu.common.b.a->xt()方法,取回JsonObject并且赋值给v2复制代码

我们进入方法看看


.method public static xt()Lorg/json/JSONObject;
    .locals 5    .prologue
    .line 34 new-instance v1, Lorg/json/JSONObject; invoke-direct {v1}, Lorg/json/JSONObject;-><init>()V    .line 36 :try_start_0 const-string v0, "cpu" invoke-static {}, Lcom/lemon/faceu/common/b/a;->xv()Ljava/lang/String; move-result-object v2 invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;#取出你的cpu信息放入json    .line 37 const-string v0, "radio" invoke-static {}, Lcom/lemon/faceu/common/b/a;->xx()Ljava/lang/String; move-result-object v2 invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;#机型的RADIO信息存入json    .line 38 const-string v0, "os_version" sget v2, Landroid/os/Build$VERSION;->SDK_INT:I invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;I)Lorg/json/JSONObject;#取出你系统版本    .line 39 const-string v0, "imei" invoke-static {}, Lcom/lemon/faceu/common/e/a;->xJ()Lcom/lemon/faceu/common/e/a; move-result-object v2#取出IMEI号 invoke-virtual {v2}, Lcom/lemon/faceu/common/e/a;->getContext()Landroid/content/Context; move-result-object v2 invoke-static {v2}, Lcom/lemon/faceu/common/b/a;->bd(Landroid/content/Context;)Ljava/lang/String; move-result-object v2 invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;    .line 40 const-string v0, "imsi" invoke-static {}, Lcom/lemon/faceu/common/b/a;->xy()Ljava/lang/String; move-result-object v2 invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;    .line 41 const-string v0, "iccid" invoke-static {}, Lcom/lemon/faceu/common/b/a;->xz()Ljava/lang/String; move-result-object v2 invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;    .line 42 const-string v0, "android_id" invoke-static {}, Lcom/lemon/faceu/common/b/a;->xw()Ljava/lang/String; move-result-object v2 invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;    .line 43 const-string v0, "model" sget-object v2, Landroid/os/Build;->MODEL:Ljava/lang/String; invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;    .line 44 const-string v0, "core_count" invoke-static {}, Lcom/lemon/faceu/common/b/a;->xA()I move-result v2 invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;I)Lorg/json/JSONObject;    .line 45 const-string v0, "wifi" invoke-static {}, Lcom/lemon/faceu/common/b/a;->xu()Ljava/lang/String; move-result-object v2 invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject; :try_end_0
    .catch Lorg/json/JSONException; {:try_start_0 .. :try_end_0} :catch_0    .line 49 :goto_0 return-object v1    .line 46 :catch_0 move-exception v0    .line 47 const-string v2, "DeviceInfo" new-instance v3, Ljava/lang/StringBuilder; invoke-direct {v3}, Ljava/lang/StringBuilder;-><init>()V const-string v4, "jsonexception, " invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v3 invoke-virtual {v0}, Lorg/json/JSONException;->getMessage()Ljava/lang/String; move-result-object v0 invoke-virtual {v3, v0}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v0 invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String; move-result-object v0 invoke-static {v2, v0}, Lcom/lemon/faceu/sdk/utils/c;->e(Ljava/lang/String;Ljava/lang/String;)V goto :goto_0
.end method复制代码

我们能看到他获取了我们的cpu,radio,os_version(系统版本),imei,MODEL,cpu_count,mac地址。 看了半天代码,我们加入一些我们的代码,让程序自己把提交的信息打印出来吧。

 const-string v0, "MartinHan--map" invoke-virtual {v1}, Ljava/util/HashMap;->toString()Ljava/lang/String; move-result-object v3 invoke-static {v0, v3}, Landroid/util/Log;->v(Ljava/lang/String;Ljava/lang/String;)I const-string v3, "MartinHan---url" invoke-static {v3, v2}, Landroid/util/Log;->v(Ljava/lang/String;Ljava/lang/String;)I复制代码

然后我们执行代码

apktool d faceu
cd faceu/disk
#签名 生成文件明为_signed.apk
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore "MartinHan.jks" -signedjar "_signed.apk" "faceu.apk" "111111" << EOF
111111adb install _signed.apk复制代码

这样的流程走下来,我们的二次打包apk就安装到手机上啦,看看我们输入我们帐号,点击登录。会打印出log信息。
如下所示

03-13 14:17:15.269 10240-10240/com.lemon.faceu V/MartinHan--map: {account=159xxxxxxxx, deviceinfo={"android_id":"62fjdhu42d070400","wifi":"08:33:61:cc:b9:fc","model":"HUAWEI G630-U00","imei":"81338398767854654","iccid":"","cpu":"ARMv7 Processor rev 3 (v7l) ","radio":"203040,203040","imsi":"","core_count":4,"os_version":18}, model=HUAWEI G630-U00, pwd=4d259481d57ffc1c6b4b68cd73dbd301, councode=86, manufacture=HUAWEI, version=270540806}03-13 14:17:15.269 10240-10240/com.lemon.faceu V/MartinHan---url: https://api2.faceu.mobi/faceu/v3/login.php
复制代码

如上诉代码所示,我们在faceu登录一次,faceu会上传我们的很多个人信息
mac地址,手机型号,imei,cpu信息,radio,系统版本,国家代码, 并且找到了faceu登录的地址是https://api2.faceu.mobi/faceu/v3/login.php

以上就是我的所有思路,从问题开始,一直找代码,最后动态的打log实现在https加密前就让app自己吐出数据。

写在最后

其实我想不仅faceu,像是其他的厂商也会收集我们的个人信息,完成统计。并且通过大数据分析使用软件的人群,手机型号。
希望所有喜欢逆向的朋友们一起探讨,多多交流。

注:如有侵权,请联系我

关于我

个人博客:MartinHan的小站

博客网站:hanhan12312的专栏

知乎:MartinHan01

Android逆向之路---Faceu的登录功能真的只提交了用户名和密码吗相关推荐

  1. android 漫画切换,Android逆向之路---让我们试试另一种方法看漫画-(2)

    前言 上次我们分析到了快看漫画的协议部分,这次我们根据他的协议来手动写个脚本,然后执行以后,可以把他的漫画自动下载到电脑上面, 然后自动拼接图片,这样就可以实现在电脑上当成一个长图来看漫画了,没有广告 ...

  2. Android逆向之路---脱壳360加固原理解析

    前言 众所周知,上次说到了如何脱壳360加固,大致意思就是安装一个xposed插件,然后自动就会脱壳了,那么这个插件是如何工作的呢,本次重点说说这个. 上次说道了dumpDex脱壳360加固,其实先说 ...

  3. 如何修改以前登录过的共享文件夹的用户名和密码以及查看或删除浏览器里保存的密码...

    1.如何修改以前登录过的共享文件夹的用户名和密码: (1)打开控制面板-->用户账户,如下图: (2)然后点击 管理Windows凭据,如下图: (3)点击要修改的共享文件夹右侧的下拉箭头,如下 ...

  4. Android 客户端与服务器端交互实现登录功能

    思路: 安卓客户端输入账号和密码,使用 okHttp 向服务器端发送请求并传递输入的账号和密码,服务器端的登录接口查询数据库,判断是否能登录成功,然后返回给客户端JSON字符串,客户端使用Gson解析 ...

  5. 完成登录功能,用session记住用户名

    登录功能完成: js:设置return html:设置 form input οnclick="return fnLogin()" py: @app.route设置methods ...

  6. html登录后记住用户名,完成登录功能,用session记住用户名

    登录功能完成: 1.js:设置return function fnLogin() { var oUname=document.getElementById("uname"); va ...

  7. 作业26-完成登录功能,用session记住用户名

    登录功能完成: js:设置return html:设置 form input session: 从`flask`中导入`session` 设置`SECRET_KEY` 操作字典一样操作`session ...

  8. Android复习05【网络编程---WebView获取文章信息、保存用户名与密码、设置菜单样式、收藏文章列表】

    2020-04-02-星期四[源码可私聊我,QQ:386335886] 写篇文章不容易,点个赞再走吧,求求了~  目   录 网络访问-思维导图 玩Android网站---查看登录Cookie 适配器 ...

  9. android在哪存储当前用户名和密码,Android实战教程第七篇之如何在内存中存储用户名和密码...

    本文实例为大家分享了Android内存中存储用户名和密码的方法,供大家参考,具体内容如下 首先是配置文件: xmlns:tools="http://schemas.android.com/t ...

最新文章

  1. 三个变量互换值_02-Python基础知识学习-------Python变量
  2. 解决jquery版本冲突问题
  3. LocalDB 静默安装
  4. MobX 上手指南,写 Vue 的感觉?
  5. Matlab矩阵的拼接
  6. ZooKeeper启动报错 JAVA_HOME is incorrectly set
  7. 60秒一口Python:147个demo,助你从新手小白步步进阶编程高手,赶紧收藏!!
  8. 南大cssci期刊目录_最新版CSSCI管理学和经济学来源期刊目录(20192020)及增减变化!【南大核心】...
  9. HTML/CSS/JavaScript学习笔记【持续更新】
  10. 高阶台式计算机零组件,2010年电脑旺季!零组件缺DDR3封测紧
  11. python搭建博客项目思路_Django项目——Blog简易开发入门
  12. java中输出5个数_编写一个程序,要求用户输入5个数字,并输出这些数字中最大的数字和这些数字中最小的数字...
  13. 给服务器mongodb设置权限_认识 MongoDB
  14. 一步步学习SPD2010--第九章节--使用可重用工作流和工作流表单(13)--修改任务表单...
  15. C#中virtual与abstract的区别
  16. Red Hat 5.6-64位使用yum升级PHP
  17. react-踩坑记录——swiper报错!
  18. 【随笔】TongWeb 常见报错
  19. 网页自动跳转 5种方法
  20. 成功实施ERP的规范流程

热门文章

  1. PageHelper 使用 ThreadLocal 的线程复用问题
  2. Thread.sleep(0):线程休眠0秒有什么意义!
  3. 淘宝服务端高并发分布式架构演进之路
  4. SpringBoot第十五篇:Springboot整合RabbitMQ
  5. 在ViT、MLP-Mixer等进行4800多次实验,谷歌发现大规模预训练存在瓶颈
  6. 高校10余位博士抱着孩子参加授位仪式萌翻全场!科研人抱娃毕业成趋势?
  7. 【干货】Github标星1.2K,Visual Transformer 最全最新资源,包含期刊、顶会论文
  8. 训练时间和参数量百倍降低,直接使用标签进行预测,性能竟超GNN
  9. Keras vs PyTorch,哪一个更适合做深度学习?
  10. 轻松一刻:程序员的工作状态