2022新 穿山甲广告 百度青藤 去除教程 安卓APK去广告 通用教程 杂七杂八的教程

查看 143|回复 11
作者:芽衣   
本次教程以“七猫免费小说6.12”为例,毕竟这软件太经典了,广告家族的典范。还有一款是米读小说,不过去年被工信部点名是流氓软件了,广告可不是一般的多,而且违规获取用户隐私,广告是真是假也不知道。
时过境迁,广告sdk相比以往稍有改变,不过大体思路都是一样的,最简单的就是去看开发文档,基本上不需要再自己另外单独分析。像国外的广告或者自己插入的广告就需要通过布局ID、联网日志、线程分析找到广告老巢了。

建议软件
1、MT管理器
比较简单,适合新手,不适合小白。可以去掉一些没有防护,或者防护比较弱的广告。

七猫免费小说so自带签名校验,校验大写签名SHA1,目标libcommon-encryption
checkSignUseApplicationPackageManager
函数,相关代码如下:
ARM汇编:
.text:0000DD58 ; ---------------------------------------------------------------------------
.text:0000DD58
.text:0000DD58 loc_DD58                                ; CODE XREF: checkSignUseApplicationPackageManager(_JNIEnv *)+458↑j
.text:0000DD58                 MOVS            R0, #0  ; 初始化
.text:0000DD5A                 MOV             R1, R10
.text:0000DD5C                 STRB            R0, [R6,R4] ; r0地址的数据写入r6+r4
.text:0000DD5E                 LDR.W           R0, [R11] ; r11数据写入r0
.text:0000DD62                 LDR             R2, [R0,#0x5C]
.text:0000DD64                 MOV             R0, R11
.text:0000DD66                 BLX             R2      ; 调用r2函数
.text:0000DD68                 LDR             R1, =(a846bb6e12205a3 - 0xDD70) ; 这是保存在so的正确值
.text:0000DD6A                 MOV             R0, R6  ; r6=s1,r6为读取到的实际值
.text:0000DD6C                 ADD             R1, PC  ; "846BB6E12205A3245D1E78C934EDA27EA02D5BD"...
.text:0000DD6E                 BLX             strcmp  ; r0、r1用于参数传递,传入到strcmp函数中
.text:0000DD72                 MOV             R4, R0  ; 函数返回值为r0,r0的值放入r4暂存
.text:0000DD74                 MOV             R0, R6  ; void *
.text:0000DD76                 BLX             j__ZdaPv ; operator delete[](void *)
.text:0000DD7A                 CMP             R4, #0  ; 比较r4的值是否为0
.text:0000DD7C                 BEQ.W           loc_DC2E ; 相等跳转指令
.text:0000DD80                 LDR             R1, =(aSignCheckSha1E - 0xDD86) ; "sign_check_sha1_error"
.text:0000DD82                 ADD             R1, PC  ; 不等则运行到这里,报错
.text:0000DD84                 B               loc_DDD8
.text:0000DD86 ; ---------------------------------------------------------------------------
伪代码:
v60[2 * v57] = 0;
env->functions->DeleteLocalRef(env, v56);
v73 = strcmp(v60, "846BB6E12205A3245D1E78C934EDA27EA02D5BD5");
operator delete[](v60);
if ( v73 )
{
v74 = "sign_check_sha1_error";
LABEL_67:
throwException(env, v74);
return 0;
}
如果直接签名就安装的话,会无法连网。解决方法是用MT管理器的一键HOOK,或者把sha1改成自己的。如果修改so汇编,把ADD R1, PC改成MOV R1,R6即可。
除了签名校验,还有一个是包名校验。因为广告一般要读取包名的,如果包名不对会影响到广告投放。改包名能不能去广告,我还没试,有兴趣的可以试一下。
check_package_name_valid
函数是包名校验。
ARM汇编:
.text:0000D620
.text:0000D620 ; =============== S U B R O U T I N E =======================================
.text:0000D620
.text:0000D620 ; Attributes: bp-based frame
.text:0000D620
.text:0000D620 ; _DWORD check_package_name_valid(void)
.text:0000D620                 EXPORT _Z24check_package_name_validv
.text:0000D620 _Z24check_package_name_validv           ; CODE XREF: check_package_name_valid(void)+8↑j
.text:0000D620                                         ; DATA XREF: LOAD:000027B0↑o ...
.text:0000D620
.text:0000D620 var_14          = -0x14
.text:0000D620
.text:0000D620 ; __unwind {
.text:0000D620                 PUSH            {R4-R7,LR}
.text:0000D622                 ADD             R7, SP, #0xC
.text:0000D624                 PUSH.W          {R11}
.text:0000D628                 SUB             SP, SP, #0x108
.text:0000D62A                 LDR             R0, =(__stack_chk_guard_ptr - 0xD630)
.text:0000D62C                 ADD             R0, PC  ; __stack_chk_guard_ptr
.text:0000D62E                 LDR             R6, [R0] ; __stack_chk_guard
.text:0000D630                 LDR             R0, [R6]
.text:0000D632                 STR             R0, [SP,#0x118+var_14]
.text:0000D634                 BLX             getpid  ; 获取进程pid
.text:0000D638                 MOV             R5, SP  ;栈顶指针
.text:0000D63A                 MOV             R4, R0
.text:0000D63C                 MOV             R0, R5
.text:0000D63E                 MOV.W           R1, #0x100
.text:0000D642                 BLX             __aeabi_memclr8
.text:0000D646                 MOV             R0, R4  ; int
.text:0000D648                 MOV             R1, R5  ; char *
.text:0000D64A                 BLX             j__Z14getPackageNameiPc ; 使用/proc/%d/cmdline
.text:0000D64E                 CMP             R0, #1
.text:0000D650                 BLT             loc_D660
.text:0000D652                 LDR             R1, =(aComKmxsReader - 0xD65C) ; "com.kmxs.reader"
.text:0000D654                 MOV             R0, SP  ; s1
.text:0000D656                 MOVS            R2, #0x10 ; 对比16个字符串,最后一个是00,实际字符串个数为16-1
.text:0000D658                 ADD             R1, PC  ; "com.kmxs.reader"
.text:0000D65A                 BLX             memcmp
.text:0000D65E                 CBZ             R0, loc_D664 ; 条件跳转指令
.text:0000D660
.text:0000D660 loc_D660                                ; CODE XREF: check_package_name_valid(void)+30↑j
.text:0000D660                 MOVS            R0, #0  ; 输出结果为0,一般为假
.text:0000D662                 B               loc_D666
.text:0000D664 ; ---------------------------------------------------------------------------
.text:0000D664
.text:0000D664 loc_D664                                ; CODE XREF: check_package_name_valid(void)+3E↑j
.text:0000D664                 MOVS            R0, #1  ; 输出结果为1,一般为真
.text:0000D666
.text:0000D666 loc_D666                                ; CODE XREF: check_package_name_valid(void)+42↑j
.text:0000D666                 LDR             R1, [R6]
.text:0000D668                 LDR             R2, [SP,#0x118+var_14]
.text:0000D66A                 SUBS            R1, R1, R2
.text:0000D66C                 ITTT EQ
.text:0000D66E                 ADDEQ           SP, SP, #0x108
.text:0000D670                 POPEQ.W         {R11}
.text:0000D674                 POPEQ           {R4-R7,PC}
.text:0000D676                 BLX             __stack_chk_fail
.text:0000D676 ; End of function check_package_name_valid(void)
.text:0000D676
.text:0000D676 ; ---------------------------------------------------------------------------
.text:0000D67A                 ALIGN 4
.text:0000D67C off_D67C        DCD __stack_chk_guard_ptr - 0xD630
.text:0000D67C                                         ; DATA XREF: check_package_name_valid(void)+A↑r
.text:0000D680 off_D680        DCD aComKmxsReader - 0xD65C
.text:0000D680                                         ; DATA XREF: check_package_name_valid(void)+32↑r
.text:0000D680 ; } // starts at D620                   ; "com.kmxs.reader"
伪代码:
bool check_package_name_valid(void)         //类型为布尔
{
  int v0; // r4
  char v2[260]; // [sp+0h] [bp-118h] BYREF
  v0 = getpid();
  memset(v2, 0, 0x100u);
  return getPackageName(v0, v2) >= 1 && !strcmp(v2, "com.kmxs.reader");
}
so反调试检测TracerPid一般也是和七猫小说一样用
/proc/%d/cmdline
,这是非常方便的。
C++举例:
#include
#include
#include
#include
void check(){
    const int bufsize = 1024;
    char filename[bufsize];
    char line[bufsize];
    char name[bufsize];
    char nameline[bufsize];
    int pid = getpid();
    sprintf(filename, "/proc/%d/status", pid);
    FILE *fd;
    fd = fopen(filename, "r");    //“r”为读取,常见的dex校验要有这个
    if (fd != nullptr)
        while (fgets(line, bufsize, fd))
            if (strstr(line, "TracerPid") != nullptr) {    //被调试的时候不为0
                int statue;
                statue = atoi(&line[10]);
                if (statue != 0) {
                    sprintf(name, "/proc/%d/cmdline", statue);
                    FILE *fdname;
                    fdname = fopen(name, "r");
                    if (fdname != nullptr)
                        while (fgets(nameline, bufsize, fdname))
                            if (strstr(nameline, "android_server") != nullptr) {    //这是ida调试的文件
                                pthread_kill(pid, 9);
                            }
                    fclose(fdname);
                }
            }
    fclose(fd);
}


1.png (215.79 KB, 下载次数: 0)
下载附件
2022-1-8 22:35 上传

可以利用AS编译成so查看arm汇编,必要时是可以patch汇编进去的。之前我出过一个教程是拷贝寄存器的字符串,实际上就是利用AS编译C++进行指针操作。


333.jpg (20.3 KB, 下载次数: 1)
下载附件
2022-1-8 22:45 上传

(为什么MD有一段汇编是鸭绿色的)

首先是新版穿山甲广告,看一下现在如何修改。之前的教程直接查找dex的字符串【管理员】好像已经不管用了,因为里面已经没有穿山甲的相关代码了。查看开发文档,实际上广告放在了安装包的assets目录下。


1.png (46.8 KB, 下载次数: 1)
下载附件
2022-1-8 22:49 上传

如上图,这个md5是一个apk文件,用winrar打开后是apk的结构。里面的dex就是广告sdk。搜了一下字符串,果然还是熟悉的3个【管理员】。因为他已经单独分离出来了,所以直接删掉这个安装包就好了。
AndroidManifest
中也有不少腾讯广告的权限。
权限列表:
[Asm] 纯文本查看 复制代码
        
        
        
        
            
        
        
            
        
        
        
        
        
        
        
        
以上这些权限全删。然后assets目录下的
gdt_plugin文件夹、bdxadsdk.jar、39285EFA.dex
也全部删掉。
修改完毕后重新安装,现在还有个广告是百度的青藤。


1.png (360.85 KB, 下载次数: 1)
下载附件
2022-1-8 23:10 上传

和以往稍有不同,不过都大同小异。反编译dex,百度广告sdk一般在com/baidu/mobads/sdk,广告sdk混淆后会导致异常,所以一般来说这些广告文件都是固定的目录,基本上不会变。百度广告有个类名叫做
SplashAd
,翻译过来就是开屏广告,位于com/baidu/mobads/sdk/api/SplashAd。进入后找到.method public final load()V和.method public loadAndShow(Landroid/view/ViewGroup;)V。
loadAndShow的源码:
public void loadAndShow(ViewGroup viewGroup) {
    if (viewGroup == null) {
      SplashAdListener splashAdListener = this.mListener;
    if (splashAdListener != null) {
      splashAdListener.onAdFailed("传入容器不可以为空");
     }
    } else if (this.mIsAdaptiveSplashAd) {
    SplashAdListener splashAdListener2 = this.mListener;
    if (splashAdListener2 != null) {
        splashAdListener2.onAdFailed("使用自适应开屏广告能力, 需要使用showWithBottomView方法并传入合适尺寸的底部logo");
   }
} else {
   addZeroPxSurfaceViewAvoidBlink(viewGroup, this.mContext);
   bz bzVar = new bz(this.mContext);
   bzVar.a(new 3(this, bzVar));
   bzVar.setLayoutParams(new ViewGroup.LayoutParams(-1, -1));
   viewGroup.addView(bzVar);
  }
}
loadAndShow翻译过来就是加载和展示。去广告一般的做法就是代码全删,load()V和loadAndShow(Landroid/view/ViewGroup;)V直接return-void就可以了,不过我习惯是先查看这些代码调用了哪些方法,把这些方法删了再清空。


1.png (57.88 KB, 下载次数: 1)
下载附件
2022-1-9 10:24 上传

那么这样开屏广告就不见了。虽然去掉了开屏广告,但是阅读页的底部还是有广告横幅,这样又要去翻一遍代码清除了。那有没有一遍过的方法呢?有。
早些时候我发过一个去广告的教程,是搜索方法名addEventListener,现在也是可以适用的,不过路径稍稍有些改变。addEventListener是什么函数有兴趣的可以自己百度。
dex反编译后直接搜索百度sdk的代码【addEventListener】,有很多个结果。


1.png (86.33 KB, 下载次数: 0)
下载附件
2022-1-9 10:51 上传

红框的几个类名是广告联网的老巢,七猫小说的话n()V直接返回void就能去掉开屏广告和阅读页底部的横幅广告了。为了保险起见,其它的也应该都全部删掉。去掉广告后有些地方有广告布局,怎么修改这些布局之前出过教程,这里就不再重复一次了。

除此之外,在 主页→我的 还有个“抽大奖”的图标。我实在想不通为什么要在这里设计一个图标,横幅已经有个入口了,为啥还要另外搞一个,虽然叫幸运大转盘。这是怕别人不识字吗?


1.png (87.37 KB, 下载次数: 0)
下载附件
2022-1-9 12:03 上传

根据布局名称,home_float_ad_layout是显示抽大奖的id。dex里的值为0x7f0903a3,搜索它,定位到com/kmxs/reader/home/view/HomeScreenPopupView,把k(Landroid/view/View;)V这个方法的代码全删即可去掉那个烦人的图标。


1.png (45.09 KB, 下载次数: 0)
下载附件
2022-1-9 12:10 上传

广告, 下载次数

落雨碎江南   



chuanshanjia.png (378.16 KB, 下载次数: 0)
下载附件
2022-1-10 09:49 上传

[color=]虎虎生威,新年快乐!
不搭落俗笑忘书   

值得学习!
芽衣
OP
  


wushidi 发表于 2022-1-31 21:33
穿山甲那个不能直接删,还是需要像以前一样改,不然有的软件第二次打开会卡启动屏(比如实用工具箱

卡屏需要分析日志查看代码,是否有检测文件的行为,删肯定是可以删。
bestwars   

学习了 感谢分享~~
潋天堂   

来学习来了,表示看不懂
Luck_MC   

顶一下大佬
212lb   

感谢大佬 很不错的案例
gunanyi   

感谢大佬分享
慵懒丶L先森   

感谢分享,干货满满的一篇去广告的思路教程文章
您需要登录后才可以回帖 登录 | 立即注册