应客户需求,今天来研究下tiktok的一些算法风控和视频播放量检测的问题。以安卓版为例,这里我们用的是tiktok 25.9.4的较新版本
一、抓包预准备
抓包对于绝大多数海外tt玩家是一件比较头疼的事。android的,网络通信协议绕不过去,好不容易xposed能搞定的绕过去了,发现手机参数搞不定,不展示大陆区内容,直接黑屏。ios的改改手机参数倒是能用,然鹅,新系统新版本一律不让抓包。
对此,笔者提供2个目前来看最完美的解决方案“思路”,android的so魔改和ios的升级策略,可以避开国区检测,也可以避开通讯协议检测。so魔改涉及的东西太多,包括jada逆向、ida反编译、adb操作。大致跟各位分享下过程:
android:使用重编译的apk,加上修改的libsscronet.so,可完美避开检测和断网
ios:登录账号后,升级ipa的策略对于抓包来说,可直接通过缓存证书无视网络检测
二、抓包进行时
1、风控算法
(1)设备注册算法
跟国内某音的设备算法不一样。某音再某些接口对设备的要求极高,得正确加密register接口+点击确认接口+活动范库接口+日志或者监控接口+配置接口+激活策略之一,才能做一些比较高端的操作(播放、点赞、关注等,采集之类的接口可仅保留头尾策略即可),而tiktok相对简洁,只需要正确加密register接口+mac绑定+google频道绑定+激活策略之一即可,相比流程少了很多

{
'device_id': 7165349508607477253,
'install_id': 7165350779095746309
}
(2)加密算法
早期的加密算法只有x-gorgon和x-khronos两个核心参数,新版本加上了x-argus和x-ladon,并且在jadx里面通过关键字已经无法定位到算法入口了。对于绝大部分的接口,其实可以不需要这两个参数,比如feed、视频post、search等,但是user、stats、follow、digg之类的是需要新的加密参数的

{
'x-gorgon': '0404009200006554a694efece28b9e104bd2b035e5534edb1039',
'x-khronos': '1668316731',
'x-ladon': '3ZUzVd9TsVZQCYAqzNTkcjcz/7VFZsvgPfl/euzI2zqogVdX',
'x-argus': 'Sk1EW3Y8M+z+iSOS1j3+TvvcbwKOpgxMksDXdntgvzV6bNlX77GQhPewX1FqhUb/ufeSl8IEvSUe1GkRYiwXyPVaWbmMSL0rYcWuIL+3gHV0J2SPjhLBQsG8qlDwn8CHBWbrS5ensYnQw0n3wTVcX65g9M0tQnTSTpZRcJa+JL5lRxQx5ru2IHpaA0Be39O5ZNLqxKayJQ2j7DOfhrXMSI/kIk/xWDQUw9HKEzLcQIi+5eIV8g2lhu9UCsd8+gklnA2sgcJk167lREK0laBMVV0h'
}
{
"log_pb": {
"impr_id": "202211130520592109A770F334650DD710"
},
"status_code": 0,
"user": {
"ad_virtual": false,
"avatar_medium": {
"url_list": [
"https://p16-sign-sg.tiktokcdn.com/tos-alisg-avt-0068/9eda8ac4a89de8afa23fdefe99f42ac2~tplv-tiktok-shrink:282:282.jpeg?x-expires\u003d1668337200\u0026x-signature\u003dB3vl0lpZN0Dh5JpXH2VHAC2Upbs%3D\u0026s\u003dPACK_GO_API\u0026se\u003dfalse\u0026sh\u003d282_282\u0026sc\u003davatar\u0026l\u003d202211130520592109A770F334650DD710",
"https://p16-sign-sg.tiktokcdn.com/aweme/720x720/tos-alisg-avt-0068/9eda8ac4a89de8afa23fdefe99f42ac2.webp?x-expires\u003d1668488400\u0026x-signature\u003dG2MwwtSHLG707Id9hXGJmADuil8%3D",
"https://p16-sign-sg.tiktokcdn.com/aweme/720x720/tos-alisg-avt-0068/9eda8ac4a89de8afa23fdefe99f42ac2.jpeg?x-expires\u003d1668488400\u0026x-signature\u003dd1hTbqRFLjHBuU8IHGWBzJ3f%2BDk%3D"
],
"uri": "tos-alisg-avt-0068/9eda8ac4a89de8afa23fdefe99f42ac2"
},
"avatar_300x300": {
"uri": "tos-alisg-avt-0068/9eda8ac4a89de8afa23fdefe99f42ac2",
"url_list": [
"https://p16-sign-sg.tiktokcdn.com/tos-alisg-avt-0068/9eda8ac4a89de8afa23fdefe99f42ac2~tplv-tiktok-shrink:282:282.jpeg?x-expires\u003d1668337200\u0026x-signature\u003dB3vl0lpZN0Dh5JpXH2VHAC2Upbs%3D\u0026s\u003dPACK_GO_API\u0026se\u003dfalse\u0026sh\u003d282_282\u0026sc\u003davatar\u0026l\u003d202211130520592109A770F334650DD710",
"https://p16-sign-sg.tiktokcdn.com/tos-alisg-avt-0068/9eda8ac4a89de8afa23fdefe99f42ac2~c5_300x300.webp?x-expires\u003d1668488400\u0026x-signature\u003dIbM9MHdGvc7WW0Jast4uZoCbcNQ%3D",
"https://p16-sign-sg.tiktokcdn.com/tos-alisg-avt-0068/9eda8ac4a89de8afa23fdefe99f42ac2~c5_300x300.jpeg?x-expires\u003d1668488400\u0026x-signature\u003dHv3J8TK0fD2kGORSlh%2FioTMcO%2F0%3D"
]
},
"avatar_168x168": {
"url_list": [
"https://p16-sign-sg.tiktokcdn.com/tos-alisg-avt-0068/9eda8ac4a89de8afa23fdefe99f42ac2~tplv-tiktok-shrink:282:282.jpeg?x-expires\u003d1668337200\u0026x-signature\u003dB3vl0lpZN0Dh5JpXH2VHAC2Upbs%3D\u0026s\u003dPACK_GO_API\u0026se\u003dfalse\u0026sh\u003d282_282\u0026sc\u003davatar\u0026l\u003d202211130520592109A770F334650DD710",
"https://p16-sign-sg.tiktokcdn.com/tos-alisg-avt-0068/9eda8ac4a89de8afa23fdefe99f42ac2~c5_168x168.webp?x-expires\u003d1668488400\u0026x-signature\u003d2zVQsGCz38Lng1sajUTxzogN%2FSk%3D",
"https://p16-sign-sg.tiktokcdn.com/tos-alisg-avt-0068/9eda8ac4a89de8afa23fdefe99f42ac2~c5_168x168.jpeg?x-expires\u003d1668488400\u0026x-signature\u003dL3f1peRZhFCpeNGHNKsb7HaO28w%3D"
],
"uri": "tos-alisg-avt-0068/9eda8ac4a89de8afa23fdefe99f42ac2"
},
"message_chat_entry": false,
"recommend_reason_relation": "",
"profile_tab_type": 0,
"is_star": false,
"twitter_name": "",
"mplatform_followers_count": 0,
"follower_count": 4549,
"supporting_ngo": {},
"is_effect_artist": false,
"account_type": 3,
"avatar_larger": {
"url_list": [
"https://p16-sign-sg.tiktokcdn.com/aweme/1080x1080/tos-alisg-avt-0068/9eda8ac4a89de8afa23fdefe99f42ac2.webp?x-expires\u003d1668488400\u0026x-signature\u003dRdSqFnSIdUOdpRzJp0Cay32Lphc%3D",
"https://p16-sign-sg.tiktokcdn.com/aweme/1080x1080/tos-alisg-avt-0068/9eda8ac4a89de8afa23fdefe99f42ac2.jpeg?x-expires\u003d1668488400\u0026x-signature\u003dxdXdDGH7%2BCceLYN0Miuxs%2BsMlEc%3D"
],
"uri": "tos-alisg-avt-0068/9eda8ac4a89de8afa23fdefe99f42ac2"
},
"commerce_user_info": {
"ad_experience_entry": true,
"ad_experience_text": "Ads",
"ad_revenue_rits": []
},
"is_blocked": false,
"twitter_id": "",
"qa_status": 0,
"video_icon": {
"uri": "",
"url_list": []
},
"verification_type": 0,
"enterprise_verify_reason": "",
"sec_uid": "MS4wLjABAAAAzVo22dPcsRtqwQ1zBz1pwFUg0dm_V7XdfWAjfUfcMvJuAS6HrFufw48PIzSYOYIT",
"with_commerce_entry": false,
"category": "Personal Blog",
"watch_status": false,
"with_new_goods": false,
"aweme_count": 127,
"commerce_user_level": 0,
"apple_account": 0,
"unique_id": "monirul1382",
"favoriting_count": 0,
"total_favorited": 21040,
"follower_status": 0,
"following_count": 7259,
"youtube_channel_id": "",
"ins_id": "",
"live_push_notification_status": 2,
"nudge_guide_info": {
"guide_time": 0,
"show_guide": false
},
"tab_settings": {
"private_tab": {
"show_private_tab": false,
"private_tab_style": 1
}
},
"follow_status": 0,
"youtube_channel_title": "",
"nickname": "p.k",
"share_info": {
"share_desc": "Check out p.k! #TikTok",
"share_image_url": {
"uri": "tos-alisg-p-0037/d1a5001fa23541b2ab34fcd17f2cc3fe_1668310237",
"url_list": [
"https://p16-sign-sg.tiktokcdn.com/obj/tos-alisg-p-0037/d1a5001fa23541b2ab34fcd17f2cc3fe_1668310237?x-expires\u003d1668337200\u0026x-signature\u003dUDs6%2FX8aiEIP7QzD83pSGn%2FBKg8%3D"
]
},
"bool_persist": 1,
"share_title_myself": "This TikTok app is soooooo fun! Follow me @monirul1382 on TikTok and check out my videos!",
"share_url": "https://www.tiktok.com/@monirul1382?_r\u003d1\u0026_d\u003de4m574m23g7672\u0026language\u003den\u0026sec_uid\u003dMS4wLjABAAAAzVo22dPcsRtqwQ1zBz1pwFUg0dm_V7XdfWAjfUfcMvJuAS6HrFufw48PIzSYOYIT\u0026share_author_id\u003d6927144936274412545\u0026source\u003dh5_m",
"share_title_other": "This TikTok user is really cool. Follow @monirul1382 on TikTok and check out those amazing videos!",
"share_title": "Join TikTok and see what I\u0027ve been up to!",
"share_desc_info": "TikTok: Make Every Second Count"
},
"is_block": false,
"short_id": "0",
"with_commerce_enterprise_tab_entry": false,
"secret": 0,
"avatar_thumb": {
"uri": "tos-alisg-avt-0068/9eda8ac4a89de8afa23fdefe99f42ac2",
"url_list": [
"https://p16-sign-sg.tiktokcdn.com/tos-alisg-avt-0068/9eda8ac4a89de8afa23fdefe99f42ac2~tplv-tiktok-shrink:282:282.jpeg?x-expires\u003d1668337200\u0026x-signature\u003dB3vl0lpZN0Dh5JpXH2VHAC2Upbs%3D\u0026s\u003dPACK_GO_API\u0026se\u003dfalse\u0026sh\u003d282_282\u0026sc\u003davatar\u0026l\u003d202211130520592109A770F334650DD710",
"https://p16-sign-sg.tiktokcdn.com/aweme/100x100/tos-alisg-avt-0068/9eda8ac4a89de8afa23fdefe99f42ac2.webp?x-expires\u003d1668488400\u0026x-signature\u003dfNikR946UDcPIUj2JDqbZIEZWiY%3D",
"https://p16-sign-sg.tiktokcdn.com/aweme/100x100/tos-alisg-avt-0068/9eda8ac4a89de8afa23fdefe99f42ac2.jpeg?x-expires\u003d1668488400\u0026x-signature\u003dvqam8wUbb6URwcIekbNdZk0eSwM%3D"
]
},
"signature": "",
"signature_language": "un",
"show_favorite_list": false,
"room_id": 0,
"privacy_setting": {
"following_visibility": 1
},
"live_commerce": false,
"story_status": 0,
"uid": "6927144936274412545",
"biz_account_info": {
"permission_list": [
"001002",
"001003",
"002001",
"002002",
"004001",
"004006",
"007001",
"007003",
"007004",
"008001",
"010001",
"010002",
"015001",
"015002"
],
"leads_gen": {
"action_name": "",
"page_id": 0,
"business_data": "",
"schema_url": "",
"has_leads_gen": false
}
},
"custom_verify": "",
"original_musician": {
"music_count": 0,
"music_used_count": 0,
"digg_count": 0
},
"forward_count": 0
},
"extra": {
"now": 1668316859000,
"fatal_item_ids": [],
"logid": "202211130520592109A770F334650DD710"
}
}
2、风控策略
ok,说了那么多,我们开始研究播放量的问题,我们找了一个冷门的网红、一个冷门的视频来测试:Tiktok视频链接
(我也不知道这老哥是谁)

原始播放为206,手机打开这个视频,看了一会,发现播放量变成 207

抓包发现api为:
https://api26-normal-hl.amemv.com/aweme/v1/aweme/stats/?开头
然后再次请求该api,发现播放量变成208

再用我们生成的设备去请求
{'device_id': 7165366997055489542, 'install_id': 7165368214708061957}
{'X-Gorgon': '040460910000b4fe5e5c679b1a5aca8d0565b3de7aeac3798f6d', 'X-Khronos': '1668317354', 'X-Ladon': 'tLkHbGCrhmcvTPmlKHGkTta6Ti/YLihAsfKVgFEWFRiQV9YD', 'X-Argus': 'sCyeoOH45ibTP/CRUzAMJV1RJ337mffXnKw7lg4DOesS3htUSiUzUQy8i/csmSpKh/1ZqlycbmpLBsQEcHhXAY/jvNc6LkhmqBjn6xrYmSXrqL3JCb09o04fAaXQesxY2PBU3+JeBznMpjU1Gd7mRSEYEIXomcoH/CAyLAaoCcBGvB+DMH3xRm1TKLwj0/qorwsi6iO5x8w3t9MKpj1TX9raqMDo591OBvpEXG29XJR1gVd4bpgJeP6Ckc01p+2hfm8gpvKy1Y7MDeYXo6UDFQA0'}
post参数
pre_item_playtime=&first_install_time=1598329642&item_id=7165147705835015461&follow_status=0&sync_origin=false&follower_status=0&hide_mix_entry=true&action_time= 1668317412&tab_type=0&pre_hot_sentence=&play_delta=1&aweme_type=0&pre_item_id=
ok变成209

咱们新生成一个新的设备,联系请求100次,看下效果

掌声!!!!!
三、总结
1、经测试,要想短时间大量上,需要高并发+高频率切换device_id,要想花费少量的device_id,需要低频请求
2、高并发可以短时间单个设备完成多则12W的量,少则几千
3、风控为两种:ip和设备。好的设备上量多,好的ip上量多
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub
我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search
由于fast-stemmer的问题,我很难安装我想要的任何rubygem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=
当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。
导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri
首先回顾一下拉格朗日定理的内容:函数f(x)是在闭区间[a,b]上连续、开区间(a,b)上可导的函数,那么至少存在一个,使得:通过这个表达式我们可以知道,f(x)是函数的主体,a和b可以看作是主体函数f(x)中所取的两个值。那么可以有, 也就意味着我们可以用来替换 这种替换可以用在求某些多项式差的极限中。方法: 外层函数f(x)是一致的,并且h(x)和g(x)是等价无穷小。此时,利用拉格朗日定理,将原式替换为 ,再进行求解,往往会省去复合函数求极限的很多麻烦。使用要注意:1.要先找到主体函数f(x),即外层函数必须相同。2.f(x)找到后,复合部分是等价无穷小。3.要满足作差的形式。如果是加